================ @@ -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 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits