-
Notifications
You must be signed in to change notification settings - Fork 15.4k
[acc] Make getDominatingDataClauses a public OpenACC utility #170549
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
@llvm/pr-subscribers-openacc @llvm/pr-subscribers-mlir-openacc Author: None (nvptm) ChangesMoving getDominatingDataClauses to OpenACCUtils allows reuse. Full diff: https://github.com/llvm/llvm-project/pull/170549.diff 3 Files Affected:
diff --git a/mlir/include/mlir/Dialect/OpenACC/OpenACCUtils.h b/mlir/include/mlir/Dialect/OpenACC/OpenACCUtils.h
index 2852e0917c3fb..de4f1b0298767 100644
--- a/mlir/include/mlir/Dialect/OpenACC/OpenACCUtils.h
+++ b/mlir/include/mlir/Dialect/OpenACC/OpenACCUtils.h
@@ -10,8 +10,13 @@
#define MLIR_DIALECT_OPENACC_OPENACCUTILS_H_
#include "mlir/Dialect/OpenACC/OpenACC.h"
+#include "llvm/ADT/SmallVector.h"
namespace mlir {
+class DominanceInfo;
+class PostDominanceInfo;
+class Value;
+class Operation;
namespace acc {
/// Used to obtain the enclosing compute construct operation that contains
@@ -62,6 +67,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
diff --git a/mlir/lib/Dialect/OpenACC/Transforms/ACCImplicitData.cpp b/mlir/lib/Dialect/OpenACC/Transforms/ACCImplicitData.cpp
index 8bdde7c9691bf..67cdf100a7a48 100644
--- a/mlir/lib/Dialect/OpenACC/Transforms/ACCImplicitData.cpp
+++ b/mlir/lib/Dialect/OpenACC/Transforms/ACCImplicitData.cpp
@@ -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>
@@ -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,
@@ -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,
diff --git a/mlir/lib/Dialect/OpenACC/Utils/OpenACCUtils.cpp b/mlir/lib/Dialect/OpenACC/Utils/OpenACCUtils.cpp
index aebc248e02ea0..7f27b4495045f 100644
--- a/mlir/lib/Dialect/OpenACC/Utils/OpenACCUtils.cpp
+++ b/mlir/lib/Dialect/OpenACC/Utils/OpenACCUtils.cpp
@@ -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"
@@ -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();
+}
|
razvanlupusoru
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you!
Please add some unit tests in mlir/unittests/Dialect/OpenACC/OpenACCUtilsTest.cpp
3c82411 to
9956814
Compare
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
razvanlupusoru
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Outstanding work and testing! Thank you
Moving getDominatingDataClauses to OpenACCUtils allows reuse.