@@ -1047,6 +1047,11 @@ struct OpWithBodyGenInfo {
1047
1047
return *this ;
1048
1048
}
1049
1049
1050
+ OpWithBodyGenInfo &setEntryBlockArgs (const EntryBlockArgs *value) {
1051
+ blockArgs = value;
1052
+ return *this ;
1053
+ }
1054
+
1050
1055
OpWithBodyGenInfo &setGenRegionEntryCb (GenOMPRegionEntryCBFn value) {
1051
1056
genRegionEntryCB = value;
1052
1057
return *this ;
@@ -1073,8 +1078,12 @@ struct OpWithBodyGenInfo {
1073
1078
const List<Clause> *clauses = nullptr ;
1074
1079
// / [in] if provided, processes the construct's data-sharing attributes.
1075
1080
DataSharingProcessor *dsp = nullptr ;
1076
- // / [in] if provided, emits the op's region entry. Otherwise, an emtpy block
1077
- // / is created in the region.
1081
+ // / [in] if provided, it is used to create the op's region entry block. It is
1082
+ // / overriden when a \see genRegionEntryCB is provided. This is only valid for
1083
+ // / operations implementing the \see mlir::omp::BlockArgOpenMPOpInterface.
1084
+ const EntryBlockArgs *blockArgs = nullptr ;
1085
+ // / [in] if provided, it overrides the default op's region entry block
1086
+ // / creation.
1078
1087
GenOMPRegionEntryCBFn genRegionEntryCB = nullptr ;
1079
1088
// / [in] if set to `true`, skip generating nested evaluations and dispatching
1080
1089
// / any further leaf constructs.
@@ -1098,18 +1107,33 @@ static void createBodyOfOp(mlir::Operation &op, const OpWithBodyGenInfo &info,
1098
1107
return undef.getDefiningOp ();
1099
1108
};
1100
1109
1101
- // If an argument for the region is provided then create the block with that
1102
- // argument. Also update the symbol's address with the mlir argument value.
1103
- // e.g. For loops the argument is the induction variable. And all further
1104
- // uses of the induction variable should use this mlir value.
1110
+ // Create the entry block for the region and collect its arguments for use
1111
+ // within the region. The entry block will be created as follows:
1112
+ // - By default, it will be empty and have no arguments.
1113
+ // - Operations implementing the omp::BlockArgOpenMPOpInterface can set the
1114
+ // `info.blockArgs` pointer so that block arguments will be those
1115
+ // corresponding to entry block argument-generating clauses. Binding of
1116
+ // Fortran symbols to the new MLIR values is done automatically.
1117
+ // - If the `info.genRegionEntryCB` callback is set, it takes precedence and
1118
+ // allows callers to manually create the entry block with its intended
1119
+ // list of arguments and to bind these arguments to their corresponding
1120
+ // Fortran symbols. This is used for e.g. loop induction variables.
1105
1121
auto regionArgs = [&]() -> llvm::SmallVector<const semantics::Symbol *> {
1106
- if (info.genRegionEntryCB != nullptr ) {
1122
+ if (info.genRegionEntryCB )
1107
1123
return info.genRegionEntryCB (&op);
1124
+
1125
+ if (info.blockArgs ) {
1126
+ genEntryBlock (firOpBuilder, *info.blockArgs , op.getRegion (0 ));
1127
+ bindEntryBlockArgs (info.converter ,
1128
+ llvm::cast<mlir::omp::BlockArgOpenMPOpInterface>(op),
1129
+ *info.blockArgs );
1130
+ return llvm::to_vector (info.blockArgs ->getSyms ());
1108
1131
}
1109
1132
1110
1133
firOpBuilder.createBlock (&op.getRegion (0 ));
1111
1134
return {};
1112
1135
}();
1136
+
1113
1137
// Mark the earliest insertion point.
1114
1138
mlir::Operation *marker = insertMarker (firOpBuilder);
1115
1139
@@ -1977,20 +2001,14 @@ genParallelOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
1977
2001
mlir::omp::ParallelOperands &clauseOps,
1978
2002
const EntryBlockArgs &args, DataSharingProcessor *dsp,
1979
2003
bool isComposite = false ) {
1980
- auto genRegionEntryCB = [&](mlir::Operation *op) {
1981
- genEntryBlock (converter.getFirOpBuilder (), args, op->getRegion (0 ));
1982
- bindEntryBlockArgs (
1983
- converter, llvm::cast<mlir::omp::BlockArgOpenMPOpInterface>(op), args);
1984
- return llvm::to_vector (args.getSyms ());
1985
- };
1986
-
1987
2004
assert ((!enableDelayedPrivatization || dsp) &&
1988
2005
" expected valid DataSharingProcessor" );
2006
+
1989
2007
OpWithBodyGenInfo genInfo =
1990
2008
OpWithBodyGenInfo (converter, symTable, semaCtx, loc, eval,
1991
2009
llvm::omp::Directive::OMPD_parallel)
1992
2010
.setClauses (&item->clauses )
1993
- .setGenRegionEntryCb (genRegionEntryCB )
2011
+ .setEntryBlockArgs (&args )
1994
2012
.setGenSkeletonOnly (isComposite)
1995
2013
.setDataSharingProcessor (dsp);
1996
2014
@@ -2066,13 +2084,6 @@ genSectionsOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
2066
2084
mlir::Operation *terminator =
2067
2085
lower::genOpenMPTerminator (builder, sectionsOp, loc);
2068
2086
2069
- auto genRegionEntryCB = [&](mlir::Operation *op) {
2070
- genEntryBlock (builder, args, op->getRegion (0 ));
2071
- bindEntryBlockArgs (
2072
- converter, llvm::cast<mlir::omp::BlockArgOpenMPOpInterface>(op), args);
2073
- return llvm::to_vector (args.getSyms ());
2074
- };
2075
-
2076
2087
// Generate nested SECTION constructs.
2077
2088
// This is done here rather than in genOMP([...], OpenMPSectionConstruct )
2078
2089
// because we need to run genReductionVars on each omp.section so that the
@@ -2096,7 +2107,7 @@ genSectionsOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
2096
2107
OpWithBodyGenInfo (converter, symTable, semaCtx, loc, nestedEval,
2097
2108
llvm::omp::Directive::OMPD_section)
2098
2109
.setClauses (§ionQueue.begin ()->clauses )
2099
- .setGenRegionEntryCb (genRegionEntryCB ),
2110
+ .setEntryBlockArgs (&args ),
2100
2111
sectionQueue, sectionQueue.begin ());
2101
2112
}
2102
2113
@@ -2435,20 +2446,12 @@ genTaskOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
2435
2446
taskArgs.priv .syms = dsp.getDelayedPrivSymbols ();
2436
2447
taskArgs.priv .vars = clauseOps.privateVars ;
2437
2448
2438
- auto genRegionEntryCB = [&](mlir::Operation *op) {
2439
- genEntryBlock (converter.getFirOpBuilder (), taskArgs, op->getRegion (0 ));
2440
- bindEntryBlockArgs (converter,
2441
- llvm::cast<mlir::omp::BlockArgOpenMPOpInterface>(op),
2442
- taskArgs);
2443
- return llvm::to_vector (taskArgs.priv .syms );
2444
- };
2445
-
2446
2449
return genOpWithBody<mlir::omp::TaskOp>(
2447
2450
OpWithBodyGenInfo (converter, symTable, semaCtx, loc, eval,
2448
2451
llvm::omp::Directive::OMPD_task)
2449
2452
.setClauses (&item->clauses )
2450
2453
.setDataSharingProcessor (&dsp)
2451
- .setGenRegionEntryCb (genRegionEntryCB ),
2454
+ .setEntryBlockArgs (&taskArgs ),
2452
2455
queue, item, clauseOps);
2453
2456
}
2454
2457
@@ -2524,18 +2527,11 @@ genTeamsOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
2524
2527
args.reduction .syms = reductionSyms;
2525
2528
args.reduction .vars = clauseOps.reductionVars ;
2526
2529
2527
- auto genRegionEntryCB = [&](mlir::Operation *op) {
2528
- genEntryBlock (converter.getFirOpBuilder (), args, op->getRegion (0 ));
2529
- bindEntryBlockArgs (
2530
- converter, llvm::cast<mlir::omp::BlockArgOpenMPOpInterface>(op), args);
2531
- return llvm::to_vector (args.getSyms ());
2532
- };
2533
-
2534
2530
return genOpWithBody<mlir::omp::TeamsOp>(
2535
2531
OpWithBodyGenInfo (converter, symTable, semaCtx, loc, eval,
2536
2532
llvm::omp::Directive::OMPD_teams)
2537
2533
.setClauses (&item->clauses )
2538
- .setGenRegionEntryCb (genRegionEntryCB ),
2534
+ .setEntryBlockArgs (&args ),
2539
2535
queue, item, clauseOps);
2540
2536
}
2541
2537
0 commit comments