@@ -2250,6 +2250,17 @@ createAndSetPrivatizedLoopVar(Fortran::lower::AbstractConverter &converter,
2250
2250
return storeOp;
2251
2251
}
2252
2252
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
+
2253
2264
// / Create the body (block) for an OpenMP Operation.
2254
2265
// /
2255
2266
// / \param [in] op - the operation the body belongs to.
@@ -2263,13 +2274,8 @@ createAndSetPrivatizedLoopVar(Fortran::lower::AbstractConverter &converter,
2263
2274
// / \param [in] outerCombined - is this an outer operation - prevents
2264
2275
// / privatization.
2265
2276
template <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 ();
2273
2279
2274
2280
auto insertMarker = [](fir::FirOpBuilder &builder) {
2275
2281
mlir::Value undef = builder.create <fir::UndefOp>(builder.getUnknownLoc (),
@@ -2281,22 +2287,22 @@ static void createBodyOfOp(
2281
2287
// argument. Also update the symbol's address with the mlir argument value.
2282
2288
// e.g. For loops the argument is the induction variable. And all further
2283
2289
// uses of the induction variable should use this mlir value.
2284
- if (args.size ()) {
2290
+ if (info. args .size ()) {
2285
2291
std::size_t loopVarTypeSize = 0 ;
2286
- for (const Fortran::semantics::Symbol *arg : args)
2292
+ for (const Fortran::semantics::Symbol *arg : info. args )
2287
2293
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 );
2291
2297
firOpBuilder.createBlock (&op.getRegion (), {}, tiv, locs);
2292
2298
// The argument is not currently in memory, so make a temporary for the
2293
2299
// argument, and store it there, then bind that location to the argument.
2294
2300
mlir::Operation *storeOp = nullptr ;
2295
- for (auto [argIndex, argSymbol] : llvm::enumerate (args)) {
2301
+ for (auto [argIndex, argSymbol] : llvm::enumerate (info. args )) {
2296
2302
mlir::Value indexVal =
2297
2303
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);
2300
2306
}
2301
2307
firOpBuilder.setInsertionPointAfter (storeOp);
2302
2308
} else {
@@ -2308,44 +2314,44 @@ static void createBodyOfOp(
2308
2314
2309
2315
// If it is an unstructured region and is not the outer region of a combined
2310
2316
// construct, create empty blocks for all evaluations.
2311
- if (eval.lowerAsUnstructured () && !outerCombined)
2317
+ if (info. eval .lowerAsUnstructured () && !info. outerCombined )
2312
2318
Fortran::lower::createEmptyRegionBlocks<mlir::omp::TerminatorOp,
2313
2319
mlir::omp::YieldOp>(
2314
- firOpBuilder, eval.getNestedEvaluations ());
2320
+ firOpBuilder, info. eval .getNestedEvaluations ());
2315
2321
2316
2322
// Start with privatization, so that the lowering of the nested
2317
2323
// code will use the right symbols.
2318
2324
constexpr bool isLoop = std::is_same_v<Op, mlir::omp::WsLoopOp> ||
2319
2325
std::is_same_v<Op, mlir::omp::SimdLoopOp>;
2320
- bool privatize = clauses && !outerCombined;
2326
+ bool privatize = info. clauses && !info. outerCombined ;
2321
2327
2322
2328
firOpBuilder.setInsertionPoint (marker);
2323
2329
std::optional<DataSharingProcessor> tempDsp;
2324
2330
if (privatize) {
2325
- if (!dsp) {
2326
- tempDsp.emplace (converter, *clauses, eval);
2331
+ if (!info. dsp ) {
2332
+ tempDsp.emplace (info. converter , *info. clauses , info. eval );
2327
2333
tempDsp->processStep1 ();
2328
2334
}
2329
2335
}
2330
2336
2331
2337
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 ) {
2334
2340
firOpBuilder.setInsertionPoint (marker);
2335
- ClauseProcessor (converter, *clauses).processCopyin ();
2341
+ ClauseProcessor (info. converter , *info. clauses ).processCopyin ();
2336
2342
}
2337
2343
}
2338
2344
2339
- if (genNested) {
2345
+ if (info. genNested ) {
2340
2346
// genFIR(Evaluation&) tries to patch up unterminated blocks, causing
2341
2347
// a lot of complications for our approach if the terminator generation
2342
2348
// is delayed past this point. Insert a temporary terminator here, then
2343
2349
// delete it.
2344
2350
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 );
2347
2353
firOpBuilder.setInsertionPointAfter (marker);
2348
- genNestedEvaluations (converter, eval);
2354
+ genNestedEvaluations (info. converter , info. eval );
2349
2355
temp->erase ();
2350
2356
}
2351
2357
@@ -2380,28 +2386,28 @@ static void createBodyOfOp(
2380
2386
mlir::Block *exit = firOpBuilder.createBlock (®ion);
2381
2387
for (mlir::Block *b : exits) {
2382
2388
firOpBuilder.setInsertionPointToEnd (b);
2383
- firOpBuilder.create <mlir::cf::BranchOp>(loc, exit);
2389
+ firOpBuilder.create <mlir::cf::BranchOp>(info. loc , exit);
2384
2390
}
2385
2391
return exit;
2386
2392
};
2387
2393
2388
2394
if (auto *exitBlock = getUniqueExit (op.getRegion ())) {
2389
2395
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 );
2392
2398
// Only insert lastprivate code when there actually is an exit block.
2393
2399
// Such a block may not exist if the nested code produced an infinite
2394
2400
// loop (this may not make sense in production code, but a user could
2395
2401
// write that and we should handle it).
2396
2402
firOpBuilder.setInsertionPoint (term);
2397
2403
if (privatize) {
2398
- if (!dsp) {
2404
+ if (!info. dsp ) {
2399
2405
assert (tempDsp.has_value ());
2400
2406
tempDsp->processStep2 (op, isLoop);
2401
2407
} 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);
2405
2411
}
2406
2412
}
2407
2413
}
@@ -2475,39 +2481,50 @@ static void genBodyOfTargetDataOp(
2475
2481
genNestedEvaluations (converter, eval);
2476
2482
}
2477
2483
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
+
2478
2493
template <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>(op, {.converter = info.converter ,
2498
+ .loc = info.currentLocation ,
2499
+ .eval = info.eval ,
2500
+ .genNested = info.genNested ,
2501
+ .clauses = info.clauseList ,
2502
+ .outerCombined = info.outerCombined });
2489
2503
return op;
2490
2504
}
2491
2505
2492
2506
static mlir::omp::MasterOp
2493
2507
genMasterOp (Fortran::lower::AbstractConverter &converter,
2494
2508
Fortran::lower::pft::Evaluation &eval, bool genNested,
2495
2509
mlir::Location currentLocation) {
2496
- return genOpWithBody<mlir::omp::MasterOp>(converter, eval, genNested,
2497
- currentLocation,
2498
- /* outerCombined=*/ false ,
2499
- /* clauseList=*/ nullptr ,
2500
- /* resultTypes=*/ mlir::TypeRange ());
2510
+ return genOpWithBody<mlir::omp::MasterOp>(
2511
+ {.converter = converter,
2512
+ .eval = eval,
2513
+ .genNested = genNested,
2514
+ .currentLocation = currentLocation},
2515
+ /* resultTypes=*/ mlir::TypeRange ());
2501
2516
}
2502
2517
2503
2518
static mlir::omp::OrderedRegionOp
2504
2519
genOrderedRegionOp (Fortran::lower::AbstractConverter &converter,
2505
2520
Fortran::lower::pft::Evaluation &eval, bool genNested,
2506
2521
mlir::Location currentLocation) {
2507
2522
return genOpWithBody<mlir::omp::OrderedRegionOp>(
2508
- converter, eval, genNested, currentLocation,
2509
- /* outerCombined=*/ false ,
2510
- /* clauseList=*/ nullptr , /* simd=*/ false );
2523
+ {.converter = converter,
2524
+ .eval = eval,
2525
+ .genNested = genNested,
2526
+ .currentLocation = currentLocation},
2527
+ /* simd=*/ false );
2511
2528
}
2512
2529
2513
2530
static mlir::omp::ParallelOp
@@ -2534,7 +2551,12 @@ genParallelOp(Fortran::lower::AbstractConverter &converter,
2534
2551
cp.processReduction (currentLocation, reductionVars, reductionDeclSymbols);
2535
2552
2536
2553
return genOpWithBody<mlir::omp::ParallelOp>(
2537
- converter, eval, genNested, currentLocation, outerCombined, &clauseList,
2554
+ {.converter = converter,
2555
+ .eval = eval,
2556
+ .genNested = genNested,
2557
+ .currentLocation = currentLocation,
2558
+ .outerCombined = outerCombined,
2559
+ .clauseList = &clauseList},
2538
2560
/* resultTypes=*/ mlir::TypeRange (), ifClauseOperand,
2539
2561
numThreadsClauseOperand, allocateOperands, allocatorOperands,
2540
2562
reductionVars,
@@ -2553,8 +2575,11 @@ genSectionOp(Fortran::lower::AbstractConverter &converter,
2553
2575
// Currently only private/firstprivate clause is handled, and
2554
2576
// all privatization is done within `omp.section` operations.
2555
2577
return genOpWithBody<mlir::omp::SectionOp>(
2556
- converter, eval, genNested, currentLocation,
2557
- /* outerCombined=*/ false , §ionsClauseList);
2578
+ {.converter = converter,
2579
+ .eval = eval,
2580
+ .genNested = genNested,
2581
+ .currentLocation = currentLocation,
2582
+ .clauseList = §ionsClauseList});
2558
2583
}
2559
2584
2560
2585
static mlir::omp::SingleOp
@@ -2573,10 +2598,13 @@ genSingleOp(Fortran::lower::AbstractConverter &converter,
2573
2598
2574
2599
ClauseProcessor (converter, endClauseList).processNowait (nowaitAttr);
2575
2600
2576
- return genOpWithBody<mlir::omp::SingleOp>(
2577
- converter, eval, genNested, currentLocation,
2578
- /* outerCombined=*/ false , &beginClauseList, allocateOperands,
2579
- allocatorOperands, nowaitAttr);
2601
+ return genOpWithBody<mlir::omp::SingleOp>({.converter = converter,
2602
+ .eval = eval,
2603
+ .genNested = genNested,
2604
+ .currentLocation = currentLocation,
2605
+ .clauseList = &beginClauseList},
2606
+ allocateOperands, allocatorOperands,
2607
+ nowaitAttr);
2580
2608
}
2581
2609
2582
2610
static mlir::omp::TaskOp
@@ -2607,9 +2635,12 @@ genTaskOp(Fortran::lower::AbstractConverter &converter,
2607
2635
currentLocation, llvm::omp::Directive::OMPD_task);
2608
2636
2609
2637
return genOpWithBody<mlir::omp::TaskOp>(
2610
- converter, eval, genNested, currentLocation,
2611
- /* outerCombined=*/ false , &clauseList, ifClauseOperand, finalClauseOperand,
2612
- untiedAttr, mergeableAttr,
2638
+ {.converter = converter,
2639
+ .eval = eval,
2640
+ .genNested = genNested,
2641
+ .currentLocation = currentLocation,
2642
+ .clauseList = &clauseList},
2643
+ ifClauseOperand, finalClauseOperand, untiedAttr, mergeableAttr,
2613
2644
/* in_reduction_vars=*/ mlir::ValueRange (),
2614
2645
/* in_reductions=*/ nullptr , priorityClauseOperand,
2615
2646
dependTypeOperands.empty ()
@@ -2630,8 +2661,11 @@ genTaskGroupOp(Fortran::lower::AbstractConverter &converter,
2630
2661
cp.processTODO <Fortran::parser::OmpClause::TaskReduction>(
2631
2662
currentLocation, llvm::omp::Directive::OMPD_taskgroup);
2632
2663
return genOpWithBody<mlir::omp::TaskGroupOp>(
2633
- converter, eval, genNested, currentLocation,
2634
- /* outerCombined=*/ false , &clauseList,
2664
+ {.converter = converter,
2665
+ .eval = eval,
2666
+ .genNested = genNested,
2667
+ .currentLocation = currentLocation,
2668
+ .clauseList = &clauseList},
2635
2669
/* task_reduction_vars=*/ mlir::ValueRange (),
2636
2670
/* task_reductions=*/ nullptr , allocateOperands, allocatorOperands);
2637
2671
}
@@ -3014,7 +3048,12 @@ genTeamsOp(Fortran::lower::AbstractConverter &converter,
3014
3048
currentLocation, llvm::omp::Directive::OMPD_teams);
3015
3049
3016
3050
return genOpWithBody<mlir::omp::TeamsOp>(
3017
- converter, eval, genNested, currentLocation, outerCombined, &clauseList,
3051
+ {.converter = converter,
3052
+ .eval = eval,
3053
+ .genNested = genNested,
3054
+ .currentLocation = currentLocation,
3055
+ .outerCombined = outerCombined,
3056
+ .clauseList = &clauseList},
3018
3057
/* num_teams_lower=*/ nullptr , numTeamsClauseOperand, ifClauseOperand,
3019
3058
threadLimitClauseOperand, allocateOperands, allocatorOperands,
3020
3059
reductionVars,
@@ -3258,9 +3297,13 @@ createSimdLoop(Fortran::lower::AbstractConverter &converter,
3258
3297
3259
3298
auto *nestedEval = getCollapsedLoopEval (
3260
3299
eval, Fortran::lower::getCollapseValue (loopOpClauseList));
3261
- createBodyOfOp<mlir::omp::SimdLoopOp>(simdLoopOp, converter, loc, *nestedEval,
3262
- /* genNested=*/ true , &loopOpClauseList,
3263
- iv, /* outer=*/ false , &dsp);
3300
+ createBodyOfOp<mlir::omp::SimdLoopOp>(simdLoopOp,
3301
+ {.converter = converter,
3302
+ .loc = loc,
3303
+ .eval = *nestedEval,
3304
+ .clauses = &loopOpClauseList,
3305
+ .args = iv,
3306
+ .dsp = &dsp});
3264
3307
}
3265
3308
3266
3309
static void createWsLoop (Fortran::lower::AbstractConverter &converter,
@@ -3333,9 +3376,12 @@ static void createWsLoop(Fortran::lower::AbstractConverter &converter,
3333
3376
3334
3377
auto *nestedEval = getCollapsedLoopEval (
3335
3378
eval, Fortran::lower::getCollapseValue (beginClauseList));
3336
- createBodyOfOp<mlir::omp::WsLoopOp>(wsLoopOp, converter, loc, *nestedEval,
3337
- /* genNested=*/ true , &beginClauseList, iv,
3338
- /* outer=*/ false , &dsp);
3379
+ createBodyOfOp<mlir::omp::WsLoopOp>(wsLoopOp, {.converter = converter,
3380
+ .loc = loc,
3381
+ .eval = *nestedEval,
3382
+ .clauses = &beginClauseList,
3383
+ .args = iv,
3384
+ .dsp = &dsp});
3339
3385
}
3340
3386
3341
3387
static void createSimdWsLoop (
@@ -3616,8 +3662,9 @@ genOMP(Fortran::lower::AbstractConverter &converter,
3616
3662
currentLocation, mlir::FlatSymbolRefAttr::get (firOpBuilder.getContext (),
3617
3663
global.getSymName ()));
3618
3664
}();
3619
- createBodyOfOp<mlir::omp::CriticalOp>(criticalOp, converter, currentLocation,
3620
- eval, /* genNested=*/ true );
3665
+ createBodyOfOp<mlir::omp::CriticalOp>(
3666
+ criticalOp,
3667
+ {.converter = converter, .loc = currentLocation, .eval = eval});
3621
3668
}
3622
3669
3623
3670
static void
@@ -3659,10 +3706,9 @@ genOMP(Fortran::lower::AbstractConverter &converter,
3659
3706
}
3660
3707
3661
3708
// SECTIONS construct
3662
- genOpWithBody<mlir::omp::SectionsOp>(converter, eval,
3663
- /* genNested=*/ false , currentLocation,
3664
- /* outerCombined=*/ false ,
3665
- /* clauseList=*/ nullptr ,
3709
+ genOpWithBody<mlir::omp::SectionsOp>({.converter = converter,
3710
+ .eval = eval,
3711
+ .currentLocation = currentLocation},
3666
3712
/* reduction_vars=*/ mlir::ValueRange (),
3667
3713
/* reductions=*/ nullptr , allocateOperands,
3668
3714
allocatorOperands, nowaitClauseOperand);
0 commit comments