@@ -2250,6 +2250,17 @@ createAndSetPrivatizedLoopVar(Fortran::lower::AbstractConverter &converter,
22502250 return storeOp;
22512251}
22522252
2253+ struct CreateBodyOfOpInfo {
2254+ Fortran::lower::AbstractConverter &converter;
2255+ mlir::Location &loc;
2256+ Fortran::lower::pft::Evaluation &eval;
2257+ bool genNested = true ;
2258+ const Fortran::parser::OmpClauseList *clauses = nullptr ;
2259+ const llvm::SmallVector<const Fortran::semantics::Symbol *> &args = {};
2260+ bool outerCombined = false ;
2261+ DataSharingProcessor *dsp = nullptr ;
2262+ };
2263+
22532264// / Create the body (block) for an OpenMP Operation.
22542265// /
22552266// / \param [in] op - the operation the body belongs to.
@@ -2263,13 +2274,8 @@ createAndSetPrivatizedLoopVar(Fortran::lower::AbstractConverter &converter,
22632274// / \param [in] outerCombined - is this an outer operation - prevents
22642275// / privatization.
22652276template <typename Op>
2266- static void createBodyOfOp (
2267- Op &op, Fortran::lower::AbstractConverter &converter, mlir::Location &loc,
2268- Fortran::lower::pft::Evaluation &eval, bool genNested,
2269- const Fortran::parser::OmpClauseList *clauses = nullptr ,
2270- const llvm::SmallVector<const Fortran::semantics::Symbol *> &args = {},
2271- bool outerCombined = false , DataSharingProcessor *dsp = nullptr ) {
2272- fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder ();
2277+ static void createBodyOfOp (Op &op, CreateBodyOfOpInfo info) {
2278+ fir::FirOpBuilder &firOpBuilder = info.converter .getFirOpBuilder ();
22732279
22742280 auto insertMarker = [](fir::FirOpBuilder &builder) {
22752281 mlir::Value undef = builder.create <fir::UndefOp>(builder.getUnknownLoc (),
@@ -2281,22 +2287,22 @@ static void createBodyOfOp(
22812287 // argument. Also update the symbol's address with the mlir argument value.
22822288 // e.g. For loops the argument is the induction variable. And all further
22832289 // uses of the induction variable should use this mlir value.
2284- if (args.size ()) {
2290+ if (info. args .size ()) {
22852291 std::size_t loopVarTypeSize = 0 ;
2286- for (const Fortran::semantics::Symbol *arg : args)
2292+ for (const Fortran::semantics::Symbol *arg : info. args )
22872293 loopVarTypeSize = std::max (loopVarTypeSize, arg->GetUltimate ().size ());
2288- mlir::Type loopVarType = getLoopVarType (converter, loopVarTypeSize);
2289- llvm::SmallVector<mlir::Type> tiv (args.size (), loopVarType);
2290- llvm::SmallVector<mlir::Location> locs (args.size (), loc);
2294+ mlir::Type loopVarType = getLoopVarType (info. converter , loopVarTypeSize);
2295+ llvm::SmallVector<mlir::Type> tiv (info. args .size (), loopVarType);
2296+ llvm::SmallVector<mlir::Location> locs (info. args .size (), info. loc );
22912297 firOpBuilder.createBlock (&op.getRegion (), {}, tiv, locs);
22922298 // The argument is not currently in memory, so make a temporary for the
22932299 // argument, and store it there, then bind that location to the argument.
22942300 mlir::Operation *storeOp = nullptr ;
2295- for (auto [argIndex, argSymbol] : llvm::enumerate (args)) {
2301+ for (auto [argIndex, argSymbol] : llvm::enumerate (info. args )) {
22962302 mlir::Value indexVal =
22972303 fir::getBase (op.getRegion ().front ().getArgument (argIndex));
2298- storeOp =
2299- createAndSetPrivatizedLoopVar (converter, loc, indexVal, argSymbol);
2304+ storeOp = createAndSetPrivatizedLoopVar (info. converter , info. loc ,
2305+ indexVal, argSymbol);
23002306 }
23012307 firOpBuilder.setInsertionPointAfter (storeOp);
23022308 } else {
@@ -2308,44 +2314,44 @@ static void createBodyOfOp(
23082314
23092315 // If it is an unstructured region and is not the outer region of a combined
23102316 // construct, create empty blocks for all evaluations.
2311- if (eval.lowerAsUnstructured () && !outerCombined)
2317+ if (info. eval .lowerAsUnstructured () && !info. outerCombined )
23122318 Fortran::lower::createEmptyRegionBlocks<mlir::omp::TerminatorOp,
23132319 mlir::omp::YieldOp>(
2314- firOpBuilder, eval.getNestedEvaluations ());
2320+ firOpBuilder, info. eval .getNestedEvaluations ());
23152321
23162322 // Start with privatization, so that the lowering of the nested
23172323 // code will use the right symbols.
23182324 constexpr bool isLoop = std::is_same_v<Op, mlir::omp::WsLoopOp> ||
23192325 std::is_same_v<Op, mlir::omp::SimdLoopOp>;
2320- bool privatize = clauses && !outerCombined;
2326+ bool privatize = info. clauses && !info. outerCombined ;
23212327
23222328 firOpBuilder.setInsertionPoint (marker);
23232329 std::optional<DataSharingProcessor> tempDsp;
23242330 if (privatize) {
2325- if (!dsp) {
2326- tempDsp.emplace (converter, *clauses, eval);
2331+ if (!info. dsp ) {
2332+ tempDsp.emplace (info. converter , *info. clauses , info. eval );
23272333 tempDsp->processStep1 ();
23282334 }
23292335 }
23302336
23312337 if constexpr (std::is_same_v<Op, mlir::omp::ParallelOp>) {
2332- threadPrivatizeVars (converter, eval);
2333- if (clauses) {
2338+ threadPrivatizeVars (info. converter , info. eval );
2339+ if (info. clauses ) {
23342340 firOpBuilder.setInsertionPoint (marker);
2335- ClauseProcessor (converter, *clauses).processCopyin ();
2341+ ClauseProcessor (info. converter , *info. clauses ).processCopyin ();
23362342 }
23372343 }
23382344
2339- if (genNested) {
2345+ if (info. genNested ) {
23402346 // genFIR(Evaluation&) tries to patch up unterminated blocks, causing
23412347 // a lot of complications for our approach if the terminator generation
23422348 // is delayed past this point. Insert a temporary terminator here, then
23432349 // delete it.
23442350 firOpBuilder.setInsertionPointToEnd (&op.getRegion ().back ());
2345- auto *temp = Fortran::lower::genOpenMPTerminator (firOpBuilder,
2346- op.getOperation (), loc);
2351+ auto *temp = Fortran::lower::genOpenMPTerminator (
2352+ firOpBuilder, op.getOperation (), info. loc );
23472353 firOpBuilder.setInsertionPointAfter (marker);
2348- genNestedEvaluations (converter, eval);
2354+ genNestedEvaluations (info. converter , info. eval );
23492355 temp->erase ();
23502356 }
23512357
@@ -2380,28 +2386,28 @@ static void createBodyOfOp(
23802386 mlir::Block *exit = firOpBuilder.createBlock (®ion);
23812387 for (mlir::Block *b : exits) {
23822388 firOpBuilder.setInsertionPointToEnd (b);
2383- firOpBuilder.create <mlir::cf::BranchOp>(loc, exit);
2389+ firOpBuilder.create <mlir::cf::BranchOp>(info. loc , exit);
23842390 }
23852391 return exit;
23862392 };
23872393
23882394 if (auto *exitBlock = getUniqueExit (op.getRegion ())) {
23892395 firOpBuilder.setInsertionPointToEnd (exitBlock);
2390- auto *term = Fortran::lower::genOpenMPTerminator (firOpBuilder,
2391- op.getOperation (), loc);
2396+ auto *term = Fortran::lower::genOpenMPTerminator (
2397+ firOpBuilder, op.getOperation (), info. loc );
23922398 // Only insert lastprivate code when there actually is an exit block.
23932399 // Such a block may not exist if the nested code produced an infinite
23942400 // loop (this may not make sense in production code, but a user could
23952401 // write that and we should handle it).
23962402 firOpBuilder.setInsertionPoint (term);
23972403 if (privatize) {
2398- if (!dsp) {
2404+ if (!info. dsp ) {
23992405 assert (tempDsp.has_value ());
24002406 tempDsp->processStep2 (op, isLoop);
24012407 } else {
2402- if (isLoop && args.size () > 0 )
2403- dsp->setLoopIV (converter.getSymbolAddress (*args[0 ]));
2404- dsp->processStep2 (op, isLoop);
2408+ if (isLoop && info. args .size () > 0 )
2409+ info. dsp ->setLoopIV (info. converter .getSymbolAddress (*info. args [0 ]));
2410+ info. dsp ->processStep2 (op, isLoop);
24052411 }
24062412 }
24072413 }
@@ -2475,39 +2481,43 @@ static void genBodyOfTargetDataOp(
24752481 genNestedEvaluations (converter, eval);
24762482}
24772483
2484+ struct GenOpWithBodyInfo {
2485+ Fortran::lower::AbstractConverter &converter;
2486+ Fortran::lower::pft::Evaluation &eval;
2487+ bool genNested = false ;
2488+ mlir::Location currentLocation;
2489+ bool outerCombined = false ;
2490+ const Fortran::parser::OmpClauseList *clauseList = nullptr ;
2491+ };
2492+
24782493template <typename OpTy, typename ... Args>
2479- static OpTy genOpWithBody (Fortran::lower::AbstractConverter &converter,
2480- Fortran::lower::pft::Evaluation &eval, bool genNested,
2481- mlir::Location currentLocation, bool outerCombined,
2482- const Fortran::parser::OmpClauseList *clauseList,
2483- Args &&...args) {
2484- auto op = converter.getFirOpBuilder ().create <OpTy>(
2485- currentLocation, std::forward<Args>(args)...);
2486- createBodyOfOp<OpTy>(op, converter, currentLocation, eval, genNested,
2487- clauseList,
2488- /* args=*/ {}, outerCombined);
2494+ static OpTy genOpWithBody (GenOpWithBodyInfo info, Args &&...args) {
2495+ auto op = info.converter .getFirOpBuilder ().create <OpTy>(
2496+ info.currentLocation , std::forward<Args>(args)...);
2497+ createBodyOfOp<OpTy>(
2498+ op, {info.converter , info.currentLocation , info.eval , info.genNested ,
2499+ info.clauseList ,
2500+ /* args*/ llvm::SmallVector<const Fortran::semantics::Symbol *>{},
2501+ info.outerCombined });
24892502 return op;
24902503}
24912504
24922505static mlir::omp::MasterOp
24932506genMasterOp (Fortran::lower::AbstractConverter &converter,
24942507 Fortran::lower::pft::Evaluation &eval, bool genNested,
24952508 mlir::Location currentLocation) {
2496- return genOpWithBody<mlir::omp::MasterOp>(converter, eval, genNested,
2497- currentLocation,
2498- /* outerCombined=*/ false ,
2499- /* clauseList=*/ nullptr ,
2500- /* resultTypes=*/ mlir::TypeRange ());
2509+ return genOpWithBody<mlir::omp::MasterOp>(
2510+ {converter, eval, genNested, currentLocation},
2511+ /* resultTypes=*/ mlir::TypeRange ());
25012512}
25022513
25032514static mlir::omp::OrderedRegionOp
25042515genOrderedRegionOp (Fortran::lower::AbstractConverter &converter,
25052516 Fortran::lower::pft::Evaluation &eval, bool genNested,
25062517 mlir::Location currentLocation) {
25072518 return genOpWithBody<mlir::omp::OrderedRegionOp>(
2508- converter, eval, genNested, currentLocation,
2509- /* outerCombined=*/ false ,
2510- /* clauseList=*/ nullptr , /* simd=*/ false );
2519+ {converter, eval, genNested, currentLocation},
2520+ /* simd=*/ false );
25112521}
25122522
25132523static mlir::omp::ParallelOp
@@ -2534,7 +2544,7 @@ genParallelOp(Fortran::lower::AbstractConverter &converter,
25342544 cp.processReduction (currentLocation, reductionVars, reductionDeclSymbols);
25352545
25362546 return genOpWithBody<mlir::omp::ParallelOp>(
2537- converter, eval, genNested, currentLocation, outerCombined, &clauseList,
2547+ { converter, eval, genNested, currentLocation, outerCombined, &clauseList} ,
25382548 /* resultTypes=*/ mlir::TypeRange (), ifClauseOperand,
25392549 numThreadsClauseOperand, allocateOperands, allocatorOperands,
25402550 reductionVars,
@@ -2553,8 +2563,8 @@ genSectionOp(Fortran::lower::AbstractConverter &converter,
25532563 // Currently only private/firstprivate clause is handled, and
25542564 // all privatization is done within `omp.section` operations.
25552565 return genOpWithBody<mlir::omp::SectionOp>(
2556- converter, eval, genNested, currentLocation,
2557- /* outerCombined=*/ false , §ionsClauseList);
2566+ { converter, eval, genNested, currentLocation,
2567+ /* outerCombined=*/ false , §ionsClauseList} );
25582568}
25592569
25602570static mlir::omp::SingleOp
@@ -2574,9 +2584,9 @@ genSingleOp(Fortran::lower::AbstractConverter &converter,
25742584 ClauseProcessor (converter, endClauseList).processNowait (nowaitAttr);
25752585
25762586 return genOpWithBody<mlir::omp::SingleOp>(
2577- converter, eval, genNested, currentLocation,
2578- /* outerCombined=*/ false , &beginClauseList, allocateOperands ,
2579- allocatorOperands, nowaitAttr);
2587+ { converter, eval, genNested, currentLocation,
2588+ /* outerCombined=*/ false , &beginClauseList} ,
2589+ allocateOperands, allocatorOperands, nowaitAttr);
25802590}
25812591
25822592static mlir::omp::TaskOp
@@ -2607,9 +2617,9 @@ genTaskOp(Fortran::lower::AbstractConverter &converter,
26072617 currentLocation, llvm::omp::Directive::OMPD_task);
26082618
26092619 return genOpWithBody<mlir::omp::TaskOp>(
2610- converter, eval, genNested, currentLocation,
2611- /* outerCombined=*/ false , &clauseList, ifClauseOperand, finalClauseOperand ,
2612- untiedAttr, mergeableAttr,
2620+ { converter, eval, genNested, currentLocation,
2621+ /* outerCombined=*/ false , &clauseList} ,
2622+ ifClauseOperand, finalClauseOperand, untiedAttr, mergeableAttr,
26132623 /* in_reduction_vars=*/ mlir::ValueRange (),
26142624 /* in_reductions=*/ nullptr , priorityClauseOperand,
26152625 dependTypeOperands.empty ()
@@ -2630,8 +2640,8 @@ genTaskGroupOp(Fortran::lower::AbstractConverter &converter,
26302640 cp.processTODO <Fortran::parser::OmpClause::TaskReduction>(
26312641 currentLocation, llvm::omp::Directive::OMPD_taskgroup);
26322642 return genOpWithBody<mlir::omp::TaskGroupOp>(
2633- converter, eval, genNested, currentLocation,
2634- /* outerCombined=*/ false , &clauseList,
2643+ { converter, eval, genNested, currentLocation,
2644+ /* outerCombined=*/ false , &clauseList} ,
26352645 /* task_reduction_vars=*/ mlir::ValueRange (),
26362646 /* task_reductions=*/ nullptr , allocateOperands, allocatorOperands);
26372647}
@@ -3014,7 +3024,7 @@ genTeamsOp(Fortran::lower::AbstractConverter &converter,
30143024 currentLocation, llvm::omp::Directive::OMPD_teams);
30153025
30163026 return genOpWithBody<mlir::omp::TeamsOp>(
3017- converter, eval, genNested, currentLocation, outerCombined, &clauseList,
3027+ { converter, eval, genNested, currentLocation, outerCombined, &clauseList} ,
30183028 /* num_teams_lower=*/ nullptr , numTeamsClauseOperand, ifClauseOperand,
30193029 threadLimitClauseOperand, allocateOperands, allocatorOperands,
30203030 reductionVars,
@@ -3258,9 +3268,10 @@ createSimdLoop(Fortran::lower::AbstractConverter &converter,
32583268
32593269 auto *nestedEval = getCollapsedLoopEval (
32603270 eval, Fortran::lower::getCollapseValue (loopOpClauseList));
3261- createBodyOfOp<mlir::omp::SimdLoopOp>(simdLoopOp, converter, loc, *nestedEval,
3262- /* genNested=*/ true , &loopOpClauseList,
3263- iv, /* outer=*/ false , &dsp);
3271+ createBodyOfOp<mlir::omp::SimdLoopOp>(
3272+ simdLoopOp, {converter, loc, *nestedEval,
3273+ /* genNested=*/ true , &loopOpClauseList, iv,
3274+ /* outerCombined=*/ false , &dsp});
32643275}
32653276
32663277static void createWsLoop (Fortran::lower::AbstractConverter &converter,
@@ -3333,9 +3344,10 @@ static void createWsLoop(Fortran::lower::AbstractConverter &converter,
33333344
33343345 auto *nestedEval = getCollapsedLoopEval (
33353346 eval, Fortran::lower::getCollapseValue (beginClauseList));
3336- createBodyOfOp<mlir::omp::WsLoopOp>(wsLoopOp, converter, loc, *nestedEval,
3337- /* genNested=*/ true , &beginClauseList, iv,
3338- /* outer=*/ false , &dsp);
3347+ createBodyOfOp<mlir::omp::WsLoopOp>(wsLoopOp,
3348+ {converter, loc, *nestedEval,
3349+ /* genNested=*/ true , &beginClauseList, iv,
3350+ /* outerCombined=*/ false , &dsp});
33393351}
33403352
33413353static void createSimdWsLoop (
@@ -3616,8 +3628,8 @@ genOMP(Fortran::lower::AbstractConverter &converter,
36163628 currentLocation, mlir::FlatSymbolRefAttr::get (firOpBuilder.getContext (),
36173629 global.getSymName ()));
36183630 }();
3619- createBodyOfOp<mlir::omp::CriticalOp>(criticalOp, converter, currentLocation,
3620- eval, /* genNested= */ true );
3631+ createBodyOfOp<mlir::omp::CriticalOp>(criticalOp,
3632+ {converter, currentLocation, eval} );
36213633}
36223634
36233635static void
@@ -3659,10 +3671,8 @@ genOMP(Fortran::lower::AbstractConverter &converter,
36593671 }
36603672
36613673 // SECTIONS construct
3662- genOpWithBody<mlir::omp::SectionsOp>(converter, eval,
3663- /* genNested=*/ false , currentLocation,
3664- /* outerCombined=*/ false ,
3665- /* clauseList=*/ nullptr ,
3674+ genOpWithBody<mlir::omp::SectionsOp>({converter, eval,
3675+ /* genNested=*/ false , currentLocation},
36663676 /* reduction_vars=*/ mlir::ValueRange (),
36673677 /* reductions=*/ nullptr , allocateOperands,
36683678 allocatorOperands, nowaitClauseOperand);
0 commit comments