@@ -2326,12 +2326,52 @@ genParallelOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
23262326
23272327static mlir::omp::ScanOp
23282328genScanOp (lower::AbstractConverter &converter, lower::SymMap &symTable,
2329- semantics::SemanticsContext &semaCtx, mlir::Location loc,
2330- const ConstructQueue &queue, ConstructQueue::const_iterator item) {
2329+ semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval,
2330+ mlir::Location loc, const ConstructQueue &queue,
2331+ ConstructQueue::const_iterator item) {
23312332 mlir::omp::ScanOperands clauseOps;
23322333 genScanClauses (converter, semaCtx, item->clauses , loc, clauseOps);
2333- return mlir::omp::ScanOp::create (converter.getFirOpBuilder (),
2334- converter.getCurrentLocation (), clauseOps);
2334+ mlir::omp::ScanOp scanOp = mlir::omp::ScanOp::create (
2335+ converter.getFirOpBuilder (), converter.getCurrentLocation (), clauseOps);
2336+
2337+ // / Scan redution is not implemented with nested workshare loops, linear
2338+ // / clause, tiling
2339+ mlir::omp::LoopNestOp loopNestOp =
2340+ scanOp->getParentOfType <mlir::omp::LoopNestOp>();
2341+ mlir::omp::WsloopOp wsLoopOp = scanOp->getParentOfType <mlir::omp::WsloopOp>();
2342+ bool isNested =
2343+ (loopNestOp.getNumLoops () > 1 ) ||
2344+ (wsLoopOp && (wsLoopOp->getParentOfType <mlir::omp::WsloopOp>()));
2345+ if (isNested)
2346+ TODO (loc, " Scan directive inside nested workshare loops" );
2347+ if (wsLoopOp && !wsLoopOp.getLinearVars ().empty ())
2348+ TODO (loc, " Scan directive with linear clause" );
2349+ if (loopNestOp.getTileSizes ())
2350+ TODO (loc, " Scan directive with loop tiling" );
2351+
2352+ // All loop indices should be loaded after the scan construct as otherwise,
2353+ // it would result in using the index variable across scan directive.
2354+ // (`Intra-iteration dependences from a statement in the structured
2355+ // block sequence that precede a scan directive to a statement in the
2356+ // structured block sequence that follows a scan directive must not exist,
2357+ // except for dependences for the list items specified in an inclusive or
2358+ // exclusive clause.`).
2359+ // TODO: Nested loops are not handled.
2360+ mlir::Region ®ion = loopNestOp->getRegion (0 );
2361+ mlir::Value indexVal = fir::getBase (region.getArgument (0 ));
2362+ lower::pft::Evaluation *doConstructEval = eval.parentConstruct ;
2363+ fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder ();
2364+ lower::pft::Evaluation *doLoop = &doConstructEval->getFirstNestedEvaluation ();
2365+ auto *doStmt = doLoop->getIf <parser::NonLabelDoStmt>();
2366+ assert (doStmt && " Expected do loop to be in the nested evaluation" );
2367+ const auto &loopControl =
2368+ std::get<std::optional<parser::LoopControl>>(doStmt->t );
2369+ const parser::LoopControl::Bounds *bounds =
2370+ std::get_if<parser::LoopControl::Bounds>(&loopControl->u );
2371+ mlir::Operation *storeOp =
2372+ setLoopVar (converter, loc, indexVal, bounds->name .thing .symbol );
2373+ firOpBuilder.setInsertionPointAfter (storeOp);
2374+ return scanOp;
23352375}
23362376
23372377static mlir::omp::SectionsOp
@@ -3416,7 +3456,7 @@ static void genOMPDispatch(lower::AbstractConverter &converter,
34163456 loc, queue, item);
34173457 break ;
34183458 case llvm::omp::Directive::OMPD_scan:
3419- newOp = genScanOp (converter, symTable, semaCtx, loc, queue, item);
3459+ newOp = genScanOp (converter, symTable, semaCtx, eval, loc, queue, item);
34203460 break ;
34213461 case llvm::omp::Directive::OMPD_section:
34223462 llvm_unreachable (" genOMPDispatch: OMPD_section" );
0 commit comments