@@ -776,9 +776,10 @@ mustBeDefaultInitializedAtRuntime(const Fortran::lower::pft::Variable &var) {
776
776
// / Call default initialization runtime routine to initialize \p var.
777
777
void Fortran::lower::defaultInitializeAtRuntime (
778
778
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) {
780
780
fir::FirOpBuilder &builder = converter.getFirOpBuilder ();
781
781
mlir::Location loc = converter.getCurrentLocation ();
782
+ const Fortran::semantics::Symbol &sym = var.getSymbol ();
782
783
fir::ExtendedValue exv = converter.getSymbolExtendedValue (sym, &symMap);
783
784
if (Fortran::semantics::IsOptional (sym)) {
784
785
// 15.5.2.12 point 3, absent optional dummies are not initialized.
@@ -793,11 +794,35 @@ void Fortran::lower::defaultInitializeAtRuntime(
793
794
})
794
795
.end ();
795
796
} 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
+ }
798
824
}
799
825
}
800
-
801
826
enum class VariableCleanUp { Finalize, Deallocate };
802
827
// / Check whether a local variable needs to be finalized according to clause
803
828
// / 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,
943
968
if (needDummyIntentoutFinalization (var))
944
969
finalizeAtRuntime (converter, var, symMap);
945
970
if (mustBeDefaultInitializedAtRuntime (var))
946
- Fortran::lower::defaultInitializeAtRuntime (converter, var.getSymbol (),
947
- symMap);
971
+ Fortran::lower::defaultInitializeAtRuntime (converter, var, symMap);
948
972
if (Fortran::semantics::NeedCUDAAlloc (var.getSymbol ())) {
949
973
auto *builder = &converter.getFirOpBuilder ();
950
974
mlir::Location loc = converter.getCurrentLocation ();
@@ -1185,8 +1209,7 @@ static void instantiateAlias(Fortran::lower::AbstractConverter &converter,
1185
1209
// do not try optimizing this to single default initializations of
1186
1210
// the equivalenced storages. Keep lowering simple.
1187
1211
if (mustBeDefaultInitializedAtRuntime (var))
1188
- Fortran::lower::defaultInitializeAtRuntime (converter, var.getSymbol (),
1189
- symMap);
1212
+ Fortran::lower::defaultInitializeAtRuntime (converter, var, symMap);
1190
1213
}
1191
1214
1192
1215
// ===--------------------------------------------------------------===//
0 commit comments