Skip to content

Commit 62f3165

Browse files
committed
[Flang][OpenMP] Separate creation of work-sharing and SIMD loops, NFC
These two constructs were both handled in `genOMP` for loop constructs. There is some shared code between the two, but there are also enough differences to separate these two cases into individual functions. The shared code may be placed into a helper function later if needed. Recursive lowering [1/5]
1 parent 959a430 commit 62f3165

File tree

1 file changed

+153
-99
lines changed

1 file changed

+153
-99
lines changed

flang/lib/Lower/OpenMP.cpp

Lines changed: 153 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -2968,24 +2968,150 @@ genOMP(Fortran::lower::AbstractConverter &converter,
29682968
standaloneConstruct.u);
29692969
}
29702970

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) {
29752977
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;
29782982
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;
29803046
mlir::omp::ClauseOrderKindAttr orderClauseOperand;
29813047
mlir::omp::ClauseScheduleKindAttr scheduleValClauseOperand;
2982-
mlir::omp::ScheduleModifierAttr scheduleModClauseOperand;
29833048
mlir::UnitAttr nowaitClauseOperand, scheduleSimdClauseOperand;
2984-
llvm::SmallVector<mlir::Attribute> reductionDeclSymbols;
2985-
Fortran::lower::StatementContext stmtCtx;
3049+
mlir::IntegerAttr orderedClauseOperand;
3050+
mlir::omp::ScheduleModifierAttr scheduleModClauseOperand;
29863051
std::size_t loopVarTypeSize;
2987-
llvm::SmallVector<const Fortran::semantics::Symbol *> iv;
29883052

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) {
29893115
const auto &beginLoopDirective =
29903116
std::get<Fortran::parser::OmpBeginLoopDirective>(loopConstruct.t);
29913117
const auto &loopOpClauseList =
@@ -2995,6 +3121,17 @@ static void genOMP(Fortran::lower::AbstractConverter &converter,
29953121
const auto ompDirective =
29963122
std::get<Fortran::parser::OmpLoopDirective>(beginLoopDirective.t).v;
29973123

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+
29983135
bool validDirective = false;
29993136
if (llvm::omp::topTaskloopSet.test(ompDirective)) {
30003137
validDirective = true;
@@ -3033,97 +3170,14 @@ static void genOMP(Fortran::lower::AbstractConverter &converter,
30333170
")");
30343171
}
30353172

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-
30603173
// 2.9.3.1 SIMD construct
30613174
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);
31223180
}
3123-
3124-
createBodyOfOp<mlir::omp::WsLoopOp>(wsLoopOp, converter, currentLocation,
3125-
eval, &loopOpClauseList, iv,
3126-
/*outer=*/false, &dsp);
31273181
}
31283182

31293183
static void

0 commit comments

Comments
 (0)