Skip to content

Commit 1710c8c

Browse files
authored
[flang] Lowering changes for assigning dummy_scope to hlfir.declare. (llvm#90989)
The lowering produces fir.dummy_scope operation if the current function has dummy arguments. Each hlfir.declare generated for a dummy argument is then using the result of fir.dummy_scope as its dummy_scope operand. This is only done for HLFIR. I was not able to find a reliable way to identify dummy symbols in `genDeclareSymbol`, so I added a set of registered dummy symbols that is alive during the variables instantiation for the current function. The set is initialized during the mapping of the dummy argument symbols to their MLIR values. It is reset right after all variables are instantiated - this is done to avoid generating hlfir.declare operations with dummy_scope for the clones of the dummy symbols (e.g. this happens with OpenMP privatization). If this can be done in a cleaner way, please advise.
1 parent 36d8b37 commit 1710c8c

File tree

137 files changed

+806
-696
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

137 files changed

+806
-696
lines changed

flang/include/flang/Lower/AbstractConverter.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,18 @@ class AbstractConverter {
219219
/// function.
220220
virtual void bindHostAssocTuple(mlir::Value val) = 0;
221221

222+
/// Returns fir.dummy_scope operation's result value to be used
223+
/// as dummy_scope operand of hlfir.declare operations for the dummy
224+
/// arguments of this function.
225+
virtual mlir::Value dummyArgsScopeValue() const = 0;
226+
227+
/// Returns true if the given symbol is a dummy argument of this function.
228+
/// Note that it returns false for all the symbols after all the variables
229+
/// are instantiated for this function, i.e. it can only be used reliably
230+
/// during the instatiation of the variables.
231+
virtual bool
232+
isRegisteredDummySymbol(Fortran::semantics::SymbolRef symRef) const = 0;
233+
222234
//===--------------------------------------------------------------------===//
223235
// Types
224236
//===--------------------------------------------------------------------===//

flang/include/flang/Optimizer/Builder/HLFIRTools.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@ fir::FortranVariableOpInterface
238238
genDeclare(mlir::Location loc, fir::FirOpBuilder &builder,
239239
const fir::ExtendedValue &exv, llvm::StringRef name,
240240
fir::FortranVariableFlagsAttr flags,
241+
mlir::Value dummyScope = nullptr,
241242
fir::CUDADataAttributeAttr cudaAttr = {});
242243

243244
/// Generate an hlfir.associate to build a variable from an expression value.

flang/include/flang/Optimizer/HLFIR/HLFIROps.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ def hlfir_DeclareOp : hlfir_Op<"declare", [AttrSizedOperandSegments,
104104
let builders = [
105105
OpBuilder<(ins "mlir::Value":$memref, "llvm::StringRef":$uniq_name,
106106
CArg<"mlir::Value", "{}">:$shape, CArg<"mlir::ValueRange", "{}">:$typeparams,
107+
CArg<"mlir::Value", "{}">:$dummy_scope,
107108
CArg<"fir::FortranVariableFlagsAttr", "{}">:$fortran_attrs,
108109
CArg<"fir::CUDADataAttributeAttr", "{}">:$cuda_attr)>];
109110

flang/lib/Lower/Bridge.cpp

Lines changed: 62 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -900,6 +900,16 @@ class FirConverter : public Fortran::lower::AbstractConverter {
900900
hostAssocTuple = val;
901901
}
902902

903+
mlir::Value dummyArgsScopeValue() const override final {
904+
return dummyArgsScope;
905+
}
906+
907+
bool isRegisteredDummySymbol(
908+
Fortran::semantics::SymbolRef symRef) const override final {
909+
auto *sym = &*symRef;
910+
return registeredDummySymbols.contains(sym);
911+
}
912+
903913
void registerTypeInfo(mlir::Location loc,
904914
Fortran::lower::SymbolRef typeInfoSym,
905915
const Fortran::semantics::DerivedTypeSpec &typeSpec,
@@ -1145,10 +1155,11 @@ class FirConverter : public Fortran::lower::AbstractConverter {
11451155
/// yet. The final mapping will be done using this pre-mapping in
11461156
/// Fortran::lower::mapSymbolAttributes.
11471157
bool mapBlockArgToDummyOrResult(const Fortran::semantics::SymbolRef sym,
1148-
mlir::Value val, bool forced = false) {
1149-
if (!forced && lookupSymbol(sym))
1150-
return false;
1151-
localSymbols.addSymbol(sym, val, forced);
1158+
mlir::Value val, bool isResult) {
1159+
localSymbols.addSymbol(sym, val);
1160+
if (!isResult)
1161+
registerDummySymbol(sym);
1162+
11521163
return true;
11531164
}
11541165

@@ -4559,7 +4570,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
45594570
const Fortran::lower::CalleeInterface &callee) {
45604571
assert(builder && "require a builder object at this point");
45614572
using PassBy = Fortran::lower::CalleeInterface::PassEntityBy;
4562-
auto mapPassedEntity = [&](const auto arg) {
4573+
auto mapPassedEntity = [&](const auto arg, bool isResult = false) {
45634574
if (arg.passBy == PassBy::AddressAndLength) {
45644575
if (callee.characterize().IsBindC())
45654576
return;
@@ -4569,10 +4580,11 @@ class FirConverter : public Fortran::lower::AbstractConverter {
45694580
fir::factory::CharacterExprHelper charHelp{*builder, loc};
45704581
mlir::Value box =
45714582
charHelp.createEmboxChar(arg.firArgument, arg.firLength);
4572-
mapBlockArgToDummyOrResult(arg.entity->get(), box);
4583+
mapBlockArgToDummyOrResult(arg.entity->get(), box, isResult);
45734584
} else {
45744585
if (arg.entity.has_value()) {
4575-
mapBlockArgToDummyOrResult(arg.entity->get(), arg.firArgument);
4586+
mapBlockArgToDummyOrResult(arg.entity->get(), arg.firArgument,
4587+
isResult);
45764588
} else {
45774589
assert(funit.parentHasTupleHostAssoc() && "expect tuple argument");
45784590
}
@@ -4581,15 +4593,19 @@ class FirConverter : public Fortran::lower::AbstractConverter {
45814593
for (const Fortran::lower::CalleeInterface::PassedEntity &arg :
45824594
callee.getPassedArguments())
45834595
mapPassedEntity(arg);
4596+
if (lowerToHighLevelFIR() && !callee.getPassedArguments().empty()) {
4597+
mlir::Value scopeOp = builder->create<fir::DummyScopeOp>(toLocation());
4598+
setDummyArgsScope(scopeOp);
4599+
}
45844600
if (std::optional<Fortran::lower::CalleeInterface::PassedEntity>
45854601
passedResult = callee.getPassedResult()) {
4586-
mapPassedEntity(*passedResult);
4602+
mapPassedEntity(*passedResult, /*isResult=*/true);
45874603
// FIXME: need to make sure things are OK here. addSymbol may not be OK
45884604
if (funit.primaryResult &&
45894605
passedResult->entity->get() != *funit.primaryResult)
45904606
mapBlockArgToDummyOrResult(
4591-
*funit.primaryResult,
4592-
getSymbolAddress(passedResult->entity->get()));
4607+
*funit.primaryResult, getSymbolAddress(passedResult->entity->get()),
4608+
/*isResult=*/true);
45934609
}
45944610
}
45954611

@@ -4766,7 +4782,8 @@ class FirConverter : public Fortran::lower::AbstractConverter {
47664782
Fortran::lower::StatementContext stmtCtx;
47674783
if (std::optional<Fortran::lower::CalleeInterface::PassedEntity>
47684784
passedResult = callee.getPassedResult()) {
4769-
mapBlockArgToDummyOrResult(altResult.getSymbol(), resultArg.getAddr());
4785+
mapBlockArgToDummyOrResult(altResult.getSymbol(), resultArg.getAddr(),
4786+
/*isResult=*/true);
47704787
Fortran::lower::mapSymbolAttributes(*this, altResult, localSymbols,
47714788
stmtCtx);
47724789
} else {
@@ -4810,6 +4827,11 @@ class FirConverter : public Fortran::lower::AbstractConverter {
48104827
if (!funit.getHostAssoc().empty())
48114828
funit.getHostAssoc().hostProcedureBindings(*this, localSymbols);
48124829

4830+
// Unregister all dummy symbols, so that their cloning (e.g. for OpenMP
4831+
// privatization) does not create the cloned hlfir.declare operations
4832+
// with dummy_scope operands.
4833+
resetRegisteredDummySymbols();
4834+
48134835
// Create most function blocks in advance.
48144836
createEmptyBlocks(funit.evaluationList);
48154837

@@ -4929,6 +4951,8 @@ class FirConverter : public Fortran::lower::AbstractConverter {
49294951
hostAssocTuple = mlir::Value{};
49304952
localSymbols.clear();
49314953
blockId = 0;
4954+
dummyArgsScope = mlir::Value{};
4955+
resetRegisteredDummySymbols();
49324956
}
49334957

49344958
/// Helper to generate GlobalOps when the builder is not positioned in any
@@ -4957,6 +4981,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
49574981
delete builder;
49584982
builder = nullptr;
49594983
localSymbols.clear();
4984+
resetRegisteredDummySymbols();
49604985
}
49614986

49624987
/// Instantiate the data from a BLOCK DATA unit.
@@ -5374,6 +5399,23 @@ class FirConverter : public Fortran::lower::AbstractConverter {
53745399
globalOmpRequiresSymbol);
53755400
}
53765401

5402+
/// Record fir.dummy_scope operation for this function.
5403+
/// It will be used to set dummy_scope operand of the hlfir.declare
5404+
/// operations.
5405+
void setDummyArgsScope(mlir::Value val) {
5406+
assert(!dummyArgsScope && val);
5407+
dummyArgsScope = val;
5408+
}
5409+
5410+
/// Record the given symbol as a dummy argument of this function.
5411+
void registerDummySymbol(Fortran::semantics::SymbolRef symRef) {
5412+
auto *sym = &*symRef;
5413+
registeredDummySymbols.insert(sym);
5414+
}
5415+
5416+
/// Reset all registered dummy symbols.
5417+
void resetRegisteredDummySymbols() { registeredDummySymbols.clear(); }
5418+
53775419
//===--------------------------------------------------------------------===//
53785420

53795421
Fortran::lower::LoweringBridge &bridge;
@@ -5400,6 +5442,15 @@ class FirConverter : public Fortran::lower::AbstractConverter {
54005442
/// Tuple of host associated variables
54015443
mlir::Value hostAssocTuple;
54025444

5445+
/// Value of fir.dummy_scope operation for this function.
5446+
mlir::Value dummyArgsScope;
5447+
5448+
/// A set of dummy argument symbols for this function.
5449+
/// The set is only preserved during the instatiation
5450+
/// of variables for this function.
5451+
llvm::SmallPtrSet<const Fortran::semantics::Symbol *, 16>
5452+
registeredDummySymbols;
5453+
54035454
/// A map of unique names for constant expressions.
54045455
/// The names are used for representing the constant expressions
54055456
/// with global constant initialized objects.

flang/lib/Lower/ConvertArrayConstructor.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ class RuntimeTempStrategy : public StrategyBase {
318318
mlir::Value shape = builder.genShape(loc, extents);
319319
declare = builder.create<hlfir::DeclareOp>(
320320
loc, tempStorage, tempName, shape, lengths,
321-
fir::FortranVariableFlagsAttr{});
321+
/*dummy_scope=*/nullptr, fir::FortranVariableFlagsAttr{});
322322
initialBoxValue =
323323
builder.createBox(loc, boxType, declare->getOriginalBase(), shape,
324324
/*slice=*/mlir::Value{}, lengths, /*tdesc=*/{});

flang/lib/Lower/ConvertExprToHLFIR.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1676,7 +1676,8 @@ class HlfirBuilder {
16761676
mlir::Value storagePtr = builder.createTemporary(loc, recTy);
16771677
auto varOp = hlfir::EntityWithAttributes{builder.create<hlfir::DeclareOp>(
16781678
loc, storagePtr, "ctor.temp", /*shape=*/nullptr,
1679-
/*typeparams=*/mlir::ValueRange{}, fir::FortranVariableFlagsAttr{})};
1679+
/*typeparams=*/mlir::ValueRange{}, /*dummy_scope=*/nullptr,
1680+
fir::FortranVariableFlagsAttr{})};
16801681

16811682
// Initialize any components that need initialization.
16821683
mlir::Value box = builder.createBox(loc, fir::ExtendedValue{varOp});

flang/lib/Lower/ConvertVariable.cpp

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1683,7 +1683,8 @@ static void genDeclareSymbol(Fortran::lower::AbstractConverter &converter,
16831683

16841684
// Declare a local pointer variable.
16851685
auto newBase = builder.create<hlfir::DeclareOp>(
1686-
loc, boxAlloc, name, /*shape=*/nullptr, lenParams, attributes);
1686+
loc, boxAlloc, name, /*shape=*/nullptr, lenParams,
1687+
/*dummy_scope=*/nullptr, attributes);
16871688
mlir::Value nullAddr = builder.createNullConstant(
16881689
loc, llvm::cast<fir::BaseBoxType>(ptrBoxType).getEleTy());
16891690

@@ -1710,8 +1711,12 @@ static void genDeclareSymbol(Fortran::lower::AbstractConverter &converter,
17101711
symMap.addVariableDefinition(sym, newBase, force);
17111712
return;
17121713
}
1714+
mlir::Value dummyScope;
1715+
if (converter.isRegisteredDummySymbol(sym))
1716+
dummyScope = converter.dummyArgsScopeValue();
17131717
auto newBase = builder.create<hlfir::DeclareOp>(
1714-
loc, base, name, shapeOrShift, lenParams, attributes, cudaAttr);
1718+
loc, base, name, shapeOrShift, lenParams, dummyScope, attributes,
1719+
cudaAttr);
17151720
symMap.addVariableDefinition(sym, newBase, force);
17161721
return;
17171722
}
@@ -1761,8 +1766,11 @@ void Fortran::lower::genDeclareSymbol(
17611766
Fortran::lower::translateSymbolCUDADataAttribute(builder.getContext(),
17621767
sym.GetUltimate());
17631768
auto name = converter.mangleName(sym);
1764-
hlfir::EntityWithAttributes declare =
1765-
hlfir::genDeclare(loc, builder, exv, name, attributes, cudaAttr);
1769+
mlir::Value dummyScope;
1770+
if (converter.isRegisteredDummySymbol(sym))
1771+
dummyScope = converter.dummyArgsScopeValue();
1772+
hlfir::EntityWithAttributes declare = hlfir::genDeclare(
1773+
loc, builder, exv, name, attributes, dummyScope, cudaAttr);
17661774
symMap.addVariableDefinition(sym, declare.getIfVariableInterface(), force);
17671775
return;
17681776
}
@@ -2022,7 +2030,9 @@ void Fortran::lower::mapSymbolAttributes(
20222030
fir::factory::genMutableBoxRead(
20232031
builder, loc,
20242032
fir::factory::createTempMutableBox(builder, loc, ty, {}, {},
2025-
isPolymorphic)));
2033+
isPolymorphic)),
2034+
fir::FortranVariableFlagsEnum::None,
2035+
converter.isRegisteredDummySymbol(sym));
20262036
return true;
20272037
}
20282038
return false;

flang/lib/Lower/OpenACC.cpp

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,8 @@ static void genPrivateLikeInitRegion(mlir::OpBuilder &builder, RecipeOp recipe,
425425
auto alloca = builder.create<fir::AllocaOp>(loc, refTy.getEleTy());
426426
auto declareOp = builder.create<hlfir::DeclareOp>(
427427
loc, alloca, accPrivateInitName, /*shape=*/nullptr,
428-
llvm::ArrayRef<mlir::Value>{}, fir::FortranVariableFlagsAttr{});
428+
llvm::ArrayRef<mlir::Value>{}, /*dummy_scope=*/nullptr,
429+
fir::FortranVariableFlagsAttr{});
429430
retVal = declareOp.getBase();
430431
} else if (auto seqTy = mlir::dyn_cast_or_null<fir::SequenceType>(
431432
refTy.getEleTy())) {
@@ -446,7 +447,8 @@ static void genPrivateLikeInitRegion(mlir::OpBuilder &builder, RecipeOp recipe,
446447
loc, seqTy, /*typeparams=*/mlir::ValueRange{}, extents);
447448
auto declareOp = builder.create<hlfir::DeclareOp>(
448449
loc, alloca, accPrivateInitName, shape,
449-
llvm::ArrayRef<mlir::Value>{}, fir::FortranVariableFlagsAttr{});
450+
llvm::ArrayRef<mlir::Value>{}, /*dummy_scope=*/nullptr,
451+
fir::FortranVariableFlagsAttr{});
450452
retVal = declareOp.getBase();
451453
}
452454
}
@@ -666,10 +668,12 @@ mlir::acc::FirstprivateRecipeOp Fortran::lower::createOrGetFirstprivateRecipe(
666668

667669
auto leftDeclOp = builder.create<hlfir::DeclareOp>(
668670
loc, recipe.getCopyRegion().getArgument(0), llvm::StringRef{}, shape,
669-
llvm::ArrayRef<mlir::Value>{}, fir::FortranVariableFlagsAttr{});
671+
llvm::ArrayRef<mlir::Value>{}, /*dummy_scope=*/nullptr,
672+
fir::FortranVariableFlagsAttr{});
670673
auto rightDeclOp = builder.create<hlfir::DeclareOp>(
671674
loc, recipe.getCopyRegion().getArgument(1), llvm::StringRef{}, shape,
672-
llvm::ArrayRef<mlir::Value>{}, fir::FortranVariableFlagsAttr{});
675+
llvm::ArrayRef<mlir::Value>{}, /*dummy_scope=*/nullptr,
676+
fir::FortranVariableFlagsAttr{});
673677

