Skip to content

Commit 871d462

Browse files
committed
Address review feedback
1 parent 13c8a3d commit 871d462

File tree

5 files changed

+51
-56
lines changed

5 files changed

+51
-56
lines changed

clang/include/clang/CIR/Dialect/IR/CIROps.td

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2260,7 +2260,9 @@ def CIR_ArrayCtor : CIR_ArrayInitDestroy<"array.ctor"> {
22602260
let description = [{
22612261
Initialize each array element using the same C++ constructor. This
22622262
operation has one region, with one single block. The block has an
2263-
incoming argument for the current array index to initialize.
2263+
incoming argument for the current array element to initialize.
2264+
2265+
Example:
22642266

22652267
```mlir
22662268
cir.array.ctor(%0 : !cir.ptr<!cir.array<!rec_S x 42>>) {
@@ -2277,7 +2279,9 @@ def CIR_ArrayDtor : CIR_ArrayInitDestroy<"array.dtor"> {
22772279
let description = [{
22782280
Destroy each array element using the same C++ destructor. This
22792281
operation has one region, with one single block. The block has an
2280-
incoming argument for the current array index to initialize.
2282+
incoming argument for the current array element to destruct.
2283+
2284+
Example:
22812285

22822286
```mlir
22832287
cir.array.dtor(%0 : !cir.ptr<!cir.array<!rec_S x 42>>) {

clang/lib/CIR/CodeGen/CIRGenDecl.cpp

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -659,28 +659,25 @@ void CIRGenFunction::emitNullabilityCheck(LValue lhs, mlir::Value rhs,
659659
void CIRGenFunction::emitArrayDestroy(mlir::Value begin, mlir::Value end,
660660
QualType elementType,
661661
CharUnits elementAlign,
662-
Destroyer *destroyer,
663-
bool checkZeroLength) {
662+
Destroyer *destroyer) {
664663
assert(!elementType->isArrayType());
665-
if (checkZeroLength)
666-
cgm.errorNYI("emitArrayDestroy: check for zero length");
667664

668665
// Differently from LLVM traditional codegen, use a higher level
669666
// representation instead of lowering directly to a loop.
670667
mlir::Type cirElementType = convertTypeForMem(elementType);
671668
cir::PointerType ptrToElmType = builder.getPointerTo(cirElementType);
672669

673670
// Emit the dtor call that will execute for every array element.
674-
builder.create<cir::ArrayDtor>(
675-
*currSrcLoc, begin, [&](mlir::OpBuilder &b, mlir::Location loc) {
671+
cir::ArrayDtor::create(
672+
builder, *currSrcLoc, begin, [&](mlir::OpBuilder &b, mlir::Location loc) {
676673
auto arg = b.getInsertionBlock()->addArgument(ptrToElmType, loc);
677674
Address curAddr = Address(arg, cirElementType, elementAlign);
678675
assert(!cir::MissingFeatures::dtorCleanups());
679676

680677
// Perform the actual destruction there.
681678
destroyer(*this, curAddr, elementType);
682679

683-
builder.create<cir::YieldOp>(loc);
680+
cir::YieldOp::create(builder, loc);
684681
});
685682
}
686683

@@ -702,25 +699,21 @@ void CIRGenFunction::emitDestroy(Address addr, QualType type,
702699
CharUnits elementAlign = addr.getAlignment().alignmentOfArrayElement(
703700
getContext().getTypeSizeInChars(type));
704701

705-
// Normally we have to check whether the array is zero-length.
706-
bool checkZeroLength = true;
707-
708-
// But if the array length is constant, we can suppress that.
709-
auto constantCount = dyn_cast<cir::ConstantOp>(length.getDefiningOp());
710-
if (constantCount) {
711-
auto constIntAttr = mlir::dyn_cast<cir::IntAttr>(constantCount.getValue());
712-
// ...and if it's constant zero, we can just skip the entire thing.
713-
if (constIntAttr && constIntAttr.getUInt() == 0)
714-
return;
715-
checkZeroLength = false;
716-
} else {
702+
auto constantCount = length.getDefiningOp<cir::ConstantOp>();
703+
if (!constantCount) {
704+
assert(!cir::MissingFeatures::vlas());
717705
cgm.errorNYI("emitDestroy: variable length array");
718706
return;
719707
}
720708

709+
auto constIntAttr = mlir::dyn_cast<cir::IntAttr>(constantCount.getValue());
710+
// If it's constant zero, we can just skip the entire thing.
711+
if (constIntAttr && constIntAttr.getUInt() == 0)
712+
return;
713+
721714
mlir::Value begin = addr.getPointer();
722715
mlir::Value end; // This will be used for future non-constant counts.
723-
emitArrayDestroy(begin, end, type, elementAlign, destroyer, checkZeroLength);
716+
emitArrayDestroy(begin, end, type, elementAlign, destroyer);
724717

725718
// If the array destroy didn't use the length op, we can erase it.
726719
if (constantCount.use_empty())

clang/lib/CIR/CodeGen/CIRGenFunction.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -850,7 +850,7 @@ class CIRGenFunction : public CIRGenTypeCache {
850850

851851
void emitArrayDestroy(mlir::Value begin, mlir::Value end,
852852
QualType elementType, CharUnits elementAlign,
853-
Destroyer *destroyer, bool checkZeroLength);
853+
Destroyer *destroyer);
854854

855855
mlir::Value emitArrayLength(const clang::ArrayType *arrayType,
856856
QualType &baseType, Address &addr);

clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ struct LoweringPreparePass : public LoweringPrepareBase<LoweringPreparePass> {
2929
void runOnOp(mlir::Operation *op);
3030
void lowerCastOp(cir::CastOp op);
3131
void lowerUnaryOp(cir::UnaryOp op);
32-
void lowerArrayDtor(ArrayDtor op);
33-
void lowerArrayCtor(ArrayCtor op);
32+
void lowerArrayDtor(cir::ArrayDtor op);
33+
void lowerArrayCtor(cir::ArrayCtor op);
3434

3535
///
3636
/// AST related
@@ -182,13 +182,14 @@ static void lowerArrayDtorCtorIntoLoop(cir::CIRBaseBuilderTy &builder,
182182
// PtrDiffTy and unify with CIRGen stuff.
183183
const unsigned sizeTypeSize =
184184
astCtx->getTypeSize(astCtx->getSignedSizeType());
185-
mlir::Value numArrayElementsConst =
186-
builder.getUnsignedInt(loc, arrayLen, sizeTypeSize);
187-
188-
auto begin = builder.create<cir::CastOp>(
189-
loc, eltTy, cir::CastKind::array_to_ptrdecay, arrayAddr);
190-
mlir::Value end = builder.create<cir::PtrStrideOp>(loc, eltTy, begin,
191-
numArrayElementsConst);
185+
uint64_t endOffset = isCtor ? arrayLen : arrayLen - 1;
186+
mlir::Value endOffsetVal =
187+
builder.getUnsignedInt(loc, endOffset, sizeTypeSize);
188+
189+
auto begin = cir::CastOp::create(builder, loc, eltTy,
190+
cir::CastKind::array_to_ptrdecay, arrayAddr);
191+
mlir::Value end =
192+
cir::PtrStrideOp::create(builder, loc, eltTy, begin, endOffsetVal);
192193
mlir::Value start = isCtor ? begin : end;
193194
mlir::Value stop = isCtor ? end : begin;
194195

@@ -216,20 +217,16 @@ static void lowerArrayDtorCtorIntoLoop(cir::CIRBaseBuilderTy &builder,
216217
assert(ctorCall && "expected ctor call");
217218

218219
// Array elements get constructed in order but destructed in reverse.
219-
cir::PtrStrideOp nextElement;
220-
if (isCtor) {
221-
mlir::Value stride = builder.getUnsignedInt(loc, 1, sizeTypeSize);
222-
ctorCall->moveBefore(stride.getDefiningOp());
223-
ctorCall->setOperand(0, currentElement);
224-
nextElement = builder.create<cir::PtrStrideOp>(
225-
loc, eltTy, currentElement, stride);
226-
} else {
227-
mlir::Value stride = builder.getSignedInt(loc, -1, sizeTypeSize);
228-
nextElement = builder.create<cir::PtrStrideOp>(
229-
loc, eltTy, currentElement, stride);
230-
ctorCall->moveAfter(nextElement);
231-
ctorCall->setOperand(0, nextElement);
232-
}
220+
mlir::Value stride;
221+
if (isCtor)
222+
stride = builder.getUnsignedInt(loc, 1, sizeTypeSize);
223+
else
224+
stride = builder.getSignedInt(loc, -1, sizeTypeSize);
225+
226+
ctorCall->moveBefore(stride.getDefiningOp());
227+
ctorCall->setOperand(0, currentElement);
228+
auto nextElement = cir::PtrStrideOp::create(builder, loc, eltTy,
229+
currentElement, stride);
233230

234231
// Store the element pointer to the temporary variable
235232
builder.createStore(loc, nextElement, tmpAddr);
@@ -240,11 +237,12 @@ static void lowerArrayDtorCtorIntoLoop(cir::CIRBaseBuilderTy &builder,
240237
op->erase();
241238
}
242239

243-
void LoweringPreparePass::lowerArrayDtor(ArrayDtor op) {
240+
void LoweringPreparePass::lowerArrayDtor(cir::ArrayDtor op) {
244241
CIRBaseBuilderTy builder(getContext());
245242
builder.setInsertionPointAfter(op.getOperation());
246243

247244
mlir::Type eltTy = op->getRegion(0).getArgument(0).getType();
245+
assert(!cir::MissingFeatures::vlas());
248246
auto arrayLen =
249247
mlir::cast<cir::ArrayType>(op.getAddr().getType().getPointee()).getSize();
250248
lowerArrayDtorCtorIntoLoop(builder, astCtx, op, eltTy, op.getAddr(), arrayLen,
@@ -266,12 +264,12 @@ void LoweringPreparePass::lowerArrayCtor(cir::ArrayCtor op) {
266264
void LoweringPreparePass::runOnOp(mlir::Operation *op) {
267265
if (auto arrayCtor = dyn_cast<ArrayCtor>(op))
268266
lowerArrayCtor(arrayCtor);
267+
else if (auto arrayDtor = dyn_cast<cir::ArrayDtor>(op))
268+
lowerArrayDtor(arrayDtor);
269269
else if (auto cast = mlir::dyn_cast<cir::CastOp>(op))
270270
lowerCastOp(cast);
271271
else if (auto unary = mlir::dyn_cast<cir::UnaryOp>(op))
272272
lowerUnaryOp(unary);
273-
else if (auto arrayDtor = dyn_cast<ArrayDtor>(op))
274-
lowerArrayDtor(arrayDtor);
275273
}
276274

277275
void LoweringPreparePass::runOnOperation() {

clang/test/CIR/CodeGen/array-dtor.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,16 @@ void test_cleanup_array() {
2525

2626
// CIR: cir.func{{.*}} @_Z18test_cleanup_arrayv()
2727
// CIR: %[[S:.*]] = cir.alloca !cir.array<!rec_S x 42>, !cir.ptr<!cir.array<!rec_S x 42>>, ["s"]
28-
// CIR: %[[CONST42:.*]] = cir.const #cir.int<42> : !u64i
28+
// CIR: %[[CONST41:.*]] = cir.const #cir.int<41> : !u64i
2929
// CIR: %[[DECAY:.*]] = cir.cast(array_to_ptrdecay, %[[S]] : !cir.ptr<!cir.array<!rec_S x 42>>), !cir.ptr<!rec_S>
30-
// CIR: %[[END_PTR:.*]] = cir.ptr_stride(%[[DECAY]] : !cir.ptr<!rec_S>, %[[CONST42]] : !u64i), !cir.ptr<!rec_S>
30+
// CIR: %[[END_PTR:.*]] = cir.ptr_stride(%[[DECAY]] : !cir.ptr<!rec_S>, %[[CONST41]] : !u64i), !cir.ptr<!rec_S>
3131
// CIR: %[[ITER:.*]] = cir.alloca !cir.ptr<!rec_S>, !cir.ptr<!cir.ptr<!rec_S>>, ["__array_idx"]
3232
// CIR: cir.store %[[END_PTR]], %[[ITER]] : !cir.ptr<!rec_S>, !cir.ptr<!cir.ptr<!rec_S>>
3333
// CIR: cir.do {
3434
// CIR: %[[CURRENT:.*]] = cir.load %[[ITER]] : !cir.ptr<!cir.ptr<!rec_S>>, !cir.ptr<!rec_S>
35+
// CIR: cir.call @_ZN1SD1Ev(%[[CURRENT]]) nothrow : (!cir.ptr<!rec_S>) -> ()
3536
// CIR: %[[CONST_MINUS1:.*]] = cir.const #cir.int<-1> : !s64i
3637
// CIR: %[[NEXT:.*]] = cir.ptr_stride(%[[CURRENT]] : !cir.ptr<!rec_S>, %[[CONST_MINUS1]] : !s64i), !cir.ptr<!rec_S>
37-
// CIR: cir.call @_ZN1SD1Ev(%[[NEXT]]) nothrow : (!cir.ptr<!rec_S>) -> ()
3838
// CIR: cir.store %[[NEXT]], %[[ITER]] : !cir.ptr<!rec_S>, !cir.ptr<!cir.ptr<!rec_S>>
3939
// CIR: cir.yield
4040
// CIR: } while {
@@ -47,7 +47,7 @@ void test_cleanup_array() {
4747
// LLVM: define{{.*}} void @_Z18test_cleanup_arrayv()
4848
// LLVM: %[[ARRAY:.*]] = alloca [42 x %struct.S]
4949
// LLVM: %[[START:.*]] = getelementptr %struct.S, ptr %[[ARRAY]], i32 0
50-
// LLVM: %[[END:.*]] = getelementptr %struct.S, ptr %[[START]], i64 42
50+
// LLVM: %[[END:.*]] = getelementptr %struct.S, ptr %[[START]], i64 41
5151
// LLVM: %[[ITER:.*]] = alloca ptr
5252
// LLVM: store ptr %[[END]], ptr %[[ITER]]
5353
// LLVM: br label %[[LOOP:.*]]
@@ -57,9 +57,9 @@ void test_cleanup_array() {
5757
// LLVM: br i1 %[[DONE]], label %[[LOOP]], label %[[EXIT:.*]]
5858
// LLVM: [[LOOP]]:
5959
// LLVM: %[[CURRENT:.*]] = load ptr, ptr %[[ITER]]
60-
// LLVM: %[[LAST:.*]] = getelementptr %struct.S, ptr %[[CURRENT]], i64 -1
61-
// LLVM: call void @_ZN1SD1Ev(ptr %[[LAST]])
62-
// LLVM: store ptr %[[LAST]], ptr %[[ITER]]
60+
// LLVM: call void @_ZN1SD1Ev(ptr %[[CURRENT]])
61+
// LLVM: %[[NEXT:.*]] = getelementptr %struct.S, ptr %[[CURRENT]], i64 -1
62+
// LLVM: store ptr %[[NEXT]], ptr %[[ITER]]
6363
// LLVM: br label %[[COND]]
6464
// LLVM: [[EXIT]]:
6565
// LLVM: ret void

0 commit comments

Comments
 (0)