[Mlir-commits] [flang] [mlir] [openmp] [MLIR][OpenMP] Add scan reduction lowering to llvm (PR #167031)
Sergio Afonso
llvmlistbot at llvm.org
Tue Nov 25 07:21:57 PST 2025
================
@@ -2320,12 +2326,52 @@ genParallelOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
static mlir::omp::ScanOp
genScanOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
- semantics::SemanticsContext &semaCtx, mlir::Location loc,
- const ConstructQueue &queue, ConstructQueue::const_iterator item) {
+ semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval,
+ mlir::Location loc, const ConstructQueue &queue,
+ ConstructQueue::const_iterator item) {
mlir::omp::ScanOperands clauseOps;
genScanClauses(converter, semaCtx, item->clauses, loc, clauseOps);
- return mlir::omp::ScanOp::create(converter.getFirOpBuilder(),
- converter.getCurrentLocation(), clauseOps);
+ mlir::omp::ScanOp scanOp = mlir::omp::ScanOp::create(
+ converter.getFirOpBuilder(), converter.getCurrentLocation(), clauseOps);
+
+ /// Scan redution is not implemented with nested workshare loops, linear
+ /// clause, tiling
+ mlir::omp::LoopNestOp loopNestOp =
+ scanOp->getParentOfType<mlir::omp::LoopNestOp>();
+ mlir::omp::WsloopOp wsLoopOp = scanOp->getParentOfType<mlir::omp::WsloopOp>();
+ bool isNested =
+ (loopNestOp.getNumLoops() > 1) ||
+ (wsLoopOp && (wsLoopOp->getParentOfType<mlir::omp::WsloopOp>()));
+ if (isNested)
+ TODO(loc, "Scan directive inside nested workshare loops");
+ if (wsLoopOp && !wsLoopOp.getLinearVars().empty())
+ TODO(loc, "Scan directive with linear clause");
+ if (loopNestOp.getTileSizes())
+ TODO(loc, "Scan directive with loop tiling");
+
+ // All loop indices should be loaded after the scan construct as otherwise,
+ // it would result in using the index variable across scan directive.
+ // (`Intra-iteration dependences from a statement in the structured
+ // block sequence that precede a scan directive to a statement in the
+ // structured block sequence that follows a scan directive must not exist,
+ // except for dependences for the list items specified in an inclusive or
+ // exclusive clause.`).
+ // TODO: Nested loops are not handled.
+ mlir::Region ®ion = loopNestOp->getRegion(0);
+ mlir::Value indexVal = fir::getBase(region.getArgument(0));
+ lower::pft::Evaluation *doConstructEval = eval.parentConstruct;
+ fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
+ lower::pft::Evaluation *doLoop = &doConstructEval->getFirstNestedEvaluation();
+ auto *doStmt = doLoop->getIf<parser::NonLabelDoStmt>();
+ assert(doStmt && "Expected do loop to be in the nested evaluation");
+ const auto &loopControl =
+ std::get<std::optional<parser::LoopControl>>(doStmt->t);
+ const parser::LoopControl::Bounds *bounds =
+ std::get_if<parser::LoopControl::Bounds>(&loopControl->u);
+ mlir::Operation *storeOp =
+ setLoopVar(converter, loc, indexVal, bounds->name.thing.symbol);
----------------
skatrak wrote:
I'm not quite sure whether we should use `createAndSetPrivatizedLoopVar` or `setLoopVar` in this case, perhaps @Meinersbur can help out figuring out when we can actually assert that the symbol is present in the symbol table regarding induction variables.
https://github.com/llvm/llvm-project/pull/167031
More information about the Mlir-commits
mailing list