Skip to content

Commit f8dcb05

Browse files
authored
[flang][fir][OpenMP] Refactor privtization code into shared location (#141767)
Refactors the utils needed to create privtization/locatization ops for both the fir and OpenMP dialects into a shared location isolating OpenMP stuff out of it as much as possible.
1 parent 7bd8e37 commit f8dcb05

File tree

5 files changed

+239
-183
lines changed

5 files changed

+239
-183
lines changed

flang/include/flang/Lower/Support/Utils.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,14 @@ bool isEqual(const Fortran::lower::SomeExpr *x,
9494
const Fortran::lower::SomeExpr *y);
9595
bool isEqual(const Fortran::lower::ExplicitIterSpace::ArrayBases &x,
9696
const Fortran::lower::ExplicitIterSpace::ArrayBases &y);
97+
98+
template <typename OpType, typename OperandsStructType>
99+
void privatizeSymbol(
100+
lower::AbstractConverter &converter, fir::FirOpBuilder &firOpBuilder,
101+
lower::SymMap &symTable, std::function<void(OpType, mlir::Type)> initGen,
102+
llvm::SetVector<const semantics::Symbol *> &allPrivatizedSymbols,
103+
const semantics::Symbol *symToPrivatize, OperandsStructType *clauseOps);
104+
97105
} // end namespace Fortran::lower
98106

99107
// DenseMapInfo for pointers to Fortran::lower::SomeExpr.

