diff --git a/flang/include/flang/Lower/ConvertExprToHLFIR.h b/flang/include/flang/Lower/ConvertExprToHLFIR.h --- a/flang/include/flang/Lower/ConvertExprToHLFIR.h +++ b/flang/include/flang/Lower/ConvertExprToHLFIR.h @@ -32,11 +32,10 @@ class StatementContext; class SymMap; -hlfir::FortranEntity convertExprToHLFIR(mlir::Location loc, - Fortran::lower::AbstractConverter &, - const Fortran::lower::SomeExpr &, - Fortran::lower::SymMap &, - Fortran::lower::StatementContext &); +hlfir::EntityWithAttributes +convertExprToHLFIR(mlir::Location loc, Fortran::lower::AbstractConverter &, + const Fortran::lower::SomeExpr &, Fortran::lower::SymMap &, + Fortran::lower::StatementContext &); } // namespace Fortran::lower #endif // FORTRAN_LOWER_CONVERTEXPRTOHLFIR_H diff --git a/flang/include/flang/Optimizer/Builder/HLFIRTools.h b/flang/include/flang/Optimizer/Builder/HLFIRTools.h --- a/flang/include/flang/Optimizer/Builder/HLFIRTools.h +++ b/flang/include/flang/Optimizer/Builder/HLFIRTools.h @@ -41,26 +41,28 @@ /// original source or can be legally defined: temporaries created to store /// expression values are considered to be variables, and so are PARAMETERs /// global constant address. -inline bool isFortranVariable(mlir::Value value) { +inline bool isFortranVariableWithAttributes(mlir::Value value) { return value.getDefiningOp(); } -/// Is this a Fortran variable or expression value? -inline bool isFortranEntity(mlir::Value value) { - return isFortranValue(value) || isFortranVariable(value); +/// Is this a Fortran expression value, or a Fortran variable for which the +/// defining op carrying the Fortran attributes is visible? +inline bool isFortranEntityWithAttributes(mlir::Value value) { + return isFortranValue(value) || isFortranVariableWithAttributes(value); } /// Wrapper over an mlir::Value that can be viewed as a Fortran entity. /// This provides some Fortran specific helpers as well as a guarantee /// in the compiler source that a certain mlir::Value must be a Fortran -/// entity. -class FortranEntity : public mlir::Value { +/// entity, and if it is a variable, its defining operation carrying its +/// Fortran attributes must be visible. +class EntityWithAttributes : public mlir::Value { public: - explicit FortranEntity(mlir::Value value) : mlir::Value(value) { - assert(isFortranEntity(value) && + explicit EntityWithAttributes(mlir::Value value) : mlir::Value(value) { + assert(isFortranEntityWithAttributes(value) && "must be a value representing a Fortran value or variable"); } - FortranEntity(fir::FortranVariableOpInterface variable) + EntityWithAttributes(fir::FortranVariableOpInterface variable) : mlir::Value(variable.getBase()) {} bool isValue() const { return isFortranValue(*this); } bool isVariable() const { return !isValue(); } @@ -70,7 +72,7 @@ mlir::Value getBase() const { return *this; } }; -/// Functions to translate hlfir::FortranEntity to fir::ExtendedValue. +/// Functions to translate hlfir::EntityWithAttributes to fir::ExtendedValue. /// For Fortran arrays, character, and derived type values, this require /// allocating a storage since these can only be represented in memory in FIR. /// In that case, a cleanup function is provided to generate the finalization @@ -78,7 +80,7 @@ using CleanupFunction = std::function; std::pair> translateToExtendedValue(mlir::Location loc, fir::FirOpBuilder &builder, - FortranEntity entity); + EntityWithAttributes entity); /// Function to translate FortranVariableOpInterface to fir::ExtendedValue. /// It does not generate any IR, and is a simple packaging operation. @@ -86,9 +88,10 @@ translateToExtendedValue(fir::FortranVariableOpInterface fortranVariable); /// Generate declaration for a fir::ExtendedValue in memory. -FortranEntity genDeclare(mlir::Location loc, fir::FirOpBuilder &builder, - const fir::ExtendedValue &exv, llvm::StringRef name, - fir::FortranVariableFlagsAttr flags); +EntityWithAttributes genDeclare(mlir::Location loc, fir::FirOpBuilder &builder, + const fir::ExtendedValue &exv, + llvm::StringRef name, + fir::FortranVariableFlagsAttr flags); } // namespace hlfir diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp --- a/flang/lib/Lower/Bridge.cpp +++ b/flang/lib/Lower/Bridge.cpp @@ -419,7 +419,8 @@ } fir::ExtendedValue - translateToExtendedValue(mlir::Location loc, hlfir::FortranEntity entity, + translateToExtendedValue(mlir::Location loc, + hlfir::EntityWithAttributes entity, Fortran::lower::StatementContext &context) { auto [exv, exvCleanup] = hlfir::translateToExtendedValue(loc, getFirOpBuilder(), entity); @@ -434,8 +435,9 @@ mlir::Location *locPtr = nullptr) override final { mlir::Location loc = locPtr ? *locPtr : toLocation(); if (bridge.getLoweringOptions().getLowerToHighLevelFIR()) { - hlfir::FortranEntity loweredExpr = Fortran::lower::convertExprToHLFIR( - loc, *this, expr, localSymbols, context); + hlfir::EntityWithAttributes loweredExpr = + Fortran::lower::convertExprToHLFIR(loc, *this, expr, localSymbols, + context); if (fir::FortranVariableOpInterface variable = loweredExpr.getIfVariable()) if (!variable.isBox()) @@ -453,8 +455,9 @@ mlir::Location *locPtr = nullptr) override final { mlir::Location loc = locPtr ? *locPtr : toLocation(); if (bridge.getLoweringOptions().getLowerToHighLevelFIR()) { - hlfir::FortranEntity loweredExpr = Fortran::lower::convertExprToHLFIR( - loc, *this, expr, localSymbols, context); + hlfir::EntityWithAttributes loweredExpr = + Fortran::lower::convertExprToHLFIR(loc, *this, expr, localSymbols, + context); fir::ExtendedValue exv = translateToExtendedValue(loc, loweredExpr, context); // Load scalar references to integer, logical, real, or complex value @@ -488,8 +491,9 @@ genExprBox(mlir::Location loc, const Fortran::lower::SomeExpr &expr, Fortran::lower::StatementContext &stmtCtx) override final { if (bridge.getLoweringOptions().getLowerToHighLevelFIR()) { - hlfir::FortranEntity loweredExpr = Fortran::lower::convertExprToHLFIR( - loc, *this, expr, localSymbols, stmtCtx); + hlfir::EntityWithAttributes loweredExpr = + Fortran::lower::convertExprToHLFIR(loc, *this, expr, localSymbols, + stmtCtx); if (fir::FortranVariableOpInterface variable = loweredExpr.getIfVariable()) if (variable.isBoxValue() || !variable.isBoxAddress()) { diff --git a/flang/lib/Lower/ConvertExprToHLFIR.cpp b/flang/lib/Lower/ConvertExprToHLFIR.cpp --- a/flang/lib/Lower/ConvertExprToHLFIR.cpp +++ b/flang/lib/Lower/ConvertExprToHLFIR.cpp @@ -32,44 +32,50 @@ using CharacterDesignators = decltype(Fortran::evaluate::Designator>::u); - hlfir::FortranEntity gen(const CharacterDesignators &designatorVariant) { + hlfir::EntityWithAttributes + gen(const CharacterDesignators &designatorVariant) { return std::visit([&](const auto &x) { return gen(x); }, designatorVariant); } // Character designators variant contains complex parts using RealDesignators = decltype(Fortran::evaluate::Designator>::u); - hlfir::FortranEntity gen(const RealDesignators &designatorVariant) { + hlfir::EntityWithAttributes gen(const RealDesignators &designatorVariant) { return std::visit([&](const auto &x) { return gen(x); }, designatorVariant); } // All other designators are similar using OtherDesignators = decltype(Fortran::evaluate::Designator>::u); - hlfir::FortranEntity gen(const OtherDesignators &designatorVariant) { + hlfir::EntityWithAttributes gen(const OtherDesignators &designatorVariant) { return std::visit([&](const auto &x) { return gen(x); }, designatorVariant); } private: - hlfir::FortranEntity gen(const Fortran::evaluate::SymbolRef &symbolRef) { + hlfir::EntityWithAttributes + gen(const Fortran::evaluate::SymbolRef &symbolRef) { if (llvm::Optional varDef = getSymMap().lookupVariableDefinition(symbolRef)) return *varDef; TODO(getLoc(), "lowering symbol to HLFIR"); } - hlfir::FortranEntity gen(const Fortran::evaluate::Component &component) { + hlfir::EntityWithAttributes + gen(const Fortran::evaluate::Component &component) { TODO(getLoc(), "lowering component to HLFIR"); } - hlfir::FortranEntity gen(const Fortran::evaluate::ArrayRef &arrayRef) { + hlfir::EntityWithAttributes gen(const Fortran::evaluate::ArrayRef &arrayRef) { TODO(getLoc(), "lowering ArrayRef to HLFIR"); } - hlfir::FortranEntity gen(const Fortran::evaluate::CoarrayRef &coarrayRef) { + hlfir::EntityWithAttributes + gen(const Fortran::evaluate::CoarrayRef &coarrayRef) { TODO(getLoc(), "lowering CoarrayRef to HLFIR"); } - hlfir::FortranEntity gen(const Fortran::evaluate::ComplexPart &complexPart) { + hlfir::EntityWithAttributes + gen(const Fortran::evaluate::ComplexPart &complexPart) { TODO(getLoc(), "lowering complex part to HLFIR"); } - hlfir::FortranEntity gen(const Fortran::evaluate::Substring &substring) { + hlfir::EntityWithAttributes + gen(const Fortran::evaluate::Substring &substring) { TODO(getLoc(), "lowering substrings to HLFIR"); } @@ -94,38 +100,42 @@ : converter{converter}, symMap{symMap}, stmtCtx{stmtCtx}, loc{loc} {} template - hlfir::FortranEntity gen(const Fortran::evaluate::Expr &expr) { + hlfir::EntityWithAttributes gen(const Fortran::evaluate::Expr &expr) { return std::visit([&](const auto &x) { return gen(x); }, expr.u); } private: - hlfir::FortranEntity gen(const Fortran::evaluate::BOZLiteralConstant &expr) { + hlfir::EntityWithAttributes + gen(const Fortran::evaluate::BOZLiteralConstant &expr) { fir::emitFatalError(loc, "BOZ literal must be replaced by semantics"); } - hlfir::FortranEntity gen(const Fortran::evaluate::NullPointer &expr) { + hlfir::EntityWithAttributes gen(const Fortran::evaluate::NullPointer &expr) { TODO(getLoc(), "lowering NullPointer to HLFIR"); } - hlfir::FortranEntity gen(const Fortran::evaluate::ProcedureDesignator &expr) { + hlfir::EntityWithAttributes + gen(const Fortran::evaluate::ProcedureDesignator &expr) { TODO(getLoc(), "lowering ProcDes to HLFIR"); } - hlfir::FortranEntity gen(const Fortran::evaluate::ProcedureRef &expr) { + hlfir::EntityWithAttributes gen(const Fortran::evaluate::ProcedureRef &expr) { TODO(getLoc(), "lowering ProcRef to HLFIR"); } template - hlfir::FortranEntity gen(const Fortran::evaluate::Designator &designator) { + hlfir::EntityWithAttributes + gen(const Fortran::evaluate::Designator &designator) { return HlfirDesignatorBuilder(getLoc(), getConverter(), getSymMap(), getStmtCtx()) .gen(designator.u); } template - hlfir::FortranEntity gen(const Fortran::evaluate::FunctionRef &expr) { + hlfir::EntityWithAttributes + gen(const Fortran::evaluate::FunctionRef &expr) { TODO(getLoc(), "lowering funcRef to HLFIR"); } template - hlfir::FortranEntity gen(const Fortran::evaluate::Constant &expr) { + hlfir::EntityWithAttributes gen(const Fortran::evaluate::Constant &expr) { mlir::Location loc = getLoc(); if constexpr (std::is_same_v) { TODO(loc, "lowering derived type constant to HLFIR"); @@ -136,7 +146,7 @@ builder, loc, expr, /*outlineBigConstantInReadOnlyMemory=*/true); if (const auto *scalarBox = exv.getUnboxed()) if (fir::isa_trivial(scalarBox->getType())) - return hlfir::FortranEntity(*scalarBox); + return hlfir::EntityWithAttributes(*scalarBox); if (auto addressOf = fir::getBase(exv).getDefiningOp()) { auto flags = fir::FortranVariableFlagsAttr::get( builder.getContext(), fir::FortranVariableFlagsEnum::parameter); @@ -149,47 +159,52 @@ } template - hlfir::FortranEntity gen(const Fortran::evaluate::ArrayConstructor &expr) { + hlfir::EntityWithAttributes + gen(const Fortran::evaluate::ArrayConstructor &expr) { TODO(getLoc(), "lowering ArrayCtor to HLFIR"); } template - hlfir::FortranEntity + hlfir::EntityWithAttributes gen(const Fortran::evaluate::Convert, TC2> &convert) { TODO(getLoc(), "lowering convert to HLFIR"); } template - hlfir::FortranEntity gen(const Fortran::evaluate::Operation &op) { + hlfir::EntityWithAttributes + gen(const Fortran::evaluate::Operation &op) { TODO(getLoc(), "lowering unary op to HLFIR"); } template - hlfir::FortranEntity + hlfir::EntityWithAttributes gen(const Fortran::evaluate::Operation &op) { TODO(getLoc(), "lowering binary op to HLFIR"); } - hlfir::FortranEntity + hlfir::EntityWithAttributes gen(const Fortran::evaluate::Relational &op) { return std::visit([&](const auto &x) { return gen(x); }, op.u); } - hlfir::FortranEntity gen(const Fortran::evaluate::TypeParamInquiry &) { + hlfir::EntityWithAttributes gen(const Fortran::evaluate::TypeParamInquiry &) { TODO(getLoc(), "lowering type parameter inquiry to HLFIR"); } - hlfir::FortranEntity gen(const Fortran::evaluate::DescriptorInquiry &desc) { + hlfir::EntityWithAttributes + gen(const Fortran::evaluate::DescriptorInquiry &desc) { TODO(getLoc(), "lowering descriptor inquiry to HLFIR"); } - hlfir::FortranEntity gen(const Fortran::evaluate::ImpliedDoIndex &var) { + hlfir::EntityWithAttributes + gen(const Fortran::evaluate::ImpliedDoIndex &var) { TODO(getLoc(), "lowering implied do index to HLFIR"); } - hlfir::FortranEntity gen(const Fortran::evaluate::StructureConstructor &var) { + hlfir::EntityWithAttributes + gen(const Fortran::evaluate::StructureConstructor &var) { TODO(getLoc(), "lowering structure constructor to HLFIR"); } @@ -207,7 +222,7 @@ } // namespace -hlfir::FortranEntity Fortran::lower::convertExprToHLFIR( +hlfir::EntityWithAttributes Fortran::lower::convertExprToHLFIR( mlir::Location loc, Fortran::lower::AbstractConverter &converter, const Fortran::lower::SomeExpr &expr, Fortran::lower::SymMap &symMap, Fortran::lower::StatementContext &stmtCtx) { diff --git a/flang/lib/Optimizer/Builder/HLFIRTools.cpp b/flang/lib/Optimizer/Builder/HLFIRTools.cpp --- a/flang/lib/Optimizer/Builder/HLFIRTools.cpp +++ b/flang/lib/Optimizer/Builder/HLFIRTools.cpp @@ -68,7 +68,7 @@ std::pair> hlfir::translateToExtendedValue(mlir::Location loc, fir::FirOpBuilder &, - hlfir::FortranEntity entity) { + hlfir::EntityWithAttributes entity) { if (auto variable = entity.getIfVariable()) return {hlfir::translateToExtendedValue(variable), {}}; if (entity.getType().isa()) @@ -98,11 +98,10 @@ return variable.getBase(); } -hlfir::FortranEntity hlfir::genDeclare(mlir::Location loc, - fir::FirOpBuilder &builder, - const fir::ExtendedValue &exv, - llvm::StringRef name, - fir::FortranVariableFlagsAttr flags) { +hlfir::EntityWithAttributes +hlfir::genDeclare(mlir::Location loc, fir::FirOpBuilder &builder, + const fir::ExtendedValue &exv, llvm::StringRef name, + fir::FortranVariableFlagsAttr flags) { mlir::Value base = fir::getBase(exv); assert(fir::isa_passbyref_type(base.getType()) && diff --git a/flang/unittests/Optimizer/Builder/HLFIRToolsTest.cpp b/flang/unittests/Optimizer/Builder/HLFIRToolsTest.cpp --- a/flang/unittests/Optimizer/Builder/HLFIRToolsTest.cpp +++ b/flang/unittests/Optimizer/Builder/HLFIRToolsTest.cpp @@ -86,7 +86,7 @@ mlir::Type scalarf32Type = builder.getRefType(f32Type); mlir::Value scalarf32Addr = builder.create(loc, scalarf32Type); fir::ExtendedValue scalarf32{scalarf32Addr}; - hlfir::FortranEntity scalarf32Entity(createDeclare(scalarf32)); + hlfir::EntityWithAttributes scalarf32Entity(createDeclare(scalarf32)); auto [scalarf32Result, cleanup] = hlfir::translateToExtendedValue(loc, builder, scalarf32Entity); auto *unboxed = scalarf32Result.getUnboxed(); @@ -110,7 +110,7 @@ mlir::Type arrayf32Type = builder.getRefType(seqf32Type); mlir::Value arrayf32Addr = builder.create(loc, arrayf32Type); fir::ArrayBoxValue arrayf32{arrayf32Addr, extents, lbounds}; - hlfir::FortranEntity arrayf32Entity(createDeclare(arrayf32)); + hlfir::EntityWithAttributes arrayf32Entity(createDeclare(arrayf32)); auto [arrayf32Result, cleanup] = hlfir::translateToExtendedValue(loc, builder, arrayf32Entity); auto *res = arrayf32Result.getBoxOf(); @@ -138,7 +138,7 @@ mlir::Value scalarCharAddr = builder.create(loc, scalarCharType); fir::CharBoxValue scalarChar{scalarCharAddr, len}; - hlfir::FortranEntity scalarCharEntity(createDeclare(scalarChar)); + hlfir::EntityWithAttributes scalarCharEntity(createDeclare(scalarChar)); auto [scalarCharResult, cleanup] = hlfir::translateToExtendedValue(loc, builder, scalarCharEntity); auto *res = scalarCharResult.getBoxOf(); @@ -163,7 +163,7 @@ mlir::Type arrayCharType = builder.getRefType(seqCharType); mlir::Value arrayCharAddr = builder.create(loc, arrayCharType); fir::CharArrayBoxValue arrayChar{arrayCharAddr, len, extents, lbounds}; - hlfir::FortranEntity arrayCharEntity(createDeclare(arrayChar)); + hlfir::EntityWithAttributes arrayCharEntity(createDeclare(arrayChar)); auto [arrayCharResult, cleanup] = hlfir::translateToExtendedValue(loc, builder, arrayCharEntity); auto *res = arrayCharResult.getBoxOf(); @@ -196,7 +196,7 @@ builder.create(loc, arrayCharBoxType); llvm::SmallVector explicitTypeParams{len}; fir::BoxValue arrayChar{arrayCharAddr, lbounds, explicitTypeParams}; - hlfir::FortranEntity arrayCharEntity(createDeclare(arrayChar)); + hlfir::EntityWithAttributes arrayCharEntity(createDeclare(arrayChar)); auto [arrayCharResult, cleanup] = hlfir::translateToExtendedValue(loc, builder, arrayCharEntity); auto *res = arrayCharResult.getBoxOf();