diff --git a/flang/include/flang/Lower/ConvertVariable.h b/flang/include/flang/Lower/ConvertVariable.h index b9d7f891380322..9214209d4e63c0 100644 --- a/flang/include/flang/Lower/ConvertVariable.h +++ b/flang/include/flang/Lower/ConvertVariable.h @@ -67,7 +67,7 @@ bool hasDefaultInitialization(const Fortran::semantics::Symbol &sym); /// Call default initialization runtime routine to initialize \p var. void defaultInitializeAtRuntime(Fortran::lower::AbstractConverter &converter, - const Fortran::semantics::Symbol &sym, + const Fortran::lower::pft::Variable &var, Fortran::lower::SymMap &symMap); /// Call clone initialization runtime routine to initialize \p sym's value. diff --git a/flang/lib/Lower/ConvertVariable.cpp b/flang/lib/Lower/ConvertVariable.cpp index 87236dc293ebbc..ab6e347906aedf 100644 --- a/flang/lib/Lower/ConvertVariable.cpp +++ b/flang/lib/Lower/ConvertVariable.cpp @@ -780,9 +780,10 @@ mustBeDefaultInitializedAtRuntime(const Fortran::lower::pft::Variable &var) { /// Call default initialization runtime routine to initialize \p var. void Fortran::lower::defaultInitializeAtRuntime( Fortran::lower::AbstractConverter &converter, - const Fortran::semantics::Symbol &sym, Fortran::lower::SymMap &symMap) { + const Fortran::lower::pft::Variable &var, Fortran::lower::SymMap &symMap) { fir::FirOpBuilder &builder = converter.getFirOpBuilder(); mlir::Location loc = converter.getCurrentLocation(); + const Fortran::semantics::Symbol &sym = var.getSymbol(); fir::ExtendedValue exv = converter.getSymbolExtendedValue(sym, &symMap); if (Fortran::semantics::IsOptional(sym)) { // 15.5.2.12 point 3, absent optional dummies are not initialized. @@ -797,8 +798,59 @@ void Fortran::lower::defaultInitializeAtRuntime( }) .end(); } else { - mlir::Value box = builder.createBox(loc, exv); - fir::runtime::genDerivedTypeInitialize(builder, loc, box); + /// For "simpler" types, relying on "_FortranAInitialize" + /// leads to poor runtime performance. Hence optimize + /// the same. + const Fortran::semantics::DeclTypeSpec *declTy = sym.GetType(); + mlir::Type symTy = converter.genType(var); + const auto *details = + sym.detailsIf(); + if (details && Fortran::lower::hasDefaultInitialization(sym) && + declTy->category() == + Fortran::semantics::DeclTypeSpec::Category::TypeDerived && + !mlir::isa(symTy) && + !sym.test(Fortran::semantics::Symbol::Flag::OmpPrivate) && + !sym.test(Fortran::semantics::Symbol::Flag::OmpFirstPrivate)) { + std::string globalName = converter.mangleName(*declTy->AsDerived()); + mlir::Location loc = genLocation(converter, sym); + mlir::StringAttr linkage = builder.createInternalLinkage(); + cuf::DataAttributeAttr dataAttr = + Fortran::lower::translateSymbolCUFDataAttribute(builder.getContext(), + sym); + fir::GlobalOp global = builder.getNamedGlobal(globalName); + if (!global && details->init()) { + Fortran::lower::createGlobalInitialization( + builder, global, [&](fir::FirOpBuilder &builder) { + Fortran::lower::StatementContext stmtCtx( + /*cleanupProhibited=*/true); + fir::ExtendedValue initVal = genInitializerExprValue( + converter, loc, details->init().value(), stmtCtx); + mlir::Value castTo = + builder.createConvert(loc, symTy, fir::getBase(initVal)); + builder.create(loc, castTo); + }); + } else if (!global) { + global = builder.createGlobal(loc, symTy, globalName, linkage, + mlir::Attribute{}, isConstant(sym), + var.isTarget(), dataAttr); + Fortran::lower::createGlobalInitialization( + builder, global, [&](fir::FirOpBuilder &builder) { + Fortran::lower::StatementContext stmtCtx( + /*cleanupProhibited=*/true); + mlir::Value initVal = genDefaultInitializerValue( + converter, loc, sym, symTy, stmtCtx); + mlir::Value castTo = builder.createConvert(loc, symTy, initVal); + builder.create(loc, castTo); + }); + } + auto addrOf = builder.create(loc, global.resultType(), + global.getSymbol()); + fir::LoadOp load = builder.create(loc, addrOf.getResult()); + builder.create(loc, load, fir::getBase(exv)); + } else { + mlir::Value box = builder.createBox(loc, exv); + fir::runtime::genDerivedTypeInitialize(builder, loc, box); + } } } @@ -961,8 +1013,7 @@ static void instantiateLocal(Fortran::lower::AbstractConverter &converter, if (needDummyIntentoutFinalization(var)) finalizeAtRuntime(converter, var, symMap); if (mustBeDefaultInitializedAtRuntime(var)) - Fortran::lower::defaultInitializeAtRuntime(converter, var.getSymbol(), - symMap); + Fortran::lower::defaultInitializeAtRuntime(converter, var, symMap); if (Fortran::semantics::NeedCUDAAlloc(var.getSymbol())) { auto *builder = &converter.getFirOpBuilder(); mlir::Location loc = converter.getCurrentLocation(); @@ -1203,8 +1254,7 @@ static void instantiateAlias(Fortran::lower::AbstractConverter &converter, // do not try optimizing this to single default initializations of // the equivalenced storages. Keep lowering simple. if (mustBeDefaultInitializedAtRuntime(var)) - Fortran::lower::defaultInitializeAtRuntime(converter, var.getSymbol(), - symMap); + Fortran::lower::defaultInitializeAtRuntime(converter, var, symMap); } //===--------------------------------------------------------------===// diff --git a/flang/test/Lower/HLFIR/structure-constructor.f90 b/flang/test/Lower/HLFIR/structure-constructor.f90 index 3a82145ddf4f62..0795f26575d3a4 100644 --- a/flang/test/Lower/HLFIR/structure-constructor.f90 +++ b/flang/test/Lower/HLFIR/structure-constructor.f90 @@ -98,12 +98,9 @@ end subroutine test3 ! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.type<_QMtypesTt3{r:!fir.box>>}> ! CHECK: %[[VAL_2:.*]] = fir.alloca !fir.type<_QMtypesTt3{r:!fir.box>>}> {bindc_name = "res", uniq_name = "_QFtest3Eres"} ! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_2]] {uniq_name = "_QFtest3Eres"} : (!fir.ref>>}>>) -> (!fir.ref>>}>>, !fir.ref>>}>>) -! CHECK: %[[VAL_4:.*]] = fir.embox %[[VAL_3]]#1 : (!fir.ref>>}>>) -> !fir.box>>}>> -! CHECK: %[[VAL_5:.*]] = fir.address_of(@_QQclX{{.*}}) : !fir.ref> -! CHECK: %[[VAL_6:.*]] = arith.constant {{[0-9]*}} : i32 -! CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_4]] : (!fir.box>>}>>) -> !fir.box -! CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_5]] : (!fir.ref>) -> !fir.ref -! CHECK: fir.call @_FortranAInitialize(%[[VAL_7]], %[[VAL_8]], %[[VAL_6]]) fastmath : (!fir.box, !fir.ref, i32) -> () +! CHECK: %[[ADDR:.*]] = fir.address_of(@_QMtypesTt3) : !fir.ref>>}>> +! CHECK: %[[LOAD:.*]] = fir.load %[[ADDR]] : !fir.ref>>}>> +! CHECK: fir.store %[[LOAD]] to %[[VAL_3]]#1 : !fir.ref>>}>> ! CHECK: %[[VAL_10:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %{{[0-9]+}} {fortran_attrs = #fir.var_attrs, uniq_name = "_QFtest3Ex"} : (!fir.ref>>>, !fir.dscope) -> (!fir.ref>>>, !fir.ref>>>) ! CHECK: %[[VAL_11:.*]]:2 = hlfir.declare %[[VAL_1]] {uniq_name = "ctor.temp"} : (!fir.ref>>}>>) -> (!fir.ref>>}>>, !fir.ref>>}>>) ! CHECK: %[[VAL_12:.*]] = fir.embox %[[VAL_11]]#0 : (!fir.ref>>}>>) -> !fir.box>>}>> @@ -134,12 +131,9 @@ end subroutine test4 ! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.type<_QMtypesTt4{c:!fir.box>>>}> ! CHECK: %[[VAL_2:.*]] = fir.alloca !fir.type<_QMtypesTt4{c:!fir.box>>>}> {bindc_name = "res", uniq_name = "_QFtest4Eres"} ! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_2]] {uniq_name = "_QFtest4Eres"} : (!fir.ref>>>}>>) -> (!fir.ref>>>}>>, !fir.ref>>>}>>) -! CHECK: %[[VAL_4:.*]] = fir.embox %[[VAL_3]]#1 : (!fir.ref>>>}>>) -> !fir.box>>>}>> -! CHECK: %[[VAL_5:.*]] = fir.address_of(@_QQclX{{.*}}) : !fir.ref> -! CHECK: %[[VAL_6:.*]] = arith.constant {{[0-9]*}} : i32 -! CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_4]] : (!fir.box>>>}>>) -> !fir.box -! CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_5]] : (!fir.ref>) -> !fir.ref -! CHECK: fir.call @_FortranAInitialize(%[[VAL_7]], %[[VAL_8]], %[[VAL_6]]) fastmath : (!fir.box, !fir.ref, i32) -> () +! CHECK: %[[ADDR:.*]] = fir.address_of(@_QMtypesTt4) : !fir.ref>>>}>> +! CHECK: %[[LOAD:.*]] = fir.load %[[ADDR]] : !fir.ref>>>}>> +! CHECK: fir.store %[[LOAD]] to %[[VAL_3]]#1 : !fir.ref>>>}>> ! CHECK: %[[VAL_10:.*]] = arith.constant 2 : index ! CHECK: %[[VAL_11:.*]]:2 = hlfir.declare %[[VAL_0]] typeparams %[[VAL_10]] dummy_scope %{{[0-9]+}} {fortran_attrs = #fir.var_attrs, uniq_name = "_QFtest4Ex"} : (!fir.ref>>>>, index, !fir.dscope) -> (!fir.ref>>>>, !fir.ref>>>>) ! CHECK: %[[VAL_12:.*]]:2 = hlfir.declare %[[VAL_1]] {uniq_name = "ctor.temp"} : (!fir.ref>>>}>>) -> (!fir.ref>>>}>>, !fir.ref>>>}>>) @@ -178,12 +172,9 @@ end subroutine test5 ! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.type<_QMtypesTt5{t5m:!fir.box>>>}>>>>}> ! CHECK: %[[VAL_2:.*]] = fir.alloca !fir.type<_QMtypesTt5{t5m:!fir.box>>>}>>>>}> {bindc_name = "res", uniq_name = "_QFtest5Eres"} ! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_2]] {uniq_name = "_QFtest5Eres"} : (!fir.ref>>>}>>>>}>>) -> (!fir.ref>>>}>>>>}>>, !fir.ref>>>}>>>>}>>) -! CHECK: %[[VAL_4:.*]] = fir.embox %[[VAL_3]]#1 : (!fir.ref>>>}>>>>}>>) -> !fir.box>>>}>>>>}>> -! CHECK: %[[VAL_5:.*]] = fir.address_of(@_QQclX{{.*}}) : !fir.ref> -! CHECK: %[[VAL_6:.*]] = arith.constant {{[0-9]*}} : i32 -! CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_4]] : (!fir.box>>>}>>>>}>>) -> !fir.box -! CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_5]] : (!fir.ref>) -> !fir.ref -! CHECK: fir.call @_FortranAInitialize(%[[VAL_7]], %[[VAL_8]], %[[VAL_6]]) fastmath : (!fir.box, !fir.ref, i32) -> () +! CHECK: %[[ADDR:.*]] = fir.address_of(@_QMtypesTt5) : !fir.ref>>>}>>>>}>> +! CHECK: %[[LOAD:.*]] = fir.load %[[ADDR]] : !fir.ref>>>}>>>>}>> +! CHECK: fir.store %[[LOAD]] to %[[VAL_3]]#1 : !fir.ref>>>}>>>>}>> ! CHECK: %[[VAL_10:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %{{[0-9]+}} {fortran_attrs = #fir.var_attrs, uniq_name = "_QFtest5Ex"} : (!fir.ref>>>}>>>>>, !fir.dscope) -> (!fir.ref>>>}>>>>>, !fir.ref>>>}>>>>>) ! CHECK: %[[VAL_11:.*]]:2 = hlfir.declare %[[VAL_1]] {uniq_name = "ctor.temp"} : (!fir.ref>>>}>>>>}>>) -> (!fir.ref>>>}>>>>}>>, !fir.ref>>>}>>>>}>>) ! CHECK: %[[VAL_12:.*]] = fir.embox %[[VAL_11]]#0 : (!fir.ref>>>}>>>>}>>) -> !fir.box>>>}>>>>}>> @@ -229,12 +220,9 @@ end subroutine test6 ! CHECK: %[[VAL_10:.*]]:2 = hlfir.declare %[[VAL_8]] typeparams %[[VAL_9]] dummy_scope %{{[0-9]+}} {uniq_name = "_QFtest6Ec"} : (!fir.ref>, index, !fir.dscope) -> (!fir.ref>, !fir.ref>) ! CHECK: %[[VAL_11:.*]] = fir.alloca !fir.type<_QMtypesTt6{t5:!fir.type<_QMtypesTt5{t5m:!fir.box>>>}>>>>}>,t6m:!fir.array<1x!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>}> {bindc_name = "res", uniq_name = "_QFtest6Eres"} ! CHECK: %[[VAL_12:.*]]:2 = hlfir.declare %[[VAL_11]] {uniq_name = "_QFtest6Eres"} : (!fir.ref>>>}>>>>}>,t6m:!fir.array<1x!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>}>>) -> (!fir.ref>>>}>>>>}>,t6m:!fir.array<1x!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>}>>, !fir.ref>>>}>>>>}>,t6m:!fir.array<1x!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>}>>) -! CHECK: %[[VAL_13:.*]] = fir.embox %[[VAL_12]]#1 : (!fir.ref>>>}>>>>}>,t6m:!fir.array<1x!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>}>>) -> !fir.box>>>}>>>>}>,t6m:!fir.array<1x!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>}>> -! CHECK: %[[VAL_14:.*]] = fir.address_of(@_QQclX{{.*}}) : !fir.ref> -! CHECK: %[[VAL_15:.*]] = arith.constant {{[0-9]*}} : i32 -! CHECK: %[[VAL_16:.*]] = fir.convert %[[VAL_13]] : (!fir.box>>>}>>>>}>,t6m:!fir.array<1x!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>}>>) -> !fir.box -! CHECK: %[[VAL_17:.*]] = fir.convert %[[VAL_14]] : (!fir.ref>) -> !fir.ref -! CHECK: fir.call @_FortranAInitialize(%[[VAL_16]], %[[VAL_17]], %[[VAL_15]]) fastmath : (!fir.box, !fir.ref, i32) -> () +! CHECK: %[[ADDR:.*]] = fir.address_of(@_QMtypesTt6) : !fir.ref>>>}>>>>}>,t6m:!fir.array<1x!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>}>> +! CHECK: %[[LOAD:.*]] = fir.load %[[ADDR]] : !fir.ref>>>}>>>>}>,t6m:!fir.array<1x!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>}>> +! CHECK: fir.store %[[LOAD]] to %[[VAL_12]]#1 : !fir.ref>>>}>>>>}>,t6m:!fir.array<1x!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>}>> ! CHECK: %[[VAL_19:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %{{[0-9]+}} {fortran_attrs = #fir.var_attrs, uniq_name = "_QFtest6Ex"} : (!fir.ref>>>}>>>>>, !fir.dscope) -> (!fir.ref>>>}>>>>>, !fir.ref>>>}>>>>>) ! CHECK: %[[VAL_20:.*]]:2 = hlfir.declare %[[VAL_6]] {uniq_name = "ctor.temp"} : (!fir.ref>>>}>>>>}>,t6m:!fir.array<1x!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>}>>) -> (!fir.ref>>>}>>>>}>,t6m:!fir.array<1x!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>}>>, !fir.ref>>>}>>>>}>,t6m:!fir.array<1x!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>}>>) ! CHECK: %[[VAL_21:.*]] = fir.embox %[[VAL_20]]#0 : (!fir.ref>>>}>>>>}>,t6m:!fir.array<1x!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>}>>) -> !fir.box>>>}>>>>}>,t6m:!fir.array<1x!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>}>> @@ -318,12 +306,9 @@ end subroutine test7 ! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %{{[0-9]+}} {fortran_attrs = #fir.var_attrs, uniq_name = "_QFtest7En"} : (!fir.ref, !fir.dscope) -> (!fir.ref, !fir.ref) ! CHECK: %[[VAL_3:.*]] = fir.alloca !fir.type<_QMtypesTt7{c1:i32,c2:!fir.box>>}> {bindc_name = "x", uniq_name = "_QFtest7Ex"} ! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_3]] {uniq_name = "_QFtest7Ex"} : (!fir.ref>>}>>) -> (!fir.ref>>}>>, !fir.ref>>}>>) -! CHECK: %[[VAL_5:.*]] = fir.embox %[[VAL_4]]#1 : (!fir.ref>>}>>) -> !fir.box>>}>> -! CHECK: %[[VAL_6:.*]] = fir.address_of(@_QQclX{{.*}}) : !fir.ref> -! CHECK: %[[VAL_7:.*]] = arith.constant {{[0-9]*}} : i32 -! CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_5]] : (!fir.box>>}>>) -> !fir.box -! CHECK: %[[VAL_9:.*]] = fir.convert %[[VAL_6]] : (!fir.ref>) -> !fir.ref -! CHECK: fir.call @_FortranAInitialize(%[[VAL_8]], %[[VAL_9]], %[[VAL_7]]) fastmath : (!fir.box, !fir.ref, i32) -> () +! CHECK: %[[ADDR:.*]] = fir.address_of(@_QMtypesTt7) : !fir.ref>>}>> +! CHECK: %[[LOAD:.*]] = fir.load %[[ADDR]] : !fir.ref>>}>> +! CHECK: fir.store %[[LOAD]] to %[[VAL_4]]#1 : !fir.ref>>}>> ! CHECK: %[[VAL_11:.*]]:2 = hlfir.declare %[[VAL_1]] {uniq_name = "ctor.temp"} : (!fir.ref>>}>>) -> (!fir.ref>>}>>, !fir.ref>>}>>) ! CHECK: %[[VAL_12:.*]] = fir.embox %[[VAL_11]]#0 : (!fir.ref>>}>>) -> !fir.box>>}>> ! CHECK: %[[VAL_13:.*]] = fir.address_of(@_QQclX{{.*}}) : !fir.ref> @@ -350,12 +335,9 @@ end subroutine test8 ! CHECK: %[[VAL_0:.*]] = fir.alloca !fir.type<_QMtypesTt8{c:!fir.box>>}> ! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.type<_QMtypesTt8{c:!fir.box>>}> {bindc_name = "res", uniq_name = "_QFtest8Eres"} ! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_1]] {uniq_name = "_QFtest8Eres"} : (!fir.ref>>}>>) -> (!fir.ref>>}>>, !fir.ref>>}>>) -! CHECK: %[[VAL_3:.*]] = fir.embox %[[VAL_2]]#1 : (!fir.ref>>}>>) -> !fir.box>>}>> -! CHECK: %[[VAL_4:.*]] = fir.address_of(@_QQclX{{.*}}) : !fir.ref> -! CHECK: %[[VAL_5:.*]] = arith.constant {{[0-9]*}} : i32 -! CHECK: %[[VAL_6:.*]] = fir.convert %[[VAL_3]] : (!fir.box>>}>>) -> !fir.box -! CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_4]] : (!fir.ref>) -> !fir.ref -! CHECK: fir.call @_FortranAInitialize(%[[VAL_6]], %[[VAL_7]], %[[VAL_5]]) fastmath : (!fir.box, !fir.ref, i32) -> () +! CHECK: %[[ADDR:.*]] = fir.address_of(@_QMtypesTt8) : !fir.ref>>}>> +! CHECK: %[[LOAD:.*]] = fir.load %[[ADDR]] : !fir.ref>>}>> +! CHECK: fir.store %[[LOAD]] to %[[VAL_2]]#1 : !fir.ref>>}>> ! CHECK: %[[VAL_9:.*]] = fir.alloca !fir.box>> {bindc_name = "x", uniq_name = "_QFtest8Ex"} ! CHECK: %[[VAL_10:.*]] = arith.constant 12 : index ! CHECK: %[[VAL_11:.*]] = fir.zero_bits !fir.heap> @@ -399,12 +381,9 @@ end subroutine test9 ! CHECK: %[[VAL_0:.*]] = fir.alloca !fir.type<_QMtypesTt8{c:!fir.box>>}> ! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.type<_QMtypesTt8{c:!fir.box>>}> {bindc_name = "res", uniq_name = "_QFtest9Eres"} ! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_1]] {uniq_name = "_QFtest9Eres"} : (!fir.ref>>}>>) -> (!fir.ref>>}>>, !fir.ref>>}>>) -! CHECK: %[[VAL_3:.*]] = fir.embox %[[VAL_2]]#1 : (!fir.ref>>}>>) -> !fir.box>>}>> -! CHECK: %[[VAL_4:.*]] = fir.address_of(@_QQclX{{.*}}) : !fir.ref> -! CHECK: %[[VAL_5:.*]] = arith.constant {{[0-9]*}} : i32 -! CHECK: %[[VAL_6:.*]] = fir.convert %[[VAL_3]] : (!fir.box>>}>>) -> !fir.box -! CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_4]] : (!fir.ref>) -> !fir.ref -! CHECK: fir.call @_FortranAInitialize(%[[VAL_6]], %[[VAL_7]], %[[VAL_5]]) fastmath : (!fir.box, !fir.ref, i32) -> () +! CHECK: %[[ADDR:.*]] = fir.address_of(@_QMtypesTt8) : !fir.ref>>}>> +! CHECK: %[[LOAD:.*]] = fir.load %[[ADDR]] : !fir.ref>>}>> +! CHECK: fir.store %[[LOAD]] to %[[VAL_2]]#1 : !fir.ref>>}>> ! CHECK: %[[VAL_9:.*]] = arith.constant 12 : index ! CHECK: %[[VAL_10:.*]] = fir.alloca !fir.char<1,12> {bindc_name = "x", uniq_name = "_QFtest9Ex"} ! CHECK: %[[VAL_11:.*]]:2 = hlfir.declare %[[VAL_10]] typeparams %[[VAL_9]] {uniq_name = "_QFtest9Ex"} : (!fir.ref>, index) -> (!fir.ref>, !fir.ref>) diff --git a/flang/test/Lower/OpenMP/private-derived-type.f90 b/flang/test/Lower/OpenMP/private-derived-type.f90 index df1c7c3f922271..b122c7e2322fc7 100644 --- a/flang/test/Lower/OpenMP/private-derived-type.f90 +++ b/flang/test/Lower/OpenMP/private-derived-type.f90 @@ -29,18 +29,15 @@ end subroutine s4 ! CHECK-LABEL: func.func @_QPs4() { ! Example of how the lowering for regular derived type variables: -! CHECK: %[[VAL_8:.*]] = fir.alloca !fir.type<_QFs4Ty3{x:!fir.box>}> {bindc_name = "v", uniq_name = "_QFs4Ev"} -! CHECK: %[[VAL_9:.*]]:2 = hlfir.declare %[[VAL_8]] {uniq_name = "_QFs4Ev"} : (!fir.ref>}>>) -> (!fir.ref>}>>, !fir.ref>}>>) -! CHECK: %[[VAL_10:.*]] = fir.embox %[[VAL_9]]#1 : (!fir.ref>}>>) -> !fir.box>}>> -! CHECK: %[[VAL_11:.*]] = fir.address_of -! CHECK: %[[VAL_12:.*]] = arith.constant 4 : i32 -! CHECK: %[[VAL_13:.*]] = fir.convert %[[VAL_10]] : (!fir.box>}>>) -> !fir.box -! CHECK: %[[VAL_14:.*]] = fir.convert %[[VAL_11]] : (!fir.ref>) -> !fir.ref -! CHECK: fir.call @_FortranAInitialize(%[[VAL_13]], %[[VAL_14]], %[[VAL_12]]) fastmath : (!fir.box, !fir.ref, i32) -> () +! CHECK: %[[VAL_DERIVED_ALLOCA:.*]] = fir.alloca !fir.type<_QFs4Ty3{x:!fir.box>}> {bindc_name = "v", uniq_name = "_QFs4Ev"} +! CHECK: %[[VAL_DERIVED_DECLARE:.*]]:2 = hlfir.declare %[[VAL_DERIVED_ALLOCA]] {{.*}} +! CHECK: %[[ADDR:.*]] = fir.address_of(@_QFs4Ty3) : !fir.ref>}>> +! CHECK: %[[LOAD:.*]] = fir.load %[[ADDR]] {{.*}} +! CHECK: fir.store %[[LOAD]] to %[[VAL_DERIVED_DECLARE]]#1 : !fir.ref>}>> ! CHECK: omp.parallel { ! CHECK: omp.wsloop private(@[[DERIVED_PRIV]] %{{.*}}#0 -> %{{.*}}, @{{.*}} %{{.*}}#0 -> %{{.*}} : !fir.ref>}>>, !fir.ref) { ! CHECK: } -! CHECK: %[[VAL_39:.*]] = fir.embox %[[VAL_9]]#1 : (!fir.ref>}>>) -> !fir.box>}>> +! CHECK: %[[VAL_39:.*]] = fir.embox %[[VAL_DERIVED_DECLARE]]#1 : (!fir.ref>}>>) -> !fir.box>}>> ! CHECK: %[[VAL_40:.*]] = fir.convert %[[VAL_39]] : (!fir.box>}>>) -> !fir.box ! Check the derived type is destroyed ! CHECK: fir.call @_FortranADestroy(%[[VAL_40]]) fastmath : (!fir.box) -> () diff --git a/flang/test/Lower/default-initialization.f90 b/flang/test/Lower/default-initialization.f90 index a3a36d5a1c3de1..47b6e1fed00139 100644 --- a/flang/test/Lower/default-initialization.f90 +++ b/flang/test/Lower/default-initialization.f90 @@ -21,10 +21,10 @@ module test_dinit ! Test local scalar is default initialized ! CHECK-LABEL: func @_QMtest_dinitPlocal() subroutine local - ! CHECK: %[[x:.*]] = fir.alloca !fir.type<_QMtest_dinitTt{i:i32}> - ! CHECK: %[[xbox:.*]] = fir.embox %[[x]] : (!fir.ref>) -> !fir.box> - ! CHECK: %[[xboxNone:.*]] = fir.convert %[[xbox]] - ! CHECK: fir.call @_FortranAInitialize(%[[xboxNone]], %{{.*}}, %{{.*}}) {{.*}}: (!fir.box, !fir.ref, i32) -> () + !CHECK: %[[x:.*]] = fir.alloca !fir.type<_QMtest_dinitTt{i:i32}> {bindc_name = "x", uniq_name = "_QMtest_dinitFlocalEx"} + !CHECK: %[[ADDR:.*]] = fir.address_of(@_QMtest_dinitTt) : !fir.ref> + !CHECK: %[[LOAD:.*]] = fir.load %[[ADDR]] : !fir.ref> + !CHECK: fir.store %[[LOAD]] to %[[x]] : !fir.ref> type(t) :: x print *, x%i end subroutine @@ -45,20 +45,20 @@ subroutine local_array() ! scalars. ! CHECK-LABEL: func @_QMtest_dinitPlocal_alloc_comp() subroutine local_alloc_comp - ! CHECK: %[[x:.*]] = fir.alloca !fir.type<_QMtest_dinitTt_alloc_comp{i:!fir.box>>}> - ! CHECK: %[[xbox:.*]] = fir.embox %[[x]] : (!fir.ref>>}>>) -> !fir.box>>}>> - ! CHECK: %[[xboxNone:.*]] = fir.convert %[[xbox]] - ! CHECK: fir.call @_FortranAInitialize(%[[xboxNone]], %{{.*}}, %{{.*}}) {{.*}}: (!fir.box, !fir.ref, i32) -> () + !CHECK: %[[x:.*]] = fir.alloca !fir.type<_QMtest_dinitTt_alloc_comp{i:!fir.box>>}> {bindc_name = "x", uniq_name = "_QMtest_dinitFlocal_alloc_compEx"} + !CHECK: %[[ADDR:.*]] = fir.address_of(@_QMtest_dinitTt_alloc_comp) : !fir.ref>>}>> + !CHECK: %[[LOAD:.*]] = fir.load %[[ADDR]] : !fir.ref>>}>> + !CHECK: fir.store %[[LOAD]] to %[[x]] : !fir.ref>>}>> type(t_alloc_comp) :: x end subroutine ! Test function results are default initialized. ! CHECK-LABEL: func @_QMtest_dinitPresult() -> !fir.type<_QMtest_dinitTt{i:i32}> function result() - ! CHECK: %[[x:.*]] = fir.alloca !fir.type<_QMtest_dinitTt{i:i32}> - ! CHECK: %[[xbox:.*]] = fir.embox %[[x]] : (!fir.ref>) -> !fir.box> - ! CHECK: %[[xboxNone:.*]] = fir.convert %[[xbox]] - ! CHECK: fir.call @_FortranAInitialize(%[[xboxNone]], %{{.*}}, %{{.*}}) {{.*}}: (!fir.box, !fir.ref, i32) -> () + !CHECK: %[[x:.*]] = fir.alloca !fir.type<_QMtest_dinitTt{i:i32}> {bindc_name = "result", uniq_name = "_QMtest_dinitFresultEresult"} + !CHECK: %[[ADDR:.*]] = fir.address_of(@_QMtest_dinitTt) : !fir.ref> + !CHECK: %[[LOAD:.*]] = fir.load %[[ADDR]] : !fir.ref> + !CHECK: fir.store %[[LOAD]] to %[[x]] : !fir.ref> type(t) :: result end function @@ -66,9 +66,9 @@ function result() ! CHECK-LABEL: func @_QMtest_dinitPintent_out( ! CHECK-SAME: %[[x:.*]]: !fir.ref> subroutine intent_out(x) - ! CHECK: %[[xbox:.*]] = fir.embox %[[x]] : (!fir.ref>) -> !fir.box> - ! CHECK: %[[xboxNone:.*]] = fir.convert %[[xbox]] - ! CHECK: fir.call @_FortranAInitialize(%[[xboxNone]], %{{.*}}, %{{.*}}) {{.*}}: (!fir.box, !fir.ref, i32) -> () + !CHECK: %[[ADDR:.*]] = fir.address_of(@_QMtest_dinitTt) : !fir.ref> + !CHECK: %[[LOAD:.*]] = fir.load %[[ADDR]] : !fir.ref> + !CHECK: fir.store %[[LOAD]] to %[[x]] : !fir.ref> type(t), intent(out) :: x end subroutine @@ -94,9 +94,9 @@ subroutine local_eq() ! CHECK: %[[equiv:.*]] = fir.alloca !fir.array<4xi8> ! CHECK: %[[xcoor:.*]] = fir.coordinate_of %[[equiv]], %c0{{.*}} : (!fir.ref>, index) -> !fir.ref ! CHECK: %[[x:.*]] = fir.convert %[[xcoor]] : (!fir.ref) -> !fir.ptr> - ! CHECK: %[[xbox:.*]] = fir.embox %[[x]] : (!fir.ptr>) -> !fir.box> - ! CHECK: %[[xboxNone:.*]] = fir.convert %[[xbox]] - ! CHECK: fir.call @_FortranAInitialize(%[[xboxNone]], %{{.*}}, %{{.*}}) {{.*}}: (!fir.box, !fir.ref, i32) -> () + ! CHECK: %[[ADDR:.*]] = fir.address_of(@_QMtest_dinitTtseq) : !fir.ref> + ! CHECK: %[[LOAD:.*]] = fir.load %[[ADDR]] : !fir.ref> + ! CHECK: fir.store %[[LOAD]] to %[[x]] : !fir.ptr> equivalence (x, zi) print *, i end subroutine @@ -112,16 +112,16 @@ subroutine local_eq2() ! CHECK: %[[equiv:.*]] = fir.alloca !fir.array<4xi8> ! CHECK: %[[xcoor:.*]] = fir.coordinate_of %[[equiv]], %c0{{.*}} : (!fir.ref>, index) -> !fir.ref ! CHECK: %[[x:.*]] = fir.convert %[[xcoor]] : (!fir.ref) -> !fir.ptr> - ! CHECK: %[[xbox:.*]] = fir.embox %[[x]] : (!fir.ptr>) -> !fir.box> - ! CHECK: %[[xboxNone:.*]] = fir.convert %[[xbox]] - ! CHECK: fir.call @_FortranAInitialize(%[[xboxNone]], %{{.*}}, %{{.*}}) {{.*}}: (!fir.box, !fir.ref, i32) -> () + ! CHECK: %[[ADDR:.*]] = fir.address_of(@_QMtest_dinitTtseq) : !fir.ref> + ! CHECK: %[[LOAD:.*]] = fir.load %[[ADDR]] : !fir.ref> + ! CHECK: fir.store %[[LOAD]] to %[[x]] : !fir.ptr> ! CHECK: %[[ycoor:.*]] = fir.coordinate_of %[[equiv]], %c0{{.*}} : (!fir.ref>, index) -> !fir.ref ! CHECK: %[[y:.*]] = fir.convert %[[ycoor]] : (!fir.ref) -> !fir.ptr> - ! CHECK: %[[ybox:.*]] = fir.embox %[[y]] : (!fir.ptr>) -> !fir.box> - ! CHECK: %[[yboxNone:.*]] = fir.convert %[[ybox]] - ! CHECK: fir.call @_FortranAInitialize(%[[yboxNone]], %{{.*}}, %{{.*}}) {{.*}}: (!fir.box, !fir.ref, i32) -> () + ! CHECK: %[[ADDR:.*]] = fir.address_of(@_QMtest_dinitTtseq) : !fir.ref> + ! CHECK: %[[LOAD:.*]] = fir.load %[[ADDR]] : !fir.ref> + ! CHECK: fir.store %[[LOAD]] to %[[y]] : !fir.ptr> equivalence (x, y) print *, y%i end subroutine diff --git a/flang/test/Lower/derived-type-finalization.f90 b/flang/test/Lower/derived-type-finalization.f90 index b38fcd8ba5766b..8ecd2f79448c34 100644 --- a/flang/test/Lower/derived-type-finalization.f90 +++ b/flang/test/Lower/derived-type-finalization.f90 @@ -97,7 +97,9 @@ subroutine test_target_finalization() ! CHECK-LABEL: func.func @_QMderived_type_finalizationPtest_target_finalization() { ! CHECK: %[[P:.*]] = fir.alloca !fir.box>> {bindc_name = "p", uniq_name = "_QMderived_type_finalizationFtest_target_finalizationEp"} -! CHECK: fir.call @_FortranAInitialize +! CHECK: %[[ADDR:.*]] = fir.alloca !fir.ptr> {uniq_name = "_QMderived_type_finalizationFtest_target_finalizationEp.addr"} +! CHECK: %[[zero:.*]] = fir.zero_bits !fir.ptr> +! CHECK: fir.store %[[zero]] to %[[ADDR]] : !fir.ref>> ! CHECK: fir.call @_FortranAPointerAllocateSource ! CHECK: %[[P_BOX_NONE:.*]] = fir.convert %[[P]] : (!fir.ref>>>) -> !fir.ref> ! CHECK: %{{.*}} = fir.call @_FortranAPointerDeallocate(%[[P_BOX_NONE]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 @@ -200,7 +202,10 @@ subroutine test_avoid_double_finalization(a) end subroutine ! CHECK-LABEL: func.func @_QMderived_type_finalizationPtest_avoid_double_finalization( -! CHECK: fir.call @_FortranAInitialize( +! CHECK: %[[b:.*]] = fir.alloca !fir.type<_QMderived_type_finalizationTt3{t:!fir.type<_QMderived_type_finalizationTt2{a:!fir.box>>}>}> {bindc_name = "b", uniq_name = "_QMderived_type_finalizationFtest_avoid_double_finalizationEb"} +! CHECK: %[[ADDR:.*]] = fir.address_of(@_QMderived_type_finalizationTt3) : !fir.ref>>}>}>> +! CHECK: %[[LOAD:.*]] = fir.load %[[ADDR]] : !fir.ref>>}>}>> +! CHECK: fir.store %[[LOAD]] to %[[b]] : !fir.ref>>}>}>> ! CHECK-NOT: fir.call @_FortranADestroy ! CHECK: fir.call @_FortranAAssign( ! CHECK: fir.call @_FortranADestroy( diff --git a/flang/test/Lower/derived-type-temp.f90 b/flang/test/Lower/derived-type-temp.f90 index 4f1d4f2d51cf5c..e77454d4d93d28 100644 --- a/flang/test/Lower/derived-type-temp.f90 +++ b/flang/test/Lower/derived-type-temp.f90 @@ -13,7 +13,7 @@ program derived_temp_init y = t2(x) end -! CHECK: %[[temp:.*]] = fir.alloca !fir.type<_QFTt1{i:!fir.box>}> {bindc_name = "x", uniq_name = "_QFEx"} -! CHECK: %[[box:.*]] = fir.embox %[[temp]] : (!fir.ref>}>>) -> !fir.box>}>> -! CHECK: %[[box_none:.*]] = fir.convert %[[box]] : (!fir.box>}>>) -> !fir.box -! CHECK: fir.call @_FortranAInitialize(%[[box_none]], %{{.*}}, %{{.*}}) {{.*}}: (!fir.box, !fir.ref, i32) -> () +! CHECK: %[[x:.*]] = fir.alloca !fir.type<_QFTt1{i:!fir.box>}> {bindc_name = "x", uniq_name = "_QFEx"} +! CHECK: %[[ADDR:.*]] = fir.address_of(@_QFTt1) : !fir.ref>}>> +! CHECK: %[[LOAD:.*]] = fir.load %[[ADDR]] : !fir.ref>}>> +! CHECK: fir.store %[[LOAD]] to %[[x]] : !fir.ref>}>> diff --git a/flang/test/Lower/forall/forall-allocatable-2.f90 b/flang/test/Lower/forall/forall-allocatable-2.f90 index f7c46acf87275f..93555c0edde6ae 100644 --- a/flang/test/Lower/forall/forall-allocatable-2.f90 +++ b/flang/test/Lower/forall/forall-allocatable-2.f90 @@ -18,12 +18,9 @@ end subroutine forall_with_allocatable2 ! CHECK-SAME: %[[VAL_0:.*]]: !fir.box>{{.*}}) { ! CHECK: %[[VAL_1:.*]] = fir.alloca i32 {adapt.valuebyref, bindc_name = "i"} ! CHECK: %[[VAL_2:.*]] = fir.alloca !fir.type<_QFforall_with_allocatable2Tt{i:i32,arr:!fir.box>>}> {bindc_name = "thing", uniq_name = "_QFforall_with_allocatable2Ething"} -! CHECK: %[[VAL_3:.*]] = fir.embox %[[VAL_2]] : (!fir.ref>>}>>) -> !fir.box>>}>> -! CHECK: %[[VAL_4:.*]] = fir.address_of(@_QQclX{{.*}}) : !fir.ref>>}>>) -> !fir.box -! CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_4]] : (!fir.ref>) -> !fir.ref -! CHECK: fir.call @_FortranAInitialize(%[[VAL_6]], %[[VAL_7]], %[[VAL_5]]) {{.*}}: (!fir.box, !fir.ref, i32) -> () +! CHECK: %[[ADDR:.*]] = fir.address_of(@_QFforall_with_allocatable2Tt) : !fir.ref>>}>> +! CHECK: %[[LOAD:.*]] = fir.load %[[ADDR]] : !fir.ref>>}>> +! CHECK: fir.store %[[LOAD]] to %[[VAL_2]] : !fir.ref>>}>> ! CHECK: %[[VAL_9:.*]] = arith.constant 5 : i32 ! CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_9]] : (i32) -> index ! CHECK: %[[VAL_11:.*]] = arith.constant 15 : i32 diff --git a/flang/test/Lower/pointer-default-init.f90 b/flang/test/Lower/pointer-default-init.f90 index 0fb42683a3486b..371f6d6b442275 100644 --- a/flang/test/Lower/pointer-default-init.f90 +++ b/flang/test/Lower/pointer-default-init.f90 @@ -38,7 +38,10 @@ subroutine test_local() type(t) :: x end subroutine ! CHECK-LABEL: func.func @_QPtest_local() { -! CHECK: fir.call @_FortranAInitialize( +! CHECK: %[[x:.*]] = fir.alloca !fir.type<_QMtestTt{i:i32,x:!fir.box>>}> {bindc_name = "x", uniq_name = "_QFtest_localEx"} +! CHECK: %[[ADDR:.*]] = fir.address_of(@_QMtestTt) : !fir.ref>>}>> +! CHECK: %[[LOAD:.*]] = fir.load %[[ADDR]] : !fir.ref>>}>> +! CHECK: fir.store %[[LOAD]] to %[[x]] : !fir.ref>>}>> subroutine test_saved() use test, only : t