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

via flang-commits flang-commits at lists.llvm.org
Mon Mar 24 01:55:40 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();
+
+    for (mlir::Operation *op : opsToMove)
+      rewriter.moveOpBefore(op, allocIt->getBlock(), allocIt);
+
+    rewriter.setInsertionPointAfter(doConcurentOp);
+    fir::DoLoopOp innermostUnorderdLoop;
+    mlir::IRMapping mapper;
+
+    for (auto [lb, ub, st, iv] :
+         llvm::zip_equal(loop.getLowerBound(), loop.getUpperBound(),
+                         loop.getStep(), *loop.getLoopInductionVars())) {
+      innermostUnorderdLoop = rewriter.create<fir::DoLoopOp>(
+          doConcurentOp.getLoc(), lb, ub, st,
+          /*unordred=*/true, /*finalCountValue=*/false,
+          /*iterArgs=*/std::nullopt, loop.getReduceOperands(),
+          loop.getReduceAttrsAttr());
+      mapper.map(iv, innermostUnorderdLoop.getInductionVar());
+      rewriter.setInsertionPointToStart(innermostUnorderdLoop.getBody());
+    }
+
+    for (mlir::Operation &op : loopBlock)
+      rewriter.clone(op, mapper);
----------------
jeanPerier wrote:

@matthias-springer, do you know if it is OK to use `mlir::Region::takeBody` inside an `OpRewritePattern`?

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


More information about the flang-commits mailing list