Skip to content

Commit 10f9807

Browse files
committed
[mlir][flang][openmp] Rework parallel reduction operations
This patch reworks the way that parallel reduction operations function to better match the expected semantics from the OpenMP specification. Previously specific omp.reduction operations were used inside the region, meaning that the reduction only applied when the correct operation was used, whereas the specification states that any change to the variable inside the region should be taken into account for the reduction. The new semantics create a private reduction variable as a block argument which should be used normally for all operations on that variable in the region; this private variable is then combined with the others into the shared variable. This way no special omp.reduction operations are needed inside the region. This patch only makes the change for the `parallel` operation, the change for the `wsloop` operation will be in a separate patch.
1 parent b52fe2d commit 10f9807

File tree

8 files changed

+213
-75
lines changed

8 files changed

+213
-75
lines changed

flang/lib/Lower/OpenMP.cpp

Lines changed: 62 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -621,10 +621,12 @@ class ClauseProcessor {
621621
llvm::SmallVectorImpl<mlir::Location> *mapSymLocs = nullptr,
622622
llvm::SmallVectorImpl<const Fortran::semantics::Symbol *>
623623
*mapSymbols = nullptr) const;
624-
bool processReduction(
625-
mlir::Location currentLocation,
626-
llvm::SmallVectorImpl<mlir::Value> &reductionVars,
627-
llvm::SmallVectorImpl<mlir::Attribute> &reductionDeclSymbols) const;
624+
bool
625+
processReduction(mlir::Location currentLocation,
626+
llvm::SmallVectorImpl<mlir::Value> &reductionVars,
627+
llvm::SmallVectorImpl<mlir::Attribute> &reductionDeclSymbols,
628+
llvm::SmallVectorImpl<const Fortran::semantics::Symbol *>
629+
*reductionSymbols = nullptr) const;
628630
bool processSectionsReduction(mlir::Location currentLocation) const;
629631
bool processTo(llvm::SmallVectorImpl<DeclareTargetCapturePair> &result) const;
630632
bool
@@ -1075,12 +1077,14 @@ class ReductionProcessor {
10751077

10761078
/// Creates a reduction declaration and associates it with an OpenMP block
10771079
/// directive.
1078-
static void addReductionDecl(
1079-
mlir::Location currentLocation,
1080-
Fortran::lower::AbstractConverter &converter,
1081-
const Fortran::parser::OmpReductionClause &reduction,
1082-
llvm::SmallVectorImpl<mlir::Value> &reductionVars,
1083-
llvm::SmallVectorImpl<mlir::Attribute> &reductionDeclSymbols) {
1080+
static void
1081+
addReductionDecl(mlir::Location currentLocation,
1082+
Fortran::lower::AbstractConverter &converter,
1083+
const Fortran::parser::OmpReductionClause &reduction,
1084+
llvm::SmallVectorImpl<mlir::Value> &reductionVars,
1085+
llvm::SmallVectorImpl<mlir::Attribute> &reductionDeclSymbols,
1086+
llvm::SmallVectorImpl<const Fortran::semantics::Symbol *>
1087+
*reductionSymbols = nullptr) {
10841088
fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
10851089
mlir::omp::ReductionDeclareOp decl;
10861090
const auto &redOperator{
@@ -1110,6 +1114,8 @@ class ReductionProcessor {
11101114
if (const auto *name{
11111115
Fortran::parser::Unwrap<Fortran::parser::Name>(ompObject)}) {
11121116
if (const Fortran::semantics::Symbol * symbol{name->symbol}) {
1117+
if (reductionSymbols)
1118+
reductionSymbols->push_back(symbol);
11131119
mlir::Value symVal = converter.getSymbolAddress(*symbol);
11141120
if (auto declOp = symVal.getDefiningOp<hlfir::DeclareOp>())
11151121
symVal = declOp.getBase();
@@ -1142,6 +1148,8 @@ class ReductionProcessor {
11421148
if (const auto *name{
11431149
Fortran::parser::Unwrap<Fortran::parser::Name>(ompObject)}) {
11441150
if (const Fortran::semantics::Symbol * symbol{name->symbol}) {
1151+
if (reductionSymbols)
1152+
reductionSymbols->push_back(symbol);
11451153
mlir::Value symVal = converter.getSymbolAddress(*symbol);
11461154
if (auto declOp = symVal.getDefiningOp<hlfir::DeclareOp>())
11471155
symVal = declOp.getBase();
@@ -1935,13 +1943,16 @@ bool ClauseProcessor::processMap(
19351943
bool ClauseProcessor::processReduction(
19361944
mlir::Location currentLocation,
19371945
llvm::SmallVectorImpl<mlir::Value> &reductionVars,
1938-
llvm::SmallVectorImpl<mlir::Attribute> &reductionDeclSymbols) const {
1946+
llvm::SmallVectorImpl<mlir::Attribute> &reductionDeclSymbols,
1947+
llvm::SmallVectorImpl<const Fortran::semantics::Symbol *> *reductionSymbols)
1948+
const {
19391949
return findRepeatableClause<ClauseTy::Reduction>(
19401950
[&](const ClauseTy::Reduction *reductionClause,
19411951
const Fortran::parser::CharBlock &) {
19421952
ReductionProcessor rp;
19431953
rp.addReductionDecl(currentLocation, converter, reductionClause->v,
1944-
reductionVars, reductionDeclSymbols);
1954+
reductionVars, reductionDeclSymbols,
1955+
reductionSymbols);
19451956
});
19461957
}
19471958

@@ -2250,8 +2261,11 @@ static void createBodyOfOp(
22502261
Op &op, Fortran::lower::AbstractConverter &converter, mlir::Location &loc,
22512262
Fortran::lower::pft::Evaluation &eval, bool genNested,
22522263
const Fortran::parser::OmpClauseList *clauses = nullptr,
2253-
const llvm::SmallVector<const Fortran::semantics::Symbol *> &args = {},
2254-
bool outerCombined = false, DataSharingProcessor *dsp = nullptr) {
2264+
const llvm::SmallVector<const Fortran::semantics::Symbol *> &loopArgs = {},
2265+
bool outerCombined = false, DataSharingProcessor *dsp = nullptr,
2266+
const llvm::SmallVector<const Fortran::semantics::Symbol *> &reductionArgs =
2267+
{},
2268+
const llvm::SmallVector<mlir::Type> &reductionTypes = {}) {
22552269
fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
22562270

22572271
auto insertMarker = [](fir::FirOpBuilder &builder) {
@@ -2264,24 +2278,32 @@ static void createBodyOfOp(
22642278
// argument. Also update the symbol's address with the mlir argument value.
22652279
// e.g. For loops the argument is the induction variable. And all further
22662280
// uses of the induction variable should use this mlir value.
2267-
if (args.size()) {
2281+
if (loopArgs.size()) {
22682282
std::size_t loopVarTypeSize = 0;
2269-
for (const Fortran::semantics::Symbol *arg : args)
2283+
for (const Fortran::semantics::Symbol *arg : loopArgs)
22702284
loopVarTypeSize = std::max(loopVarTypeSize, arg->GetUltimate().size());
22712285
mlir::Type loopVarType = getLoopVarType(converter, loopVarTypeSize);
2272-
llvm::SmallVector<mlir::Type> tiv(args.size(), loopVarType);
2273-
llvm::SmallVector<mlir::Location> locs(args.size(), loc);
2286+
llvm::SmallVector<mlir::Type> tiv(loopArgs.size(), loopVarType);
2287+
llvm::SmallVector<mlir::Location> locs(loopArgs.size(), loc);
22742288
firOpBuilder.createBlock(&op.getRegion(), {}, tiv, locs);
22752289
// The argument is not currently in memory, so make a temporary for the
22762290
// argument, and store it there, then bind that location to the argument.
22772291
mlir::Operation *storeOp = nullptr;
2278-
for (auto [argIndex, argSymbol] : llvm::enumerate(args)) {
2292+
for (auto [argIndex, argSymbol] : llvm::enumerate(loopArgs)) {
22792293
mlir::Value indexVal =
22802294
fir::getBase(op.getRegion().front().getArgument(argIndex));
22812295
storeOp =
22822296
createAndSetPrivatizedLoopVar(converter, loc, indexVal, argSymbol);
22832297
}
22842298
firOpBuilder.setInsertionPointAfter(storeOp);
2299+
} else if (reductionArgs.size()) {
2300+
llvm::SmallVector<mlir::Location> locs(reductionArgs.size(), loc);
2301+
auto block =
2302+
firOpBuilder.createBlock(&op.getRegion(), {}, reductionTypes, locs);
2303+
for (auto [arg, prv] :
2304+
llvm::zip_equal(reductionArgs, block->getArguments())) {
2305+
converter.bindSymbol(*arg, prv);
2306+
}
22852307
} else {
22862308
firOpBuilder.createBlock(&op.getRegion());
22872309
}
@@ -2382,8 +2404,8 @@ static void createBodyOfOp(
23822404
assert(tempDsp.has_value());
23832405
tempDsp->processStep2(op, isLoop);
23842406
} else {
2385-
if (isLoop && args.size() > 0)
2386-
dsp->setLoopIV(converter.getSymbolAddress(*args[0]));
2407+
if (isLoop && loopArgs.size() > 0)
2408+
dsp->setLoopIV(converter.getSymbolAddress(*loopArgs[0]));
23872409
dsp->processStep2(op, isLoop);
23882410
}
23892411
}
@@ -2468,7 +2490,8 @@ static OpTy genOpWithBody(Fortran::lower::AbstractConverter &converter,
24682490
currentLocation, std::forward<Args>(args)...);
24692491
createBodyOfOp<OpTy>(op, converter, currentLocation, eval, genNested,
24702492
clauseList,
2471-
/*args=*/{}, outerCombined);
2493+
/*loopArgs=*/{}, outerCombined, /*dsp=*/nullptr,
2494+
/*reductionArgs=*/{}, /*reductionTypes=*/{});
24722495
return op;
24732496
}
24742497

@@ -2505,6 +2528,7 @@ genParallelOp(Fortran::lower::AbstractConverter &converter,
25052528
llvm::SmallVector<mlir::Value> allocateOperands, allocatorOperands,
25062529
reductionVars;
25072530
llvm::SmallVector<mlir::Attribute> reductionDeclSymbols;
2531+
llvm::SmallVector<const Fortran::semantics::Symbol *> reductionSymbols;
25082532

25092533
ClauseProcessor cp(converter, clauseList);
25102534
cp.processIf(Fortran::parser::OmpIfClause::DirectiveNameModifier::Parallel,
@@ -2514,18 +2538,29 @@ genParallelOp(Fortran::lower::AbstractConverter &converter,
25142538
cp.processDefault();
25152539
cp.processAllocate(allocatorOperands, allocateOperands);
25162540
if (!outerCombined)
2517-
cp.processReduction(currentLocation, reductionVars, reductionDeclSymbols);
2541+
cp.processReduction(currentLocation, reductionVars, reductionDeclSymbols,
2542+
&reductionSymbols);
25182543

2519-
return genOpWithBody<mlir::omp::ParallelOp>(
2520-
converter, eval, genNested, currentLocation, outerCombined, &clauseList,
2521-
/*resultTypes=*/mlir::TypeRange(), ifClauseOperand,
2544+
auto op = converter.getFirOpBuilder().create<mlir::omp::ParallelOp>(
2545+
currentLocation, mlir::TypeRange(), ifClauseOperand,
25222546
numThreadsClauseOperand, allocateOperands, allocatorOperands,
25232547
reductionVars,
25242548
reductionDeclSymbols.empty()
25252549
? nullptr
25262550
: mlir::ArrayAttr::get(converter.getFirOpBuilder().getContext(),
25272551
reductionDeclSymbols),
25282552
procBindKindAttr);
2553+
2554+
llvm::SmallVector<mlir::Type> reductionTypes;
2555+
reductionTypes.reserve(reductionVars.size());
2556+
llvm::transform(reductionVars, std::back_inserter(reductionTypes),
2557+
[](mlir::Value v) { return v.getType(); });
2558+
createBodyOfOp<mlir::omp::ParallelOp>(op, converter, currentLocation, eval,
2559+
genNested, &clauseList, /*loopArgs=*/{},
2560+
outerCombined, /*dsp=*/nullptr,
2561+
reductionSymbols, reductionTypes);
2562+
2563+
return op;
25292564
}
25302565

25312566
static mlir::omp::SectionOp
@@ -3517,10 +3552,8 @@ genOMP(Fortran::lower::AbstractConverter &converter,
35173552
break;
35183553
}
35193554

3520-
if (singleDirective) {
3521-
genOpenMPReduction(converter, beginClauseList);
3555+
if (singleDirective)
35223556
return;
3523-
}
35243557

35253558
// Codegen for combined directives
35263559
bool combinedDirective = false;
@@ -3556,7 +3589,6 @@ genOMP(Fortran::lower::AbstractConverter &converter,
35563589
")");
35573590

35583591
genNestedEvaluations(converter, eval);
3559-
genOpenMPReduction(converter, beginClauseList);
35603592
}
35613593

35623594
static void

flang/test/Lower/OpenMP/FIR/parallel-reduction-add.f90

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,11 @@
2727
!CHECK: %[[IREF:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFsimple_int_addEi"}
2828
!CHECK: %[[I_START:.*]] = arith.constant 0 : i32
2929
!CHECK: fir.store %[[I_START]] to %[[IREF]] : !fir.ref<i32>
30-
!CHECK: omp.parallel reduction(@[[RED_I32_NAME]] -> %[[IREF]] : !fir.ref<i32>) {
31-
!CHECK: %[[I_INCR:.*]] = arith.constant 1 : i32
32-
!CHECK: omp.reduction %[[I_INCR]], %[[IREF]] : i32, !fir.ref<i32>
30+
!CHECK: omp.parallel reduction(@[[RED_I32_NAME]] %[[IREF]] -> %[[PRV:.+]] : !fir.ref<i32>) {
31+
!CHECK: %[[LPRV:.+]] = fir.load %[[PRV]] : !fir.ref<i32>
32+
!CHECK: %[[I_INCR:.+]] = arith.constant 1 : i32
33+
!CHECK: %[[RES:.+]] = arith.addi %[[LPRV]], %[[I_INCR]]
34+
!CHECK: fir.store %[[RES]] to %[[PRV]] : !fir.ref<i32>
3335
!CHECK: omp.terminator
3436
!CHECK: }
3537
!CHECK: return
@@ -48,9 +50,11 @@ subroutine simple_int_add
4850
!CHECK: %[[RREF:.*]] = fir.alloca f32 {bindc_name = "r", uniq_name = "_QFsimple_real_addEr"}
4951
!CHECK: %[[R_START:.*]] = arith.constant 0.000000e+00 : f32
5052
!CHECK: fir.store %[[R_START]] to %[[RREF]] : !fir.ref<f32>
51-
!CHECK: omp.parallel reduction(@[[RED_F32_NAME]] -> %[[RREF]] : !fir.ref<f32>) {
52-
!CHECK: %[[R_INCR:.*]] = arith.constant 1.500000e+00 : f32
53-
!CHECK: omp.reduction %[[R_INCR]], %[[RREF]] : f32, !fir.ref<f32>
53+
!CHECK: omp.parallel reduction(@[[RED_F32_NAME]] %[[RREF]] -> %[[PRV:.+]] : !fir.ref<f32>) {
54+
!CHECK: %[[LPRV:.+]] = fir.load %[[PRV]] : !fir.ref<f32>
55+
!CHECK: %[[R_INCR:.+]] = arith.constant 1.500000e+00 : f32
56+
!CHECK: %[[RES]] = arith.addf %[[LPRV]], %[[R_INCR]] {{.*}} : f32
57+
!CHECK: fir.store %[[RES]] to %[[PRV]] : !fir.ref<f32>
5458
!CHECK: omp.terminator
5559
!CHECK: }
5660
!CHECK: return
@@ -72,11 +76,15 @@ subroutine simple_real_add
7276
!CHECK: fir.store %[[R_START]] to %[[RREF]] : !fir.ref<f32>
7377
!CHECK: %[[I_START:.*]] = arith.constant 0 : i32
7478
!CHECK: fir.store %[[I_START]] to %[[IREF]] : !fir.ref<i32>
75-
!CHECK: omp.parallel reduction(@[[RED_I32_NAME]] -> %[[IREF]] : !fir.ref<i32>, @[[RED_F32_NAME]] -> %[[RREF]] : !fir.ref<f32>) {
79+
!CHECK: omp.parallel reduction(@[[RED_I32_NAME]] %[[IREF]] -> %[[PRV0:.+]] : !fir.ref<i32>, @[[RED_F32_NAME]] %[[RREF]] -> %[[PRV1:.+]] : !fir.ref<f32>) {
7680
!CHECK: %[[R_INCR:.*]] = arith.constant 1.500000e+00 : f32
77-
!CHECK: omp.reduction %[[R_INCR]], %[[RREF]] : f32, !fir.ref<f32>
81+
!CHECK: %[[LPRV1:.+]] = fir.load %[[PRV1]] : !fir.ref<f32>
82+
!CHECK: %[[RES1:.+]] = arith.addf %[[R_INCR]], %[[LPRV1]] {{.*}} : f32
83+
!CHECK: fir.store %[[RES1]] to %[[PRV1]]
84+
!CHECK: %[[LPRV0:.+]] = fir.load %[[PRV0]] : !fir.ref<i32>
7885
!CHECK: %[[I_INCR:.*]] = arith.constant 3 : i32
79-
!CHECK: omp.reduction %[[I_INCR]], %[[IREF]] : i32, !fir.ref<i32>
86+
!CHECK: %[[RES0:.+]] = arith.addi %[[LPRV0]], %[[I_INCR]]
87+
!CHECK: fir.store %[[RES0]] to %[[PRV0]]
8088
!CHECK: omp.terminator
8189
!CHECK: }
8290
!CHECK: return

flang/test/Lower/OpenMP/parallel-reduction-add.f90

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,12 @@
2828
!CHECK: %[[I_DECL:.*]]:2 = hlfir.declare %[[IREF]] {uniq_name = "_QFsimple_int_addEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
2929
!CHECK: %[[I_START:.*]] = arith.constant 0 : i32
3030
!CHECK: hlfir.assign %[[I_START]] to %[[I_DECL]]#0 : i32, !fir.ref<i32>
31-
!CHECK: omp.parallel reduction(@[[RED_I32_NAME]] -> %[[I_DECL]]#0 : !fir.ref<i32>) {
31+
!CHECK: omp.parallel reduction(@[[RED_I32_NAME]] %[[I_DECL]]#0 -> %[[PRV:.+]] : !fir.ref<i32>) {
32+
!CHECK: %[[P_DECL:.+]]:2 = hlfir.declare %[[PRV]] {{.*}} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
33+
!CHECK: %[[LPRV:.+]] = fir.load %[[P_DECL]]#0 : !fir.ref<i32>
3234
!CHECK: %[[I_INCR:.*]] = arith.constant 1 : i32
33-
!CHECK: omp.reduction %[[I_INCR]], %[[I_DECL]]#0 : i32, !fir.ref<i32>
35+
!CHECK: %[[RES:.+]] = arith.addi %[[LPRV]], %[[I_INCR]] : i32
36+
!CHECK: hlfir.assign %[[RES]] to %[[P_DECL]]#0 : i32, !fir.ref<i32>
3437
!CHECK: omp.terminator
3538
!CHECK: }
3639
!CHECK: return
@@ -50,9 +53,12 @@ subroutine simple_int_add
5053
!CHECK: %[[R_DECL:.*]]:2 = hlfir.declare %[[RREF]] {uniq_name = "_QFsimple_real_addEr"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
5154
!CHECK: %[[R_START:.*]] = arith.constant 0.000000e+00 : f32
5255
!CHECK: hlfir.assign %[[R_START]] to %[[R_DECL]]#0 : f32, !fir.ref<f32>
53-
!CHECK: omp.parallel reduction(@[[RED_F32_NAME]] -> %[[R_DECL]]#0 : !fir.ref<f32>) {
56+
!CHECK: omp.parallel reduction(@[[RED_F32_NAME]] %[[R_DECL]]#0 -> %[[PRV:.+]] : !fir.ref<f32>) {
57+
!CHECK: %[[P_DECL:.+]]:2 = hlfir.declare %[[PRV]] {{.*}} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
58+
!CHECK: %[[LPRV:.+]] = fir.load %[[P_DECL]]#0 : !fir.ref<f32>
5459
!CHECK: %[[R_INCR:.*]] = arith.constant 1.500000e+00 : f32
55-
!CHECK: omp.reduction %[[R_INCR]], %[[R_DECL]]#0 : f32, !fir.ref<f32>
60+
!CHECK: %[[RES:.+]] = arith.addf %[[LPRV]], %[[R_INCR]] {{.*}} : f32
61+
!CHECK: hlfir.assign %[[RES]] to %[[P_DECL]]#0 : f32, !fir.ref<f32>
5662
!CHECK: omp.terminator
5763
!CHECK: }
5864
!CHECK: return
@@ -76,11 +82,17 @@ subroutine simple_real_add
7682
!CHECK: hlfir.assign %[[R_START]] to %[[R_DECL]]#0 : f32, !fir.ref<f32>
7783
!CHECK: %[[I_START:.*]] = arith.constant 0 : i32
7884
!CHECK: hlfir.assign %[[I_START]] to %[[I_DECL]]#0 : i32, !fir.ref<i32>
79-
!CHECK: omp.parallel reduction(@[[RED_I32_NAME]] -> %[[I_DECL]]#0 : !fir.ref<i32>, @[[RED_F32_NAME]] -> %[[R_DECL]]#0 : !fir.ref<f32>) {
85+
!CHECK: omp.parallel reduction(@[[RED_I32_NAME]] %[[I_DECL]]#0 -> %[[IPRV:.+]] : !fir.ref<i32>, @[[RED_F32_NAME]] %[[R_DECL]]#0 -> %[[RPRV:.+]] : !fir.ref<f32>) {
86+
!CHECK: %[[IP_DECL:.+]]:2 = hlfir.declare %[[IPRV]] {{.*}} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
87+
!CHECK: %[[RP_DECL:.+]]:2 = hlfir.declare %[[RPRV]] {{.*}} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
8088
!CHECK: %[[R_INCR:.*]] = arith.constant 1.500000e+00 : f32
81-
!CHECK: omp.reduction %[[R_INCR]], %[[R_DECL]]#0 : f32, !fir.ref<f32>
89+
!CHECK: %[[R_LPRV:.+]] = fir.load %[[RP_DECL]]#0 : !fir.ref<f32>
90+
!CHECK: %[[RES1:.+]] = arith.addf %[[R_INCR]], %[[R_LPRV]] {{.*}} : f32
91+
!CHECK: hlfir.assign %[[RES1]] to %[[RP_DECL]]#0 : f32, !fir.ref<f32>
92+
!CHECK: %[[I_LPRV:.+]] = fir.load %[[IP_DECL]]#0 : !fir.ref<i32>
8293
!CHECK: %[[I_INCR:.*]] = arith.constant 3 : i32
83-
!CHECK: omp.reduction %[[I_INCR]], %[[I_DECL]]#0 : i32, !fir.ref<i32>
94+
!CHECK: %[[RES0:.+]] = arith.addi %[[I_LPRV]], %[[I_INCR]] : i32
95+
!CHECK: hlfir.assign %[[RES0]] to %[[IP_DECL]]#0 : i32, !fir.ref<i32>
8496
!CHECK: omp.terminator
8597
!CHECK: }
8698
!CHECK: return

mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -200,19 +200,16 @@ def ParallelOp : OpenMP_Op<"parallel", [
200200
unsigned getNumReductionVars() { return getReductionVars().size(); }
201201
}];
202202
let assemblyFormat = [{
203-
oilist( `reduction` `(`
204-
custom<ReductionVarList>(
205-
$reduction_vars, type($reduction_vars), $reductions
206-
) `)`
207-
| `if` `(` $if_expr_var `:` type($if_expr_var) `)`
203+
oilist(
204+
`if` `(` $if_expr_var `:` type($if_expr_var) `)`
208205
| `num_threads` `(` $num_threads_var `:` type($num_threads_var) `)`
209206
| `allocate` `(`
210207
custom<AllocateAndAllocator>(
211208
$allocate_vars, type($allocate_vars),
212209
$allocators_vars, type($allocators_vars)
213210
) `)`
214211
| `proc_bind` `(` custom<ClauseAttr>($proc_bind_val) `)`
215-
) $region attr-dict
212+
) custom<ParallelRegion>($region, $reduction_vars, type($reduction_vars), $reductions) attr-dict
216213
}];
217214
let hasVerifier = 1;
218215
}

0 commit comments

Comments
 (0)