674678
hlfir::DesignateOp::Subscripts triplets =
675679
getSubscriptsFromArgs(recipe.getCopyRegion().getArguments());
@@ -975,7 +979,8 @@ static mlir::Value genReductionInitRegion(fir::FirOpBuilder &builder,
975979
mlir::Value alloca = builder.create<fir::AllocaOp>(loc, ty);
976980
auto declareOp = builder.create<hlfir::DeclareOp>(
977981
loc, alloca, accReductionInitName, /*shape=*/nullptr,
978-
llvm::ArrayRef<mlir::Value>{}, fir::FortranVariableFlagsAttr{});
982+
llvm::ArrayRef<mlir::Value>{}, /*dummy_scope=*/nullptr,
983+
fir::FortranVariableFlagsAttr{});
979984
builder.create<fir::StoreOp>(loc, builder.createConvert(loc, ty, initValue),
980985
declareOp.getBase());
981986
return declareOp.getBase();
@@ -991,7 +996,8 @@ static mlir::Value genReductionInitRegion(fir::FirOpBuilder &builder,
991996
loc, seqTy, /*typeparams=*/mlir::ValueRange{}, extents);
992997
auto declareOp = builder.create<hlfir::DeclareOp>(
993998
loc, alloca, accReductionInitName, shape,
994-
llvm::ArrayRef<mlir::Value>{}, fir::FortranVariableFlagsAttr{});
999+
llvm::ArrayRef<mlir::Value>{}, /*dummy_scope=*/nullptr,
1000+
fir::FortranVariableFlagsAttr{});
9951001
mlir::Type idxTy = builder.getIndexType();
9961002
mlir::Type refTy = fir::ReferenceType::get(seqTy.getEleTy());
9971003
llvm::SmallVector<fir::DoLoopOp> loops;
@@ -1143,10 +1149,10 @@ static void genCombiner(fir::FirOpBuilder &builder, mlir::Location loc,
11431149
recipe.getCombinerRegion().getArguments());
11441150
auto v1DeclareOp = builder.create<hlfir::DeclareOp>(
11451151
loc, value1, llvm::StringRef{}, shape, llvm::ArrayRef<mlir::Value>{},
1146-
fir::FortranVariableFlagsAttr{});
1152+
/*dummy_scope=*/nullptr, fir::FortranVariableFlagsAttr{});
11471153
auto v2DeclareOp = builder.create<hlfir::DeclareOp>(
11481154
loc, value2, llvm::StringRef{}, shape, llvm::ArrayRef<mlir::Value>{},
1149-
fir::FortranVariableFlagsAttr{});
1155+
/*dummy_scope=*/nullptr, fir::FortranVariableFlagsAttr{});
11501156
hlfir::DesignateOp::Subscripts triplets = getTripletsFromArgs(recipe);
11511157

