Skip to content

Commit b2f9735

Browse files
sitio-coutolanza
authored andcommitted
[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 f28b65b commit b2f9735

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
@@ -1281,14 +1281,12 @@ class CIRGlobalOpLowering
12811281
return mlir::success();
12821282
} else if (isa<mlir::cir::ZeroAttr, mlir::cir::NullAttr>(init.value())) {
12831283
// TODO(cir): once LLVM's dialect has a proper zeroinitializer attribute
1284-
// this should be updated. For now, we tag the LLVM global with a
1285-
// cir.zero attribute that is later replaced with a zeroinitializer.
1286-
// Null pointers also use this path for simplicity, as we would
1287-
// otherwise require a region-based initialization for the global op.
1288-
auto llvmGlobalOp = rewriter.replaceOpWithNewOp<mlir::LLVM::GlobalOp>(
1289-
op, llvmType, isConst, linkage, symbol, nullptr);
1290-
auto cirZeroAttr = mlir::cir::ZeroAttr::get(getContext(), llvmType);
1291-
llvmGlobalOp->setAttr("cir.initial_value", cirZeroAttr);
1284+
// this should be updated. For now, we use a custom op to initialize
1285+
// globals to zero.
1286+
setupRegionInitializedLLVMGlobalOp(op, rewriter);
1287+
auto value =
1288+
lowerCirAttrAsValue(init.value(), loc, rewriter, typeConverter);
1289+
rewriter.create<mlir::LLVM::ReturnOp>(loc, value);
12921290
return mlir::success();
12931291
} else if (const auto structAttr =
12941292
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
@@ -39,17 +39,6 @@ class CIRDialectLLVMIRTranslationInterface
3939
mlir::Operation *op, llvm::ArrayRef<llvm::Instruction *> instructions,
4040
mlir::NamedAttribute attribute,
4141
mlir::LLVM::ModuleTranslation &moduleTranslation) const override {
42-
// Translate CIR's zero attribute to LLVM's zero initializer.
43-
if (isa<mlir::cir::ZeroAttr>(attribute.getValue())) {
44-
if (llvm::isa<mlir::LLVM::GlobalOp>(op)) {
45-
auto *globalVal = llvm::cast<llvm::GlobalVariable>(
46-
moduleTranslation.lookupGlobal(op));
47-
globalVal->setInitializer(
48-
llvm::Constant::getNullValue(globalVal->getValueType()));
49-
} else
50-
return op->emitError("#cir.zero not supported");
51-
}
52-
5342
// Translate CIR's extra function attributes to LLVM's function attributes.
5443
auto func = dyn_cast<mlir::LLVM::LLVMFuncOp>(op);
5544
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.zero : !llvm.ptr
141+
// MLIR: llvm.return %0 : !llvm.ptr
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} : !llvm.ptr
12+
// Should null-initialize global pointer initialized with cir.llvmir.zeroinit.
13+
llvm.mlir.global external @ptr() {addr_space = 0 : i32} : !llvm.ptr {
14+
%0 = cir.llvmir.zeroinit : !llvm.ptr
15+
llvm.return %0 : !llvm.ptr
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)