Skip to content

Commit 5f47b83

Browse files
committed
[CIR][CodeGen] Introduce cir.delete.array op
1 parent 2cec820 commit 5f47b83

File tree

7 files changed

+63
-4
lines changed

7 files changed

+63
-4
lines changed

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3497,6 +3497,21 @@ def LLVMIntrinsicCallOp : CIR_Op<"llvm.intrinsic"> {
34973497

34983498
}
34993499

3500+
//===----------------------------------------------------------------------===//
3501+
// DeleteArrayOp
3502+
//===----------------------------------------------------------------------===//
3503+
3504+
def DeleteArrayOp : CIR_Op<"delete.array">,
3505+
Arguments<(ins CIR_PointerType:$address)> {
3506+
let summary = "Delete address representing an array";
3507+
let description = [{
3508+
`cir.delete.array` operation deletes an array. For example, `delete[] ptr;`
3509+
will be translated to `cir.delete.array %ptr`.
3510+
}];
3511+
let assemblyFormat = "$address `:` type($address) attr-dict";
3512+
let hasVerifier = 0;
3513+
}
3514+
35003515
//===----------------------------------------------------------------------===//
35013516
// CallOp and TryCallOp
35023517
//===----------------------------------------------------------------------===//

clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -901,17 +901,20 @@ void CIRGenFunction::emitCXXDeleteExpr(const CXXDeleteExpr *E) {
901901
return;
902902
}
903903

904+
// In CodeGen:
904905
// We might be deleting a pointer to array. If so, GEP down to the
905906
// first non-array element.
906907
// (this assumes that A(*)[3][7] is converted to [3 x [7 x %A]]*)
908+
// In CIRGen: we handle this differently because .... .. .. . .
907909
if (DeleteTy->isConstantArrayType()) {
908-
llvm_unreachable("NYI");
910+
Ptr = Ptr;
909911
}
910912

911913
assert(convertTypeForMem(DeleteTy) == Ptr.getElementType());
912914

