@@ -780,9 +780,10 @@ mustBeDefaultInitializedAtRuntime(const Fortran::lower::pft::Variable &var) {
780780// / Call default initialization runtime routine to initialize \p var.
781781void Fortran::lower::defaultInitializeAtRuntime (
782782 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) {
784784 fir::FirOpBuilder &builder = converter.getFirOpBuilder ();
785785 mlir::Location loc = converter.getCurrentLocation ();
786+ const Fortran::semantics::Symbol &sym = var.getSymbol ();
786787 fir::ExtendedValue exv = converter.getSymbolExtendedValue (sym, &symMap);
787788 if (Fortran::semantics::IsOptional (sym)) {
788789 // 15.5.2.12 point 3, absent optional dummies are not initialized.
@@ -797,8 +798,59 @@ void Fortran::lower::defaultInitializeAtRuntime(
797798 })
798799 .end ();
799800 } 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+ }
802854 }
803855}
804856
@@ -961,8 +1013,7 @@ static void instantiateLocal(Fortran::lower::AbstractConverter &converter,
9611013 if (needDummyIntentoutFinalization (var))
9621014 finalizeAtRuntime (converter, var, symMap);
9631015 if (mustBeDefaultInitializedAtRuntime (var))
964- Fortran::lower::defaultInitializeAtRuntime (converter, var.getSymbol (),
965- symMap);
1016+ Fortran::lower::defaultInitializeAtRuntime (converter, var, symMap);
9661017 if (Fortran::semantics::NeedCUDAAlloc (var.getSymbol ())) {
9671018 auto *builder = &converter.getFirOpBuilder ();
9681019 mlir::Location loc = converter.getCurrentLocation ();
@@ -1203,8 +1254,7 @@ static void instantiateAlias(Fortran::lower::AbstractConverter &converter,
12031254 // do not try optimizing this to single default initializations of
12041255 // the equivalenced storages. Keep lowering simple.
12051256 if (mustBeDefaultInitializedAtRuntime (var))
1206- Fortran::lower::defaultInitializeAtRuntime (converter, var.getSymbol (),
1207- symMap);
1257+ Fortran::lower::defaultInitializeAtRuntime (converter, var, symMap);
12081258}
12091259
12101260// ===--------------------------------------------------------------===//
0 commit comments