[llvm-branch-commits] [flang] [flang][OpenMP] Map simple `do concurrent` loops to OpenMP host constructs (PR #127633)
Sergio Afonso via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Mon Mar 10 05:54:55 PDT 2025
================
@@ -152,26 +199,140 @@ class DoConcurrentConversion : public mlir::OpConversionPattern<fir::DoLoopOp> {
public:
using mlir::OpConversionPattern<fir::DoLoopOp>::OpConversionPattern;
- DoConcurrentConversion(mlir::MLIRContext *context, bool mapToDevice)
- : OpConversionPattern(context), mapToDevice(mapToDevice) {}
+ DoConcurrentConversion(mlir::MLIRContext *context, bool mapToDevice,
+ llvm::DenseSet<fir::DoLoopOp> &concurrentLoopsToSkip)
+ : OpConversionPattern(context), mapToDevice(mapToDevice),
+ concurrentLoopsToSkip(concurrentLoopsToSkip) {}
mlir::LogicalResult
matchAndRewrite(fir::DoLoopOp doLoop, OpAdaptor adaptor,
mlir::ConversionPatternRewriter &rewriter) const override {
- looputils::LoopNest loopNest;
+ if (mapToDevice)
+ return doLoop.emitError(
+ "not yet implemented: Mapping `do concurrent` loops to device");
+
+ looputils::LoopNestToIndVarMap loopNest;
bool hasRemainingNestedLoops =
failed(looputils::collectLoopNest(doLoop, loopNest));
if (hasRemainingNestedLoops)
mlir::emitWarning(doLoop.getLoc(),
"Some `do concurent` loops are not perfectly-nested. "
"These will be serialized.");
- // TODO This will be filled in with the next PRs that upstreams the rest of
- // the ROCm implementaion.
+ mlir::IRMapping mapper;
+ genParallelOp(doLoop.getLoc(), rewriter, loopNest, mapper);
+ mlir::omp::LoopNestOperands loopNestClauseOps;
+ genLoopNestClauseOps(doLoop.getLoc(), rewriter, loopNest, mapper,
+ loopNestClauseOps);
+
+ mlir::omp::LoopNestOp ompLoopNest =
+ genWsLoopOp(rewriter, loopNest.back().first, mapper, loopNestClauseOps,
+ /*isComposite=*/mapToDevice);
+
+ rewriter.eraseOp(doLoop);
+
+ // Mark `unordered` loops that are not perfectly nested to be skipped from
+ // the legality check of the `ConversionTarget` since we are not interested
+ // in mapping them to OpenMP.
+ ompLoopNest->walk([&](fir::DoLoopOp doLoop) {
+ if (doLoop.getUnordered()) {
+ concurrentLoopsToSkip.insert(doLoop);
+ }
+ });
+
return mlir::success();
}
+private:
+ mlir::omp::ParallelOp genParallelOp(mlir::Location loc,
+ mlir::ConversionPatternRewriter &rewriter,
+ looputils::LoopNestToIndVarMap &loopNest,
+ mlir::IRMapping &mapper) const {
+ auto parallelOp = rewriter.create<mlir::omp::ParallelOp>(loc);
+ rewriter.createBlock(¶llelOp.getRegion());
+ rewriter.setInsertionPoint(rewriter.create<mlir::omp::TerminatorOp>(loc));
+
+ genLoopNestIndVarAllocs(rewriter, loopNest, mapper);
+ return parallelOp;
+ }
+
+ void genLoopNestIndVarAllocs(mlir::ConversionPatternRewriter &rewriter,
+ looputils::LoopNestToIndVarMap &loopNest,
+ mlir::IRMapping &mapper) const {
+
+ for (auto &[_, indVarInfo] : loopNest)
+ genInductionVariableAlloc(rewriter, indVarInfo.iterVarMemDef, mapper);
+ }
+
+ mlir::Operation *
+ genInductionVariableAlloc(mlir::ConversionPatternRewriter &rewriter,
+ mlir::Operation *indVarMemDef,
+ mlir::IRMapping &mapper) const {
+ assert(
+ indVarMemDef != nullptr &&
+ "Induction variable memdef is expected to have a defining operation.");
+
+ llvm::SmallSetVector<mlir::Operation *, 2> indVarDeclareAndAlloc;
+ for (auto operand : indVarMemDef->getOperands())
+ indVarDeclareAndAlloc.insert(operand.getDefiningOp());
+ indVarDeclareAndAlloc.insert(indVarMemDef);
+
+ mlir::Operation *result;
+ for (mlir::Operation *opToClone : indVarDeclareAndAlloc)
+ result = rewriter.clone(*opToClone, mapper);
+
+ return result;
+ }
+
+ void genLoopNestClauseOps(
+ mlir::Location loc, mlir::ConversionPatternRewriter &rewriter,
+ looputils::LoopNestToIndVarMap &loopNest, mlir::IRMapping &mapper,
+ mlir::omp::LoopNestOperands &loopNestClauseOps) const {
+ assert(loopNestClauseOps.loopLowerBounds.empty() &&
+ "Loop nest bounds were already emitted!");
+
+ auto populateBounds = [&](mlir::Value var,
----------------
skatrak wrote:
Nit: No need to capture anything here.
```suggestion
auto populateBounds = [](mlir::Value var,
```
https://github.com/llvm/llvm-project/pull/127633
More information about the llvm-branch-commits
mailing list