@@ -780,9 +780,10 @@ mustBeDefaultInitializedAtRuntime(const Fortran::lower::pft::Variable &var) {
780
780
// / Call default initialization runtime routine to initialize \p var.
781
781
void Fortran::lower::defaultInitializeAtRuntime (
782
782
Fortran::lower::AbstractConverter &converter,
783
- const Fortran::semantics::Symbol &sym , Fortran::lower::SymMap &symMap) {
783
+ const Fortran::lower::pft::Variable &var , Fortran::lower::SymMap &symMap) {
784
784
fir::FirOpBuilder &builder = converter.getFirOpBuilder ();
785
785
mlir::Location loc = converter.getCurrentLocation ();
786
+ const Fortran::semantics::Symbol &sym = var.getSymbol ();
786
787
fir::ExtendedValue exv = converter.getSymbolExtendedValue (sym, &symMap);
787
788
if (Fortran::semantics::IsOptional (sym)) {
788
789
// 15.5.2.12 point 3, absent optional dummies are not initialized.
@@ -797,8 +798,59 @@ void Fortran::lower::defaultInitializeAtRuntime(
797
798
})
798
799
.end ();
799
800
} else {
800
- mlir::Value box = builder.createBox (loc, exv);
801
- fir::runtime::genDerivedTypeInitialize (builder, loc, box);
801
+ // / For "simpler" types, relying on "_FortranAInitialize"
802
+ // / leads to poor runtime performance. Hence optimize
803
+ // / the same.
804
+ const Fortran::semantics::DeclTypeSpec *declTy = sym.GetType ();
805
+ mlir::Type symTy = converter.genType (var);
806
+ const auto *details =
807
+ sym.detailsIf <Fortran::semantics::ObjectEntityDetails>();
808
+ if (details && Fortran::lower::hasDefaultInitialization (sym) &&
809
+ declTy->category () ==
810
+ Fortran::semantics::DeclTypeSpec::Category::TypeDerived &&
811
+ !mlir::isa<fir::SequenceType>(symTy) &&
812
+ !sym.test (Fortran::semantics::Symbol::Flag::OmpPrivate) &&
813
+ !sym.test (Fortran::semantics::Symbol::Flag::OmpFirstPrivate)) {
814
+ std::string globalName = converter.mangleName (*declTy->AsDerived ());
815
+ mlir::Location loc = genLocation (converter, sym);
816
+ mlir::StringAttr linkage = builder.createInternalLinkage ();
817
+ cuf::DataAttributeAttr dataAttr =
818
+ Fortran::lower::translateSymbolCUFDataAttribute (builder.getContext (),
819
+ sym);
820
+ fir::GlobalOp global = builder.getNamedGlobal (globalName);
821
+ if (!global && details->init ()) {
822
+ Fortran::lower::createGlobalInitialization (
823
+ builder, global, [&](fir::FirOpBuilder &builder) {
824
+ Fortran::lower::StatementContext stmtCtx (
825
+ /* cleanupProhibited=*/ true );
826
+ fir::ExtendedValue initVal = genInitializerExprValue (
827
+ converter, loc, details->init ().value (), stmtCtx);
828
+ mlir::Value castTo =
829
+ builder.createConvert (loc, symTy, fir::getBase (initVal));
830
+ builder.create <fir::HasValueOp>(loc, castTo);
831
+ });
832
+ } else if (!global) {
833
+ global = builder.createGlobal (loc, symTy, globalName, linkage,
834
+ mlir::Attribute{}, isConstant (sym),
835
+ var.isTarget (), dataAttr);
836
+ Fortran::lower::createGlobalInitialization (
837
+ builder, global, [&](fir::FirOpBuilder &builder) {
838
+ Fortran::lower::StatementContext stmtCtx (
839
+ /* cleanupProhibited=*/ true );
840
+ mlir::Value initVal = genDefaultInitializerValue (
841
+ converter, loc, sym, symTy, stmtCtx);
842
+ mlir::Value castTo = builder.createConvert (loc, symTy, initVal);
843
+ builder.create <fir::HasValueOp>(loc, castTo);
844
+ });
845
+ }
846
+ auto addrOf = builder.create <fir::AddrOfOp>(loc, global.resultType (),
847
+ global.getSymbol ());
848
+ fir::LoadOp load = builder.create <fir::LoadOp>(loc, addrOf.getResult ());
849
+ builder.create <fir::StoreOp>(loc, load, fir::getBase (exv));
850
+ } else {
851
+ mlir::Value box = builder.createBox (loc, exv);
852
+ fir::runtime::genDerivedTypeInitialize (builder, loc, box);
853
+ }
802
854
}
803
855
}
804
856
@@ -961,8 +1013,7 @@ static void instantiateLocal(Fortran::lower::AbstractConverter &converter,
961
1013
if (needDummyIntentoutFinalization (var))
962
1014
finalizeAtRuntime (converter, var, symMap);
963
1015
if (mustBeDefaultInitializedAtRuntime (var))
964
- Fortran::lower::defaultInitializeAtRuntime (converter, var.getSymbol (),
965
- symMap);
1016
+ Fortran::lower::defaultInitializeAtRuntime (converter, var, symMap);
966
1017
if (Fortran::semantics::NeedCUDAAlloc (var.getSymbol ())) {
967
1018
auto *builder = &converter.getFirOpBuilder ();
968
1019
mlir::Location loc = converter.getCurrentLocation ();
@@ -1203,8 +1254,7 @@ static void instantiateAlias(Fortran::lower::AbstractConverter &converter,
1203
1254
// do not try optimizing this to single default initializations of
1204
1255
// the equivalenced storages. Keep lowering simple.
1205
1256
if (mustBeDefaultInitializedAtRuntime (var))
1206
- Fortran::lower::defaultInitializeAtRuntime (converter, var.getSymbol (),
1207
- symMap);
1257
+ Fortran::lower::defaultInitializeAtRuntime (converter, var, symMap);
1208
1258
}
1209
1259
1210
1260
// ===--------------------------------------------------------------===//
0 commit comments