-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[flang][OpenMP] Map basic local
specifiers to private
clauses
#142735
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-llvm-globalisel @llvm/pr-subscribers-flang-fir-hlfir Author: Kareem Ergawy (ergawy) ChangesStarts the effort to map Full diff: https://github.com/llvm/llvm-project/pull/142735.diff 2 Files Affected:
diff --git a/flang/lib/Optimizer/OpenMP/DoConcurrentConversion.cpp b/flang/lib/Optimizer/OpenMP/DoConcurrentConversion.cpp
index 0fdb302fe10ca..283c3052c166c 100644
--- a/flang/lib/Optimizer/OpenMP/DoConcurrentConversion.cpp
+++ b/flang/lib/Optimizer/OpenMP/DoConcurrentConversion.cpp
@@ -7,9 +7,11 @@
//===----------------------------------------------------------------------===//
#include "flang/Optimizer/Builder/FIRBuilder.h"
+#include "flang/Optimizer/Builder/Todo.h"
#include "flang/Optimizer/Dialect/FIROps.h"
#include "flang/Optimizer/OpenMP/Passes.h"
#include "flang/Optimizer/OpenMP/Utils.h"
+#include "flang/Support/OpenMP-utils.h"
#include "mlir/Analysis/SliceAnalysis.h"
#include "mlir/Dialect/OpenMP/OpenMPDialect.h"
#include "mlir/IR/IRMapping.h"
@@ -308,10 +310,47 @@ class DoConcurrentConversion
fir::DoConcurrentLoopOp loop, mlir::IRMapping &mapper,
const mlir::omp::LoopNestOperands &clauseOps,
bool isComposite) const {
+ mlir::omp::WsloopOperands wsloopClauseOps;
+
+ // For `local` (and `local_init`) opernads, emit corresponding `private`
+ // clauses and attach these clauses to the workshare loop.
+ if (!loop.getLocalOperands().empty())
+ for (auto [op, sym, arg] : llvm::zip_equal(
+ loop.getLocalOperands(),
+ loop.getLocalSymsAttr().getAsRange<mlir::SymbolRefAttr>(),
+ loop.getRegionLocalArgs())) {
+ auto localizer = mlir::SymbolTable::lookupNearestSymbolFrom<
+ fir::LocalitySpecifierOp>(loop, sym);
+ if (localizer.getLocalitySpecifierType() ==
+ fir::LocalitySpecifierType::LocalInit)
+ TODO(localizer.getLoc(),
+ "local_init conversion is not supported yet");
+
+ if (!localizer.getInitRegion().empty())
+ TODO(localizer.getLoc(),
+ "non-empty `init` regions are not supported yet");
+
+ auto oldIP = rewriter.saveInsertionPoint();
+ rewriter.setInsertionPointAfter(localizer);
+ auto privatizer = rewriter.create<mlir::omp::PrivateClauseOp>(
+ localizer.getLoc(), sym.getLeafReference().str() + ".omp",
+ localizer.getTypeAttr().getValue(),
+ mlir::omp::DataSharingClauseType::Private);
+ rewriter.restoreInsertionPoint(oldIP);
+
+ wsloopClauseOps.privateVars.push_back(op);
+ wsloopClauseOps.privateSyms.push_back(
+ mlir::SymbolRefAttr::get(privatizer));
+ }
- auto wsloopOp = rewriter.create<mlir::omp::WsloopOp>(loop.getLoc());
+ auto wsloopOp =
+ rewriter.create<mlir::omp::WsloopOp>(loop.getLoc(), wsloopClauseOps);
wsloopOp.setComposite(isComposite);
- rewriter.createBlock(&wsloopOp.getRegion());
+
+ Fortran::common::openmp::EntryBlockArgs wsloopArgs;
+ wsloopArgs.priv.vars = wsloopClauseOps.privateVars;
+ Fortran::common::openmp::genEntryBlock(rewriter, wsloopArgs,
+ wsloopOp.getRegion());
auto loopNestOp =
rewriter.create<mlir::omp::LoopNestOp>(loop.getLoc(), clauseOps);
@@ -324,6 +363,18 @@ class DoConcurrentConversion
rewriter.setInsertionPointToEnd(&loopNestOp.getRegion().back());
rewriter.create<mlir::omp::YieldOp>(loop->getLoc());
+ // `local` region arguments are transferred/cloned from the `do concurrent`
+ // loop to the loopnest op when the region is cloned above. Instead, these
+ // region arguments should be on the workshare loop's region.
+ for (auto [wsloopArg, loopNestArg] :
+ llvm::zip_equal(wsloopOp.getRegion().getArguments(),
+ loopNestOp.getRegion().getArguments().drop_front(
+ clauseOps.loopLowerBounds.size())))
+ rewriter.replaceAllUsesWith(loopNestArg, wsloopArg);
+
+ for (unsigned i = 0; i < loop.getLocalVars().size(); ++i)
+ loopNestOp.getRegion().eraseArgument(clauseOps.loopLowerBounds.size());
+
return loopNestOp;
}
diff --git a/flang/test/Transforms/DoConcurrent/locality_specifiers_simple.mlir b/flang/test/Transforms/DoConcurrent/locality_specifiers_simple.mlir
new file mode 100644
index 0000000000000..160c1df040680
--- /dev/null
+++ b/flang/test/Transforms/DoConcurrent/locality_specifiers_simple.mlir
@@ -0,0 +1,48 @@
+// Tests mapping `local` locality specifier to `private` clauses for a simple
+// case (not `init` or `copy` regions).
+
+// RUN: fir-opt --omp-do-concurrent-conversion="map-to=host" %s | FileCheck %s
+
+fir.local {type = local} @_QFlocal_spec_translationElocal_var_private_f32 : f32
+
+func.func @_QPlocal_spec_translation() {
+ %3 = fir.alloca f32 {bindc_name = "local_var", uniq_name = "_QFlocal_spec_translationElocal_var"}
+ %4:2 = hlfir.declare %3 {uniq_name = "_QFlocal_spec_translationElocal_var"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
+
+ %c4_i32 = arith.constant 4 : index
+ %c11_i32 = arith.constant 11 : index
+ %c1 = arith.constant 1 : index
+
+ fir.do_concurrent {
+ %7 = fir.alloca i32 {bindc_name = "i"}
+ %8:2 = hlfir.declare %7 {uniq_name = "_QFlocal_spec_translationEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+
+ fir.do_concurrent.loop (%arg0) = (%c4_i32) to (%c11_i32) step (%c1)
+ local(@_QFlocal_spec_translationElocal_var_private_f32 %4#0 -> %arg1 : !fir.ref<f32>) {
+ %9 = fir.convert %arg0 : (index) -> i32
+ fir.store %9 to %8#0 : !fir.ref<i32>
+
+ %10:2 = hlfir.declare %arg1 {uniq_name = "_QFlocal_spec_translationElocal_var"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
+ %cst = arith.constant 4.200000e+01 : f32
+ hlfir.assign %cst to %10#0 : f32, !fir.ref<f32>
+ }
+ }
+ return
+}
+
+// CHECK: omp.private {type = private} @[[PRIVATIZER:.*local_spec_translationElocal_var.*.omp]] : f32
+
+// CHECK: func.func @_QPlocal_spec_translation
+// CHECK: %[[LOCAL_VAR:.*]] = fir.alloca f32 {bindc_name = "local_var", {{.*}}}
+// CHECK: %[[LOCAL_VAR_DECL:.*]]:2 = hlfir.declare %[[LOCAL_VAR]]
+// CHECK: omp.parallel {
+// CHECK: omp.wsloop private(@[[PRIVATIZER]] %[[LOCAL_VAR_DECL]]#0 -> %[[LOCAL_ARG:.*]] : !fir.ref<f32>) {
+// CHECK: omp.loop_nest {{.*}} {
+// CHECK: %[[PRIV_DECL:.*]]:2 = hlfir.declare %[[LOCAL_ARG]]
+// CHECK: %[[C42:.*]] = arith.constant
+// CHECK: hlfir.assign %[[C42]] to %[[PRIV_DECL]]#0
+// CHECK: omp.yield
+// CHECK: }
+// CHECK: }
+// CHECK: omp.terminator
+// CHECK: }
|
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.
Looks great!
5647d02
to
fd943c2
Compare
a0c216d
to
62596cd
Compare
fd943c2
to
445db39
Compare
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.
LGTM, maybe fix the typo.
@@ -308,10 +310,47 @@ class DoConcurrentConversion | |||
fir::DoConcurrentLoopOp loop, mlir::IRMapping &mapper, | |||
const mlir::omp::LoopNestOperands &clauseOps, | |||
bool isComposite) const { | |||
mlir::omp::WsloopOperands wsloopClauseOps; | |||
|
|||
// For `local` (and `local_init`) opernads, emit corresponding `private` |
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.
// For `local` (and `local_init`) opernads, emit corresponding `private` | |
// For `local` (and `local_init`) operands, emit corresponding `private` |
445db39
to
baaf8b2
Compare
62596cd
to
b5b0742
Compare
✅ With the latest revision this PR passed the undef deprecator. |
Starts the effort to map `do concurrent` locality specifiers to OpenMP clauses. This PR adds support for basic specifiers (no `init` or `copy` regions yet).
b5b0742
to
f2f4c10
Compare
…vm#142735) Starts the effort to map `do concurrent` locality specifiers to OpenMP clauses. This PR adds support for basic specifiers (no `init` or `copy` regions yet).
…vm#142735) Starts the effort to map `do concurrent` locality specifiers to OpenMP clauses. This PR adds support for basic specifiers (no `init` or `copy` regions yet).
…vm#142735) Starts the effort to map `do concurrent` locality specifiers to OpenMP clauses. This PR adds support for basic specifiers (no `init` or `copy` regions yet).
Starts the effort to map
do concurrent
locality specifiers to OpenMP clauses. This PR adds support for basic specifiers (noinit
orcopy
regions yet).