================
@@ -1250,6 +1253,392 @@ getSafeRepackAttrs(Fortran::lower::AbstractConverter 
&converter) {
   return attrs.empty() ? mlir::ArrayAttr{} : builder.getArrayAttr(attrs);
 }
 
+//===----------------------------------------------------------------------===//
+// -finit-local= helpers
+//===----------------------------------------------------------------------===//
+
+/// Returns true when \p var is an automatic local variable eligible for
+/// -finit-local= initialization. Excluded: variables without a symbol,
+/// globals, dummy arguments, SAVE'd vars, ALLOCATABLE/POINTER, vars in
+/// an EQUIVALENCE set, vars with explicit or default initialization, and
+/// CUDA variables whose storage is not host-accessible (device, constant,
+/// shared, usedevice).
+static bool shouldInitLocal(const Fortran::lower::pft::Variable &var) {
+  if (!var.hasSymbol() || var.isGlobal())
+    return false;
+  const Fortran::semantics::Symbol &sym = var.getSymbol();
+  if (Fortran::semantics::IsDummy(sym))
+    return false;
+  if (Fortran::semantics::IsSaved(sym))
+    return false;
+  if (Fortran::semantics::IsAllocatableOrPointer(sym))
+    return false;
+  if (Fortran::lower::hasDefaultInitialization(sym))
+    return false;
+  if (const auto *obj =
+          sym.detailsIf<Fortran::semantics::ObjectEntityDetails>())
+    if (obj->init())
+      return false;
+  if (Fortran::semantics::FindEquivalenceSet(sym))
+    return false;
+  // Cray pointees own no storage of their own; their FIR base is a
+  // pointer-box descriptor. Initializing it would overwrite the
+  // descriptor, not the pointee storage.
+  if (sym.test(Fortran::semantics::Symbol::Flag::CrayPointee))
+    return false;
+  // CUDA storage accessibility:
+  //   constant / shared / usedevice: always unreachable by a plain fir.store
+  //     from the host -- skip.
+  //   device in a HOST context: lives in global device memory; a host
+  //     fir.store cannot reach it -- skip.
+  //   device in a DEVICE subprogram: implicitly set by SetImplicitCUDADevice
+  //     for every local in a device kernel; these are per-thread stack
+  //     allocations reachable by a device fir.store -- initialize.
+  //   managed / unified / pinned: host-accessible unified memory -- 
initialize.
+  if (auto cudaAttr = Fortran::semantics::GetCUDADataAttr(&sym)) {
+    switch (*cudaAttr) {
+    case Fortran::common::CUDADataAttr::Constant:
+    case Fortran::common::CUDADataAttr::Shared:
+    case Fortran::common::CUDADataAttr::UseDevice:
+      return false;
+    case Fortran::common::CUDADataAttr::Device:
+      // In a device subprogram the attribute is implicit
+      // (SetImplicitCUDADevice) and the variable is a thread-local stack
+      // allocation -- initialize it.
+      if (!Fortran::semantics::IsCUDADeviceContext(&sym.owner()))
+        return false;
+      break;
+    default:
+      break;
+    }
+  }
+  return true;
+}
+
+/// Build a constant whose every byte equals \p bytePat.
+/// FP types: bitcast from an integer splat. Complex: apply to both parts.
+/// LOGICAL(k): returns a raw iN integer (caller stores via bitcasted address).
+/// Character: falls back to fir.zero_bits (see TODO). Derived types are
+/// handled by the caller before this function is reached.
+static mlir::Value genByteSplatInit(fir::FirOpBuilder &builder,
+                                    mlir::Location loc, mlir::Type ty,
+                                    uint8_t bytePat) {
+  mlir::Type eleTy = fir::unwrapSequenceType(ty);
+
+  // Build an integer constant of the given bit width from a byte splat.
+  auto makeIntCst = [&](unsigned bits) -> mlir::Value {
+    llvm::APInt byteVal(8, bytePat);
+    llvm::APInt splat = llvm::APInt::getSplat(bits, byteVal);
+    mlir::Type intTy = builder.getIntegerType(bits);
+    return mlir::arith::ConstantOp::create(
+        builder, loc, intTy, builder.getIntegerAttr(intTy, splat));
+  };
+
+  if (auto fpTy = mlir::dyn_cast<mlir::FloatType>(eleTy)) {
+    unsigned bits = fpTy.getWidth();
+    mlir::Value intCst = makeIntCst(bits);
+    return mlir::arith::BitcastOp::create(builder, loc, fpTy, intCst);
+  }
+  if (auto intTy = mlir::dyn_cast<mlir::IntegerType>(eleTy)) {
+    return makeIntCst(intTy.getWidth());
+  }
+  // Complex: apply the byte pattern to each (real, imag) part.
+  if (auto cplxTy = mlir::dyn_cast<mlir::ComplexType>(eleTy)) {
+    mlir::Type partTy = cplxTy.getElementType();
+    mlir::Value partVal = genByteSplatInit(builder, loc, partTy, bytePat);
+    return mlir::complex::CreateOp::create(builder, loc, cplxTy, partVal,
+                                           partVal);
+  }
+  // LOGICAL(k) has a fixed size of k bytes. Return the raw integer splat;
+  // the caller stores it via a bitcasted address to preserve the bit pattern
+  // (fir.convert from integer to !fir.logical normalizes nonzero -> true).
+  if (auto logTy = mlir::dyn_cast<fir::LogicalType>(eleTy)) {
+    return makeIntCst(logTy.getFKind() * 8);
+  }
+  // Fallback (e.g. fir.char reached via an unexpected path): zero-initialise.
+  return fir::ZeroOp::create(builder, loc, eleTy);
----------------
DanielCChen wrote:

> Could hex mode avoid silently initializing unhandled types to zero? A PowerPC 
> `vector(real(4))` local passes the eligibility check and lowers to 
> `fir::VectorType`. The lowered local reaches this fallback. The fallback 
> initializes the vector to zero instead of the requested byte pattern.
> 
> The available build lacks a PowerPC target, so I could not run a PowerPC 
> reproducer. Could `fir::VectorType` use a byte fill, or could the fallback 
> emit a diagnostic for an unhandled type? Could you add a PowerPC LLVM 
> regression test for the chosen behavior?

For the scope of this PR,  I would prefer to stay with the standard types only. 
We can certainly extend the coverage of the extension types like PPC vector 
types in a future PR if needed.

https://github.com/llvm/llvm-project/pull/216164
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to