@@ -138,11 +138,35 @@ static mlir::Type getLoopVarType(Fortran::lower::AbstractConverter &converter,
138
138
return converter.getFirOpBuilder ().getIntegerType (loopVarTypeSize);
139
139
}
140
140
141
+ // / Create empty blocks for the current region.
142
+ // / These blocks replace blocks parented to an enclosing region.
143
+ void createEmptyRegionBlocks (
144
+ fir::FirOpBuilder &firOpBuilder,
145
+ std::list<Fortran::lower::pft::Evaluation> &evaluationList) {
146
+ auto *region = &firOpBuilder.getRegion ();
147
+ for (auto &eval : evaluationList) {
148
+ if (eval.block ) {
149
+ if (eval.block ->empty ()) {
150
+ eval.block ->erase ();
151
+ eval.block = firOpBuilder.createBlock (region);
152
+ } else {
153
+ [[maybe_unused]] auto &terminatorOp = eval.block ->back ();
154
+ assert ((mlir::isa<mlir::omp::TerminatorOp>(terminatorOp) ||
155
+ mlir::isa<mlir::omp::YieldOp>(terminatorOp)) &&
156
+ " expected terminator op" );
157
+ }
158
+ }
159
+ if (eval.hasNestedEvaluations ())
160
+ createEmptyRegionBlocks (firOpBuilder, eval.getNestedEvaluations ());
161
+ }
162
+ }
163
+
141
164
// / Create the body (block) for an OpenMP Operation.
142
165
// /
143
166
// / \param [in] op - the operation the body belongs to.
144
167
// / \param [inout] converter - converter to use for the clauses.
145
168
// / \param [in] loc - location in source code.
169
+ // / \param [in] eval - current PFT node/evaluation.
146
170
// / \oaran [in] clauses - list of clauses to process.
147
171
// / \param [in] args - block arguments (induction variable[s]) for the
148
172
// // region.
@@ -151,14 +175,14 @@ static mlir::Type getLoopVarType(Fortran::lower::AbstractConverter &converter,
151
175
template <typename Op>
152
176
static void
153
177
createBodyOfOp (Op &op, Fortran::lower::AbstractConverter &converter,
154
- mlir::Location &loc,
178
+ mlir::Location &loc, Fortran::lower::pft::Evaluation &eval,
155
179
const Fortran::parser::OmpClauseList *clauses = nullptr ,
156
180
const SmallVector<const Fortran::semantics::Symbol *> &args = {},
157
181
bool outerCombined = false ) {
158
- fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder ();
159
- // If arguments for the region are provided then create the block with those
160
- // arguments . Also update the symbol's address with the mlir argument values .
161
- // e.g. For loops the arguments are the induction variable. And all further
182
+ auto &firOpBuilder = converter.getFirOpBuilder ();
183
+ // If an argument for the region is provided then create the block with that
184
+ // argument . Also update the symbol's address with the mlir argument value .
185
+ // e.g. For loops the argument is the induction variable. And all further
162
186
// uses of the induction variable should use this mlir value.
163
187
if (args.size ()) {
164
188
std::size_t loopVarTypeSize = 0 ;
@@ -184,7 +208,10 @@ createBodyOfOp(Op &op, Fortran::lower::AbstractConverter &converter,
184
208
auto &block = op.getRegion ().back ();
185
209
firOpBuilder.setInsertionPointToStart (&block);
186
210
187
- // Insert the terminator.
211
+ if (eval.lowerAsUnstructured ())
212
+ createEmptyRegionBlocks (firOpBuilder, eval.getNestedEvaluations ());
213
+
214
+ // Ensure the block is well-formed by inserting terminators.
188
215
if constexpr (std::is_same_v<Op, omp::WsLoopOp>) {
189
216
mlir::ValueRange results;
190
217
firOpBuilder.create <mlir::omp::YieldOp>(loc, results);
@@ -369,7 +396,7 @@ createCombinedParallelOp(Fortran::lower::AbstractConverter &converter,
369
396
allocateOperands, allocatorOperands, /* reduction_vars=*/ ValueRange (),
370
397
/* reductions=*/ nullptr , procBindKindAttr);
371
398
372
- createBodyOfOp<omp::ParallelOp>(parallelOp, converter, currentLocation,
399
+ createBodyOfOp<omp::ParallelOp>(parallelOp, converter, currentLocation, eval,
373
400
&opClauseList, /* iv=*/ {},
374
401
/* isCombined=*/ true );
375
402
}
@@ -461,26 +488,27 @@ genOMP(Fortran::lower::AbstractConverter &converter,
461
488
allocateOperands, allocatorOperands, /* reduction_vars=*/ ValueRange (),
462
489
/* reductions=*/ nullptr , procBindKindAttr);
463
490
createBodyOfOp<omp::ParallelOp>(parallelOp, converter, currentLocation,
464
- &opClauseList);
491
+ eval, &opClauseList);
465
492
} else if (blockDirective.v == llvm::omp::OMPD_master) {
466
493
auto masterOp =
467
494
firOpBuilder.create <mlir::omp::MasterOp>(currentLocation, argTy);
468
- createBodyOfOp<omp::MasterOp>(masterOp, converter, currentLocation);
495
+ createBodyOfOp<omp::MasterOp>(masterOp, converter, currentLocation, eval );
469
496
} else if (blockDirective.v == llvm::omp::OMPD_single) {
470
497
auto singleOp = firOpBuilder.create <mlir::omp::SingleOp>(
471
498
currentLocation, allocateOperands, allocatorOperands, nowaitAttr);
472
- createBodyOfOp<omp::SingleOp>(singleOp, converter, currentLocation);
499
+ createBodyOfOp<omp::SingleOp>(singleOp, converter, currentLocation, eval );
473
500
} else if (blockDirective.v == llvm::omp::OMPD_ordered) {
474
501
auto orderedOp = firOpBuilder.create <mlir::omp::OrderedRegionOp>(
475
502
currentLocation, /* simd=*/ nullptr );
476
- createBodyOfOp<omp::OrderedRegionOp>(orderedOp, converter, currentLocation);
503
+ createBodyOfOp<omp::OrderedRegionOp>(orderedOp, converter, currentLocation,
504
+ eval);
477
505
} else if (blockDirective.v == llvm::omp::OMPD_task) {
478
506
auto taskOp = firOpBuilder.create <mlir::omp::TaskOp>(
479
507
currentLocation, ifClauseOperand, finalClauseOperand, untiedAttr,
480
508
mergeableAttr, /* in_reduction_vars=*/ ValueRange (),
481
509
/* in_reductions=*/ nullptr , priorityClauseOperand, allocateOperands,
482
510
allocatorOperands);
483
- createBodyOfOp (taskOp, converter, currentLocation, &opClauseList);
511
+ createBodyOfOp (taskOp, converter, currentLocation, eval, &opClauseList);
484
512
} else {
485
513
TODO (converter.getCurrentLocation (), " Unhandled block directive" );
486
514
}
@@ -644,7 +672,7 @@ static void genOMP(Fortran::lower::AbstractConverter &converter,
644
672
wsLoopOp.nowaitAttr (firOpBuilder.getUnitAttr ());
645
673
}
646
674
647
- createBodyOfOp<omp::WsLoopOp>(wsLoopOp, converter, currentLocation,
675
+ createBodyOfOp<omp::WsLoopOp>(wsLoopOp, converter, currentLocation, eval,
648
676
&wsLoopOpClauseList, iv);
649
677
}
650
678
@@ -688,7 +716,7 @@ genOMP(Fortran::lower::AbstractConverter &converter,
688
716
firOpBuilder.getContext (), global.sym_name ()));
689
717
}
690
718
}();
691
- createBodyOfOp<omp::CriticalOp>(criticalOp, converter, currentLocation);
719
+ createBodyOfOp<omp::CriticalOp>(criticalOp, converter, currentLocation, eval );
692
720
}
693
721
694
722
static void
@@ -700,7 +728,7 @@ genOMP(Fortran::lower::AbstractConverter &converter,
700
728
auto currentLocation = converter.getCurrentLocation ();
701
729
mlir::omp::SectionOp sectionOp =
702
730
firOpBuilder.create <mlir::omp::SectionOp>(currentLocation);
703
- createBodyOfOp<omp::SectionOp>(sectionOp, converter, currentLocation);
731
+ createBodyOfOp<omp::SectionOp>(sectionOp, converter, currentLocation, eval );
704
732
}
705
733
706
734
// TODO: Add support for reduction
@@ -757,14 +785,15 @@ genOMP(Fortran::lower::AbstractConverter &converter,
757
785
currentLocation, /* reduction_vars*/ ValueRange (),
758
786
/* reductions=*/ nullptr , allocateOperands, allocatorOperands,
759
787
/* nowait=*/ nullptr );
760
- createBodyOfOp (sectionsOp, converter, currentLocation);
788
+ createBodyOfOp (sectionsOp, converter, currentLocation, eval );
761
789
762
790
// Sections Construct
763
791
} else if (dir == llvm::omp::Directive::OMPD_sections) {
764
792
auto sectionsOp = firOpBuilder.create <mlir::omp::SectionsOp>(
765
793
currentLocation, reductionVars, /* reductions = */ nullptr ,
766
794
allocateOperands, allocatorOperands, noWaitClauseOperand);
767
- createBodyOfOp<omp::SectionsOp>(sectionsOp, converter, currentLocation);
795
+ createBodyOfOp<omp::SectionsOp>(sectionsOp, converter, currentLocation,
796
+ eval);
768
797
}
769
798
}
770
799
0 commit comments