Skip to content

Commit baf3e8b

Browse files
sitio-coutolanza
authored andcommitted
[CIR][CIRGen] Update C++ codegen to use #cir.zero on structs
This small improvement allows for a more compact representation of structs with zero-initialized fields in the C++ codegen. ghstack-source-id: a3fe0dc Pull Request resolved: #217
1 parent 5307de0 commit baf3e8b

File tree

4 files changed

+40
-15
lines changed

4 files changed

+40
-15
lines changed

clang/lib/CIR/CodeGen/CIRGenBuilder.h

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,35 @@ class CIRGenBuilderTy : public mlir::OpBuilder {
144144
return mlir::cir::ConstArrayAttr::get(arrayTy, attrs);
145145
}
146146

147+
mlir::Attribute getConstStructOrZeroAttr(mlir::ArrayAttr arrayAttr,
148+
bool packed = false,
149+
mlir::Type type = {}) {
150+
llvm::SmallVector<mlir::Type, 8> members;
151+
auto structTy = type.dyn_cast<mlir::cir::StructType>();
152+
assert(structTy && "expected cir.struct");
153+
assert(!packed && "unpacked struct is NYI");
154+
155+
// Collect members and check if they are all zero.
156+
bool isZero = true;
157+
for (auto &attr : arrayAttr) {
158+
const auto typedAttr = attr.dyn_cast<mlir::TypedAttr>();
159+
members.push_back(typedAttr.getType());
160+
isZero &= isNullValue(typedAttr);
161+
}
162+
163+
// Struct type not specified: create type from members.
164+
if (!structTy)
165+
structTy = getType<mlir::cir::StructType>(
166+
members, mlir::StringAttr::get(getContext()),
167+
/*body=*/true, packed,
168+
/*ast=*/std::nullopt);
169+
170+
// Return zero or anonymous constant struct.
171+
if (isZero)
172+
return mlir::cir::ZeroAttr::get(getContext(), structTy);
173+
return mlir::cir::ConstStructAttr::get(structTy, arrayAttr);
174+
}
175+
147176
mlir::cir::ConstStructAttr getAnonConstStruct(mlir::ArrayAttr arrayAttr,
148177
bool packed = false,
149178
mlir::Type ty = {}) {
@@ -186,7 +215,7 @@ class CIRGenBuilderTy : public mlir::OpBuilder {
186215
// TODO(cir): Once we have CIR float types, replace this by something like a
187216
// NullableValueInterface to allow for type-independent queries.
188217
bool isNullValue(mlir::Attribute attr) const {
189-
if (attr.isa<mlir::cir::ZeroAttr>())
218+
if (attr.isa<mlir::cir::ZeroAttr, mlir::cir::NullAttr>())
190219
return true;
191220

192221
// TODO(cir): introduce char type in CIR and check for that instead.

clang/lib/CIR/CodeGen/CIRGenExprConst.cpp

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -281,10 +281,9 @@ mlir::Attribute ConstantAggregateBuilder::buildFrom(
281281

282282
// TODO(cir): emit a #cir.zero if all elements are null values.
283283
auto &builder = CGM.getBuilder();
284-
return builder.getAnonConstStruct(
285-
mlir::ArrayAttr::get(builder.getContext(),
286-
Packed ? PackedElems : UnpackedElems),
287-
Packed, DesiredTy);
284+
auto arrAttr = mlir::ArrayAttr::get(builder.getContext(),
285+
Packed ? PackedElems : UnpackedElems);
286+
return builder.getConstStructOrZeroAttr(arrAttr, Packed, DesiredTy);
288287
}
289288

290289
void ConstantAggregateBuilder::condense(CharUnits Offset,
@@ -1466,14 +1465,6 @@ mlir::Attribute ConstantEmitter::tryEmitPrivate(const APValue &Value,
14661465
const ArrayType *ArrayTy = CGM.getASTContext().getAsArrayType(DestType);
14671466
unsigned NumElements = Value.getArraySize();
14681467
unsigned NumInitElts = Value.getArrayInitializedElts();
1469-
auto isNullValue = [&](mlir::Attribute f) {
1470-
// TODO(cir): introduce char type in CIR and check for that instead.
1471-
auto intVal = f.dyn_cast_or_null<mlir::cir::IntAttr>();
1472-
assert(intVal && "not implemented");
1473-
if (intVal.getValue() == 0)
1474-
return true;
1475-
return false;
1476-
};
14771468

14781469
// Emit array filler, if there is one.
14791470
mlir::Attribute Filler;
@@ -1486,7 +1477,7 @@ mlir::Attribute ConstantEmitter::tryEmitPrivate(const APValue &Value,
14861477

14871478
// Emit initializer elements.
14881479
SmallVector<mlir::TypedAttr, 16> Elts;
1489-
if (Filler && isNullValue(Filler))
1480+
if (Filler && builder.isNullValue(Filler))
14901481
Elts.reserve(NumInitElts + 1);
14911482
else
14921483
Elts.reserve(NumElements);

clang/test/CIR/CodeGen/array.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir-enable -emit-cir %s -o %t.cir
22
// RUN: FileCheck --input-file=%t.cir %s
3-
// XFAIL: *
43

54
// Should implicitly zero-initialize global array elements.
65
struct S {

clang/test/CIR/CodeGen/array.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,9 @@ int multidim(int i, int j) {
6565
// Should globally zero-initialize null arrays.
6666
int globalNullArr[] = {0, 0};
6767
// CHECK: cir.global external @globalNullArr = #cir.zero : !cir.array<!s32i x 2>
68+
69+
// Should implicitly zero-initialize global array elements.
70+
struct S {
71+
int i;
72+
} arr[3] = {{1}};
73+
// CHECK: cir.global external @arr = #cir.const_array<[#cir.const_struct<{#cir.int<1> : !s32i}> : !ty_22struct2ES22, #cir.zero : !ty_22struct2ES22, #cir.zero : !ty_22struct2ES22]> : !cir.array<!ty_22struct2ES22 x 3>

0 commit comments

Comments
 (0)