Skip to content

Commit e31477b

Browse files
committed
[CIR][Lowering] Deprecate attributes for LLVM zero-initialization
This replaces the usage of attributes for zero-initializing global variables, with a more robust zero-initialization op-based method (cir.llvmir.zeroinit). The downside of this approach is that is not as compact or efficient as the attribute-based method, however: - Both are temporary solutions, but it's easier to track and patch the usage of a single op than an attribute in any op. - Attribute-based method is more difficult to lower, requiring more maintenance. - Op-based method may require a region, but it will populate the region with at most a couple of operations. ghstack-source-id: 4f239b8 Pull Request resolved: #221
1 parent cf09c98 commit e31477b

File tree

4 files changed

+27
-23
lines changed

4 files changed

+27
-23
lines changed

clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1267,14 +1267,12 @@ class CIRGlobalOpLowering
12671267
return mlir::success();
12681268
} else if (isa<mlir::cir::ZeroAttr, mlir::cir::NullAttr>(init.value())) {
12691269
// TODO(cir): once LLVM's dialect has a proper zeroinitializer attribute
1270-
// this should be updated. For now, we tag the LLVM global with a cir.zero
1271-
// attribute that is later replaced with a zeroinitializer. Null pointers
1272-
// also use this path for simplicity, as we would otherwise require a
1273-
// region-based initialization for the global op.
1274-
auto llvmGlobalOp = rewriter.replaceOpWithNewOp<mlir::LLVM::GlobalOp>(
1275-
op, llvmType, isConst, linkage, symbol, nullptr);
1276-
auto cirZeroAttr = mlir::cir::ZeroAttr::get(getContext(), llvmType);
1277-
llvmGlobalOp->setAttr("cir.initial_value", cirZeroAttr);
1270+
// this should be updated. For now, we use a custom op to initialize
1271+
// globals to zero.
1272+
setupRegionInitializedLLVMGlobalOp(op, rewriter);
1273+
auto value =
1274+
lowerCirAttrAsValue(init.value(), loc, rewriter, typeConverter);
1275+
rewriter.create<mlir::LLVM::ReturnOp>(loc, value);
12781276
return mlir::success();
12791277
} else if (const auto structAttr =
12801278
init.value().dyn_cast<mlir::cir::ConstStructAttr>()) {

clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVMIR.cpp

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,17 +40,6 @@ class CIRDialectLLVMIRTranslationInterface
4040
amendOperation(mlir::Operation *op, mlir::NamedAttribute attribute,
4141
mlir::LLVM::ModuleTranslation &moduleTranslation) const final {
4242

43-
// Translate CIR's zero attribute to LLVM's zero initializer.
44-
if (isa<mlir::cir::ZeroAttr>(attribute.getValue())) {
45-
if (llvm::isa<mlir::LLVM::GlobalOp>(op)) {
46-
auto *globalVal = llvm::cast<llvm::GlobalVariable>(
47-
moduleTranslation.lookupGlobal(op));
48-
globalVal->setInitializer(
49-
llvm::Constant::getNullValue(globalVal->getValueType()));
50-
} else
51-
return op->emitError("#cir.zero not supported");
52-
}
53-
5443
// Translate CIR's extra function attributes to LLVM's function attributes.
5544
auto func = dyn_cast<mlir::LLVM::LLVMFuncOp>(op);
5645
if (!func)

clang/test/CIR/Lowering/globals.cir

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
!u64i = !cir.int<u, 64>
1212
!u8i = !cir.int<u, 8>
1313
!ty_22struct2EA22 = !cir.struct<"struct.A", !s32i, !cir.array<!cir.array<!s32i x 2> x 2>, #cir.recdecl.ast>
14+
!ty_22struct2EBar22 = !cir.struct<"struct.Bar", !s32i, !s8i, #cir.recdecl.ast>
1415

1516
module {
1617
cir.global external @a = #cir.int<3> : !s32i
@@ -134,4 +135,14 @@ module {
134135
// MLIR: llvm.mlir.global external @zeroInitFlt(dense<0.000000e+00> : tensor<2xf32>) {addr_space = 0 : i32} : !llvm.array<2 x f32>
135136
cir.global "private" internal @staticVar = #cir.int<0> : !s32i
136137
// MLIR: llvm.mlir.global internal @staticVar(0 : i32) {addr_space = 0 : i32} : i32
138+
cir.global external @nullPtr = #cir.null : !cir.ptr<!s32i>
139+
// MLIR: llvm.mlir.global external @nullPtr()
140+
// MLIR: %0 = llvm.mlir.null : !llvm.ptr<i32>
141+
// MLIR: llvm.return %0 : !llvm.ptr<i32>
142+
// MLIR: }
143+
cir.global external @zeroStruct = #cir.zero : !ty_22struct2EBar22
144+
// MLIR: llvm.mlir.global external @zeroStruct()
145+
// MLIR: %0 = cir.llvmir.zeroinit : !llvm.struct<"struct.Bar", (i32, i8)>
146+
// MLIR: llvm.return %0 : !llvm.struct<"struct.Bar", (i32, i8)>
147+
// MLIR: }
137148
}

clang/test/CIR/Translation/zeroinitializer.cir

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,18 @@
22
// RUN: FileCheck --input-file=%t.ll %s
33

44
module {
5-
// Should lower #cir.zero on structs to a zeroinitializer.
6-
llvm.mlir.global external @bar() {addr_space = 0 : i32, cir.initial_value = #cir.zero : !llvm.struct<"struct.S", (i8, i32)>} : !llvm.struct<"struct.S", (i8, i32)>
5+
// Should zero-initialize global structs initialized with cir.llvmir.zeroinit.
6+
llvm.mlir.global external @bar() {addr_space = 0 : i32} : !llvm.struct<"struct.S", (i8, i32)> {
7+
%0 = cir.llvmir.zeroinit : !llvm.struct<"struct.S", (i8, i32)>
8+
llvm.return %0 : !llvm.struct<"struct.S", (i8, i32)>
9+
}
710
// CHECK: @bar = global %struct.S zeroinitializer
811

9-
// Should lower #cir.null on pointers to a null initializer.
10-
llvm.mlir.global external @ptr() {addr_space = 0 : i32, cir.initial_value = #cir.zero : !llvm.ptr<i32>} : !llvm.ptr<i32>
12+
// Should null-initialize global pointer initialized with cir.llvmir.zeroinit.
13+
llvm.mlir.global external @ptr() {addr_space = 0 : i32} : !llvm.ptr<i32> {
14+
%0 = cir.llvmir.zeroinit : !llvm.ptr<i32>
15+
llvm.return %0 : !llvm.ptr<i32>
16+
}
1117
// CHECK: @ptr = global ptr null
1218

1319
// Should lower aggregates types with elements initialized with cir.llvmir.zeroinit.

0 commit comments

Comments
 (0)