@@ -2968,24 +2968,150 @@ genOMP(Fortran::lower::AbstractConverter &converter,
2968
2968
standaloneConstruct.u );
2969
2969
}
2970
2970
2971
- static void genOMP (Fortran::lower::AbstractConverter &converter,
2972
- Fortran::lower::pft::Evaluation &eval,
2973
- Fortran::semantics::SemanticsContext &semanticsContext,
2974
- const Fortran::parser::OpenMPLoopConstruct &loopConstruct) {
2971
+ static void
2972
+ createSimdLoop (Fortran::lower::AbstractConverter &converter,
2973
+ Fortran::lower::pft::Evaluation &eval,
2974
+ llvm::omp::Directive ompDirective,
2975
+ const Fortran::parser::OmpClauseList &loopOpClauseList,
2976
+ mlir::Location loc) {
2975
2977
fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder ();
2976
- llvm::SmallVector<mlir::Value> lowerBound, upperBound, step, linearVars,
2977
- linearStepVars, reductionVars;
2978
+ DataSharingProcessor dsp (converter, loopOpClauseList, eval);
2979
+ dsp.processStep1 ();
2980
+
2981
+ Fortran::lower::StatementContext stmtCtx;
2978
2982
mlir::Value scheduleChunkClauseOperand;
2979
- mlir::IntegerAttr orderedClauseOperand;
2983
+ llvm::SmallVector<mlir::Value> lowerBound, upperBound, step, reductionVars;
2984
+ llvm::SmallVector<const Fortran::semantics::Symbol *> iv;
2985
+ llvm::SmallVector<mlir::Attribute> reductionDeclSymbols;
2986
+ mlir::omp::ClauseOrderKindAttr orderClauseOperand;
2987
+ std::size_t loopVarTypeSize;
2988
+
2989
+ ClauseProcessor cp (converter, loopOpClauseList);
2990
+ cp.processCollapse (loc, eval, lowerBound, upperBound, step, iv,
2991
+ loopVarTypeSize);
2992
+ cp.processScheduleChunk (stmtCtx, scheduleChunkClauseOperand);
2993
+ cp.processReduction (loc, reductionVars, reductionDeclSymbols);
2994
+ cp.processTODO <Fortran::parser::OmpClause::Linear,
2995
+ Fortran::parser::OmpClause::Order>(loc, ompDirective);
2996
+
2997
+ // The types of lower bound, upper bound, and step are converted into the
2998
+ // type of the loop variable if necessary.
2999
+ mlir::Type loopVarType = getLoopVarType (converter, loopVarTypeSize);
3000
+ for (unsigned it = 0 ; it < (unsigned )lowerBound.size (); it++) {
3001
+ lowerBound[it] =
3002
+ firOpBuilder.createConvert (loc, loopVarType, lowerBound[it]);
3003
+ upperBound[it] =
3004
+ firOpBuilder.createConvert (loc, loopVarType, upperBound[it]);
3005
+ step[it] = firOpBuilder.createConvert (loc, loopVarType, step[it]);
3006
+ }
3007
+
3008
+ llvm::SmallVector<mlir::Value> alignedVars, nontemporalVars;
3009
+ mlir::Value ifClauseOperand;
3010
+ mlir::IntegerAttr simdlenClauseOperand, safelenClauseOperand;
3011
+ cp.processIf (Fortran::parser::OmpIfClause::DirectiveNameModifier::Simd,
3012
+ ifClauseOperand);
3013
+ cp.processSimdlen (simdlenClauseOperand);
3014
+ cp.processSafelen (safelenClauseOperand);
3015
+ cp.processTODO <Fortran::parser::OmpClause::Aligned,
3016
+ Fortran::parser::OmpClause::Allocate,
3017
+ Fortran::parser::OmpClause::Nontemporal>(loc, ompDirective);
3018
+
3019
+ mlir::TypeRange resultType;
3020
+ auto simdLoopOp = firOpBuilder.create <mlir::omp::SimdLoopOp>(
3021
+ loc, resultType, lowerBound, upperBound, step, alignedVars,
3022
+ /* alignment_values=*/ nullptr , ifClauseOperand, nontemporalVars,
3023
+ orderClauseOperand, simdlenClauseOperand, safelenClauseOperand,
3024
+ /* inclusive=*/ firOpBuilder.getUnitAttr ());
3025
+ createBodyOfOp<mlir::omp::SimdLoopOp>(simdLoopOp, converter, loc, eval,
3026
+ &loopOpClauseList, iv,
3027
+ /* outer=*/ false , &dsp);
3028
+ }
3029
+
3030
+ static void createWsLoop (Fortran::lower::AbstractConverter &converter,
3031
+ Fortran::lower::pft::Evaluation &eval,
3032
+ llvm::omp::Directive ompDirective,
3033
+ const Fortran::parser::OmpClauseList &beginClauseList,
3034
+ const Fortran::parser::OmpClauseList *endClauseList,
3035
+ mlir::Location loc) {
3036
+ fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder ();
3037
+ DataSharingProcessor dsp (converter, beginClauseList, eval);
3038
+ dsp.processStep1 ();
3039
+
3040
+ Fortran::lower::StatementContext stmtCtx;
3041
+ mlir::Value scheduleChunkClauseOperand;
3042
+ llvm::SmallVector<mlir::Value> lowerBound, upperBound, step, reductionVars,
3043
+ linearVars, linearStepVars;
3044
+ llvm::SmallVector<const Fortran::semantics::Symbol *> iv;
3045
+ llvm::SmallVector<mlir::Attribute> reductionDeclSymbols;
2980
3046
mlir::omp::ClauseOrderKindAttr orderClauseOperand;
2981
3047
mlir::omp::ClauseScheduleKindAttr scheduleValClauseOperand;
2982
- mlir::omp::ScheduleModifierAttr scheduleModClauseOperand;
2983
3048
mlir::UnitAttr nowaitClauseOperand, scheduleSimdClauseOperand;
2984
- llvm::SmallVector< mlir::Attribute> reductionDeclSymbols ;
2985
- Fortran::lower::StatementContext stmtCtx ;
3049
+ mlir::IntegerAttr orderedClauseOperand ;
3050
+ mlir::omp::ScheduleModifierAttr scheduleModClauseOperand ;
2986
3051
std::size_t loopVarTypeSize;
2987
- llvm::SmallVector<const Fortran::semantics::Symbol *> iv;
2988
3052
3053
+ ClauseProcessor cp (converter, beginClauseList);
3054
+ cp.processCollapse (loc, eval, lowerBound, upperBound, step, iv,
3055
+ loopVarTypeSize);
3056
+ cp.processScheduleChunk (stmtCtx, scheduleChunkClauseOperand);
3057
+ cp.processReduction (loc, reductionVars, reductionDeclSymbols);
3058
+ cp.processTODO <Fortran::parser::OmpClause::Linear,
3059
+ Fortran::parser::OmpClause::Order>(loc, ompDirective);
3060
+
3061
+ // The types of lower bound, upper bound, and step are converted into the
3062
+ // type of the loop variable if necessary.
3063
+ mlir::Type loopVarType = getLoopVarType (converter, loopVarTypeSize);
3064
+ for (unsigned it = 0 ; it < (unsigned )lowerBound.size (); it++) {
3065
+ lowerBound[it] =
3066
+ firOpBuilder.createConvert (loc, loopVarType, lowerBound[it]);
3067
+ upperBound[it] =
3068
+ firOpBuilder.createConvert (loc, loopVarType, upperBound[it]);
3069
+ step[it] = firOpBuilder.createConvert (loc, loopVarType, step[it]);
3070
+ }
3071
+
3072
+ auto wsLoopOp = firOpBuilder.create <mlir::omp::WsLoopOp>(
3073
+ loc, lowerBound, upperBound, step, linearVars, linearStepVars,
3074
+ reductionVars,
3075
+ reductionDeclSymbols.empty ()
3076
+ ? nullptr
3077
+ : mlir::ArrayAttr::get (firOpBuilder.getContext (),
3078
+ reductionDeclSymbols),
3079
+ scheduleValClauseOperand, scheduleChunkClauseOperand,
3080
+ /* schedule_modifiers=*/ nullptr ,
3081
+ /* simd_modifier=*/ nullptr , nowaitClauseOperand, orderedClauseOperand,
3082
+ orderClauseOperand,
3083
+ /* inclusive=*/ firOpBuilder.getUnitAttr ());
3084
+
3085
+ // Handle attribute based clauses.
3086
+ if (cp.processOrdered (orderedClauseOperand))
3087
+ wsLoopOp.setOrderedValAttr (orderedClauseOperand);
3088
+
3089
+ if (cp.processSchedule (scheduleValClauseOperand, scheduleModClauseOperand,
3090
+ scheduleSimdClauseOperand)) {
3091
+ wsLoopOp.setScheduleValAttr (scheduleValClauseOperand);
3092
+ wsLoopOp.setScheduleModifierAttr (scheduleModClauseOperand);
3093
+ wsLoopOp.setSimdModifierAttr (scheduleSimdClauseOperand);
3094
+ }
3095
+ // In FORTRAN `nowait` clause occur at the end of `omp do` directive.
3096
+ // i.e
3097
+ // !$omp do
3098
+ // <...>
3099
+ // !$omp end do nowait
3100
+ if (endClauseList) {
3101
+ if (ClauseProcessor (converter, *endClauseList)
3102
+ .processNowait (nowaitClauseOperand))
3103
+ wsLoopOp.setNowaitAttr (nowaitClauseOperand);
3104
+ }
3105
+
3106
+ createBodyOfOp<mlir::omp::WsLoopOp>(wsLoopOp, converter, loc, eval,
3107
+ &beginClauseList, iv,
3108
+ /* outer=*/ false , &dsp);
3109
+ }
3110
+
3111
+ static void genOMP (Fortran::lower::AbstractConverter &converter,
3112
+ Fortran::lower::pft::Evaluation &eval,
3113
+ Fortran::semantics::SemanticsContext &semanticsContext,
3114
+ const Fortran::parser::OpenMPLoopConstruct &loopConstruct) {
2989
3115
const auto &beginLoopDirective =
2990
3116
std::get<Fortran::parser::OmpBeginLoopDirective>(loopConstruct.t );
2991
3117
const auto &loopOpClauseList =
@@ -2995,6 +3121,17 @@ static void genOMP(Fortran::lower::AbstractConverter &converter,
2995
3121
const auto ompDirective =
2996
3122
std::get<Fortran::parser::OmpLoopDirective>(beginLoopDirective.t ).v ;
2997
3123
3124
+ const auto *endClauseList = [&]() {
3125
+ using RetTy = const Fortran::parser::OmpClauseList *;
3126
+ if (auto &endLoopDirective =
3127
+ std::get<std::optional<Fortran::parser::OmpEndLoopDirective>>(
3128
+ loopConstruct.t )) {
3129
+ return RetTy (
3130
+ &std::get<Fortran::parser::OmpClauseList>((*endLoopDirective).t ));
3131
+ }
3132
+ return RetTy ();
3133
+ }();
3134
+
2998
3135
bool validDirective = false ;
2999
3136
if (llvm::omp::topTaskloopSet.test (ompDirective)) {
3000
3137
validDirective = true ;
@@ -3033,97 +3170,14 @@ static void genOMP(Fortran::lower::AbstractConverter &converter,
3033
3170
" )" );
3034
3171
}
3035
3172
3036
- DataSharingProcessor dsp (converter, loopOpClauseList, eval);
3037
- dsp.processStep1 ();
3038
-
3039
- ClauseProcessor cp (converter, loopOpClauseList);
3040
- cp.processCollapse (currentLocation, eval, lowerBound, upperBound, step, iv,
3041
- loopVarTypeSize);
3042
- cp.processScheduleChunk (stmtCtx, scheduleChunkClauseOperand);
3043
- cp.processReduction (currentLocation, reductionVars, reductionDeclSymbols);
3044
- cp.processTODO <Fortran::parser::OmpClause::Linear,
3045
- Fortran::parser::OmpClause::Order>(currentLocation,
3046
- ompDirective);
3047
-
3048
- // The types of lower bound, upper bound, and step are converted into the
3049
- // type of the loop variable if necessary.
3050
- mlir::Type loopVarType = getLoopVarType (converter, loopVarTypeSize);
3051
- for (unsigned it = 0 ; it < (unsigned )lowerBound.size (); it++) {
3052
- lowerBound[it] = firOpBuilder.createConvert (currentLocation, loopVarType,
3053
- lowerBound[it]);
3054
- upperBound[it] = firOpBuilder.createConvert (currentLocation, loopVarType,
3055
- upperBound[it]);
3056
- step[it] =
3057
- firOpBuilder.createConvert (currentLocation, loopVarType, step[it]);
3058
- }
3059
-
3060
3173
// 2.9.3.1 SIMD construct
3061
3174
if (llvm::omp::allSimdSet.test (ompDirective)) {
3062
- llvm::SmallVector<mlir::Value> alignedVars, nontemporalVars;
3063
- mlir::Value ifClauseOperand;
3064
- mlir::IntegerAttr simdlenClauseOperand, safelenClauseOperand;
3065
- cp.processIf (Fortran::parser::OmpIfClause::DirectiveNameModifier::Simd,
3066
- ifClauseOperand);
3067
- cp.processSimdlen (simdlenClauseOperand);
3068
- cp.processSafelen (safelenClauseOperand);
3069
- cp.processTODO <Fortran::parser::OmpClause::Aligned,
3070
- Fortran::parser::OmpClause::Allocate,
3071
- Fortran::parser::OmpClause::Nontemporal>(currentLocation,
3072
- ompDirective);
3073
-
3074
- mlir::TypeRange resultType;
3075
- auto simdLoopOp = firOpBuilder.create <mlir::omp::SimdLoopOp>(
3076
- currentLocation, resultType, lowerBound, upperBound, step, alignedVars,
3077
- /* alignment_values=*/ nullptr , ifClauseOperand, nontemporalVars,
3078
- orderClauseOperand, simdlenClauseOperand, safelenClauseOperand,
3079
- /* inclusive=*/ firOpBuilder.getUnitAttr ());
3080
- createBodyOfOp<mlir::omp::SimdLoopOp>(
3081
- simdLoopOp, converter, currentLocation, eval, &loopOpClauseList, iv,
3082
- /* outer=*/ false , &dsp);
3083
- return ;
3084
- }
3085
-
3086
- auto wsLoopOp = firOpBuilder.create <mlir::omp::WsLoopOp>(
3087
- currentLocation, lowerBound, upperBound, step, linearVars, linearStepVars,
3088
- reductionVars,
3089
- reductionDeclSymbols.empty ()
3090
- ? nullptr
3091
- : mlir::ArrayAttr::get (firOpBuilder.getContext (),
3092
- reductionDeclSymbols),
3093
- scheduleValClauseOperand, scheduleChunkClauseOperand,
3094
- /* schedule_modifiers=*/ nullptr ,
3095
- /* simd_modifier=*/ nullptr , nowaitClauseOperand, orderedClauseOperand,
3096
- orderClauseOperand,
3097
- /* inclusive=*/ firOpBuilder.getUnitAttr ());
3098
-
3099
- // Handle attribute based clauses.
3100
- if (cp.processOrdered (orderedClauseOperand))
3101
- wsLoopOp.setOrderedValAttr (orderedClauseOperand);
3102
-
3103
- if (cp.processSchedule (scheduleValClauseOperand, scheduleModClauseOperand,
3104
- scheduleSimdClauseOperand)) {
3105
- wsLoopOp.setScheduleValAttr (scheduleValClauseOperand);
3106
- wsLoopOp.setScheduleModifierAttr (scheduleModClauseOperand);
3107
- wsLoopOp.setSimdModifierAttr (scheduleSimdClauseOperand);
3108
- }
3109
- // In FORTRAN `nowait` clause occur at the end of `omp do` directive.
3110
- // i.e
3111
- // !$omp do
3112
- // <...>
3113
- // !$omp end do nowait
3114
- if (const auto &endClauseList =
3115
- std::get<std::optional<Fortran::parser::OmpEndLoopDirective>>(
3116
- loopConstruct.t )) {
3117
- const auto &clauseList =
3118
- std::get<Fortran::parser::OmpClauseList>((*endClauseList).t );
3119
- if (ClauseProcessor (converter, clauseList)
3120
- .processNowait (nowaitClauseOperand))
3121
- wsLoopOp.setNowaitAttr (nowaitClauseOperand);
3175
+ createSimdLoop (converter, eval, ompDirective, loopOpClauseList,
3176
+ currentLocation);
3177
+ } else {
3178
+ createWsLoop (converter, eval, ompDirective, loopOpClauseList, endClauseList,
3179
+ currentLocation);
3122
3180
}
3123
-
3124
- createBodyOfOp<mlir::omp::WsLoopOp>(wsLoopOp, converter, currentLocation,
3125
- eval, &loopOpClauseList, iv,
3126
- /* outer=*/ false , &dsp);
3127
3181
}
3128
3182
3129
3183
static void
0 commit comments