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