Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions mlir/include/mlir/Dialect/OpenACC/OpenACCUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@
#define MLIR_DIALECT_OPENACC_OPENACCUTILS_H_

#include "mlir/Dialect/OpenACC/OpenACC.h"
#include "llvm/ADT/SmallVector.h"

namespace mlir {
class DominanceInfo;
class PostDominanceInfo;
namespace acc {

/// Used to obtain the enclosing compute construct operation that contains
Expand Down Expand Up @@ -62,6 +65,22 @@ mlir::Value getBaseEntity(mlir::Value val);
bool isValidSymbolUse(mlir::Operation *user, mlir::SymbolRefAttr symbol,
mlir::Operation **definingOpPtr = nullptr);

/// Collects all data clauses that dominate the compute construct.
/// This includes data clauses from:
/// - The compute construct itself
/// - Enclosing data constructs
/// - Applicable declare directives (those that dominate and post-dominate)
/// This is used to determine if a variable is already covered by an existing
/// data clause.
/// \param computeConstructOp The compute construct operation
/// \param domInfo Dominance information
/// \param postDomInfo Post-dominance information
/// \return Vector of data clause values that dominate the compute construct
llvm::SmallVector<mlir::Value>
getDominatingDataClauses(mlir::Operation *computeConstructOp,
mlir::DominanceInfo &domInfo,
mlir::PostDominanceInfo &postDomInfo);

} // namespace acc
} // namespace mlir

