Skip to content

Commit 1b3ab16

Browse files
committed
[flang] Rely on global initialization for simpler derived types
1 parent 44b8574 commit 1b3ab16

9 files changed

+127
-96
lines changed

flang/include/flang/Lower/ConvertVariable.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ bool hasDefaultInitialization(const Fortran::semantics::Symbol &sym);
6767

6868
/// Call default initialization runtime routine to initialize \p var.
6969
void defaultInitializeAtRuntime(Fortran::lower::AbstractConverter &converter,
70-
const Fortran::semantics::Symbol &sym,
70+
const Fortran::lower::pft::Variable &var,
7171
Fortran::lower::SymMap &symMap);
7272

7373
/// Call clone initialization runtime routine to initialize \p sym's value.

flang/lib/Lower/ConvertVariable.cpp

+57-7
Original file line numberDiff line numberDiff line change
@@ -780,9 +780,10 @@ mustBeDefaultInitializedAtRuntime(const Fortran::lower::pft::Variable &var) {
780780
/// Call default initialization runtime routine to initialize \p var.
781781
void 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

Comments
 (0)