@@ -776,9 +776,10 @@ mustBeDefaultInitializedAtRuntime(const Fortran::lower::pft::Variable &var) {
776776// / Call default initialization runtime routine to initialize \p var.
777777void 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-
801826enum 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// ===--------------------------------------------------------------===//
0 commit comments