[flang-commits] [flang] [flang] Rely on global initialization for simpler derived types (PR #114002)

via flang-commits flang-commits at lists.llvm.org
Mon Jan 27 06:22:03 PST 2025


================
@@ -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(
----------------
jeanPerier wrote:

> When does global initialization run?

There is not dynamic initialization in Fortran, this is just adding a static initializer.

> Does this do the right thing for allocatable components?

Yes, `genDefaultInitializerValue` set them to a deallocated descriptor ([here](https://github.com/llvm/llvm-project/blob/e9e06bea8661ddd474557a0db2cdc8770a55b66f/flang/lib/Lower/ConvertVariable.cpp#L351)).

https://github.com/llvm/llvm-project/pull/114002


More information about the flang-commits mailing list