================
@@ -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);
----------------
erichkeane wrote:
Why does the insertion guard not reset this properly? Alternatively, why hte
guard if you're going to unconditionally reset the region here?
https://github.com/llvm/llvm-project/pull/181276
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits