Skip to content

Commit

Permalink
[CIR][CodeGen] Introduce cir.delete.array op
Browse files Browse the repository at this point in the history
  • Loading branch information
ChuanqiXu9 committed Nov 28, 2024
1 parent 2cec820 commit 5f47b83
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 4 deletions.
15 changes: 15 additions & 0 deletions clang/include/clang/CIR/Dialect/IR/CIROps.td
Original file line number Diff line number Diff line change
Expand Up @@ -3497,6 +3497,21 @@ def LLVMIntrinsicCallOp : CIR_Op<"llvm.intrinsic"> {

}

//===----------------------------------------------------------------------===//
// DeleteArrayOp
//===----------------------------------------------------------------------===//

def DeleteArrayOp : CIR_Op<"delete.array">,
Arguments<(ins CIR_PointerType:$address)> {
let summary = "Delete address representing an array";
let description = [{
`cir.delete.array` operation deletes an array. For example, `delete[] ptr;`
will be translated to `cir.delete.array %ptr`.
}];
let assemblyFormat = "$address `:` type($address) attr-dict";
let hasVerifier = 0;
}

//===----------------------------------------------------------------------===//
// CallOp and TryCallOp
//===----------------------------------------------------------------------===//
Expand Down
7 changes: 5 additions & 2 deletions clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -901,17 +901,20 @@ void CIRGenFunction::emitCXXDeleteExpr(const CXXDeleteExpr *E) {
return;
}

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

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

if (E->isArrayForm()) {
llvm_unreachable("NYI");
builder.create<cir::DeleteArrayOp>(Ptr.getPointer().getLoc(),
Ptr.getPointer());
} else {
(void)EmitObjectDelete(*this, E, Ptr, DeleteTy);
}
Expand Down
18 changes: 16 additions & 2 deletions clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ struct LoweringPreparePass : public LoweringPrepareBase<LoweringPreparePass> {
void lowerComplexBinOp(ComplexBinOp op);
void lowerThreeWayCmpOp(CmpThreeWayOp op);
void lowerVAArgOp(VAArgOp op);
void lowerDeleteArrayOp(DeleteArrayOp op);
void lowerGlobalOp(GlobalOp op);
void lowerDynamicCastOp(DynamicCastOp op);
void lowerStdFindOp(StdFindOp op);
Expand Down Expand Up @@ -157,6 +158,8 @@ struct LoweringPreparePass : public LoweringPrepareBase<LoweringPreparePass> {
/// Tracks current module.
ModuleOp theModule;

std::optional<cir::CIRDataLayout> datalayout;

/// Tracks existing dynamic initializers.
llvm::StringMap<uint32_t> dynamicInitializerNames;
llvm::SmallVector<FuncOp, 4> dynamicInitializers;
Expand Down Expand Up @@ -344,16 +347,26 @@ static void canonicalizeIntrinsicThreeWayCmp(CIRBaseBuilderTy &builder,
void LoweringPreparePass::lowerVAArgOp(VAArgOp op) {
CIRBaseBuilderTy builder(getContext());
builder.setInsertionPoint(op);
cir::CIRDataLayout datalayout(theModule);

auto res = cxxABI->lowerVAArg(builder, op, datalayout);
auto res = cxxABI->lowerVAArg(builder, op, *datalayout);
if (res) {
op.replaceAllUsesWith(res);
op.erase();
}
return;
}

void LoweringPreparePass::lowerDeleteArrayOp(DeleteArrayOp op) {
CIRBaseBuilderTy builder(getContext());
builder.setInsertionPoint(op);

cxxABI->lowerDeleteArray(builder, op, *datalayout);
// DeleteArrayOp won't have a result, so we don't need to replace
// the uses.
op.erase();
return;
}

void LoweringPreparePass::lowerUnaryOp(UnaryOp op) {
auto ty = op.getType();
if (!mlir::isa<cir::ComplexType>(ty))
Expand Down Expand Up @@ -1188,6 +1201,7 @@ void LoweringPreparePass::runOnOperation() {
auto *op = getOperation();
if (isa<::mlir::ModuleOp>(op)) {
theModule = cast<::mlir::ModuleOp>(op);
datalayout.emplace(theModule);
}

llvm::SmallVector<Operation *> opsToTransform;
Expand Down
4 changes: 4 additions & 0 deletions clang/lib/CIR/Dialect/Transforms/LoweringPrepareCXXABI.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ class LoweringPrepareCXXABI {

virtual mlir::Value lowerVAArg(CIRBaseBuilderTy &builder, cir::VAArgOp op,
const cir::CIRDataLayout &datalayout) = 0;

virtual mlir::Value
lowerDeleteArray(cir::CIRBaseBuilderTy &builder, cir::DeleteArrayOp op,
const cir::CIRDataLayout &datalayout) = 0;
virtual ~LoweringPrepareCXXABI() {}

virtual mlir::Value lowerDynamicCast(CIRBaseBuilderTy &builder,
Expand Down
12 changes: 12 additions & 0 deletions clang/lib/CIR/Dialect/Transforms/LoweringPrepareItaniumCXXABI.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,16 @@ class LoweringPrepareItaniumCXXABI : public cir::LoweringPrepareCXXABI {
cir::DynamicCastOp op) override;
mlir::Value lowerVAArg(cir::CIRBaseBuilderTy &builder, cir::VAArgOp op,
const cir::CIRDataLayout &datalayout) override;

mlir::Value lowerDeleteArray(cir::CIRBaseBuilderTy &builder,
cir::DeleteArrayOp op,
const cir::CIRDataLayout &datalayout) override {
// Note: look at `CIRGenFunction::EmitCXXDeleteExpr(const CXXDeleteExpr *)`
// in CIRGenExprCXX.cpp.
// In traditional code gen, we need handle ABI related array cookie to
// generate codes to handle the expression to delete array. We need similar
// mechanism here for ItaniumCXXABI.
llvm_unreachable("NYI && Delete Array is not supported to be lowered in "
"Itanium CXX ABI");
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -164,4 +164,7 @@ class LoweringPrepareItaniumCXXABI : public cir::LoweringPrepareCXXABI {
cir::DynamicCastOp op) override;
mlir::Value lowerVAArg(cir::CIRBaseBuilderTy &builder, cir::VAArgOp op,
const cir::CIRDataLayout &datalayout) override;
mlir::Value lowerDeleteArray(cir::CIRBaseBuilderTy &builder,
cir::DeleteArrayOp op,
const cir::CIRDataLayout &datalayout) override;
};
8 changes: 8 additions & 0 deletions clang/test/CIR/CodeGen/delete-array.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++20 -fclangir -emit-cir %s -o %t.cir
// RUN: FileCheck --input-file=%t.cir %s

void test_delete_array(int *ptr) {
delete[] ptr;
}

// CHECK: cir.delete.array

0 comments on commit 5f47b83

Please sign in to comment.