Skip to content

[flang] Lowering changes for assigning dummy_scope to hlfir.declare. #90989

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions flang/include/flang/Lower/AbstractConverter.h
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,18 @@ class AbstractConverter {
/// function.
virtual void bindHostAssocTuple(mlir::Value val) = 0;

/// Returns fir.dummy_scope operation's result value to be used
/// as dummy_scope operand of hlfir.declare operations for the dummy
/// arguments of this function.
virtual mlir::Value dummyArgsScopeValue() const = 0;

/// Returns true if the given symbol is a dummy argument of this function.
/// Note that it returns false for all the symbols after all the variables
/// are instantiated for this function, i.e. it can only be used reliably
/// during the instatiation of the variables.
virtual bool
isRegisteredDummySymbol(Fortran::semantics::SymbolRef symRef) const = 0;

//===--------------------------------------------------------------------===//
// Types
//===--------------------------------------------------------------------===//
Expand Down
1 change: 1 addition & 0 deletions flang/include/flang/Optimizer/Builder/HLFIRTools.h
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ fir::FortranVariableOpInterface
genDeclare(mlir::Location loc, fir::FirOpBuilder &builder,
const fir::ExtendedValue &exv, llvm::StringRef name,
fir::FortranVariableFlagsAttr flags,
mlir::Value dummyScope = nullptr,
fir::CUDADataAttributeAttr cudaAttr = {});

/// Generate an hlfir.associate to build a variable from an expression value.
Expand Down
1 change: 1 addition & 0 deletions flang/include/flang/Optimizer/HLFIR/HLFIROps.td
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ def hlfir_DeclareOp : hlfir_Op<"declare", [AttrSizedOperandSegments,
let builders = [
OpBuilder<(ins "mlir::Value":$memref, "llvm::StringRef":$uniq_name,
CArg<"mlir::Value", "{}">:$shape, CArg<"mlir::ValueRange", "{}">:$typeparams,
CArg<"mlir::Value", "{}">:$dummy_scope,
CArg<"fir::FortranVariableFlagsAttr", "{}">:$fortran_attrs,
CArg<"fir::CUDADataAttributeAttr", "{}">:$cuda_attr)>];

Expand Down
73 changes: 62 additions & 11 deletions flang/lib/Lower/Bridge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -900,6 +900,16 @@ class FirConverter : public Fortran::lower::AbstractConverter {
hostAssocTuple = val;
}

mlir::Value dummyArgsScopeValue() const override final {
return dummyArgsScope;
}

bool isRegisteredDummySymbol(
Fortran::semantics::SymbolRef symRef) const override final {
auto *sym = &*symRef;
return registeredDummySymbols.contains(sym);
}

void registerTypeInfo(mlir::Location loc,
Fortran::lower::SymbolRef typeInfoSym,
const Fortran::semantics::DerivedTypeSpec &typeSpec,
Expand Down Expand Up @@ -1145,10 +1155,11 @@ class FirConverter : public Fortran::lower::AbstractConverter {
/// yet. The final mapping will be done using this pre-mapping in
/// Fortran::lower::mapSymbolAttributes.
bool mapBlockArgToDummyOrResult(const Fortran::semantics::SymbolRef sym,
mlir::Value val, bool forced = false) {
if (!forced && lookupSymbol(sym))
return false;
localSymbols.addSymbol(sym, val, forced);
mlir::Value val, bool isResult) {
localSymbols.addSymbol(sym, val);
if (!isResult)
registerDummySymbol(sym);

return true;
}

Expand Down Expand Up @@ -4559,7 +4570,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
const Fortran::lower::CalleeInterface &callee) {
assert(builder && "require a builder object at this point");
using PassBy = Fortran::lower::CalleeInterface::PassEntityBy;
auto mapPassedEntity = [&](const auto arg) {
auto mapPassedEntity = [&](const auto arg, bool isResult = false) {
if (arg.passBy == PassBy::AddressAndLength) {
if (callee.characterize().IsBindC())
return;
Expand All @@ -4569,10 +4580,11 @@ class FirConverter : public Fortran::lower::AbstractConverter {
fir::factory::CharacterExprHelper charHelp{*builder, loc};
mlir::Value box =
charHelp.createEmboxChar(arg.firArgument, arg.firLength);
mapBlockArgToDummyOrResult(arg.entity->get(), box);
mapBlockArgToDummyOrResult(arg.entity->get(), box, isResult);
} else {
if (arg.entity.has_value()) {
mapBlockArgToDummyOrResult(arg.entity->get(), arg.firArgument);
mapBlockArgToDummyOrResult(arg.entity->get(), arg.firArgument,
isResult);
} else {
assert(funit.parentHasTupleHostAssoc() && "expect tuple argument");
}
Expand All @@ -4581,15 +4593,19 @@ class FirConverter : public Fortran::lower::AbstractConverter {
for (const Fortran::lower::CalleeInterface::PassedEntity &arg :
callee.getPassedArguments())
mapPassedEntity(arg);
if (lowerToHighLevelFIR() && !callee.getPassedArguments().empty()) {
mlir::Value scopeOp = builder->create<fir::DummyScopeOp>(toLocation());
setDummyArgsScope(scopeOp);
}
if (std::optional<Fortran::lower::CalleeInterface::PassedEntity>
passedResult = callee.getPassedResult()) {
mapPassedEntity(*passedResult);
mapPassedEntity(*passedResult, /*isResult=*/true);
// FIXME: need to make sure things are OK here. addSymbol may not be OK
if (funit.primaryResult &&
passedResult->entity->get() != *funit.primaryResult)
mapBlockArgToDummyOrResult(
*funit.primaryResult,
getSymbolAddress(passedResult->entity->get()));
*funit.primaryResult, getSymbolAddress(passedResult->entity->get()),
/*isResult=*/true);
}
}

Expand Down Expand Up @@ -4766,7 +4782,8 @@ class FirConverter : public Fortran::lower::AbstractConverter {
Fortran::lower::StatementContext stmtCtx;
if (std::optional<Fortran::lower::CalleeInterface::PassedEntity>
passedResult = callee.getPassedResult()) {
mapBlockArgToDummyOrResult(altResult.getSymbol(), resultArg.getAddr());
mapBlockArgToDummyOrResult(altResult.getSymbol(), resultArg.getAddr(),
/*isResult=*/true);
Fortran::lower::mapSymbolAttributes(*this, altResult, localSymbols,
stmtCtx);
} else {
Expand Down Expand Up @@ -4810,6 +4827,11 @@ class FirConverter : public Fortran::lower::AbstractConverter {
if (!funit.getHostAssoc().empty())
funit.getHostAssoc().hostProcedureBindings(*this, localSymbols);

// Unregister all dummy symbols, so that their cloning (e.g. for OpenMP
// privatization) does not create the cloned hlfir.declare operations
// with dummy_scope operands.
resetRegisteredDummySymbols();

// Create most function blocks in advance.
createEmptyBlocks(funit.evaluationList);

Expand Down Expand Up @@ -4929,6 +4951,8 @@ class FirConverter : public Fortran::lower::AbstractConverter {
hostAssocTuple = mlir::Value{};
localSymbols.clear();
blockId = 0;
dummyArgsScope = mlir::Value{};
resetRegisteredDummySymbols();
}

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

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

/// Record fir.dummy_scope operation for this function.
/// It will be used to set dummy_scope operand of the hlfir.declare
/// operations.
void setDummyArgsScope(mlir::Value val) {
assert(!dummyArgsScope && val);
dummyArgsScope = val;
}

/// Record the given symbol as a dummy argument of this function.
void registerDummySymbol(Fortran::semantics::SymbolRef symRef) {
auto *sym = &*symRef;
registeredDummySymbols.insert(sym);
}

/// Reset all registered dummy symbols.
void resetRegisteredDummySymbols() { registeredDummySymbols.clear(); }

//===--------------------------------------------------------------------===//

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

/// Value of fir.dummy_scope operation for this function.
mlir::Value dummyArgsScope;

/// A set of dummy argument symbols for this function.
/// The set is only preserved during the instatiation
/// of variables for this function.
llvm::SmallPtrSet<const Fortran::semantics::Symbol *, 16>
registeredDummySymbols;

/// A map of unique names for constant expressions.
/// The names are used for representing the constant expressions
/// with global constant initialized objects.
Expand Down
2 changes: 1 addition & 1 deletion flang/lib/Lower/ConvertArrayConstructor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ class RuntimeTempStrategy : public StrategyBase {
mlir::Value shape = builder.genShape(loc, extents);
declare = builder.create<hlfir::DeclareOp>(
loc, tempStorage, tempName, shape, lengths,
fir::FortranVariableFlagsAttr{});
/*dummy_scope=*/nullptr, fir::FortranVariableFlagsAttr{});
initialBoxValue =
builder.createBox(loc, boxType, declare->getOriginalBase(), shape,
/*slice=*/mlir::Value{}, lengths, /*tdesc=*/{});
Expand Down
3 changes: 2 additions & 1 deletion flang/lib/Lower/ConvertExprToHLFIR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1676,7 +1676,8 @@ class HlfirBuilder {
mlir::Value storagePtr = builder.createTemporary(loc, recTy);
auto varOp = hlfir::EntityWithAttributes{builder.create<hlfir::DeclareOp>(
loc, storagePtr, "ctor.temp", /*shape=*/nullptr,
/*typeparams=*/mlir::ValueRange{}, fir::FortranVariableFlagsAttr{})};
/*typeparams=*/mlir::ValueRange{}, /*dummy_scope=*/nullptr,
fir::FortranVariableFlagsAttr{})};

// Initialize any components that need initialization.
mlir::Value box = builder.createBox(loc, fir::ExtendedValue{varOp});
Expand Down
20 changes: 15 additions & 5 deletions flang/lib/Lower/ConvertVariable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1683,7 +1683,8 @@ static void genDeclareSymbol(Fortran::lower::AbstractConverter &converter,

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

Expand All @@ -1710,8 +1711,12 @@ static void genDeclareSymbol(Fortran::lower::AbstractConverter &converter,
symMap.addVariableDefinition(sym, newBase, force);
return;
}
mlir::Value dummyScope;
if (converter.isRegisteredDummySymbol(sym))
dummyScope = converter.dummyArgsScopeValue();
auto newBase = builder.create<hlfir::DeclareOp>(
loc, base, name, shapeOrShift, lenParams, attributes, cudaAttr);
loc, base, name, shapeOrShift, lenParams, dummyScope, attributes,
cudaAttr);
symMap.addVariableDefinition(sym, newBase, force);
return;
}
Expand Down Expand Up @@ -1761,8 +1766,11 @@ void Fortran::lower::genDeclareSymbol(
Fortran::lower::translateSymbolCUDADataAttribute(builder.getContext(),
sym.GetUltimate());
auto name = converter.mangleName(sym);
hlfir::EntityWithAttributes declare =
hlfir::genDeclare(loc, builder, exv, name, attributes, cudaAttr);
mlir::Value dummyScope;
if (converter.isRegisteredDummySymbol(sym))
dummyScope = converter.dummyArgsScopeValue();
hlfir::EntityWithAttributes declare = hlfir::genDeclare(
loc, builder, exv, name, attributes, dummyScope, cudaAttr);
symMap.addVariableDefinition(sym, declare.getIfVariableInterface(), force);
return;
}
Expand Down Expand Up @@ -2022,7 +2030,9 @@ void Fortran::lower::mapSymbolAttributes(
fir::factory::genMutableBoxRead(
builder, loc,
fir::factory::createTempMutableBox(builder, loc, ty, {}, {},
isPolymorphic)));
isPolymorphic)),
fir::FortranVariableFlagsEnum::None,
converter.isRegisteredDummySymbol(sym));
return true;
}
return false;
Expand Down
22 changes: 14 additions & 8 deletions flang/lib/Lower/OpenACC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,8 @@ static void genPrivateLikeInitRegion(mlir::OpBuilder &builder, RecipeOp recipe,
auto alloca = builder.create<fir::AllocaOp>(loc, refTy.getEleTy());
auto declareOp = builder.create<hlfir::DeclareOp>(
loc, alloca, accPrivateInitName, /*shape=*/nullptr,
llvm::ArrayRef<mlir::Value>{}, fir::FortranVariableFlagsAttr{});
llvm::ArrayRef<mlir::Value>{}, /*dummy_scope=*/nullptr,
fir::FortranVariableFlagsAttr{});
retVal = declareOp.getBase();
} else if (auto seqTy = mlir::dyn_cast_or_null<fir::SequenceType>(
refTy.getEleTy())) {
Expand All @@ -446,7 +447,8 @@ static void genPrivateLikeInitRegion(mlir::OpBuilder &builder, RecipeOp recipe,
loc, seqTy, /*typeparams=*/mlir::ValueRange{}, extents);
auto declareOp = builder.create<hlfir::DeclareOp>(
loc, alloca, accPrivateInitName, shape,
llvm::ArrayRef<mlir::Value>{}, fir::FortranVariableFlagsAttr{});
llvm::ArrayRef<mlir::Value>{}, /*dummy_scope=*/nullptr,
fir::FortranVariableFlagsAttr{});
retVal = declareOp.getBase();
}
}
Expand Down Expand Up @@ -666,10 +668,12 @@ mlir::acc::FirstprivateRecipeOp Fortran::lower::createOrGetFirstprivateRecipe(

auto leftDeclOp = builder.create<hlfir::DeclareOp>(
loc, recipe.getCopyRegion().getArgument(0), llvm::StringRef{}, shape,
llvm::ArrayRef<mlir::Value>{}, fir::FortranVariableFlagsAttr{});
llvm::ArrayRef<mlir::Value>{}, /*dummy_scope=*/nullptr,
fir::FortranVariableFlagsAttr{});
auto rightDeclOp = builder.create<hlfir::DeclareOp>(
loc, recipe.getCopyRegion().getArgument(1), llvm::StringRef{}, shape,
llvm::ArrayRef<mlir::Value>{}, fir::FortranVariableFlagsAttr{});
llvm::ArrayRef<mlir::Value>{}, /*dummy_scope=*/nullptr,
fir::FortranVariableFlagsAttr{});

