================
@@ -1072,6 +1073,84 @@ void 
LoweringPreparePass::lowerTrivialCopyCall(cir::CallOp op) {
   }
 }
 
+void LoweringPreparePass::lowerStoreOfConstAggregate(cir::StoreOp op) {
+  // Check if the value operand is a cir.const with aggregate type.
+  auto constOp = op.getValue().getDefiningOp<cir::ConstantOp>();
+  if (!constOp)
+    return;
+
+  mlir::Type ty = constOp.getType();
+  if (!mlir::isa<cir::ArrayType, cir::RecordType>(ty))
+    return;
+
+  // Only transform stores to local variables (backed by cir.alloca).
+  // Stores to other addresses (e.g. base_class_addr) should not be
+  // transformed as they may be partial initializations.
+  auto alloca = op.getAddr().getDefiningOp<cir::AllocaOp>();
+  if (!alloca)
+    return;
+
+  mlir::TypedAttr constant = constOp.getValue();
+
+  // OG implements several optimization tiers for constant aggregate
+  // initialization. For now we always create a global constant + memcpy
+  // (shouldCreateMemCpyFromGlobal). Future work can add the intermediate
+  // tiers.
+  assert(!cir::MissingFeatures::shouldUseBZeroPlusStoresToInitialize());
+  assert(!cir::MissingFeatures::shouldUseMemSetToInitialize());
+  assert(!cir::MissingFeatures::shouldSplitConstantStore());
+
+  // Get function name from parent cir.func.
+  auto func = op->getParentOfType<cir::FuncOp>();
+  if (!func)
+    return;
+  llvm::StringRef funcName = func.getSymName();
+
+  // Get variable name from the alloca.
+  llvm::StringRef varName = alloca.getName();
+
+  // Build name: __const.<func>.<var>
+  std::string name = ("__const." + funcName + "." + varName).str();
+
+  // Create the global constant.
+  CIRBaseBuilderTy builder(getContext());
+
+  // Use InsertionGuard to create the global at module level.
+  {
+    mlir::OpBuilder::InsertionGuard guard(builder);
+    builder.setInsertionPointToStart(mlirModule.getBody());
+
+    // If a global with this name already exists (e.g. CIRGen materializes
+    // constexpr locals as globals when their address is taken), reuse it.
+    if (!mlir::SymbolTable::lookupNearestSymbolFrom(
+            mlirModule, mlir::StringAttr::get(&getContext(), name))) {
+      auto gv = cir::GlobalOp::create(builder, op.getLoc(), name, ty,
+                                      /*isConstant=*/true,
+                                      cir::GlobalLinkageKind::PrivateLinkage);
+      mlir::SymbolTable::setSymbolVisibility(
+          gv, mlir::SymbolTable::Visibility::Private);
+      gv.setInitialValueAttr(constant);
+    }
+  }
+
+  // Now replace the store with get_global + copy.
+  builder.setInsertionPoint(op);
----------------
bcardosolopes wrote:

Fixed

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

Reply via email to