Expand Down
66 changes: 4 additions & 62 deletions mlir/lib/Dialect/OpenACC/Transforms/ACCImplicitData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -237,11 +237,6 @@ class ACCImplicitData : public acc::impl::ACCImplicitDataBase<ACCImplicitData> {
void runOnOperation() override;

private:
/// Collects all data clauses that dominate the compute construct.
/// Needed to determine if a variable is already covered by an existing data
/// clause.
SmallVector<Value> getDominatingDataClauses(Operation *computeConstructOp);

/// Looks through the `dominatingDataClauses` to find the original data clause
/// op for an alias. Returns nullptr if no original data clause op is found.
template <typename OpT>
Expand Down Expand Up @@ -300,62 +295,6 @@ static bool isCandidateForImplicitData(Value val, Region &accRegion) {
return true;
}

SmallVector<Value>
ACCImplicitData::getDominatingDataClauses(Operation *computeConstructOp) {
llvm::SmallSetVector<Value, 8> dominatingDataClauses;

llvm::TypeSwitch<Operation *>(computeConstructOp)
.Case<acc::ParallelOp, acc::KernelsOp, acc::SerialOp>([&](auto op) {
for (auto dataClause : op.getDataClauseOperands()) {
dominatingDataClauses.insert(dataClause);
}
})
.Default([](Operation *) {});

// Collect the data clauses from enclosing data constructs.
Operation *currParentOp = computeConstructOp->getParentOp();
while (currParentOp) {
if (isa<acc::DataOp>(currParentOp)) {
for (auto dataClause :
dyn_cast<acc::DataOp>(currParentOp).getDataClauseOperands()) {
dominatingDataClauses.insert(dataClause);
}
}
currParentOp = currParentOp->getParentOp();
}

// Find the enclosing function/subroutine
auto funcOp = computeConstructOp->getParentOfType<FunctionOpInterface>();
if (!funcOp)
return dominatingDataClauses.takeVector();

// Walk the function to find `acc.declare_enter`/`acc.declare_exit` pairs that
// dominate and post-dominate the compute construct and add their data
// clauses to the list.
auto &domInfo = this->getAnalysis<DominanceInfo>();
auto &postDomInfo = this->getAnalysis<PostDominanceInfo>();
funcOp->walk([&](acc::DeclareEnterOp declareEnterOp) {
if (domInfo.dominates(declareEnterOp.getOperation(), computeConstructOp)) {
// Collect all `acc.declare_exit` ops for this token.
SmallVector<acc::DeclareExitOp> exits;
for (auto *user : declareEnterOp.getToken().getUsers())
if (auto declareExit = dyn_cast<acc::DeclareExitOp>(user))
exits.push_back(declareExit);

// Only add clauses if every `acc.declare_exit` op post-dominates the
// compute construct.
if (!exits.empty() && llvm::all_of(exits, [&](acc::DeclareExitOp exitOp) {
return postDomInfo.postDominates(exitOp, computeConstructOp);
})) {
for (auto dataClause : declareEnterOp.getDataClauseOperands())
dominatingDataClauses.insert(dataClause);
}
}
});

return dominatingDataClauses.takeVector();
}

template <typename OpT>
Operation *ACCImplicitData::getOriginalDataClauseOpForAlias(
Value var, OpBuilder &builder, OpT computeConstructOp,
Expand Down Expand Up @@ -775,7 +714,10 @@ void ACCImplicitData::generateImplicitDataOps(
LLVM_DEBUG(llvm::dbgs() << "== Generating clauses for ==\n"
<< computeConstructOp << "\n");
}
auto dominatingDataClauses = getDominatingDataClauses(computeConstructOp);
auto &domInfo = this->getAnalysis<DominanceInfo>();
auto &postDomInfo = this->getAnalysis<PostDominanceInfo>();
auto dominatingDataClauses =
acc::getDominatingDataClauses(computeConstructOp, domInfo, postDomInfo);
for (auto var : candidateVars) {
auto newDataClauseOp = generateDataClauseOpForCandidate(
var, module, builder, computeConstructOp, dominatingDataClauses,
Expand Down
61 changes: 61 additions & 0 deletions mlir/lib/Dialect/OpenACC/Utils/OpenACCUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@
#include "mlir/Dialect/OpenACC/OpenACCUtils.h"

#include "mlir/Dialect/OpenACC/OpenACC.h"
#include "mlir/IR/Dominance.h"
#include "mlir/IR/SymbolTable.h"
#include "mlir/Interfaces/FunctionInterfaces.h"
#include "mlir/Interfaces/ViewLikeInterface.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/TypeSwitch.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/Support/Casting.h"
Expand Down Expand Up @@ -205,3 +207,62 @@ bool mlir::acc::isValidSymbolUse(mlir::Operation *user,
bool hasDeclare = definingOp->hasAttr(mlir::acc::getDeclareAttrName());
return hasDeclare;
}

llvm::SmallVector<mlir::Value>
mlir::acc::getDominatingDataClauses(mlir::Operation *computeConstructOp,
mlir::DominanceInfo &domInfo,
mlir::PostDominanceInfo &postDomInfo) {
llvm::SmallSetVector<mlir::Value, 8> dominatingDataClauses;

llvm::TypeSwitch<mlir::Operation *>(computeConstructOp)
.Case<mlir::acc::ParallelOp, mlir::acc::KernelsOp, mlir::acc::SerialOp>(
[&](auto op) {
for (auto dataClause : op.getDataClauseOperands()) {
dominatingDataClauses.insert(dataClause);
}
})
.Default([](mlir::Operation *) {});

// Collect the data clauses from enclosing data constructs.
mlir::Operation *currParentOp = computeConstructOp->getParentOp();
while (currParentOp) {
if (mlir::isa<mlir::acc::DataOp>(currParentOp)) {
for (auto dataClause : mlir::dyn_cast<mlir::acc::DataOp>(currParentOp)
.getDataClauseOperands()) {
dominatingDataClauses.insert(dataClause);
}
}
currParentOp = currParentOp->getParentOp();
}

// Find the enclosing function/subroutine
auto funcOp =
computeConstructOp->getParentOfType<mlir::FunctionOpInterface>();
if (!funcOp)
return dominatingDataClauses.takeVector();

// Walk the function to find `acc.declare_enter`/`acc.declare_exit` pairs that
// dominate and post-dominate the compute construct and add their data
// clauses to the list.
funcOp->walk([&](mlir::acc::DeclareEnterOp declareEnterOp) {
if (domInfo.dominates(declareEnterOp.getOperation(), computeConstructOp)) {
// Collect all `acc.declare_exit` ops for this token.
llvm::SmallVector<mlir::acc::DeclareExitOp> exits;
for (auto *user : declareEnterOp.getToken().getUsers())
if (auto declareExit = mlir::dyn_cast<mlir::acc::DeclareExitOp>(user))
exits.push_back(declareExit);

// Only add clauses if every `acc.declare_exit` op post-dominates the
// compute construct.
if (!exits.empty() &&
llvm::all_of(exits, [&](mlir::acc::DeclareExitOp exitOp) {
return postDomInfo.postDominates(exitOp, computeConstructOp);
})) {
for (auto dataClause : declareEnterOp.getDataClauseOperands())
dominatingDataClauses.insert(dataClause);
}
}
});

return dominatingDataClauses.takeVector();
}
Loading
Loading