-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[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
base: users/ergawy/convert_locality_specs_to_clauses_2
Are you sure you want to change the base?
[flang][OpenMP] Map basic local
specifiers to private
clauses
#142735
Conversation
@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!
Extends support for locality specifiers in `do concurrent` by supporting data types that need `init` regions. This further unifies the paths taken by the compiler for OpenMP privatization clauses and `do concurrent` locality specifiers.
5647d02
to
fd943c2
Compare
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).
a0c216d
to
62596cd
Compare
fd943c2
to
445db39
Compare
Starts the effort to map
do concurrent
locality specifiers to OpenMP clauses. This PR adds support for basic specifiers (noinit
orcopy
regions yet).