hlfir::DesignateOp::Subscripts triplets =
getSubscriptsFromArgs(recipe.getCopyRegion().getArguments());
Expand Down Expand Up @@ -975,7 +979,8 @@ static mlir::Value genReductionInitRegion(fir::FirOpBuilder &builder,
mlir::Value alloca = builder.create<fir::AllocaOp>(loc, ty);
auto declareOp = builder.create<hlfir::DeclareOp>(
loc, alloca, accReductionInitName, /*shape=*/nullptr,
llvm::ArrayRef<mlir::Value>{}, fir::FortranVariableFlagsAttr{});
llvm::ArrayRef<mlir::Value>{}, /*dummy_scope=*/nullptr,
fir::FortranVariableFlagsAttr{});
builder.create<fir::StoreOp>(loc, builder.createConvert(loc, ty, initValue),
declareOp.getBase());
return declareOp.getBase();
Expand All @@ -991,7 +996,8 @@ static mlir::Value genReductionInitRegion(fir::FirOpBuilder &builder,
loc, seqTy, /*typeparams=*/mlir::ValueRange{}, extents);
auto declareOp = builder.create<hlfir::DeclareOp>(
loc, alloca, accReductionInitName, shape,
llvm::ArrayRef<mlir::Value>{}, fir::FortranVariableFlagsAttr{});
llvm::ArrayRef<mlir::Value>{}, /*dummy_scope=*/nullptr,
fir::FortranVariableFlagsAttr{});
mlir::Type idxTy = builder.getIndexType();
mlir::Type refTy = fir::ReferenceType::get(seqTy.getEleTy());
llvm::SmallVector<fir::DoLoopOp> loops;
Expand Down Expand Up @@ -1143,10 +1149,10 @@ static void genCombiner(fir::FirOpBuilder &builder, mlir::Location loc,
recipe.getCombinerRegion().getArguments());
auto v1DeclareOp = builder.create<hlfir::DeclareOp>(
loc, value1, llvm::StringRef{}, shape, llvm::ArrayRef<mlir::Value>{},
fir::FortranVariableFlagsAttr{});
/*dummy_scope=*/nullptr, fir::FortranVariableFlagsAttr{});
auto v2DeclareOp = builder.create<hlfir::DeclareOp>(
loc, value2, llvm::StringRef{}, shape, llvm::ArrayRef<mlir::Value>{},
fir::FortranVariableFlagsAttr{});
/*dummy_scope=*/nullptr, fir::FortranVariableFlagsAttr{});
hlfir::DesignateOp::Subscripts triplets = getTripletsFromArgs(recipe);

