Skip to content

Commit 1bc03e8

Browse files
committed
[flang] Basic PFT to MLIR lowering for do concurrent locality specifiers
1 parent 0eee95b commit 1bc03e8

File tree

4 files changed

+78
-17
lines changed

4 files changed

+78
-17
lines changed

flang/include/flang/Lower/AbstractConverter.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,9 @@ class AbstractConverter {
348348
virtual Fortran::lower::SymbolBox
349349
lookupOneLevelUpSymbol(const Fortran::semantics::Symbol &sym) = 0;
350350

351+
virtual Fortran::lower::SymbolBox
352+
shallowLookupSymbol(const Fortran::semantics::Symbol &sym) = 0;
353+
351354
/// Return the mlir::SymbolTable associated to the ModuleOp.
352355
/// Look-ups are faster using it than using module.lookup<>,
353356
/// but the module op should be queried in case of failure

flang/lib/Lower/Bridge.cpp

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212

1313
#include "flang/Lower/Bridge.h"
1414

15+
#include "OpenMP/DataSharingProcessor.h"
16+
#include "OpenMP/Utils.h"
1517
#include "flang/Lower/Allocatable.h"
1618
#include "flang/Lower/CallInterface.h"
1719
#include "flang/Lower/Coarray.h"
@@ -1136,6 +1138,14 @@ class FirConverter : public Fortran::lower::AbstractConverter {
11361138
return name;
11371139
}
11381140

1141+
/// Find the symbol in the inner-most level of the local map or return null.
1142+
Fortran::lower::SymbolBox
1143+
shallowLookupSymbol(const Fortran::semantics::Symbol &sym) override {
1144+
if (Fortran::lower::SymbolBox v = localSymbols.shallowLookupSymbol(sym))
1145+
return v;
1146+
return {};
1147+
}
1148+
11391149
private:
11401150
FirConverter() = delete;
11411151
FirConverter(const FirConverter &) = delete;
@@ -1210,14 +1220,6 @@ class FirConverter : public Fortran::lower::AbstractConverter {
12101220
return {};
12111221
}
12121222

1213-
/// Find the symbol in the inner-most level of the local map or return null.
1214-
Fortran::lower::SymbolBox
1215-
shallowLookupSymbol(const Fortran::semantics::Symbol &sym) {
1216-
if (Fortran::lower::SymbolBox v = localSymbols.shallowLookupSymbol(sym))
1217-
return v;
1218-
return {};
1219-
}
1220-
12211223
/// Find the symbol in one level up of symbol map such as for host-association
12221224
/// in OpenMP code or return null.
12231225
Fortran::lower::SymbolBox
@@ -2017,12 +2019,29 @@ class FirConverter : public Fortran::lower::AbstractConverter {
20172019

20182020
/// Create DO CONCURRENT construct symbol bindings and generate LOCAL_INIT
20192021
/// assignments.
2020-
void handleLocalitySpecs(const IncrementLoopInfo &info) {
2022+
void handleLocalitySpecs(IncrementLoopInfo &info) {
20212023
Fortran::semantics::SemanticsContext &semanticsContext =
20222024
bridge.getSemanticsContext();
2023-
for (const Fortran::semantics::Symbol *sym : info.localSymList)
2025+
Fortran::lower::omp::DataSharingProcessor dsp(
2026+
*this, semanticsContext, getEval(),
2027+
/*useDelayedPrivatization=*/true, localSymbols);
2028+
mlir::omp::PrivateClauseOps privateClauseOps;
2029+
2030+
for (const Fortran::semantics::Symbol *sym : info.localSymList) {
2031+
if (enableDelayedPrivatizationStaging) {
2032+
dsp.doPrivatize(sym, &privateClauseOps);
2033+
continue;
2034+
}
2035+
20242036
createHostAssociateVarClone(*sym, /*skipDefaultInit=*/false);
2037+
}
2038+
20252039
for (const Fortran::semantics::Symbol *sym : info.localInitSymList) {
2040+
if (enableDelayedPrivatizationStaging) {
2041+
dsp.doPrivatize(sym, &privateClauseOps);
2042+
continue;
2043+
}
2044+
20262045
createHostAssociateVarClone(*sym, /*skipDefaultInit=*/true);
20272046
const auto *hostDetails =
20282047
sym->detailsIf<Fortran::semantics::HostAssocDetails>();
@@ -2036,11 +2055,27 @@ class FirConverter : public Fortran::lower::AbstractConverter {
20362055
assign.u = Fortran::evaluate::Assignment::BoundsSpec{};
20372056
genAssignment(assign);
20382057
}
2058+
20392059
for (const Fortran::semantics::Symbol *sym : info.sharedSymList) {
20402060
const auto *hostDetails =
20412061
sym->detailsIf<Fortran::semantics::HostAssocDetails>();
20422062
copySymbolBinding(hostDetails->symbol(), *sym);
20432063
}
2064+
2065+
info.doLoop.getPrivateVarsMutable().assign(privateClauseOps.privateVars);
2066+
info.doLoop.setPrivateSymsAttr(
2067+
builder->getArrayAttr(privateClauseOps.privateSyms));
2068+
2069+
for (auto [sym, privateVar] : llvm::zip_equal(
2070+
dsp.getAllSymbolsToPrivatize(), privateClauseOps.privateVars)) {
2071+
auto arg = info.doLoop.getRegion().begin()->addArgument(
2072+
privateVar.getType(), info.doLoop.getLoc());
2073+
bindSymbol(*sym, hlfir::translateToExtendedValue(
2074+
privateVar.getLoc(), *builder, hlfir::Entity{arg},
2075+
/*contiguousHint=*/true)
2076+
.first);
2077+
}
2078+
20442079
// Note that allocatable, types with ultimate components, and type
20452080
// requiring finalization are forbidden in LOCAL/LOCAL_INIT (F2023 C1130),
20462081
// so no clean-up needs to be generated for these entities.

flang/lib/Lower/OpenMP/DataSharingProcessor.cpp

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,15 @@ DataSharingProcessor::DataSharingProcessor(
5353
});
5454
}
5555

56+
DataSharingProcessor::DataSharingProcessor(lower::AbstractConverter &converter,
57+
semantics::SemanticsContext &semaCtx,
58+
lower::pft::Evaluation &eval,
59+
bool useDelayedPrivatization,
60+
lower::SymMap &symTable)
61+
: DataSharingProcessor(converter, semaCtx, {}, eval,
62+
/*shouldCollectPreDeterminedSymols=*/false,
63+
useDelayedPrivatization, symTable) {}
64+
5665
void DataSharingProcessor::processStep1(
5766
mlir::omp::PrivateClauseOps *clauseOps) {
5867
collectSymbolsForPrivatization();
@@ -504,22 +513,28 @@ void DataSharingProcessor::copyLastPrivatize(mlir::Operation *op) {
504513
}
505514
}
506515

507-
void DataSharingProcessor::doPrivatize(const semantics::Symbol *sym,
516+
void DataSharingProcessor::doPrivatize(const semantics::Symbol *symToPrivatize,
508517
mlir::omp::PrivateClauseOps *clauseOps) {
509518
if (!useDelayedPrivatization) {
510-
cloneSymbol(sym);
511-
copyFirstPrivateSymbol(sym);
519+
cloneSymbol(symToPrivatize);
520+
copyFirstPrivateSymbol(symToPrivatize);
512521
return;
513522
}
514523

515-
lower::SymbolBox hsb = converter.lookupOneLevelUpSymbol(*sym);
524+
const semantics::Symbol *sym = symToPrivatize->HasLocalLocality()
525+
? &symToPrivatize->GetUltimate()
526+
: symToPrivatize;
527+
lower::SymbolBox hsb = symToPrivatize->HasLocalLocality()
528+
? converter.shallowLookupSymbol(*sym)
529+
: converter.lookupOneLevelUpSymbol(*sym);
516530
assert(hsb && "Host symbol box not found");
517531
hlfir::Entity entity{hsb.getAddr()};
518532
bool cannotHaveNonDefaultLowerBounds = !entity.mayHaveNonDefaultLowerBounds();
519533

520534
mlir::Location symLoc = hsb.getAddr().getLoc();
521535
std::string privatizerName = sym->name().ToString() + ".privatizer";
522-
bool isFirstPrivate = sym->test(semantics::Symbol::Flag::OmpFirstPrivate);
536+
bool isFirstPrivate = sym->test(semantics::Symbol::Flag::OmpFirstPrivate) ||
537+
sym->test(semantics::Symbol::Flag::LocalityLocalInit);
523538

524539
mlir::Value privVal = hsb.getAddr();
525540
mlir::Type allocType = privVal.getType();
@@ -645,6 +660,8 @@ void DataSharingProcessor::doPrivatize(const semantics::Symbol *sym,
645660
}
646661

647662
symToPrivatizer[sym] = privatizerOp;
663+
if (symToPrivatize->HasLocalLocality())
664+
allPrivatizedSymbols.insert(symToPrivatize);
648665
}
649666

650667
} // namespace omp

flang/lib/Lower/OpenMP/DataSharingProcessor.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,6 @@ class DataSharingProcessor {
105105
void collectImplicitSymbols();
106106
void collectPreDeterminedSymbols();
107107
void privatize(mlir::omp::PrivateClauseOps *clauseOps);
108-
void doPrivatize(const semantics::Symbol *sym,
109-
mlir::omp::PrivateClauseOps *clauseOps);
110108
void copyLastPrivatize(mlir::Operation *op);
111109
void insertLastPrivateCompare(mlir::Operation *op);
112110
void cloneSymbol(const semantics::Symbol *sym);
@@ -125,6 +123,11 @@ class DataSharingProcessor {
125123
bool shouldCollectPreDeterminedSymbols,
126124
bool useDelayedPrivatization, lower::SymMap &symTable);
127125

126+
DataSharingProcessor(lower::AbstractConverter &converter,
127+
semantics::SemanticsContext &semaCtx,
128+
lower::pft::Evaluation &eval,
129+
bool useDelayedPrivatization, lower::SymMap &symTable);
130+
128131
// Privatisation is split into two steps.
129132
// Step1 performs cloning of all privatisation clauses and copying for
130133
// firstprivates. Step1 is performed at the place where process/processStep1
@@ -151,6 +154,9 @@ class DataSharingProcessor {
151154
? allPrivatizedSymbols.getArrayRef()
152155
: llvm::ArrayRef<const semantics::Symbol *>();
153156
}
157+
158+
void doPrivatize(const semantics::Symbol *sym,
159+
mlir::omp::PrivateClauseOps *clauseOps);
154160
};
155161

156162
} // namespace omp

0 commit comments

Comments
 (0)