Skip to content

Commit

Permalink
[flang] Rely on global initialization for simpler derived types
Browse files Browse the repository at this point in the history
  • Loading branch information
NimishMishra committed Jan 26, 2025
1 parent 44b8574 commit 1b3ab16
Show file tree
Hide file tree
Showing 9 changed files with 127 additions and 96 deletions.
2 changes: 1 addition & 1 deletion flang/include/flang/Lower/ConvertVariable.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ bool hasDefaultInitialization(const Fortran::semantics::Symbol &sym);

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

/// Call clone initialization runtime routine to initialize \p sym's value.
Expand Down
64 changes: 57 additions & 7 deletions flang/lib/Lower/ConvertVariable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -780,9 +780,10 @@ mustBeDefaultInitializedAtRuntime(const Fortran::lower::pft::Variable &var) {
/// Call default initialization runtime routine to initialize \p var.
void Fortran::lower::defaultInitializeAtRuntime(
Fortran::lower::AbstractConverter &converter,
const Fortran::semantics::Symbol &sym, Fortran::lower::SymMap &symMap) {
const Fortran::lower::pft::Variable &var, Fortran::lower::SymMap &symMap) {
fir::FirOpBuilder &builder = converter.getFirOpBuilder();
mlir::Location loc = converter.getCurrentLocation();
const Fortran::semantics::Symbol &sym = var.getSymbol();
fir::ExtendedValue exv = converter.getSymbolExtendedValue(sym, &symMap);
if (Fortran::semantics::IsOptional(sym)) {
// 15.5.2.12 point 3, absent optional dummies are not initialized.
Expand All @@ -797,8 +798,59 @@ void Fortran::lower::defaultInitializeAtRuntime(
})
.end();
} else {
mlir::Value box = builder.createBox(loc, exv);
fir::runtime::genDerivedTypeInitialize(builder, loc, box);
/// For "simpler" types, relying on "_FortranAInitialize"
/// leads to poor runtime performance. Hence optimize
/// the same.
const Fortran::semantics::DeclTypeSpec *declTy = sym.GetType();
mlir::Type symTy = converter.genType(var);
const auto *details =
sym.detailsIf<Fortran::semantics::ObjectEntityDetails>();
if (details && Fortran::lower::hasDefaultInitialization(sym) &&
declTy->category() ==
Fortran::semantics::DeclTypeSpec::Category::TypeDerived &&
!mlir::isa<fir::SequenceType>(symTy) &&
!sym.test(Fortran::semantics::Symbol::Flag::OmpPrivate) &&
!sym.test(Fortran::semantics::Symbol::Flag::OmpFirstPrivate)) {
std::string globalName = converter.mangleName(*declTy->AsDerived());
mlir::Location loc = genLocation(converter, sym);
mlir::StringAttr linkage = builder.createInternalLinkage();
cuf::DataAttributeAttr dataAttr =
Fortran::lower::translateSymbolCUFDataAttribute(builder.getContext(),
sym);
fir::GlobalOp global = builder.getNamedGlobal(globalName);
if (!global && details->init()) {
Fortran::lower::createGlobalInitialization(
builder, global, [&](fir::FirOpBuilder &builder) {
Fortran::lower::StatementContext stmtCtx(
/*cleanupProhibited=*/true);
fir::ExtendedValue initVal = genInitializerExprValue(
converter, loc, details->init().value(), stmtCtx);
mlir::Value castTo =
builder.createConvert(loc, symTy, fir::getBase(initVal));
builder.create<fir::HasValueOp>(loc, castTo);
});
} else if (!global) {
global = builder.createGlobal(loc, symTy, globalName, linkage,
mlir::Attribute{}, isConstant(sym),
var.isTarget(), dataAttr);
Fortran::lower::createGlobalInitialization(
builder, global, [&](fir::FirOpBuilder &builder) {
Fortran::lower::StatementContext stmtCtx(
/*cleanupProhibited=*/true);
mlir::Value initVal = genDefaultInitializerValue(
converter, loc, sym, symTy, stmtCtx);
mlir::Value castTo = builder.createConvert(loc, symTy, initVal);
builder.create<fir::HasValueOp>(loc, castTo);
});
}
auto addrOf = builder.create<fir::AddrOfOp>(loc, global.resultType(),
global.getSymbol());
fir::LoadOp load = builder.create<fir::LoadOp>(loc, addrOf.getResult());
builder.create<fir::StoreOp>(loc, load, fir::getBase(exv));
} else {
mlir::Value box = builder.createBox(loc, exv);
fir::runtime::genDerivedTypeInitialize(builder, loc, box);
}
}
}

Expand Down Expand Up @@ -961,8 +1013,7 @@ static void instantiateLocal(Fortran::lower::AbstractConverter &converter,
if (needDummyIntentoutFinalization(var))
finalizeAtRuntime(converter, var, symMap);
if (mustBeDefaultInitializedAtRuntime(var))
Fortran::lower::defaultInitializeAtRuntime(converter, var.getSymbol(),
symMap);
Fortran::lower::defaultInitializeAtRuntime(converter, var, symMap);
if (Fortran::semantics::NeedCUDAAlloc(var.getSymbol())) {
auto *builder = &converter.getFirOpBuilder();
mlir::Location loc = converter.getCurrentLocation();
Expand Down Expand Up @@ -1203,8 +1254,7 @@ static void instantiateAlias(Fortran::lower::AbstractConverter &converter,
// do not try optimizing this to single default initializations of
// the equivalenced storages. Keep lowering simple.
if (mustBeDefaultInitializedAtRuntime(var))
Fortran::lower::defaultInitializeAtRuntime(converter, var.getSymbol(),
symMap);
Fortran::lower::defaultInitializeAtRuntime(converter, var, symMap);
}

//===--------------------------------------------------------------===//
Expand Down
Loading

0 comments on commit 1b3ab16

Please sign in to comment.