llvm::SmallVector<mlir::Value> lenParamsLeft;
Expand Down
12 changes: 6 additions & 6 deletions flang/lib/Lower/OpenMP/ClauseProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -657,12 +657,12 @@ createCopyFunc(mlir::Location loc, Fortran::lower::AbstractConverter &converter,
builder.createIntegerConstant(loc, builder.getIndexType(), extent));
shape = builder.create<fir::ShapeOp>(loc, extents);
}
auto declDst = builder.create<hlfir::DeclareOp>(loc, funcOp.getArgument(0),
copyFuncName + "_dst", shape,
typeparams, attrs);
auto declSrc = builder.create<hlfir::DeclareOp>(loc, funcOp.getArgument(1),
copyFuncName + "_src", shape,
typeparams, attrs);
auto declDst = builder.create<hlfir::DeclareOp>(
loc, funcOp.getArgument(0), copyFuncName + "_dst", shape, typeparams,
/*dummy_scope=*/nullptr, attrs);
auto declSrc = builder.create<hlfir::DeclareOp>(
loc, funcOp.getArgument(1), copyFuncName + "_src", shape, typeparams,
/*dummy_scope=*/nullptr, attrs);
converter.copyVar(loc, declDst.getBase(), declSrc.getBase());
builder.create<mlir::func::ReturnOp>(loc);
return funcOp;
Expand Down
Loading
Loading