aboutsummaryrefslogtreecommitdiff
path: root/flang/lib/Lower/OpenMP/OpenMP.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'flang/lib/Lower/OpenMP/OpenMP.cpp')
-rw-r--r--flang/lib/Lower/OpenMP/OpenMP.cpp150
1 files changed, 73 insertions, 77 deletions
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 12089d6..d1efd8e 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -407,16 +407,9 @@ static void processHostEvalClauses(lower::AbstractConverter &converter,
common::visit(
common::visitors{
[&](const parser::OpenMPBlockConstruct &ompConstruct) {
- const auto &beginDirective =
- std::get<parser::OmpBeginBlockDirective>(ompConstruct.t);
- beginClauseList =
- &std::get<parser::OmpClauseList>(beginDirective.t);
- if (auto &endDirective =
- std::get<std::optional<parser::OmpEndBlockDirective>>(
- ompConstruct.t)) {
- endClauseList =
- &std::get<parser::OmpClauseList>(endDirective->t);
- }
+ beginClauseList = &ompConstruct.BeginDir().Clauses();
+ if (auto &endSpec = ompConstruct.EndDir())
+ endClauseList = &endSpec->Clauses();
},
[&](const parser::OpenMPLoopConstruct &ompConstruct) {
const auto &beginDirective =
@@ -697,20 +690,16 @@ static void threadPrivatizeVars(lower::AbstractConverter &converter,
}
}
-static mlir::Operation *
-createAndSetPrivatizedLoopVar(lower::AbstractConverter &converter,
- mlir::Location loc, mlir::Value indexVal,
- const semantics::Symbol *sym) {
+static mlir::Operation *setLoopVar(lower::AbstractConverter &converter,
+ mlir::Location loc, mlir::Value indexVal,
+ const semantics::Symbol *sym) {
fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
+
mlir::OpBuilder::InsertPoint insPt = firOpBuilder.saveInsertionPoint();
firOpBuilder.setInsertionPointToStart(firOpBuilder.getAllocaBlock());
-
mlir::Type tempTy = converter.genType(*sym);
-
- assert(converter.isPresentShallowLookup(*sym) &&
- "Expected symbol to be in symbol table.");
-
firOpBuilder.restoreInsertionPoint(insPt);
+
mlir::Value cvtVal = firOpBuilder.createConvert(loc, tempTy, indexVal);
hlfir::Entity lhs{converter.getSymbolAddress(*sym)};
@@ -721,6 +710,15 @@ createAndSetPrivatizedLoopVar(lower::AbstractConverter &converter,
return storeOp;
}
+static mlir::Operation *
+createAndSetPrivatizedLoopVar(lower::AbstractConverter &converter,
+ mlir::Location loc, mlir::Value indexVal,
+ const semantics::Symbol *sym) {
+ assert(converter.isPresentShallowLookup(*sym) &&
+ "Expected symbol to be in symbol table.");
+ return setLoopVar(converter, loc, indexVal, sym);
+}
+
// This helper function implements the functionality of "promoting" non-CPTR
// arguments of use_device_ptr to use_device_addr arguments (automagic
// conversion of use_device_ptr -> use_device_addr in these cases). The way we
@@ -1123,6 +1121,11 @@ struct OpWithBodyGenInfo {
return *this;
}
+ OpWithBodyGenInfo &setPrivatize(bool value) {
+ privatize = value;
+ return *this;
+ }
+
/// [inout] converter to use for the clauses.
lower::AbstractConverter &converter;
/// [in] Symbol table
@@ -1149,6 +1152,8 @@ struct OpWithBodyGenInfo {
/// [in] if set to `true`, skip generating nested evaluations and dispatching
/// any further leaf constructs.
bool genSkeletonOnly = false;
+ /// [in] enables handling of privatized variable unless set to `false`.
+ bool privatize = true;
};
/// Create the body (block) for an OpenMP Operation.
@@ -1209,7 +1214,7 @@ static void createBodyOfOp(mlir::Operation &op, const OpWithBodyGenInfo &info,
// code will use the right symbols.
bool isLoop = llvm::omp::getDirectiveAssociation(info.dir) ==
llvm::omp::Association::Loop;
- bool privatize = info.clauses;
+ bool privatize = info.clauses && info.privatize;
firOpBuilder.setInsertionPoint(marker);
std::optional<DataSharingProcessor> tempDsp;
@@ -2083,7 +2088,7 @@ genCanonicalLoopOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
const ConstructQueue &queue,
ConstructQueue::const_iterator item,
llvm::ArrayRef<const semantics::Symbol *> ivs,
- llvm::omp::Directive directive, DataSharingProcessor &dsp) {
+ llvm::omp::Directive directive) {
fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
assert(ivs.size() == 1 && "Nested loops not yet implemented");
@@ -2176,10 +2181,8 @@ genCanonicalLoopOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
mlir::Value userVal =
firOpBuilder.create<mlir::arith::AddIOp>(loc, loopLBVar, scaled);
- // The argument is not currently in memory, so make a temporary for the
- // argument, and store it there, then bind that location to the argument.
- mlir::Operation *storeOp =
- createAndSetPrivatizedLoopVar(converter, loc, userVal, iv);
+ // Write loop value to loop variable
+ mlir::Operation *storeOp = setLoopVar(converter, loc, userVal, iv);
firOpBuilder.setInsertionPointAfter(storeOp);
return {iv};
@@ -2190,7 +2193,7 @@ genCanonicalLoopOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
OpWithBodyGenInfo(converter, symTable, semaCtx, loc, nestedEval,
directive)
.setClauses(&item->clauses)
- .setDataSharingProcessor(&dsp)
+ .setPrivatize(false)
.setGenRegionEntryCb(ivCallback),
queue, item, tripcount, cli);
@@ -2216,17 +2219,10 @@ static void genUnrollOp(Fortran::lower::AbstractConverter &converter,
cp.processTODO<clause::Partial, clause::Full>(
loc, llvm::omp::Directive::OMPD_unroll);
- // Even though unroll does not support data-sharing clauses, but this is
- // required to fill the symbol table.
- DataSharingProcessor dsp(converter, semaCtx, item->clauses, eval,
- /*shouldCollectPreDeterminedSymbols=*/true,
- /*useDelayedPrivatization=*/false, symTable);
- dsp.processStep1();
-
// Emit the associated loop
auto canonLoop =
genCanonicalLoopOp(converter, symTable, semaCtx, eval, loc, queue, item,
- iv, llvm::omp::Directive::OMPD_unroll, dsp);
+ iv, llvm::omp::Directive::OMPD_unroll);
// Apply unrolling to it
auto cli = canonLoop.getCli();
@@ -2329,7 +2325,7 @@ genSectionsOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
assert(sectionsConstruct && "Missing additional parsing information");
const auto &sectionBlocks =
- std::get<parser::OmpSectionBlocks>(sectionsConstruct->t);
+ std::get<std::list<parser::OpenMPConstruct>>(sectionsConstruct->t);
mlir::omp::SectionsOperands clauseOps;
llvm::SmallVector<const semantics::Symbol *> reductionSyms;
genSectionsClauses(converter, semaCtx, item->clauses, loc, clauseOps,
@@ -2382,7 +2378,7 @@ genSectionsOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
// because we need to run genReductionVars on each omp.section so that the
// reduction variable gets mapped to the private version
for (auto [construct, nestedEval] :
- llvm::zip(sectionBlocks.v, eval.getNestedEvaluations())) {
+ llvm::zip(sectionBlocks, eval.getNestedEvaluations())) {
const auto *sectionConstruct =
std::get_if<parser::OpenMPSectionConstruct>(&construct.u);
if (!sectionConstruct) {
@@ -3145,11 +3141,16 @@ static mlir::omp::DistributeOp genCompositeDistributeSimd(
genSimdClauses(converter, semaCtx, simdItem->clauses, loc, simdClauseOps,
simdReductionSyms);
- // TODO: Support delayed privatization.
- DataSharingProcessor dsp(converter, semaCtx, simdItem->clauses, eval,
- /*shouldCollectPreDeterminedSymbols=*/true,
- /*useDelayedPrivatization=*/false, symTable);
- dsp.processStep1();
+ DataSharingProcessor distributeItemDSP(
+ converter, semaCtx, distributeItem->clauses, eval,
+ /*shouldCollectPreDeterminedSymbols=*/false,
+ /*useDelayedPrivatization=*/true, symTable);
+ distributeItemDSP.processStep1(&distributeClauseOps);
+
+ DataSharingProcessor simdItemDSP(converter, semaCtx, simdItem->clauses, eval,
+ /*shouldCollectPreDeterminedSymbols=*/true,
+ /*useDelayedPrivatization=*/true, symTable);
+ simdItemDSP.processStep1(&simdClauseOps);
// Pass the innermost leaf construct's clauses because that's where COLLAPSE
// is placed by construct decomposition.
@@ -3160,13 +3161,15 @@ static mlir::omp::DistributeOp genCompositeDistributeSimd(
// Operation creation.
EntryBlockArgs distributeArgs;
- // TODO: Add private syms and vars.
+ distributeArgs.priv.syms = distributeItemDSP.getDelayedPrivSymbols();
+ distributeArgs.priv.vars = distributeClauseOps.privateVars;
auto distributeOp = genWrapperOp<mlir::omp::DistributeOp>(
converter, loc, distributeClauseOps, distributeArgs);
distributeOp.setComposite(/*val=*/true);
EntryBlockArgs simdArgs;
- // TODO: Add private syms and vars.
+ simdArgs.priv.syms = simdItemDSP.getDelayedPrivSymbols();
+ simdArgs.priv.vars = simdClauseOps.privateVars;
simdArgs.reduction.syms = simdReductionSyms;
simdArgs.reduction.vars = simdClauseOps.reductionVars;
auto simdOp =
@@ -3176,7 +3179,7 @@ static mlir::omp::DistributeOp genCompositeDistributeSimd(
genLoopNestOp(converter, symTable, semaCtx, eval, loc, queue, simdItem,
loopNestClauseOps, iv,
{{distributeOp, distributeArgs}, {simdOp, simdArgs}},
- llvm::omp::Directive::OMPD_distribute_simd, dsp);
+ llvm::omp::Directive::OMPD_distribute_simd, simdItemDSP);
return distributeOp;
}
@@ -3200,11 +3203,16 @@ static mlir::omp::WsloopOp genCompositeDoSimd(
genSimdClauses(converter, semaCtx, simdItem->clauses, loc, simdClauseOps,
simdReductionSyms);
- // TODO: Support delayed privatization.
- DataSharingProcessor dsp(converter, semaCtx, simdItem->clauses, eval,
- /*shouldCollectPreDeterminedSymbols=*/true,
- /*useDelayedPrivatization=*/false, symTable);
- dsp.processStep1();
+ DataSharingProcessor wsloopItemDSP(
+ converter, semaCtx, doItem->clauses, eval,
+ /*shouldCollectPreDeterminedSymbols=*/false,
+ /*useDelayedPrivatization=*/true, symTable);
+ wsloopItemDSP.processStep1(&wsloopClauseOps);
+
+ DataSharingProcessor simdItemDSP(converter, semaCtx, simdItem->clauses, eval,
+ /*shouldCollectPreDeterminedSymbols=*/true,
+ /*useDelayedPrivatization=*/true, symTable);
+ simdItemDSP.processStep1(&simdClauseOps);
// Pass the innermost leaf construct's clauses because that's where COLLAPSE
// is placed by construct decomposition.
@@ -3215,7 +3223,8 @@ static mlir::omp::WsloopOp genCompositeDoSimd(
// Operation creation.
EntryBlockArgs wsloopArgs;
- // TODO: Add private syms and vars.
+ wsloopArgs.priv.syms = wsloopItemDSP.getDelayedPrivSymbols();
+ wsloopArgs.priv.vars = wsloopClauseOps.privateVars;
wsloopArgs.reduction.syms = wsloopReductionSyms;
wsloopArgs.reduction.vars = wsloopClauseOps.reductionVars;
auto wsloopOp = genWrapperOp<mlir::omp::WsloopOp>(
@@ -3223,7 +3232,8 @@ static mlir::omp::WsloopOp genCompositeDoSimd(
wsloopOp.setComposite(/*val=*/true);
EntryBlockArgs simdArgs;
- // TODO: Add private syms and vars.
+ simdArgs.priv.syms = simdItemDSP.getDelayedPrivSymbols();
+ simdArgs.priv.vars = simdClauseOps.privateVars;
simdArgs.reduction.syms = simdReductionSyms;
simdArgs.reduction.vars = simdClauseOps.reductionVars;
auto simdOp =
@@ -3233,7 +3243,7 @@ static mlir::omp::WsloopOp genCompositeDoSimd(
genLoopNestOp(converter, symTable, semaCtx, eval, loc, queue, simdItem,
loopNestClauseOps, iv,
{{wsloopOp, wsloopArgs}, {simdOp, simdArgs}},
- llvm::omp::Directive::OMPD_do_simd, dsp);
+ llvm::omp::Directive::OMPD_do_simd, simdItemDSP);
return wsloopOp;
}
@@ -3716,25 +3726,16 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
semantics::SemanticsContext &semaCtx,
lower::pft::Evaluation &eval,
const parser::OpenMPBlockConstruct &blockConstruct) {
- const auto &beginBlockDirective =
- std::get<parser::OmpBeginBlockDirective>(blockConstruct.t);
- mlir::Location currentLocation =
- converter.genLocation(beginBlockDirective.source);
- const auto origDirective =
- std::get<parser::OmpBlockDirective>(beginBlockDirective.t).v;
- List<Clause> clauses = makeClauses(
- std::get<parser::OmpClauseList>(beginBlockDirective.t), semaCtx);
-
- if (const auto &endBlockDirective =
- std::get<std::optional<parser::OmpEndBlockDirective>>(
- blockConstruct.t)) {
- clauses.append(makeClauses(
- std::get<parser::OmpClauseList>(endBlockDirective->t), semaCtx));
- }
-
- assert(llvm::omp::blockConstructSet.test(origDirective) &&
+ const parser::OmpDirectiveSpecification &beginSpec =
+ blockConstruct.BeginDir();
+ List<Clause> clauses = makeClauses(beginSpec.Clauses(), semaCtx);
+ if (auto &endSpec = blockConstruct.EndDir())
+ clauses.append(makeClauses(endSpec->Clauses(), semaCtx));
+
+ llvm::omp::Directive directive = beginSpec.DirId();
+ assert(llvm::omp::blockConstructSet.test(directive) &&
"Expected block construct");
- (void)origDirective;
+ mlir::Location currentLocation = converter.genLocation(beginSpec.source);
for (const Clause &clause : clauses) {
mlir::Location clauseLocation = converter.genLocation(clause.source);
@@ -3777,13 +3778,9 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
}
}
- llvm::omp::Directive directive =
- std::get<parser::OmpBlockDirective>(beginBlockDirective.t).v;
- const parser::CharBlock &source =
- std::get<parser::OmpBlockDirective>(beginBlockDirective.t).source;
ConstructQueue queue{
buildConstructQueue(converter.getFirOpBuilder().getModule(), semaCtx,
- eval, source, directive, clauses)};
+ eval, beginSpec.source, directive, clauses)};
genOMPDispatch(converter, symTable, semaCtx, eval, currentLocation, queue,
queue.begin());
}
@@ -4071,8 +4068,7 @@ bool Fortran::lower::isOpenMPTargetConstruct(
const parser::OpenMPConstruct &omp) {
llvm::omp::Directive dir = llvm::omp::Directive::OMPD_unknown;
if (const auto *block = std::get_if<parser::OpenMPBlockConstruct>(&omp.u)) {
- const auto &begin = std::get<parser::OmpBeginBlockDirective>(block->t);
- dir = std::get<parser::OmpBlockDirective>(begin.t).v;
+ dir = block->BeginDir().DirId();
} else if (const auto *loop =
std::get_if<parser::OpenMPLoopConstruct>(&omp.u)) {
const auto &begin = std::get<parser::OmpBeginLoopDirective>(loop->t);