@@ -30,6 +30,7 @@ struct DoLoopConversion : public mlir::OpRewritePattern<fir::DoLoopOp> {
3030 mlir::PatternRewriter &rewriter) const override {
3131 mlir::Location loc = doLoopOp.getLoc ();
3232 bool hasFinalValue = doLoopOp.getFinalValue ().has_value ();
33+ bool isUnordered = doLoopOp.getUnordered ().has_value ();
3334
3435 // Get loop values from the DoLoopOp
3536 mlir::Value low = doLoopOp.getLowerBound ();
@@ -53,37 +54,47 @@ struct DoLoopConversion : public mlir::OpRewritePattern<fir::DoLoopOp> {
5354 mlir::arith::DivSIOp::create (rewriter, loc, distance, step);
5455 auto zero = mlir::arith::ConstantIndexOp::create (rewriter, loc, 0 );
5556 auto one = mlir::arith::ConstantIndexOp::create (rewriter, loc, 1 );
56- auto scfForOp =
57- mlir::scf::ForOp::create (rewriter, loc, zero, tripCount, one, iterArgs);
5857
58+ // Create the scf.for or scf.parallel operation
59+ mlir::Operation *scfLoopOp = nullptr ;
60+ if (isUnordered) {
61+ scfLoopOp = mlir::scf::ParallelOp::create (rewriter, loc, {zero},
62+ {tripCount}, {one}, iterArgs);
63+ } else {
64+ scfLoopOp = mlir::scf::ForOp::create (rewriter, loc, zero, tripCount, one,
65+ iterArgs);
66+ }
67+
68+ // Move the body of the fir.do_loop to the scf.for or scf.parallel
5969 auto &loopOps = doLoopOp.getBody ()->getOperations ();
6070 auto resultOp =
6171 mlir::cast<fir::ResultOp>(doLoopOp.getBody ()->getTerminator ());
6272 auto results = resultOp.getOperands ();
63- mlir::Block *loweredBody = scfForOp.getBody ();
73+ auto scfLoopLikeOp = mlir::cast<mlir::LoopLikeOpInterface>(scfLoopOp);
74+ mlir::Block &scfLoopBody = scfLoopLikeOp.getLoopRegions ().front ()->front ();
6475
65- loweredBody-> getOperations ().splice (loweredBody-> begin (), loopOps,
66- loopOps.begin (),
67- std::prev (loopOps.end ()));
76+ scfLoopBody. getOperations ().splice (scfLoopBody. begin (), loopOps,
77+ loopOps.begin (),
78+ std::prev (loopOps.end ()));
6879
69- rewriter.setInsertionPointToStart (loweredBody );
80+ rewriter.setInsertionPointToStart (&scfLoopBody );
7081 mlir::Value iv = mlir::arith::MulIOp::create (
71- rewriter, loc, scfForOp. getInductionVar (), step);
82+ rewriter, loc, scfLoopLikeOp. getSingleInductionVar (). value (), step);
7283 iv = mlir::arith::AddIOp::create (rewriter, loc, low, iv);
7384
7485 if (!results.empty ()) {
75- rewriter.setInsertionPointToEnd (loweredBody );
86+ rewriter.setInsertionPointToEnd (&scfLoopBody );
7687 mlir::scf::YieldOp::create (rewriter, resultOp->getLoc (), results);
7788 }
7889 doLoopOp.getInductionVar ().replaceAllUsesWith (iv);
79- rewriter.replaceAllUsesWith (doLoopOp. getRegionIterArgs (),
80- hasFinalValue
81- ? scfForOp .getRegionIterArgs ().drop_front ()
82- : scfForOp .getRegionIterArgs ());
90+ rewriter.replaceAllUsesWith (
91+ doLoopOp. getRegionIterArgs (),
92+ hasFinalValue ? scfLoopLikeOp .getRegionIterArgs ().drop_front ()
93+ : scfLoopLikeOp .getRegionIterArgs ());
8394
8495 // Copy all the attributes from the old to new op.
85- scfForOp ->setAttrs (doLoopOp->getAttrs ());
86- rewriter.replaceOp (doLoopOp, scfForOp );
96+ scfLoopOp ->setAttrs (doLoopOp->getAttrs ());
97+ rewriter.replaceOp (doLoopOp, scfLoopOp );
8798 return mlir::success ();
8899 }
89100};
0 commit comments