@@ -110,6 +110,34 @@ static void gatherFuncAndVarSyms(
110
110
}
111
111
}
112
112
113
+ static Fortran::lower::pft::Evaluation *
114
+ getCollapsedEval (Fortran::lower::pft::Evaluation &eval, int collapseValue) {
115
+ // Return the Evaluation of the innermost collapsed loop, or the current
116
+ // evaluation, if there is nothing to collapse.
117
+ if (collapseValue == 0 )
118
+ return &eval;
119
+
120
+ Fortran::lower::pft::Evaluation *curEval = &eval.getFirstNestedEvaluation ();
121
+ for (int i = 1 ; i < collapseValue; i++) {
122
+ // The nested evaluations should be DoConstructs (i.e. they should form
123
+ // a loop nest). Each DoConstruct is a tuple <NonLabelDoStmt, Block,
124
+ // EndDoStmt>.
125
+ assert (curEval->isA <Fortran::parser::DoConstruct>());
126
+ curEval = &*std::next (curEval->getNestedEvaluations ().begin ());
127
+ }
128
+ return curEval;
129
+ }
130
+
131
+ static void genNestedEvaluations (Fortran::lower::AbstractConverter &converter,
132
+ Fortran::lower::pft::Evaluation &eval,
133
+ int collapseValue = 0 ) {
134
+ Fortran::lower::pft::Evaluation *curEval =
135
+ getCollapsedEval (eval, collapseValue);
136
+
137
+ for (Fortran::lower::pft::Evaluation &e : curEval->getNestedEvaluations ())
138
+ converter.genEval (e);
139
+ }
140
+
113
141
// ===----------------------------------------------------------------------===//
114
142
// DataSharingProcessor
115
143
// ===----------------------------------------------------------------------===//
@@ -2944,8 +2972,9 @@ genOmpFlush(Fortran::lower::AbstractConverter &converter,
2944
2972
2945
2973
static void
2946
2974
genOMP (Fortran::lower::AbstractConverter &converter,
2947
- Fortran::lower::pft::Evaluation &eval ,
2975
+ Fortran::lower::SymMap &symTable ,
2948
2976
Fortran::semantics::SemanticsContext &semanticsContext,
2977
+ Fortran::lower::pft::Evaluation &eval,
2949
2978
const Fortran::parser::OpenMPStandaloneConstruct &standaloneConstruct) {
2950
2979
std::visit (
2951
2980
Fortran::common::visitors{
@@ -3034,6 +3063,9 @@ createSimdLoop(Fortran::lower::AbstractConverter &converter,
3034
3063
createBodyOfOp<mlir::omp::SimdLoopOp>(simdLoopOp, converter, loc, eval,
3035
3064
&loopOpClauseList, iv,
3036
3065
/* outer=*/ false , &dsp);
3066
+
3067
+ genNestedEvaluations (converter, eval,
3068
+ Fortran::lower::getCollapseValue (loopOpClauseList));
3037
3069
}
3038
3070
3039
3071
static void createWsLoop (Fortran::lower::AbstractConverter &converter,
@@ -3107,11 +3139,15 @@ static void createWsLoop(Fortran::lower::AbstractConverter &converter,
3107
3139
createBodyOfOp<mlir::omp::WsLoopOp>(wsLoopOp, converter, loc, eval,
3108
3140
&beginClauseList, iv,
3109
3141
/* outer=*/ false , &dsp);
3142
+
3143
+ genNestedEvaluations (converter, eval,
3144
+ Fortran::lower::getCollapseValue (beginClauseList));
3110
3145
}
3111
3146
3112
3147
static void genOMP (Fortran::lower::AbstractConverter &converter,
3113
- Fortran::lower::pft::Evaluation &eval ,
3148
+ Fortran::lower::SymMap &symTable ,
3114
3149
Fortran::semantics::SemanticsContext &semanticsContext,
3150
+ Fortran::lower::pft::Evaluation &eval,
3115
3151
const Fortran::parser::OpenMPLoopConstruct &loopConstruct) {
3116
3152
const auto &beginLoopDirective =
3117
3153
std::get<Fortran::parser::OmpBeginLoopDirective>(loopConstruct.t );
@@ -3179,12 +3215,15 @@ static void genOMP(Fortran::lower::AbstractConverter &converter,
3179
3215
createWsLoop (converter, eval, ompDirective, loopOpClauseList, endClauseList,
3180
3216
currentLocation);
3181
3217
}
3218
+
3219
+ genOpenMPReduction (converter, loopOpClauseList);
3182
3220
}
3183
3221
3184
3222
static void
3185
3223
genOMP (Fortran::lower::AbstractConverter &converter,
3186
- Fortran::lower::pft::Evaluation &eval ,
3224
+ Fortran::lower::SymMap &symTable ,
3187
3225
Fortran::semantics::SemanticsContext &semanticsContext,
3226
+ Fortran::lower::pft::Evaluation &eval,
3188
3227
const Fortran::parser::OpenMPBlockConstruct &blockConstruct) {
3189
3228
const auto &beginBlockDirective =
3190
3229
std::get<Fortran::parser::OmpBeginBlockDirective>(blockConstruct.t );
@@ -3298,10 +3337,15 @@ genOMP(Fortran::lower::AbstractConverter &converter,
3298
3337
break ;
3299
3338
}
3300
3339
}
3340
+
3341
+ genNestedEvaluations (converter, eval);
3342
+ genOpenMPReduction (converter, beginClauseList);
3301
3343
}
3302
3344
3303
3345
static void
3304
3346
genOMP (Fortran::lower::AbstractConverter &converter,
3347
+ Fortran::lower::SymMap &symTable,
3348
+ Fortran::semantics::SemanticsContext &semanticsContext,
3305
3349
Fortran::lower::pft::Evaluation &eval,
3306
3350
const Fortran::parser::OpenMPCriticalConstruct &criticalConstruct) {
3307
3351
fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder ();
@@ -3336,10 +3380,13 @@ genOMP(Fortran::lower::AbstractConverter &converter,
3336
3380
}();
3337
3381
createBodyOfOp<mlir::omp::CriticalOp>(criticalOp, converter, currentLocation,
3338
3382
eval);
3383
+ genNestedEvaluations (converter, eval);
3339
3384
}
3340
3385
3341
3386
static void
3342
3387
genOMP (Fortran::lower::AbstractConverter &converter,
3388
+ Fortran::lower::SymMap &symTable,
3389
+ Fortran::semantics::SemanticsContext &semanticsContext,
3343
3390
Fortran::lower::pft::Evaluation &eval,
3344
3391
const Fortran::parser::OpenMPSectionConstruct §ionConstruct) {
3345
3392
mlir::Location currentLocation = converter.getCurrentLocation ();
@@ -3359,13 +3406,18 @@ genOMP(Fortran::lower::AbstractConverter &converter,
3359
3406
.t );
3360
3407
// Currently only private/firstprivate clause is handled, and
3361
3408
// all privatization is done within `omp.section` operations.
3409
+ symTable.pushScope ();
3362
3410
genOpWithBody<mlir::omp::SectionOp>(converter, eval, currentLocation,
3363
3411
/* outerCombined=*/ false ,
3364
3412
§ionsClauseList);
3413
+ genNestedEvaluations (converter, eval);
3414
+ symTable.popScope ();
3365
3415
}
3366
3416
3367
3417
static void
3368
3418
genOMP (Fortran::lower::AbstractConverter &converter,
3419
+ Fortran::lower::SymMap &symTable,
3420
+ Fortran::semantics::SemanticsContext &semanticsContext,
3369
3421
Fortran::lower::pft::Evaluation &eval,
3370
3422
const Fortran::parser::OpenMPSectionsConstruct §ionsConstruct) {
3371
3423
mlir::Location currentLocation = converter.getCurrentLocation ();
@@ -3406,10 +3458,14 @@ genOMP(Fortran::lower::AbstractConverter &converter,
3406
3458
/* reduction_vars=*/ mlir::ValueRange (),
3407
3459
/* reductions=*/ nullptr , allocateOperands,
3408
3460
allocatorOperands, nowaitClauseOperand);
3461
+
3462
+ genNestedEvaluations (converter, eval);
3409
3463
}
3410
3464
3411
3465
static void
3412
3466
genOMP (Fortran::lower::AbstractConverter &converter,
3467
+ Fortran::lower::SymMap &symTable,
3468
+ Fortran::semantics::SemanticsContext &semanticsContext,
3413
3469
Fortran::lower::pft::Evaluation &eval,
3414
3470
const Fortran::parser::OpenMPAtomicConstruct &atomicConstruct) {
3415
3471
std::visit (
@@ -3453,6 +3509,8 @@ genOMP(Fortran::lower::AbstractConverter &converter,
3453
3509
}
3454
3510
3455
3511
static void genOMP (Fortran::lower::AbstractConverter &converter,
3512
+ Fortran::lower::SymMap &symTable,
3513
+ Fortran::semantics::SemanticsContext &semanticsContext,
3456
3514
Fortran::lower::pft::Evaluation &eval,
3457
3515
const Fortran::parser::OpenMPDeclareTargetConstruct
3458
3516
&declareTargetConstruct) {
@@ -3504,24 +3562,28 @@ static void genOMP(Fortran::lower::AbstractConverter &converter,
3504
3562
}
3505
3563
3506
3564
static void genOMP (Fortran::lower::AbstractConverter &converter,
3565
+ Fortran::lower::SymMap &symTable,
3507
3566
Fortran::semantics::SemanticsContext &semanticsContext,
3508
3567
Fortran::lower::pft::Evaluation &eval,
3509
3568
const Fortran::parser::OpenMPConstruct &ompConstruct) {
3510
3569
std::visit (
3511
3570
Fortran::common::visitors{
3512
3571
[&](const Fortran::parser::OpenMPStandaloneConstruct
3513
3572
&standaloneConstruct) {
3514
- genOMP (converter, eval, semanticsContext, standaloneConstruct);
3573
+ genOMP (converter, symTable, semanticsContext, eval,
3574
+ standaloneConstruct);
3515
3575
},
3516
3576
[&](const Fortran::parser::OpenMPSectionsConstruct
3517
3577
§ionsConstruct) {
3518
- genOMP (converter, eval, sectionsConstruct);
3578
+ genOMP (converter, symTable, semanticsContext, eval,
3579
+ sectionsConstruct);
3519
3580
},
3520
3581
[&](const Fortran::parser::OpenMPSectionConstruct §ionConstruct) {
3521
- genOMP (converter, eval, sectionConstruct);
3582
+ genOMP (converter, symTable, semanticsContext, eval,
3583
+ sectionConstruct);
3522
3584
},
3523
3585
[&](const Fortran::parser::OpenMPLoopConstruct &loopConstruct) {
3524
- genOMP (converter, eval , semanticsContext, loopConstruct);
3586
+ genOMP (converter, symTable , semanticsContext, eval , loopConstruct);
3525
3587
},
3526
3588
[&](const Fortran::parser::OpenMPDeclarativeAllocate
3527
3589
&execAllocConstruct) {
@@ -3536,21 +3598,25 @@ static void genOMP(Fortran::lower::AbstractConverter &converter,
3536
3598
TODO (converter.getCurrentLocation (), " OpenMPAllocatorsConstruct" );
3537
3599
},
3538
3600
[&](const Fortran::parser::OpenMPBlockConstruct &blockConstruct) {
3539
- genOMP (converter, eval , semanticsContext, blockConstruct);
3601
+ genOMP (converter, symTable , semanticsContext, eval , blockConstruct);
3540
3602
},
3541
3603
[&](const Fortran::parser::OpenMPAtomicConstruct &atomicConstruct) {
3542
- genOMP (converter, eval, atomicConstruct);
3604
+ genOMP (converter, symTable, semanticsContext, eval,
3605
+ atomicConstruct);
3543
3606
},
3544
3607
[&](const Fortran::parser::OpenMPCriticalConstruct
3545
3608
&criticalConstruct) {
3546
- genOMP (converter, eval, criticalConstruct);
3609
+ genOMP (converter, symTable, semanticsContext, eval,
3610
+ criticalConstruct);
3547
3611
},
3548
3612
},
3549
3613
ompConstruct.u );
3550
3614
}
3551
3615
3552
3616
static void
3553
3617
genOMP (Fortran::lower::AbstractConverter &converter,
3618
+ Fortran::lower::SymMap &symTable,
3619
+ Fortran::semantics::SemanticsContext &semanticsContext,
3554
3620
Fortran::lower::pft::Evaluation &eval,
3555
3621
const Fortran::parser::OpenMPDeclarativeConstruct &ompDeclConstruct) {
3556
3622
std::visit (
@@ -3570,7 +3636,8 @@ genOMP(Fortran::lower::AbstractConverter &converter,
3570
3636
},
3571
3637
[&](const Fortran::parser::OpenMPDeclareTargetConstruct
3572
3638
&declareTargetConstruct) {
3573
- genOMP (converter, eval, declareTargetConstruct);
3639
+ genOMP (converter, symTable, semanticsContext, eval,
3640
+ declareTargetConstruct);
3574
3641
},
3575
3642
[&](const Fortran::parser::OpenMPRequiresConstruct
3576
3643
&requiresConstruct) {
@@ -3607,57 +3674,19 @@ void Fortran::lower::genOpenMPConstruct(
3607
3674
Fortran::semantics::SemanticsContext &semanticsContext,
3608
3675
Fortran::lower::pft::Evaluation &eval,
3609
3676
const Fortran::parser::OpenMPConstruct &omp) {
3610
-
3611
3677
symTable.pushScope ();
3612
- genOMP (converter, semanticsContext, eval, omp);
3613
-
3614
- const Fortran::parser::OpenMPLoopConstruct *ompLoop =
3615
- std::get_if<Fortran::parser::OpenMPLoopConstruct>(&omp.u );
3616
- const Fortran::parser::OpenMPBlockConstruct *ompBlock =
3617
- std::get_if<Fortran::parser::OpenMPBlockConstruct>(&omp.u );
3618
-
3619
- // If loop is part of an OpenMP Construct then the OpenMP dialect
3620
- // workshare loop operation has already been created. Only the
3621
- // body needs to be created here and the do_loop can be skipped.
3622
- // Skip the number of collapsed loops, which is 1 when there is a
3623
- // no collapse requested.
3624
-
3625
- Fortran::lower::pft::Evaluation *curEval = &eval;
3626
- const Fortran::parser::OmpClauseList *loopOpClauseList = nullptr ;
3627
- if (ompLoop) {
3628
- loopOpClauseList = &std::get<Fortran::parser::OmpClauseList>(
3629
- std::get<Fortran::parser::OmpBeginLoopDirective>(ompLoop->t ).t );
3630
- int64_t collapseValue = Fortran::lower::getCollapseValue (*loopOpClauseList);
3631
-
3632
- curEval = &curEval->getFirstNestedEvaluation ();
3633
- for (int64_t i = 1 ; i < collapseValue; i++) {
3634
- curEval = &*std::next (curEval->getNestedEvaluations ().begin ());
3635
- }
3636
- }
3637
-
3638
- for (Fortran::lower::pft::Evaluation &e : curEval->getNestedEvaluations ())
3639
- converter.genEval (e);
3640
-
3641
- if (ompLoop) {
3642
- genOpenMPReduction (converter, *loopOpClauseList);
3643
- } else if (ompBlock) {
3644
- const auto &blockStart =
3645
- std::get<Fortran::parser::OmpBeginBlockDirective>(ompBlock->t );
3646
- const auto &blockClauses =
3647
- std::get<Fortran::parser::OmpClauseList>(blockStart.t );
3648
- genOpenMPReduction (converter, blockClauses);
3649
- }
3650
-
3678
+ genOMP (converter, symTable, semanticsContext, eval, omp);
3651
3679
symTable.popScope ();
3652
3680
}
3653
3681
3654
3682
void Fortran::lower::genOpenMPDeclarativeConstruct (
3655
3683
Fortran::lower::AbstractConverter &converter,
3684
+ Fortran::lower::SymMap &symTable,
3685
+ Fortran::semantics::SemanticsContext &semanticsContext,
3656
3686
Fortran::lower::pft::Evaluation &eval,
3657
3687
const Fortran::parser::OpenMPDeclarativeConstruct &omp) {
3658
- genOMP (converter, eval, omp);
3659
- for (Fortran::lower::pft::Evaluation &e : eval.getNestedEvaluations ())
3660
- converter.genEval (e);
3688
+ genOMP (converter, symTable, semanticsContext, eval, omp);
3689
+ genNestedEvaluations (converter, eval);
3661
3690
}
3662
3691
3663
3692
void Fortran::lower::genOpenMPSymbolProperties (
0 commit comments