Skip to content

Commit

Permalink
replace scope with blocks
Browse files Browse the repository at this point in the history
  • Loading branch information
bruteforceboy committed Feb 5, 2025
1 parent 7aec6bf commit fa80c8c
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 30 deletions.
36 changes: 28 additions & 8 deletions clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2266,21 +2266,41 @@ void CIRGenItaniumCXXABI::emitRethrow(CIRGenFunction &CGF, bool isNoReturn) {
CGF.getBuilder().getFuncType({}, CGF.getBuilder().getVoidTy());

auto Fn = CGF.CGM.createRuntimeFunction(FTy, "__cxa_rethrow");
auto loc = Fn.getLoc();

if (isNoReturn) {
auto &builder = CGF.getBuilder();

auto callOp = builder.createTryCallOp(Fn.getLoc(), Fn, {});
// The idea here is creating a separate block for the rethrow with an
// `UnreachableOp` as the terminator. So, we branch from the current block
// to the rethrow block and create a block for the remaining operations.

// The idea here is to create
// an unreachable continue block for the rethrow, but
// there is a YieldOp that terminates the TryOp already, so creating an
// UnreachableOp in-place causes us to have two terminators which isn't
// valid CIR. So, to make this valid CIR the UnreachableOp is created in a
// separate scope.
auto currentBlock = builder.getInsertionBlock();
auto reg = currentBlock->getParent();

bool branch = false;
if (currentBlock->empty())
currentBlock->erase();
else
branch = true;

auto rethrowBlock = builder.createBlock(reg);
builder.setInsertionPointToStart(rethrowBlock);
builder.createTryCallOp(Fn.getLoc(), Fn, {});
builder.create<cir::UnreachableOp>(loc);

if (branch) {
builder.setInsertionPointToEnd(currentBlock);
builder.create<cir::BrOp>(loc, rethrowBlock);
}

auto remBlock = builder.createBlock(reg);
builder.setInsertionPointToEnd(remBlock);
// This will be erased during codegen, it acts as a placeholder for the
// operations to be inserted (if any)
builder.create<cir::ScopeOp>(Fn.getLoc(), /*scopeBuilder=*/
[&](mlir::OpBuilder &b, mlir::Location loc) {
b.create<cir::UnreachableOp>(loc);
b.create<cir::YieldOp>(loc);
});
} else {
llvm_unreachable("NYI");
Expand Down
103 changes: 81 additions & 22 deletions clang/test/CIR/CodeGen/try-catch-dtors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ struct S {
S() {}
};

void refoo() {
void refoo1() {
int r = 1;
try {
S s;
Expand All @@ -354,25 +354,84 @@ void refoo() {
}
}

// CIR-LABEL: @_Z5refoov()
// CIR: %[[V0:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["r", init] {alignment = 4 : i64}
// CIR: %[[V1:.*]] = cir.const #cir.int<1> : !s32i
// CIR: cir.store %[[V1]], %[[V0]] : !s32i, !cir.ptr<!s32i>
// CIR: cir.scope {
// CIR: %[[V2:.*]] = cir.alloca !ty_S, !cir.ptr<!ty_S>, ["s", init] {alignment = 1 : i64}
// CIR: cir.try {
// CIR: cir.call exception @_ZN1SC2Ev(%[[V2]]) : (!cir.ptr<!ty_S>) -> ()
// CIR: cir.call exception @__cxa_rethrow() : () -> ()
// CIR: cir.scope {
// CIR: cir.unreachable
// CIR: }
// CIR: cir.yield
// CIR: } catch [type #cir.all {
// CIR: %[[V3:.*]] = cir.catch_param -> !cir.ptr<!void>
// CIR: %[[V4:.*]] = cir.load %[[V0]] : !cir.ptr<!s32i>, !s32i
// CIR: %[[V5:.*]] = cir.unary(inc, %[[V4]]) : !s32i, !s32i
// CIR: cir.store %[[V5]], %[[V0]] : !s32i, !cir.ptr<!s32i>
// CIR: cir.yield
// CIR: }]
// CIR-LABEL: @_Z6refoo1v()
// CIR: %[[V0:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["r", init] {alignment = 4 : i64}
// CIR: %[[V1:.*]] = cir.const #cir.int<1> : !s32i
// CIR: cir.store %[[V1]], %[[V0]] : !s32i, !cir.ptr<!s32i>
// CIR: cir.scope {
// CIR: %[[V2:.*]] = cir.alloca !ty_S, !cir.ptr<!ty_S>, ["s", init] {alignment = 1 : i64}
// CIR: cir.try {
// CIR: cir.call exception @_ZN1SC2Ev(%[[V2]]) : (!cir.ptr<!ty_S>) -> ()
// CIR: cir.call exception @__cxa_rethrow() : () -> ()
// CIR: cir.unreachable
// CIR: ^bb1: // no predecessors
// CIR: cir.yield
// CIR: } catch [type #cir.all {
// CIR: %[[V3:.*]] = cir.catch_param -> !cir.ptr<!void>
// CIR: %[[V4:.*]] = cir.load %[[V0]] : !cir.ptr<!s32i>, !s32i
// CIR: %[[V5:.*]] = cir.unary(inc, %[[V4]]) : !s32i, !s32i
// CIR: cir.store %[[V5]], %[[V0]] : !s32i, !cir.ptr<!s32i>
// CIR: cir.yield
// CIR: }]
// CIR: }
// CIR: cir.return
// CIR: }
// CIR: cir.return

void refoo2() {
int r = 1;
try {
for (int i = 0; i < 5; i++) {
S s;
throw;
}
S s;
} catch (...) {
++r;
}
}

// CIR-LABEL: @_Z6refoo2v()
// CIR: %[[V0:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["r", init] {alignment = 4 : i64}
// CIR: %[[V1:.*]] = cir.const #cir.int<1> : !s32i
// CIR: cir.store %[[V1]], %[[V0]] : !s32i, !cir.ptr<!s32i>
// CIR: cir.scope {
// CIR: %[[V2:.*]] = cir.alloca !ty_S, !cir.ptr<!ty_S>, ["s", init] {alignment = 1 : i64}
// CIR: cir.try {
// CIR: cir.scope {
// CIR: %[[V3:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["i", init] {alignment = 4 : i64}
// CIR: %[[V4:.*]] = cir.const #cir.int<0> : !s32i
// CIR: cir.store %[[V4]], %[[V3]] : !s32i, !cir.ptr<!s32i>
// CIR: cir.for : cond {
// CIR: %[[V5:.*]] = cir.load %[[V3]] : !cir.ptr<!s32i>, !s32i
// CIR: %[[V6:.*]] = cir.const #cir.int<5> : !s32i
// CIR: %[[V7:.*]] = cir.cmp(lt, %[[V5]], %[[V6]]) : !s32i, !cir.bool
// CIR: cir.condition(%[[V7]])
// CIR: } body {
// CIR: cir.scope {
// CIR: %[[V5:.*]] = cir.alloca !ty_S, !cir.ptr<!ty_S>, ["s", init] {alignment = 1 : i64}
// CIR: cir.call exception @_ZN1SC2Ev(%[[V5]]) : (!cir.ptr<!ty_S>) -> ()
// CIR: cir.call exception @__cxa_rethrow() : () -> ()
// CIR: cir.unreachable
// CIR: ^bb1: // no predecessors
// CIR: cir.yield
// CIR: }
// CIR: cir.yield
// CIR: } step {
// CIR: %[[V5:.*]] = cir.load %[[V3]] : !cir.ptr<!s32i>, !s32i
// CIR: %[[V6:.*]] = cir.unary(inc, %[[V5]]) : !s32i, !s32i
// CIR: cir.store %[[V6]], %[[V3]] : !s32i, !cir.ptr<!s32i>
// CIR: cir.yield
// CIR: }
// CIR: }
// CIR: cir.call exception @_ZN1SC2Ev(%[[V2]]) : (!cir.ptr<!ty_S>) -> ()
// CIR: cir.yield
// CIR: } catch [type #cir.all {
// CIR: %[[V3:.*]] = cir.catch_param -> !cir.ptr<!void>
// CIR: %[[V4:.*]] = cir.load %[[V0]] : !cir.ptr<!s32i>, !s32i
// CIR: %[[V5:.*]] = cir.unary(inc, %[[V4]]) : !s32i, !s32i
// CIR: cir.store %[[V5]], %[[V0]] : !s32i, !cir.ptr<!s32i>
// CIR: cir.yield
// CIR: }]
// CIR: }
// CIR: cir.return
// CIR: }

0 comments on commit fa80c8c

Please sign in to comment.