aboutsummaryrefslogtreecommitdiff
path: root/flang
diff options
context:
space:
mode:
authorKrzysztof Parzyszek <Krzysztof.Parzyszek@amd.com>2024-01-15 08:01:41 -0600
committerGitHub <noreply@github.com>2024-01-15 08:01:41 -0600
commitc5a9e354379d29ee763e9982faf57398789c8d5b (patch)
treee1999becd0c130ca582f95c104b652d8ab960341 /flang
parent5723fce088068cc91cf22e3a3da5700e213ce63e (diff)
downloadllvm-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.h5
-rw-r--r--flang/lib/Lower/Bridge.cpp3
-rw-r--r--flang/lib/Lower/OpenMP.cpp137
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 &sectionConstruct) {
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,
&sectionsClauseList);
+ 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 &sectionsConstruct) {
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
&sectionsConstruct) {
- genOMP(converter, eval, sectionsConstruct);
+ genOMP(converter, symTable, semanticsContext, eval,
+ sectionsConstruct);
},
[&](const Fortran::parser::OpenMPSectionConstruct &sectionConstruct) {
- 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(