913915
if (E->isArrayForm()) {
914-
llvm_unreachable("NYI");
916+
builder.create<cir::DeleteArrayOp>(Ptr.getPointer().getLoc(),
917+
Ptr.getPointer());
915918
} else {
916919
(void)EmitObjectDelete(*this, E, Ptr, DeleteTy);
917920
}

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

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ struct LoweringPreparePass : public LoweringPrepareBase<LoweringPreparePass> {
7777
void lowerComplexBinOp(ComplexBinOp op);
7878
void lowerThreeWayCmpOp(CmpThreeWayOp op);
7979
void lowerVAArgOp(VAArgOp op);
80+
void lowerDeleteArrayOp(DeleteArrayOp op);
8081
void lowerGlobalOp(GlobalOp op);
8182
void lowerDynamicCastOp(DynamicCastOp op);
8283
void lowerStdFindOp(StdFindOp op);
@@ -157,6 +158,8 @@ struct LoweringPreparePass : public LoweringPrepareBase<LoweringPreparePass> {
157158
/// Tracks current module.
158159
ModuleOp theModule;
159160

161+
std::optional<cir::CIRDataLayout> datalayout;
162+
160163
/// Tracks existing dynamic initializers.
161164
llvm::StringMap<uint32_t> dynamicInitializerNames;
162165
llvm::SmallVector<FuncOp, 4> dynamicInitializers;
@@ -344,16 +347,26 @@ static void canonicalizeIntrinsicThreeWayCmp(CIRBaseBuilderTy &builder,
344347
void LoweringPreparePass::lowerVAArgOp(VAArgOp op) {
345348
CIRBaseBuilderTy builder(getContext());
346349
builder.setInsertionPoint(op);
347-
cir::CIRDataLayout datalayout(theModule);
348350

349-
auto res = cxxABI->lowerVAArg(builder, op, datalayout);
351+
auto res = cxxABI->lowerVAArg(builder, op, *datalayout);
350352
if (res) {
351353
op.replaceAllUsesWith(res);
352354
op.erase();
353355
}
354356
return;
355357
}
356358

359+
void LoweringPreparePass::lowerDeleteArrayOp(DeleteArrayOp op) {
360+
CIRBaseBuilderTy builder(getContext());
361+
builder.setInsertionPoint(op);
362+
363+
cxxABI->lowerDeleteArray(builder, op, *datalayout);
364+
// DeleteArrayOp won't have a result, so we don't need to replace
365+
// the uses.
366+
op.erase();
367+
return;
368+
}
369+
357370
void LoweringPreparePass::lowerUnaryOp(UnaryOp op) {
358371
auto ty = op.getType();
359372
if (!mlir::isa<cir::ComplexType>(ty))
@@ -1188,6 +1201,7 @@ void LoweringPreparePass::runOnOperation() {
11881201
auto *op = getOperation();
11891202
if (isa<::mlir::ModuleOp>(op)) {
11901203
theModule = cast<::mlir::ModuleOp>(op);
1204+
datalayout.emplace(theModule);
11911205
}
11921206

11931207
llvm::SmallVector<Operation *> opsToTransform;

clang/lib/CIR/Dialect/Transforms/LoweringPrepareCXXABI.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ class LoweringPrepareCXXABI {
3232

3333
virtual mlir::Value lowerVAArg(CIRBaseBuilderTy &builder, cir::VAArgOp op,
3434
const cir::CIRDataLayout &datalayout) = 0;
35+
36+
virtual mlir::Value
37+
lowerDeleteArray(cir::CIRBaseBuilderTy &builder, cir::DeleteArrayOp op,
38+
const cir::CIRDataLayout &datalayout) = 0;
3539
virtual ~LoweringPrepareCXXABI() {}
3640

3741
virtual mlir::Value lowerDynamicCast(CIRBaseBuilderTy &builder,

clang/lib/CIR/Dialect/Transforms/LoweringPrepareItaniumCXXABI.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,16 @@ class LoweringPrepareItaniumCXXABI : public cir::LoweringPrepareCXXABI {
2121
cir::DynamicCastOp op) override;
2222
mlir::Value lowerVAArg(cir::CIRBaseBuilderTy &builder, cir::VAArgOp op,
2323
const cir::CIRDataLayout &datalayout) override;
24+
25+
mlir::Value lowerDeleteArray(cir::CIRBaseBuilderTy &builder,
26+
cir::DeleteArrayOp op,
27+
const cir::CIRDataLayout &datalayout) override {
28+
// Note: look at `CIRGenFunction::EmitCXXDeleteExpr(const CXXDeleteExpr *)`
29+
// in CIRGenExprCXX.cpp.
30+
// In traditional code gen, we need handle ABI related array cookie to
31+
// generate codes to handle the expression to delete array. We need similar
32+
// mechanism here for ItaniumCXXABI.
33+
llvm_unreachable("NYI && Delete Array is not supported to be lowered in "
34+
"Itanium CXX ABI");
35+
}
2436
};

clang/lib/CIR/Dialect/Transforms/TargetLowering/ItaniumCXXABI.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,4 +164,7 @@ class LoweringPrepareItaniumCXXABI : public cir::LoweringPrepareCXXABI {
164164
cir::DynamicCastOp op) override;
165165
mlir::Value lowerVAArg(cir::CIRBaseBuilderTy &builder, cir::VAArgOp op,
166166
const cir::CIRDataLayout &datalayout) override;
167+
mlir::Value lowerDeleteArray(cir::CIRBaseBuilderTy &builder,
168+
cir::DeleteArrayOp op,
169+
const cir::CIRDataLayout &datalayout) override;
167170
};
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++20 -fclangir -emit-cir %s -o %t.cir
2+
// RUN: FileCheck --input-file=%t.cir %s
3+
4+
void test_delete_array(int *ptr) {
5+
delete[] ptr;
6+
}
7+
8+
// CHECK: cir.delete.array

0 commit comments

Comments
 (0)