[flang-commits] [flang] [mlir] [mlir][OpenMP] Model memory effects of omp.section and omp.sections (PR #230167)

via flang-commits flang-commits at lists.llvm.org
Tue Oct 13 02:02:06 PDT 2026


================
@@ -3258,6 +3258,129 @@ LogicalResult SectionsOp::verifyRegions() {
   return success();
 }
 
+/// Return whether all operations in the op's regions are memory-effect-free.
+static bool areRegionsMemoryEffectFree(Operation *op) {
+  for (Region &region : op->getRegions())
+    for (Operation &nestedOp : region.getOps())
+      if (!isMemoryEffectFree(&nestedOp))
+        return false;
+  return true;
+}
+
+/// Model private storage and the effects of referenced privatisation recipes.
+template <typename OpType>
+static void getPrivatisationEffects(
+    OpType op, SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
+  std::optional<ArrayAttr> privateSyms = op.getPrivateSyms();
+  if (!privateSyms)
+    return;
+
+  MutableOperandRange privateVars = op.getPrivateVarsMutable();
+  auto iface = cast<BlockArgOpenMPOpInterface>(op.getOperation());
+  Block::BlockArgListType privateArgs = iface.getPrivateBlockArgs();
+  for (auto entry : llvm::zip_equal(privateVars, privateArgs, *privateSyms)) {
+    OpOperand &original = std::get<0>(entry);
+    BlockArgument privateCopy = std::get<1>(entry);
+
+    effects.emplace_back(MemoryEffects::Allocate::get(), privateCopy);
+    effects.emplace_back(MemoryEffects::Free::get(), privateCopy);
+    // private variables may read the original as a mold
+    // firstprivate variables do it regardless
+    effects.emplace_back(MemoryEffects::Read::get(), &original);
+
+    auto privateSym = cast<SymbolRefAttr>(std::get<2>(entry));
+    auto privatiser =
+        SymbolTable::lookupNearestSymbolFrom<PrivateClauseOp>(op, privateSym);
+    // RecursiveMemoryEffects only covers regions nested in the directive, not
+    // symbol-referenced regions, user defined types have arbitrary recipe
+    // bodies. Default to a conservative model of read and write to arbitrary
+    // memory.
+    if (!privatiser || !areRegionsMemoryEffectFree(privatiser)) {
+      effects.emplace_back(MemoryEffects::Read::get());
+      effects.emplace_back(MemoryEffects::Write::get());
+    }
+  }
+}
+
+template <typename OpType>
+static void
+getLastprivateEffects(OpType op,
+                      SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
+  auto iface = cast<BlockArgOpenMPOpInterface>(op.getOperation());
+  // We cannot determine if the variable is lastprivate, so assume all private
+  // variables are.
+  for (auto entry : llvm::zip_equal(op.getPrivateVarsMutable(),
+                                    iface.getPrivateBlockArgs())) {
----------------
JRP-arm wrote:

Done

https://github.com/llvm/llvm-project/pull/230167


More information about the flang-commits mailing list