flang/lib/Lower/Bridge.cpp

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2029,10 +2029,6 @@ class FirConverter : public Fortran::lower::AbstractConverter {
20292029
void handleLocalitySpecs(const IncrementLoopInfo &info) {
20302030
Fortran::semantics::SemanticsContext &semanticsContext =
20312031
bridge.getSemanticsContext();
2032-
// TODO Extract `DataSharingProcessor` from omp to a more general location.
2033-
Fortran::lower::omp::DataSharingProcessor dsp(
2034-
*this, semanticsContext, getEval(),
2035-
/*useDelayedPrivatization=*/true, localSymbols);
20362032
fir::LocalitySpecifierOperands privateClauseOps;
20372033
auto doConcurrentLoopOp =
20382034
mlir::dyn_cast_if_present<fir::DoConcurrentLoopOp>(info.loopOp);
@@ -2041,10 +2037,17 @@ class FirConverter : public Fortran::lower::AbstractConverter {
20412037
// complete.
20422038
bool useDelayedPriv =
20432039
enableDelayedPrivatizationStaging && doConcurrentLoopOp;
2040+
llvm::SetVector<const Fortran::semantics::Symbol *> allPrivatizedSymbols;
20442041

20452042
for (const Fortran::semantics::Symbol *sym : info.localSymList) {
20462043
if (useDelayedPriv) {
2047-
dsp.privatizeSymbol<fir::LocalitySpecifierOp>(sym, &privateClauseOps);
2044+
Fortran::lower::privatizeSymbol<fir::LocalitySpecifierOp>(
2045+
*this, this->getFirOpBuilder(), localSymbols,
2046+
[this](fir::LocalitySpecifierOp result, mlir::Type argType) {
2047+
TODO(this->toLocation(),
2048+
"Localizers that need init regions are not supported yet.");
2049+
},
2050+
allPrivatizedSymbols, sym, &privateClauseOps);
20482051
continue;
20492052
}
20502053

@@ -2053,7 +2056,13 @@ class FirConverter : public Fortran::lower::AbstractConverter {
20532056

20542057
for (const Fortran::semantics::Symbol *sym : info.localInitSymList) {
20552058
if (useDelayedPriv) {
2056-
dsp.privatizeSymbol<fir::LocalitySpecifierOp>(sym, &privateClauseOps);
2059+
Fortran::lower::privatizeSymbol<fir::LocalitySpecifierOp>(
2060+
*this, this->getFirOpBuilder(), localSymbols,
2061+
[this](fir::LocalitySpecifierOp result, mlir::Type argType) {
2062+
TODO(this->toLocation(),
2063+
"Localizers that need init regions are not supported yet.");
2064+
},
2065+
allPrivatizedSymbols, sym, &privateClauseOps);
20572066
continue;
20582067
}
20592068

@@ -2083,7 +2092,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
20832092
builder->getArrayAttr(privateClauseOps.privateSyms));
20842093

20852094
for (auto [sym, privateVar] : llvm::zip_equal(
2086-
dsp.getAllSymbolsToPrivatize(), privateClauseOps.privateVars)) {
2095+
allPrivatizedSymbols, privateClauseOps.privateVars)) {
20872096
auto arg = doConcurrentLoopOp.getRegion().begin()->addArgument(
20882097
privateVar.getType(), doConcurrentLoopOp.getLoc());
20892098
bindSymbol(*sym, hlfir::translateToExtendedValue(

flang/lib/Lower/OpenMP/DataSharingProcessor.cpp

Lines changed: 34 additions & 173 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "Utils.h"
1717
#include "flang/Lower/ConvertVariable.h"
1818
#include "flang/Lower/PFTBuilder.h"
19+
#include "flang/Lower/Support/Utils.h"
1920
#include "flang/Lower/SymbolMap.h"
2021
#include "flang/Optimizer/Builder/BoxValue.h"
2122
#include "flang/Optimizer/Builder/HLFIRTools.h"
@@ -527,188 +528,48 @@ void DataSharingProcessor::copyLastPrivatize(mlir::Operation *op) {
527528
}
528529
}
529530

530-
template <typename OpType, typename OperandsStructType>
531531
void DataSharingProcessor::privatizeSymbol(
532-
const semantics::Symbol *symToPrivatize, OperandsStructType *clauseOps) {
532+
const semantics::Symbol *symToPrivatize,
533+
mlir::omp::PrivateClauseOps *clauseOps) {
533534
if (!useDelayedPrivatization) {
534535
cloneSymbol(symToPrivatize);
535536
copyFirstPrivateSymbol(symToPrivatize);
536537
return;
537538
}
538539

539-
const semantics::Symbol *sym = symToPrivatize->HasLocalLocality()
540-
? &symToPrivatize->GetUltimate()
541-
: symToPrivatize;
542-
lower::SymbolBox hsb = symToPrivatize->HasLocalLocality()
543-
? converter.shallowLookupSymbol(*sym)
544-
: converter.lookupOneLevelUpSymbol(*sym);
545-
assert(hsb && "Host symbol box not found");
546-
hlfir::Entity entity{hsb.getAddr()};
547-
bool cannotHaveNonDefaultLowerBounds = !entity.mayHaveNonDefaultLowerBounds();
548-
549-
mlir::Location symLoc = hsb.getAddr().getLoc();
550-
std::string privatizerName = sym->name().ToString() + ".privatizer";
551-
bool isFirstPrivate =
552-
symToPrivatize->test(semantics::Symbol::Flag::OmpFirstPrivate) ||
553-
symToPrivatize->test(semantics::Symbol::Flag::LocalityLocalInit);
554-
555-
mlir::Value privVal = hsb.getAddr();
556-
mlir::Type allocType = privVal.getType();
557-
if (!mlir::isa<fir::PointerType>(privVal.getType()))
558-
allocType = fir::unwrapRefType(privVal.getType());
559-
560-
if (auto poly = mlir::dyn_cast<fir::ClassType>(allocType)) {
561-
if (!mlir::isa<fir::PointerType>(poly.getEleTy()) && isFirstPrivate)
562-
TODO(symLoc, "create polymorphic host associated copy");
563-
}
564-
565-
// fir.array<> cannot be converted to any single llvm type and fir helpers
566-
// are not available in openmp to llvmir translation so we cannot generate
567-
// an alloca for a fir.array type there. Get around this by boxing all
568-
// arrays.
569-
if (mlir::isa<fir::SequenceType>(allocType)) {
570-
entity = genVariableBox(symLoc, firOpBuilder, entity);
571-
privVal = entity.getBase();
572-
allocType = privVal.getType();
573-
}
574-
575-
if (mlir::isa<fir::BaseBoxType>(privVal.getType())) {
576-
// Boxes should be passed by reference into nested regions:
577-
auto oldIP = firOpBuilder.saveInsertionPoint();
578-
firOpBuilder.setInsertionPointToStart(firOpBuilder.getAllocaBlock());
579-
auto alloca = firOpBuilder.create<fir::AllocaOp>(symLoc, privVal.getType());
580-
firOpBuilder.restoreInsertionPoint(oldIP);
581-
firOpBuilder.create<fir::StoreOp>(symLoc, privVal, alloca);
582-
privVal = alloca;
583-
}
584-
585-
mlir::Type argType = privVal.getType();
586-
587-
OpType privatizerOp = [&]() {
588-
auto moduleOp = firOpBuilder.getModule();
589-
auto uniquePrivatizerName = fir::getTypeAsString(
590-
allocType, converter.getKindMap(),
591-
converter.mangleName(*sym) +
592-
(isFirstPrivate ? "_firstprivate" : "_private"));
593-
594-
if (auto existingPrivatizer =
595-
moduleOp.lookupSymbol<OpType>(uniquePrivatizerName))
596-
return existingPrivatizer;
597-
598-
mlir::OpBuilder::InsertionGuard guard(firOpBuilder);
599-
firOpBuilder.setInsertionPointToStart(moduleOp.getBody());
600-
OpType result;
601-
602-
if constexpr (std::is_same_v<OpType, mlir::omp::PrivateClauseOp>) {
603-
result = firOpBuilder.create<OpType>(
604-
symLoc, uniquePrivatizerName, allocType,
605-
isFirstPrivate ? mlir::omp::DataSharingClauseType::FirstPrivate
606-
: mlir::omp::DataSharingClauseType::Private);
607-
} else {
608-
result = firOpBuilder.create<OpType>(
609-
symLoc, uniquePrivatizerName, allocType,
610-
isFirstPrivate ? fir::LocalitySpecifierType::LocalInit
611-
: fir::LocalitySpecifierType::Local);
612-
}
613-
614-
fir::ExtendedValue symExV = converter.getSymbolExtendedValue(*sym);
615-
lower::SymMapScope outerScope(symTable);
616-
617-
// Populate the `init` region.
618-
// We need to initialize in the following cases:
619-
// 1. The allocation was for a derived type which requires initialization
620-
// (this can be skipped if it will be initialized anyway by the copy
621-
// region, unless the derived type has allocatable components)
622-
// 2. The allocation was for any kind of box
623-
// 3. The allocation was for a boxed character
624-
const bool needsInitialization =
625-
(Fortran::lower::hasDefaultInitialization(sym->GetUltimate()) &&
626-
(!isFirstPrivate || hlfir::mayHaveAllocatableComponent(allocType))) ||
627-
mlir::isa<fir::BaseBoxType>(allocType) ||
628-
mlir::isa<fir::BoxCharType>(allocType);
629-
if (needsInitialization) {
630-
mlir::Region &initRegion = result.getInitRegion();
631-
mlir::Block *initBlock = firOpBuilder.createBlock(
632-
&initRegion, /*insertPt=*/{}, {argType, argType}, {symLoc, symLoc});
633-
634-
populateByRefInitAndCleanupRegions(
635-
converter, symLoc, argType, /*scalarInitValue=*/nullptr, initBlock,
636-
result.getInitPrivateArg(), result.getInitMoldArg(),
637-
result.getDeallocRegion(),
638-
isFirstPrivate ? DeclOperationKind::FirstPrivate
639-
: DeclOperationKind::Private,
640-
sym, cannotHaveNonDefaultLowerBounds);
641-
// TODO: currently there are false positives from dead uses of the mold
642-
// arg
643-
if (result.initReadsFromMold())
644-
mightHaveReadHostSym.insert(sym);
645-
}
646-
647-
// Populate the `copy` region if this is a `firstprivate`.
648-
if (isFirstPrivate) {
649-
mlir::Region &copyRegion = result.getCopyRegion();
650-
// First block argument corresponding to the original/host value while
651-
// second block argument corresponding to the privatized value.
652-
mlir::Block *copyEntryBlock = firOpBuilder.createBlock(
653-
&copyRegion, /*insertPt=*/{}, {argType, argType}, {symLoc, symLoc});
654-
firOpBuilder.setInsertionPointToEnd(copyEntryBlock);
655-
656-
auto addSymbol = [&](unsigned argIdx, const semantics::Symbol *symToMap,
657-
bool force = false) {
658-
symExV.match(
659-
[&](const fir::MutableBoxValue &box) {
660-
symTable.addSymbol(
661-
*symToMap,
662-
fir::substBase(box, copyRegion.getArgument(argIdx)), force);
663-
},
664-
[&](const auto &box) {
665-
symTable.addSymbol(*symToMap, copyRegion.getArgument(argIdx),
666-
force);
667-
});
668-
};
669-
670-
addSymbol(0, sym, true);
671-
lower::SymMapScope innerScope(symTable);
672-
addSymbol(1, symToPrivatize);
673-
674-
auto ip = firOpBuilder.saveInsertionPoint();
675-
copyFirstPrivateSymbol(symToPrivatize, &ip);
676-
677-
if constexpr (std::is_same_v<OpType, mlir::omp::PrivateClauseOp>) {
678-
firOpBuilder.create<mlir::omp::YieldOp>(
679-
hsb.getAddr().getLoc(),
680-
symTable.shallowLookupSymbol(*symToPrivatize).getAddr());
681-
} else {
682-
firOpBuilder.create<fir::YieldOp>(
683-
hsb.getAddr().getLoc(),
684-
symTable.shallowLookupSymbol(*symToPrivatize).getAddr());
685-
}
686-
}
687-
688-
return result;
689-
}();
690-
691-
if (clauseOps) {
692-
clauseOps->privateSyms.push_back(mlir::SymbolRefAttr::get(privatizerOp));
693-
clauseOps->privateVars.push_back(privVal);
694-
}
540+
auto initGen = [&](mlir::omp::PrivateClauseOp result, mlir::Type argType) {
541+
lower::SymbolBox hsb = converter.lookupOneLevelUpSymbol(*symToPrivatize);
542+
assert(hsb && "Host symbol box not found");
543+
hlfir::Entity entity{hsb.getAddr()};
544+
bool cannotHaveNonDefaultLowerBounds =
545+
!entity.mayHaveNonDefaultLowerBounds();
546+
547+
mlir::Region &initRegion = result.getInitRegion();
548+
mlir::Location symLoc = hsb.getAddr().getLoc();
549+
mlir::Block *initBlock = firOpBuilder.createBlock(
550+
&initRegion, /*insertPt=*/{}, {argType, argType}, {symLoc, symLoc});
551+
552+
bool emitCopyRegion =
553+
symToPrivatize->test(semantics::Symbol::Flag::OmpFirstPrivate);
554+
555+
populateByRefInitAndCleanupRegions(
556+
converter, symLoc, argType, /*scalarInitValue=*/nullptr, initBlock,
557+
result.getInitPrivateArg(), result.getInitMoldArg(),
558+
result.getDeallocRegion(),
559+
emitCopyRegion ? omp::DeclOperationKind::FirstPrivate
560+
: omp::DeclOperationKind::Private,
561+
symToPrivatize, cannotHaveNonDefaultLowerBounds);
562+
// TODO: currently there are false positives from dead uses of the mold
563+
// arg
564+
if (result.initReadsFromMold())
565+
mightHaveReadHostSym.insert(symToPrivatize);
566+
};
695567

696-
if (symToPrivatize->HasLocalLocality())
697-
allPrivatizedSymbols.insert(symToPrivatize);
568+
Fortran::lower::privatizeSymbol<mlir::omp::PrivateClauseOp,
569+
mlir::omp::PrivateClauseOps>(
570+
converter, firOpBuilder, symTable, initGen, allPrivatizedSymbols,
571+
symToPrivatize, clauseOps);
698572
}
699-
700-
template void
701-
DataSharingProcessor::privatizeSymbol<mlir::omp::PrivateClauseOp,
702-
mlir::omp::PrivateClauseOps>(
703-
const semantics::Symbol *symToPrivatize,
704-
mlir::omp::PrivateClauseOps *clauseOps);
705-
706-
template void
707-
DataSharingProcessor::privatizeSymbol<fir::LocalitySpecifierOp,
708-
fir::LocalitySpecifierOperands>(
709-
const semantics::Symbol *symToPrivatize,
710-
fir::LocalitySpecifierOperands *clauseOps);
711-
712573
} // namespace omp
713574
} // namespace lower
714575
} // namespace Fortran

flang/lib/Lower/OpenMP/DataSharingProcessor.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -153,10 +153,8 @@ class DataSharingProcessor {
153153
: llvm::ArrayRef<const semantics::Symbol *>();
154154
}
155155

156-
template <typename OpType = mlir::omp::PrivateClauseOp,
157-
typename OperandsStructType = mlir::omp::PrivateClauseOps>
158156
void privatizeSymbol(const semantics::Symbol *symToPrivatize,
159-
OperandsStructType *clauseOps);
157+
mlir::omp::PrivateClauseOps *clauseOps);
160158
};
161159

162160
} // namespace omp

0 commit comments

Comments
 (0)