11521158
llvm::SmallVector<mlir::Value> lenParamsLeft;

flang/lib/Lower/OpenMP/ClauseProcessor.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -657,12 +657,12 @@ createCopyFunc(mlir::Location loc, Fortran::lower::AbstractConverter &converter,
657657
builder.createIntegerConstant(loc, builder.getIndexType(), extent));
658658
shape = builder.create<fir::ShapeOp>(loc, extents);
659659
}
660-
auto declDst = builder.create<hlfir::DeclareOp>(loc, funcOp.getArgument(0),
661-
copyFuncName + "_dst", shape,
662-
typeparams, attrs);
663-
auto declSrc = builder.create<hlfir::DeclareOp>(loc, funcOp.getArgument(1),
664-
copyFuncName + "_src", shape,
665-
typeparams, attrs);
660+
auto declDst = builder.create<hlfir::DeclareOp>(
661+
loc, funcOp.getArgument(0), copyFuncName + "_dst", shape, typeparams,
662+
/*dummy_scope=*/nullptr, attrs);
663+
auto declSrc = builder.create<hlfir::DeclareOp>(
664+
loc, funcOp.getArgument(1), copyFuncName + "_src", shape, typeparams,
665+
/*dummy_scope=*/nullptr, attrs);
666666
converter.copyVar(loc, declDst.getBase(), declSrc.getBase());
667667
builder.create<mlir::func::ReturnOp>(loc);
668668
return funcOp;

0 commit comments

Comments
 (0)