Skip to content

Commit 7e1f567

Browse files
committed
[flang] Fix derived types initialization
1 parent b1ede8f commit 7e1f567

File tree

6 files changed

+49
-26
lines changed

6 files changed

+49
-26
lines changed

flang/include/flang/Lower/ConvertVariable.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ bool hasDefaultInitialization(const Fortran::semantics::Symbol &sym);
6767

6868
/// Call default initialization runtime routine to initialize \p var.
6969
void defaultInitializeAtRuntime(Fortran::lower::AbstractConverter &converter,
70-
const Fortran::semantics::Symbol &sym,
70+
const Fortran::lower::pft::Variable &var,
7171
Fortran::lower::SymMap &symMap);
7272

7373
/// Create a fir::GlobalOp given a module variable definition. This is intended

flang/lib/Lower/ConvertVariable.cpp

+31-8
Original file line numberDiff line numberDiff line change
@@ -776,9 +776,10 @@ mustBeDefaultInitializedAtRuntime(const Fortran::lower::pft::Variable &var) {
776776
/// Call default initialization runtime routine to initialize \p var.
777777
void Fortran::lower::defaultInitializeAtRuntime(
778778
Fortran::lower::AbstractConverter &converter,
779-
const Fortran::semantics::Symbol &sym, Fortran::lower::SymMap &symMap) {
779+
const Fortran::lower::pft::Variable &var, Fortran::lower::SymMap &symMap) {
780780
fir::FirOpBuilder &builder = converter.getFirOpBuilder();
781781
mlir::Location loc = converter.getCurrentLocation();
782+
const Fortran::semantics::Symbol &sym = var.getSymbol();
782783
fir::ExtendedValue exv = converter.getSymbolExtendedValue(sym, &symMap);
783784
if (Fortran::semantics::IsOptional(sym)) {
784785
// 15.5.2.12 point 3, absent optional dummies are not initialized.
@@ -793,11 +794,35 @@ void Fortran::lower::defaultInitializeAtRuntime(
793794
})
794795
.end();
795796
} else {
796-
mlir::Value box = builder.createBox(loc, exv);
797-
fir::runtime::genDerivedTypeInitialize(builder, loc, box);
797+
/// For "simpler" types, relying on "_FortranAInitialize"
798+
/// leads to poor runtime performance. Hence optimize
799+
/// the same.
800+
const Fortran::semantics::DeclTypeSpec *declTy = sym.GetType();
801+
mlir::Type symTy = converter.genType(var);
802+
if (!var.isAlias() && !hasAllocatableDirectComponent(sym) &&
803+
declTy->category() ==
804+
Fortran::semantics::DeclTypeSpec::Category::TypeDerived &&
805+
!mlir::isa<fir::SequenceType>(symTy) &&
806+
!sym.test(Fortran::semantics::Symbol::Flag::OmpPrivate) &&
807+
!sym.test(Fortran::semantics::Symbol::Flag::OmpFirstPrivate)) {
808+
std::string globalName = converter.mangleName(sym) + "_globalinit";
809+
mlir::Location loc = genLocation(converter, sym);
810+
mlir::StringAttr linkage = getLinkageAttribute(builder, var);
811+
cuf::DataAttributeAttr dataAttr =
812+
Fortran::lower::translateSymbolCUFDataAttribute(builder.getContext(),
813+
sym);
814+
fir::GlobalOp global =
815+
defineGlobal(converter, var, globalName, linkage, dataAttr);
816+
auto addrOf = builder.create<fir::AddrOfOp>(loc, global.resultType(),
817+
global.getSymbol());
818+
fir::LoadOp load = builder.create<fir::LoadOp>(loc, addrOf.getResult());
819+
builder.create<fir::StoreOp>(loc, load, fir::getBase(exv));
820+
} else {
821+
mlir::Value box = builder.createBox(loc, exv);
822+
fir::runtime::genDerivedTypeInitialize(builder, loc, box);
823+
}
798824
}
799825
}
800-
801826
enum class VariableCleanUp { Finalize, Deallocate };
802827
/// Check whether a local variable needs to be finalized according to clause
803828
/// 7.5.6.3 point 3 or if it is an allocatable that must be deallocated. Note
@@ -943,8 +968,7 @@ static void instantiateLocal(Fortran::lower::AbstractConverter &converter,
943968
if (needDummyIntentoutFinalization(var))
944969
finalizeAtRuntime(converter, var, symMap);
945970
if (mustBeDefaultInitializedAtRuntime(var))
946-
Fortran::lower::defaultInitializeAtRuntime(converter, var.getSymbol(),
947-
symMap);
971+
Fortran::lower::defaultInitializeAtRuntime(converter, var, symMap);
948972
if (Fortran::semantics::NeedCUDAAlloc(var.getSymbol())) {
949973
auto *builder = &converter.getFirOpBuilder();
950974
mlir::Location loc = converter.getCurrentLocation();
@@ -1185,8 +1209,7 @@ static void instantiateAlias(Fortran::lower::AbstractConverter &converter,
11851209
// do not try optimizing this to single default initializations of
11861210
// the equivalenced storages. Keep lowering simple.
11871211
if (mustBeDefaultInitializedAtRuntime(var))
1188-
Fortran::lower::defaultInitializeAtRuntime(converter, var.getSymbol(),
1189-
symMap);
1212+
Fortran::lower::defaultInitializeAtRuntime(converter, var, symMap);
11901213
}
11911214

11921215
//===--------------------------------------------------------------===//

flang/lib/Lower/OpenMP/DataSharingProcessor.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,8 @@ void DataSharingProcessor::cloneSymbol(const semantics::Symbol *sym) {
118118
bool isFirstPrivate = sym->test(semantics::Symbol::Flag::OmpFirstPrivate);
119119
if (!isFirstPrivate &&
120120
Fortran::lower::hasDefaultInitialization(sym->GetUltimate()))
121-
Fortran::lower::defaultInitializeAtRuntime(converter, *sym, *symTable);
121+
Fortran::lower::defaultInitializeAtRuntime(converter, pft::Variable{*sym},
122+
*symTable);
122123
}
123124

124125
void DataSharingProcessor::copyFirstPrivateSymbol(

flang/test/Lower/HLFIR/structure-constructor.f90

+3-6
Original file line numberDiff line numberDiff line change
@@ -98,12 +98,9 @@ end subroutine test3
9898
! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.type<_QMtypesTt3{r:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>
9999
! CHECK: %[[VAL_2:.*]] = fir.alloca !fir.type<_QMtypesTt3{r:!fir.box<!fir.ptr<!fir.array<?xf32>>>}> {bindc_name = "res", uniq_name = "_QFtest3Eres"}
100100
! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_2]] {uniq_name = "_QFtest3Eres"} : (!fir.ref<!fir.type<_QMtypesTt3{r:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>) -> (!fir.ref<!fir.type<_QMtypesTt3{r:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>, !fir.ref<!fir.type<_QMtypesTt3{r:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>)
101-
! CHECK: %[[VAL_4:.*]] = fir.embox %[[VAL_3]]#1 : (!fir.ref<!fir.type<_QMtypesTt3{r:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>) -> !fir.box<!fir.type<_QMtypesTt3{r:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>
102-
! CHECK: %[[VAL_5:.*]] = fir.address_of(@_QQclX{{.*}}) : !fir.ref<!fir.char<1,{{[0-9]*}}>>
103-
! CHECK: %[[VAL_6:.*]] = arith.constant {{[0-9]*}} : i32
104-
! CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_4]] : (!fir.box<!fir.type<_QMtypesTt3{r:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>) -> !fir.box<none>
105-
! CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_5]] : (!fir.ref<!fir.char<1,{{[0-9]*}}>>) -> !fir.ref<i8>
106-
! CHECK: %[[VAL_9:.*]] = fir.call @_FortranAInitialize(%[[VAL_7]], %[[VAL_8]], %[[VAL_6]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i8>, i32) -> none
101+
! CHECK: %[[ADDR:.*]] = fir.address_of(@_QFtest3Eres_globalinit) : !fir.ref<!fir.type<_QMtypesTt3{r:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>
102+
! CHECK: %[[LOADED_VAL:.*]] = fir.load %[[ADDR]] : !fir.ref<!fir.type<_QMtypesTt3{r:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>
103+
! CHECK: fir.store %[[LOADED_VAL]] to %[[VAL_3]]#1 : !fir.ref<!fir.type<_QMtypesTt3{r:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>
107104
! CHECK: %[[VAL_10:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %{{[0-9]+}} {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFtest3Ex"} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>)
108105
! CHECK: %[[VAL_11:.*]]:2 = hlfir.declare %[[VAL_1]] {uniq_name = "ctor.temp"} : (!fir.ref<!fir.type<_QMtypesTt3{r:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>) -> (!fir.ref<!fir.type<_QMtypesTt3{r:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>, !fir.ref<!fir.type<_QMtypesTt3{r:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>)
109106
! CHECK: %[[VAL_12:.*]] = fir.embox %[[VAL_11]]#0 : (!fir.ref<!fir.type<_QMtypesTt3{r:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>) -> !fir.box<!fir.type<_QMtypesTt3{r:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>

flang/test/Lower/default-initialization.f90

+9-9
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ module test_dinit
2222
! CHECK-LABEL: func @_QMtest_dinitPlocal()
2323
subroutine local
2424
! CHECK: %[[x:.*]] = fir.alloca !fir.type<_QMtest_dinitTt{i:i32}>
25-
! CHECK: %[[xbox:.*]] = fir.embox %[[x]] : (!fir.ref<!fir.type<_QMtest_dinitTt{i:i32}>>) -> !fir.box<!fir.type<_QMtest_dinitTt{i:i32}>>
26-
! CHECK: %[[xboxNone:.*]] = fir.convert %[[xbox]]
27-
! CHECK: fir.call @_FortranAInitialize(%[[xboxNone]], %{{.*}}, %{{.*}}) {{.*}}: (!fir.box<none>, !fir.ref<i8>, i32) -> none
25+
! CHECK: %[[ADDR:.*]] = fir.address_of(@_QMtest_dinitFlocalEx_globalinit) : !fir.ref<!fir.type<_QMtest_dinitTt{i:i32}>>
26+
! CHECK: %[[LOADED_VAL:.*]] = fir.load %[[ADDR]] : !fir.ref<!fir.type<_QMtest_dinitTt{i:i32}>>
27+
! CHECK: fir.store %[[LOADED_VAL]] to %[[x]] : !fir.ref<!fir.type<_QMtest_dinitTt{i:i32}>>
2828
type(t) :: x
2929
print *, x%i
3030
end subroutine
@@ -56,19 +56,19 @@ subroutine local_alloc_comp
5656
! CHECK-LABEL: func @_QMtest_dinitPresult() -> !fir.type<_QMtest_dinitTt{i:i32}>
5757
function result()
5858
! CHECK: %[[x:.*]] = fir.alloca !fir.type<_QMtest_dinitTt{i:i32}>
59-
! CHECK: %[[xbox:.*]] = fir.embox %[[x]] : (!fir.ref<!fir.type<_QMtest_dinitTt{i:i32}>>) -> !fir.box<!fir.type<_QMtest_dinitTt{i:i32}>>
60-
! CHECK: %[[xboxNone:.*]] = fir.convert %[[xbox]]
61-
! CHECK: fir.call @_FortranAInitialize(%[[xboxNone]], %{{.*}}, %{{.*}}) {{.*}}: (!fir.box<none>, !fir.ref<i8>, i32) -> none
59+
! CHECK: %[[ADDR:.*]] = fir.address_of(@_QMtest_dinitFresultEresult_globalinit) : !fir.ref<!fir.type<_QMtest_dinitTt{i:i32}>>
60+
! CHECK: %[[LOADED_VAL:.*]] = fir.load %[[ADDR]] : !fir.ref<!fir.type<_QMtest_dinitTt{i:i32}>>
61+
! CHECK: fir.store %[[LOADED_VAL]] to %[[x]] : !fir.ref<!fir.type<_QMtest_dinitTt{i:i32}>>
6262
type(t) :: result
6363
end function
6464

6565
! Test intent(out) dummies are default initialized
6666
! CHECK-LABEL: func @_QMtest_dinitPintent_out(
6767
! CHECK-SAME: %[[x:.*]]: !fir.ref<!fir.type<_QMtest_dinitTt{i:i32}>>
6868
subroutine intent_out(x)
69-
! CHECK: %[[xbox:.*]] = fir.embox %[[x]] : (!fir.ref<!fir.type<_QMtest_dinitTt{i:i32}>>) -> !fir.box<!fir.type<_QMtest_dinitTt{i:i32}>>
70-
! CHECK: %[[xboxNone:.*]] = fir.convert %[[xbox]]
71-
! CHECK: fir.call @_FortranAInitialize(%[[xboxNone]], %{{.*}}, %{{.*}}) {{.*}}: (!fir.box<none>, !fir.ref<i8>, i32) -> none
69+
! CHECK: %[[ADDR:.*]] = fir.address_of(@_QMtest_dinitFintent_outEx_globalinit) : !fir.ref<!fir.type<_QMtest_dinitTt{i:i32}>>
70+
! CHECK: %[[LOADED_VAL:.*]] = fir.load %[[ADDR]] : !fir.ref<!fir.type<_QMtest_dinitTt{i:i32}>>
71+
! CHECK: fir.store %[[LOADED_VAL]] to %[[x]] : !fir.ref<!fir.type<_QMtest_dinitTt{i:i32}>>
7272
type(t), intent(out) :: x
7373
end subroutine
7474

flang/test/Lower/pointer-default-init.f90

+3-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@ subroutine test_local()
3838
type(t) :: x
3939
end subroutine
4040
! CHECK-LABEL: func.func @_QPtest_local() {
41-
! CHECK: fir.call @_FortranAInitialize(
41+
! CHECK: %[[ADDR:.*]] = fir.address_of(@_QFtest_localEx_globalinit) : !fir.ref<!fir.type<_QMtestTt{i:i32,x:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>
42+
! CHECK: %[[LOAD:.*]] = fir.load %[[ADDR]] : !fir.ref<!fir.type<_QMtestTt{i:i32,x:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>
43+
! CHECK: fir.store %[[LOAD]] to {{.*}} : !fir.ref<!fir.type<_QMtestTt{i:i32,x:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>
4244

4345
subroutine test_saved()
4446
use test, only : t

0 commit comments

Comments
 (0)