[flang-commits] [flang] [flang][fir] Add rewrite pattern to convert `fir.do_concurrent` to `fir.do_loop` (PR #132207)

Tom Eccles via flang-commits flang-commits at lists.llvm.org
Fri Mar 21 04:52:32 PDT 2025


================
@@ -122,6 +124,59 @@ mlir::LogicalResult BoxTotalElementsConversion::matchAndRewrite(
   return mlir::failure();
 }
 
+class DoConcurrentConversion
+    : public mlir::OpRewritePattern<fir::DoConcurrentOp> {
+public:
+  using mlir::OpRewritePattern<fir::DoConcurrentOp>::OpRewritePattern;
+
+  mlir::LogicalResult
+  matchAndRewrite(fir::DoConcurrentOp doConcurentOp,
+                  mlir::PatternRewriter &rewriter) const override {
+    assert(doConcurentOp.getRegion().hasOneBlock());
+    mlir::Block &wrapperBlock = doConcurentOp.getRegion().getBlocks().front();
+    auto loop =
+        mlir::cast<fir::DoConcurrentLoopOp>(wrapperBlock.getTerminator());
+    assert(loop.getRegion().hasOneBlock());
+    mlir::Block &loopBlock = loop.getRegion().getBlocks().front();
+
+    // Collect iteration variable(s) allocations do that we can move them
+    // outside the `fir.do_concurrent` wrapper.
+    llvm::SmallVector<mlir::Operation *> opsToMove;
+    for (mlir::Operation &op : llvm::drop_end(wrapperBlock))
+      opsToMove.push_back(&op);
+
+    mlir::Block &parentRegionEntry = doConcurentOp->getParentRegion()->front();
+    auto allocIt = (&parentRegionEntry == doConcurentOp->getBlock())
+                       ? doConcurentOp->getIterator()
+                       : parentRegionEntry.getTerminator()->getIterator();
----------------
tblah wrote:

I think it would be safer to use `fir::Builder::getAllocaBlock` so that special cases are handled if this is nested inside of anything surprising (OpenMP, CUDA, etc).

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


More information about the flang-commits mailing list