diff --git a/flang/include/flang/Lower/PFTBuilder.h b/flang/include/flang/Lower/PFTBuilder.h index 8d32c32352916..c2b0fdbf357cd 100644 --- a/flang/include/flang/Lower/PFTBuilder.h +++ b/flang/include/flang/Lower/PFTBuilder.h @@ -463,6 +463,9 @@ struct Variable { return *std::get(var).symbol; } + /// Is this variable a compiler generated global to describe derived types? + bool isRuntimeTypeInfoData() const; + /// Return the aggregate store. const AggregateStore &getAggregateStore() const { assert(isAggregateStore()); diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp index 4c8e0cb128744..579f94ba75684 100644 --- a/flang/lib/Lower/Bridge.cpp +++ b/flang/lib/Lower/Bridge.cpp @@ -4358,7 +4358,8 @@ class FirConverter : public Fortran::lower::AbstractConverter { if (scp->kind() == Fortran::semantics::Scope::Kind::Module) for (const auto &var : Fortran::lower::pft::getScopeVariableList( *scp, scopeVariableListMap)) - instantiateVar(var, storeMap); + if (!var.isRuntimeTypeInfoData()) + instantiateVar(var, storeMap); // Map function equivalences and variables. mlir::Value primaryFuncResultStorage; diff --git a/flang/lib/Lower/ConvertVariable.cpp b/flang/lib/Lower/ConvertVariable.cpp index afa71e9110469..8ea2557c42b37 100644 --- a/flang/lib/Lower/ConvertVariable.cpp +++ b/flang/lib/Lower/ConvertVariable.cpp @@ -134,18 +134,6 @@ static bool isConstant(const Fortran::semantics::Symbol &sym) { sym.test(Fortran::semantics::Symbol::Flag::ReadOnly); } -/// Is this a compiler generated symbol to describe derived types ? -static bool isRuntimeTypeInfoData(const Fortran::semantics::Symbol &sym) { - // So far, use flags to detect if this symbol were generated during - // semantics::BuildRuntimeDerivedTypeTables(). Scope cannot be used since the - // symbols are injected in the user scopes defining the described derived - // types. A robustness improvement for this test could be to get hands on the - // semantics::RuntimeDerivedTypeTables and to check if the symbol names - // belongs to this structure. - return sym.test(Fortran::semantics::Symbol::Flag::CompilerCreated) && - sym.test(Fortran::semantics::Symbol::Flag::ReadOnly); -} - static fir::GlobalOp defineGlobal(Fortran::lower::AbstractConverter &converter, const Fortran::lower::pft::Variable &var, llvm::StringRef globalName, @@ -626,7 +614,7 @@ getLinkageAttribute(fir::FirOpBuilder &builder, // unit. It desired to avoid having to link against module that only define a // type. Therefore the runtime type info is generated everywhere it is needed // with `linkonce_odr` LLVM linkage. - if (var.hasSymbol() && isRuntimeTypeInfoData(var.getSymbol())) + if (var.isRuntimeTypeInfoData()) return builder.createLinkOnceODRLinkage(); if (var.isModuleOrSubmoduleVariable()) return {}; // external linkage diff --git a/flang/lib/Lower/PFTBuilder.cpp b/flang/lib/Lower/PFTBuilder.cpp index 0e32e2c7d96a7..1dacd5cf64cd9 100644 --- a/flang/lib/Lower/PFTBuilder.cpp +++ b/flang/lib/Lower/PFTBuilder.cpp @@ -1802,6 +1802,27 @@ Fortran::lower::pft::BlockDataUnit::BlockDataUnit( std::get>(bd.t).source)} { } +//===----------------------------------------------------------------------===// +// Variable implementation +//===----------------------------------------------------------------------===// + +bool Fortran::lower::pft::Variable::isRuntimeTypeInfoData() const { + // So far, use flags to detect if this symbol were generated during + // semantics::BuildRuntimeDerivedTypeTables(). Scope cannot be used since the + // symbols are injected in the user scopes defining the described derived + // types. A robustness improvement for this test could be to get hands on the + // semantics::RuntimeDerivedTypeTables and to check if the symbol names + // belongs to this structure. + using Flags = Fortran::semantics::Symbol::Flag; + const auto *nominal = std::get_if(&var); + return nominal && nominal->symbol->test(Flags::CompilerCreated) && + nominal->symbol->test(Flags::ReadOnly); +} + +//===----------------------------------------------------------------------===// +// API implementation +//===----------------------------------------------------------------------===// + std::unique_ptr Fortran::lower::createPFT(const parser::Program &root, const semantics::SemanticsContext &semanticsContext) { diff --git a/flang/test/Lower/OpenACC/acc-bounds.f90 b/flang/test/Lower/OpenACC/acc-bounds.f90 index 30ce243764b22..bd96bc8bcba35 100644 --- a/flang/test/Lower/OpenACC/acc-bounds.f90 +++ b/flang/test/Lower/OpenACC/acc-bounds.f90 @@ -115,7 +115,7 @@ subroutine acc_multi_strides(a) ! CHECK: %[[BOX_DIMS2:.*]]:3 = fir.box_dims %[[DECL_ARG0]]#0, %c2{{.*}} : (!fir.box>, index) -> (index, index, index) ! CHECK: %[[BOUNDS2:.*]] = acc.bounds lowerbound(%{{.*}} : index) upperbound(%{{.*}} : index) extent(%[[BOX_DIMS2]]#1 : index) stride(%[[STRIDE2]] : index) startIdx(%{{.*}} : index) {strideInBytes = true} ! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[DECL_ARG0]]#0 : (!fir.box>) -> !fir.ref> -! CHECK: %[[PRESENT:.*]] = acc.present varPtr(%[[BOX_ADDR]] : !fir.ref>) bounds(%29, %33, %37) -> !fir.ref> {name = "a"} +! CHECK: %[[PRESENT:.*]] = acc.present varPtr(%[[BOX_ADDR]] : !fir.ref>) bounds(%[[BOUNDS0]], %[[BOUNDS1]], %[[BOUNDS2]]) -> !fir.ref> {name = "a"} ! CHECK: acc.kernels dataOperands(%[[PRESENT]] : !fir.ref>) { subroutine acc_optional_data(a) diff --git a/flang/test/Lower/allocatable-polymorphic.f90 b/flang/test/Lower/allocatable-polymorphic.f90 index a6a8c039880da..f4302144310f7 100644 --- a/flang/test/Lower/allocatable-polymorphic.f90 +++ b/flang/test/Lower/allocatable-polymorphic.f90 @@ -345,7 +345,7 @@ subroutine test_allocatable() ! CHECK: %[[TYPE_DESC_ADDR:.*]] = fir.type_desc !fir.type<_QMpolyTp1{a:i32,b:i32}> ! CHECK: %[[P_CAST:.*]] = fir.convert %[[P_DECL]]#1 : (!fir.ref>>>) -> !fir.ref> ! CHECK: %[[TYPE_NONE:.*]] = fir.convert %[[TYPE_DESC_ADDR]] : (!fir.tdesc>) -> !fir.ref -! CHECK: %{{.*}} = fir.call @_FortranAAllocatableDeallocatePolymorphic(%[[P_CAST]], %[[TYPE_NONE]], %{{.*}}, %1{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref>, !fir.ref, i1, !fir.box, !fir.ref, i32) -> i32 +! CHECK: %{{.*}} = fir.call @_FortranAAllocatableDeallocatePolymorphic(%[[P_CAST]], %[[TYPE_NONE]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref>, !fir.ref, i1, !fir.box, !fir.ref, i32) -> i32 ! CHECK: %[[TYPE_DESC_ADDR:.*]] = fir.type_desc !fir.type<_QMpolyTp1{a:i32,b:i32}> ! CHECK: %[[C1_CAST:.*]] = fir.convert %[[C1_DECL]]#1 : (!fir.ref>>>) -> !fir.ref> @@ -421,7 +421,7 @@ subroutine test_type_with_polymorphic_pointer_component() ! CHECK-LABEL: func.func @_QMpolyPtest_type_with_polymorphic_pointer_component() ! CHECK: %[[TYPE_PTR:.*]] = fir.alloca !fir.box>>}>>> {bindc_name = "a", uniq_name = "_QMpolyFtest_type_with_polymorphic_pointer_componentEa"} -! CHECK: %[[TYPE_PTR_DECL:.*]]:2 = hlfir.declare %39 {fortran_attrs = #fir.var_attrs, uniq_name = "_QMpolyFtest_type_with_polymorphic_pointer_componentEa"} : (!fir.ref>>}>>>>) -> (!fir.ref>>}>>>>, !fir.ref>>}>>>>) +! CHECK: %[[TYPE_PTR_DECL:.*]]:2 = hlfir.declare %[[TYPE_PTR]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QMpolyFtest_type_with_polymorphic_pointer_componentEa"} : (!fir.ref>>}>>>>) -> (!fir.ref>>}>>>>, !fir.ref>>}>>>>) ! CHECK: %[[TYPE_PTR_CONV:.*]] = fir.convert %[[TYPE_PTR_DECL]]#1 : (!fir.ref>>}>>>>) -> !fir.ref> ! CHECK: fir.call @_FortranAPointerAllocate(%[[TYPE_PTR_CONV]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 ! CHECK: %[[TYPE_PTR_LOAD:.*]] = fir.load %[[TYPE_PTR_DECL]]#0 : !fir.ref>>}>>>> diff --git a/flang/test/Lower/nullify-polymorphic.f90 b/flang/test/Lower/nullify-polymorphic.f90 index 005fe93b35435..ee271b815bdd5 100644 --- a/flang/test/Lower/nullify-polymorphic.f90 +++ b/flang/test/Lower/nullify-polymorphic.f90 @@ -43,7 +43,7 @@ program test ! CHECK-LABEL: func.func @_QMpolyPtest_nullify() ! CHECK: %[[C_DESC:.*]] = fir.alloca !fir.class>> {bindc_name = "c", uniq_name = "_QMpolyFtest_nullifyEc"} -! CHECK: %[[C_DESC_DECL:.*]]:2 = hlfir.declare %28 {fortran_attrs = #fir.var_attrs, uniq_name = "_QMpolyFtest_nullifyEc"} : (!fir.ref>>>) -> (!fir.ref>>>, !fir.ref>>>) +! CHECK: %[[C_DESC_DECL:.*]]:2 = hlfir.declare %[[C_DESC]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QMpolyFtest_nullifyEc"} : (!fir.ref>>>) -> (!fir.ref>>>, !fir.ref>>>) ! CHECK: %{{.*}} = fir.call @_FortranAPointerAllocate(%{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 ! CHECK: %[[DECLARED_TYPE_DESC:.*]] = fir.type_desc !fir.type<_QMpolyTp1{a:i32,b:i32}> ! CHECK: %[[C_DESC_CAST:.*]] = fir.convert %[[C_DESC_DECL]]#1 : (!fir.ref>>>) -> !fir.ref>