diff options
author | Krzysztof Parzyszek <Krzysztof.Parzyszek@amd.com> | 2024-01-15 08:01:41 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-15 08:01:41 -0600 |
commit | c5a9e354379d29ee763e9982faf57398789c8d5b (patch) | |
tree | e1999becd0c130ca582f95c104b652d8ab960341 /flang | |
parent | 5723fce088068cc91cf22e3a3da5700e213ce63e (diff) | |
download | llvm-c5a9e354379d29ee763e9982faf57398789c8d5b.zip llvm-c5a9e354379d29ee763e9982faf57398789c8d5b.tar.gz llvm-c5a9e354379d29ee763e9982faf57398789c8d5b.tar.bz2 |
[Flang][OpenMP] Push genEval calls to individual operations, NFC (#77758)
Introduce `genNestedEvaluations` that will lower all evaluations nested
in the given, accouting for a potential COLLAPSE directive.
Recursive lowering [2/5]
Diffstat (limited to 'flang')
-rw-r--r-- | flang/include/flang/Lower/OpenMP.h | 5 | ||||
-rw-r--r-- | flang/lib/Lower/Bridge.cpp | 3 | ||||
-rw-r--r-- | flang/lib/Lower/OpenMP.cpp | 137 |
3 files changed, 89 insertions, 56 deletions
diff --git a/flang/include/flang/Lower/OpenMP.h b/flang/include/flang/Lower/OpenMP.h index 6e772c4..872b7d5 100644 --- a/flang/include/flang/Lower/OpenMP.h +++ b/flang/include/flang/Lower/OpenMP.h @@ -56,7 +56,10 @@ void genOpenMPTerminator(fir::FirOpBuilder &, mlir::Operation *, void genOpenMPConstruct(AbstractConverter &, Fortran::lower::SymMap &, semantics::SemanticsContext &, pft::Evaluation &, const parser::OpenMPConstruct &); -void genOpenMPDeclarativeConstruct(AbstractConverter &, pft::Evaluation &, +void genOpenMPDeclarativeConstruct(AbstractConverter &, + Fortran::lower::SymMap &, + semantics::SemanticsContext &, + pft::Evaluation &, const parser::OpenMPDeclarativeConstruct &); /// Symbols in OpenMP code can have flags (e.g. threadprivate directive) /// that require additional handling when lowering the corresponding diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp index 2bceee0..8006b9b4 100644 --- a/flang/lib/Lower/Bridge.cpp +++ b/flang/lib/Lower/Bridge.cpp @@ -2440,7 +2440,8 @@ private: ompDeviceCodeFound = ompDeviceCodeFound || Fortran::lower::isOpenMPDeviceDeclareTarget(*this, getEval(), ompDecl); - genOpenMPDeclarativeConstruct(*this, getEval(), ompDecl); + genOpenMPDeclarativeConstruct( + *this, localSymbols, bridge.getSemanticsContext(), getEval(), ompDecl); builder->restoreInsertionPoint(insertPt); } diff --git a/flang/lib/Lower/OpenMP.cpp b/flang/lib/Lower/OpenMP.cpp index 497ad188..94c2c78 100644 --- a/flang/lib/Lower/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP.cpp @@ -110,6 +110,34 @@ static void gatherFuncAndVarSyms( } } +static Fortran::lower::pft::Evaluation * +getCollapsedEval(Fortran::lower::pft::Evaluation &eval, int collapseValue) { + // Return the Evaluation of the innermost collapsed loop, or the current + // evaluation, if there is nothing to collapse. + if (collapseValue == 0) + return &eval; + + Fortran::lower::pft::Evaluation *curEval = &eval.getFirstNestedEvaluation(); + for (int i = 1; i < collapseValue; i++) { + // The nested evaluations should be DoConstructs (i.e. they should form + // a loop nest). Each DoConstruct is a tuple <NonLabelDoStmt, Block, + // EndDoStmt>. + assert(curEval->isA<Fortran::parser::DoConstruct>()); + curEval = &*std::next(curEval->getNestedEvaluations().begin()); + } + return curEval; +} + +static void genNestedEvaluations(Fortran::lower::AbstractConverter &converter, + Fortran::lower::pft::Evaluation &eval, + int collapseValue = 0) { + Fortran::lower::pft::Evaluation *curEval = + getCollapsedEval(eval, collapseValue); + + for (Fortran::lower::pft::Evaluation &e : curEval->getNestedEvaluations()) + converter.genEval(e); +} + //===----------------------------------------------------------------------===// // DataSharingProcessor //===----------------------------------------------------------------------===// @@ -2944,8 +2972,9 @@ genOmpFlush(Fortran::lower::AbstractConverter &converter, static void genOMP(Fortran::lower::AbstractConverter &converter, - Fortran::lower::pft::Evaluation &eval, + Fortran::lower::SymMap &symTable, Fortran::semantics::SemanticsContext &semanticsContext, + Fortran::lower::pft::Evaluation &eval, const Fortran::parser::OpenMPStandaloneConstruct &standaloneConstruct) { std::visit( Fortran::common::visitors{ @@ -3034,6 +3063,9 @@ createSimdLoop(Fortran::lower::AbstractConverter &converter, createBodyOfOp<mlir::omp::SimdLoopOp>(simdLoopOp, converter, loc, eval, &loopOpClauseList, iv, /*outer=*/false, &dsp); + + genNestedEvaluations(converter, eval, + Fortran::lower::getCollapseValue(loopOpClauseList)); } static void createWsLoop(Fortran::lower::AbstractConverter &converter, @@ -3107,11 +3139,15 @@ static void createWsLoop(Fortran::lower::AbstractConverter &converter, createBodyOfOp<mlir::omp::WsLoopOp>(wsLoopOp, converter, loc, eval, &beginClauseList, iv, /*outer=*/false, &dsp); + + genNestedEvaluations(converter, eval, + Fortran::lower::getCollapseValue(beginClauseList)); } static void genOMP(Fortran::lower::AbstractConverter &converter, - Fortran::lower::pft::Evaluation &eval, + Fortran::lower::SymMap &symTable, Fortran::semantics::SemanticsContext &semanticsContext, + Fortran::lower::pft::Evaluation &eval, const Fortran::parser::OpenMPLoopConstruct &loopConstruct) { const auto &beginLoopDirective = std::get<Fortran::parser::OmpBeginLoopDirective>(loopConstruct.t); @@ -3179,12 +3215,15 @@ static void genOMP(Fortran::lower::AbstractConverter &converter, createWsLoop(converter, eval, ompDirective, loopOpClauseList, endClauseList, currentLocation); } + + genOpenMPReduction(converter, loopOpClauseList); } static void genOMP(Fortran::lower::AbstractConverter &converter, - Fortran::lower::pft::Evaluation &eval, + Fortran::lower::SymMap &symTable, Fortran::semantics::SemanticsContext &semanticsContext, + Fortran::lower::pft::Evaluation &eval, const Fortran::parser::OpenMPBlockConstruct &blockConstruct) { const auto &beginBlockDirective = std::get<Fortran::parser::OmpBeginBlockDirective>(blockConstruct.t); @@ -3298,10 +3337,15 @@ genOMP(Fortran::lower::AbstractConverter &converter, break; } } + + genNestedEvaluations(converter, eval); + genOpenMPReduction(converter, beginClauseList); } static void genOMP(Fortran::lower::AbstractConverter &converter, + Fortran::lower::SymMap &symTable, + Fortran::semantics::SemanticsContext &semanticsContext, Fortran::lower::pft::Evaluation &eval, const Fortran::parser::OpenMPCriticalConstruct &criticalConstruct) { fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); @@ -3336,10 +3380,13 @@ genOMP(Fortran::lower::AbstractConverter &converter, }(); createBodyOfOp<mlir::omp::CriticalOp>(criticalOp, converter, currentLocation, eval); + genNestedEvaluations(converter, eval); } static void genOMP(Fortran::lower::AbstractConverter &converter, + Fortran::lower::SymMap &symTable, + Fortran::semantics::SemanticsContext &semanticsContext, Fortran::lower::pft::Evaluation &eval, const Fortran::parser::OpenMPSectionConstruct §ionConstruct) { mlir::Location currentLocation = converter.getCurrentLocation(); @@ -3359,13 +3406,18 @@ genOMP(Fortran::lower::AbstractConverter &converter, .t); // Currently only private/firstprivate clause is handled, and // all privatization is done within `omp.section` operations. + symTable.pushScope(); genOpWithBody<mlir::omp::SectionOp>(converter, eval, currentLocation, /*outerCombined=*/false, §ionsClauseList); + genNestedEvaluations(converter, eval); + symTable.popScope(); } static void genOMP(Fortran::lower::AbstractConverter &converter, + Fortran::lower::SymMap &symTable, + Fortran::semantics::SemanticsContext &semanticsContext, Fortran::lower::pft::Evaluation &eval, const Fortran::parser::OpenMPSectionsConstruct §ionsConstruct) { mlir::Location currentLocation = converter.getCurrentLocation(); @@ -3406,10 +3458,14 @@ genOMP(Fortran::lower::AbstractConverter &converter, /*reduction_vars=*/mlir::ValueRange(), /*reductions=*/nullptr, allocateOperands, allocatorOperands, nowaitClauseOperand); + + genNestedEvaluations(converter, eval); } static void genOMP(Fortran::lower::AbstractConverter &converter, + Fortran::lower::SymMap &symTable, + Fortran::semantics::SemanticsContext &semanticsContext, Fortran::lower::pft::Evaluation &eval, const Fortran::parser::OpenMPAtomicConstruct &atomicConstruct) { std::visit( @@ -3453,6 +3509,8 @@ genOMP(Fortran::lower::AbstractConverter &converter, } static void genOMP(Fortran::lower::AbstractConverter &converter, + Fortran::lower::SymMap &symTable, + Fortran::semantics::SemanticsContext &semanticsContext, Fortran::lower::pft::Evaluation &eval, const Fortran::parser::OpenMPDeclareTargetConstruct &declareTargetConstruct) { @@ -3504,6 +3562,7 @@ static void genOMP(Fortran::lower::AbstractConverter &converter, } static void genOMP(Fortran::lower::AbstractConverter &converter, + Fortran::lower::SymMap &symTable, Fortran::semantics::SemanticsContext &semanticsContext, Fortran::lower::pft::Evaluation &eval, const Fortran::parser::OpenMPConstruct &ompConstruct) { @@ -3511,17 +3570,20 @@ static void genOMP(Fortran::lower::AbstractConverter &converter, Fortran::common::visitors{ [&](const Fortran::parser::OpenMPStandaloneConstruct &standaloneConstruct) { - genOMP(converter, eval, semanticsContext, standaloneConstruct); + genOMP(converter, symTable, semanticsContext, eval, + standaloneConstruct); }, [&](const Fortran::parser::OpenMPSectionsConstruct §ionsConstruct) { - genOMP(converter, eval, sectionsConstruct); + genOMP(converter, symTable, semanticsContext, eval, + sectionsConstruct); }, [&](const Fortran::parser::OpenMPSectionConstruct §ionConstruct) { - genOMP(converter, eval, sectionConstruct); + genOMP(converter, symTable, semanticsContext, eval, + sectionConstruct); }, [&](const Fortran::parser::OpenMPLoopConstruct &loopConstruct) { - genOMP(converter, eval, semanticsContext, loopConstruct); + genOMP(converter, symTable, semanticsContext, eval, loopConstruct); }, [&](const Fortran::parser::OpenMPDeclarativeAllocate &execAllocConstruct) { @@ -3536,14 +3598,16 @@ static void genOMP(Fortran::lower::AbstractConverter &converter, TODO(converter.getCurrentLocation(), "OpenMPAllocatorsConstruct"); }, [&](const Fortran::parser::OpenMPBlockConstruct &blockConstruct) { - genOMP(converter, eval, semanticsContext, blockConstruct); + genOMP(converter, symTable, semanticsContext, eval, blockConstruct); }, [&](const Fortran::parser::OpenMPAtomicConstruct &atomicConstruct) { - genOMP(converter, eval, atomicConstruct); + genOMP(converter, symTable, semanticsContext, eval, + atomicConstruct); }, [&](const Fortran::parser::OpenMPCriticalConstruct &criticalConstruct) { - genOMP(converter, eval, criticalConstruct); + genOMP(converter, symTable, semanticsContext, eval, + criticalConstruct); }, }, ompConstruct.u); @@ -3551,6 +3615,8 @@ static void genOMP(Fortran::lower::AbstractConverter &converter, static void genOMP(Fortran::lower::AbstractConverter &converter, + Fortran::lower::SymMap &symTable, + Fortran::semantics::SemanticsContext &semanticsContext, Fortran::lower::pft::Evaluation &eval, const Fortran::parser::OpenMPDeclarativeConstruct &ompDeclConstruct) { std::visit( @@ -3570,7 +3636,8 @@ genOMP(Fortran::lower::AbstractConverter &converter, }, [&](const Fortran::parser::OpenMPDeclareTargetConstruct &declareTargetConstruct) { - genOMP(converter, eval, declareTargetConstruct); + genOMP(converter, symTable, semanticsContext, eval, + declareTargetConstruct); }, [&](const Fortran::parser::OpenMPRequiresConstruct &requiresConstruct) { @@ -3607,57 +3674,19 @@ void Fortran::lower::genOpenMPConstruct( Fortran::semantics::SemanticsContext &semanticsContext, Fortran::lower::pft::Evaluation &eval, const Fortran::parser::OpenMPConstruct &omp) { - symTable.pushScope(); - genOMP(converter, semanticsContext, eval, omp); - - const Fortran::parser::OpenMPLoopConstruct *ompLoop = - std::get_if<Fortran::parser::OpenMPLoopConstruct>(&omp.u); - const Fortran::parser::OpenMPBlockConstruct *ompBlock = - std::get_if<Fortran::parser::OpenMPBlockConstruct>(&omp.u); - - // If loop is part of an OpenMP Construct then the OpenMP dialect - // workshare loop operation has already been created. Only the - // body needs to be created here and the do_loop can be skipped. - // Skip the number of collapsed loops, which is 1 when there is a - // no collapse requested. - - Fortran::lower::pft::Evaluation *curEval = &eval; - const Fortran::parser::OmpClauseList *loopOpClauseList = nullptr; - if (ompLoop) { - loopOpClauseList = &std::get<Fortran::parser::OmpClauseList>( - std::get<Fortran::parser::OmpBeginLoopDirective>(ompLoop->t).t); - int64_t collapseValue = Fortran::lower::getCollapseValue(*loopOpClauseList); - - curEval = &curEval->getFirstNestedEvaluation(); - for (int64_t i = 1; i < collapseValue; i++) { - curEval = &*std::next(curEval->getNestedEvaluations().begin()); - } - } - - for (Fortran::lower::pft::Evaluation &e : curEval->getNestedEvaluations()) - converter.genEval(e); - - if (ompLoop) { - genOpenMPReduction(converter, *loopOpClauseList); - } else if (ompBlock) { - const auto &blockStart = - std::get<Fortran::parser::OmpBeginBlockDirective>(ompBlock->t); - const auto &blockClauses = - std::get<Fortran::parser::OmpClauseList>(blockStart.t); - genOpenMPReduction(converter, blockClauses); - } - + genOMP(converter, symTable, semanticsContext, eval, omp); symTable.popScope(); } void Fortran::lower::genOpenMPDeclarativeConstruct( Fortran::lower::AbstractConverter &converter, + Fortran::lower::SymMap &symTable, + Fortran::semantics::SemanticsContext &semanticsContext, Fortran::lower::pft::Evaluation &eval, const Fortran::parser::OpenMPDeclarativeConstruct &omp) { - genOMP(converter, eval, omp); - for (Fortran::lower::pft::Evaluation &e : eval.getNestedEvaluations()) - converter.genEval(e); + genOMP(converter, symTable, semanticsContext, eval, omp); + genNestedEvaluations(converter, eval); } void Fortran::lower::genOpenMPSymbolProperties( |