Skip to content

Commit 3a64b24

Browse files
committed
[CIR][CIRGen][FlattenCFG] Exceptions: introduce cir.eh.selector
1 parent d047947 commit 3a64b24

File tree

3 files changed

+40
-8
lines changed

3 files changed

+40
-8
lines changed

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

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3233,13 +3233,13 @@ def CatchParamOp : CIR_Op<"catch_param"> {
32333233
}
32343234

32353235
//===----------------------------------------------------------------------===//
3236-
// InflightEhOp
3236+
// Exception related: EhInflightOp, EhSelectorOp
32373237
//===----------------------------------------------------------------------===//
32383238

3239-
def InflightEhOp : CIR_Op<"inflight_exception"> {
3239+
def EhInflightOp : CIR_Op<"eh.inflight_exception"> {
32403240
let summary = "Materialize the catch clause formal parameter";
32413241
let description = [{
3242-
`cir.inflight_exception` returns an exception coming from a
3242+
`cir.eh.inflight_exception` returns an exception coming from a
32433243
`cir.call exception` that might throw. The returned value is opaque
32443244
but can be further decomposed by other operations.
32453245
}];
@@ -3252,6 +3252,24 @@ def InflightEhOp : CIR_Op<"inflight_exception"> {
32523252
let hasVerifier = 0;
32533253
}
32543254

3255+
def EhSelectorOp : CIR_Op<"eh.selector"> {
3256+
let summary = "Materialize the eh selector";
3257+
let description = [{
3258+
`cir.eh.inflight_exception` returns an exception coming from a
3259+
`cir.call exception ...` that might throw. `cir.eh.selector` returns the
3260+
runtime selector value (type id) for the needed , which represents the type id used by
3261+
operations to compare against other type ids.
3262+
}];
3263+
3264+
let arguments = (ins CIR_ExceptionType:$exception);
3265+
let results = (outs UInt32:$selector);
3266+
let assemblyFormat = [{
3267+
$exception attr-dict
3268+
}];
3269+
3270+
let hasVerifier = 0;
3271+
}
3272+
32553273
//===----------------------------------------------------------------------===//
32563274
// CopyOp
32573275
//===----------------------------------------------------------------------===//

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

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -220,12 +220,24 @@ class CIRTryOpFlattening : public mlir::OpRewritePattern<mlir::cir::TryOp> {
220220
// to the catch block as a placeholder for now.
221221
rewriter.replaceOpWithNewOp<mlir::cir::BrOp>(yieldOp, catchBegin);
222222

223-
// Start the landing pad by getting the inflight exception information,
224-
// and jumping to the catchBegin phase.
223+
// Start the landing pad by getting the inflight exception information.
225224
rewriter.setInsertionPointToEnd(catchBegin);
226-
InflightEhOp exception = rewriter.create<mlir::cir::InflightEhOp>(
225+
auto exception = rewriter.create<mlir::cir::EhInflightOp>(
227226
loc, mlir::cir::ExceptionInfoType::get(rewriter.getContext()));
228-
// FIXME: TBD emission.
227+
228+
// TODO: direct catch all needs no dispatch.
229+
230+
// Handle dispatch. In could in theory use a switch, but let's just
231+
// mimic LLVM more closely since we have no specific thing to achieve
232+
// doing that (might not play as well with existing optimizers either).
233+
auto *dispatchBlock =
234+
rewriter.splitBlock(catchBegin, rewriter.getInsertionPoint());
235+
rewriter.setInsertionPointToEnd(catchBegin);
236+
rewriter.create<mlir::cir::BrOp>(loc, dispatchBlock);
237+
238+
// Fill in dispatcher.
239+
rewriter.setInsertionPointToEnd(dispatchBlock);
240+
auto selector = rewriter.create<mlir::cir::EhSelectorOp>(loc, exception);
229241
rewriter.create<mlir::cir::BrOp>(loc, continueBlock);
230242

231243
rewriter.eraseOp(tryOp);

clang/test/CIR/Lowering/try-catch.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,10 @@ unsigned long long tc() {
2626
// CIR_FLAT: cir.br ^bb3
2727

2828
// CIR_FLAT: ^bb3: // pred: ^bb2
29-
// CIR_FLAT: %14 = cir.inflight_exception
29+
// CIR_FLAT: %[[EH:.*]] = cir.eh.inflight_exception
3030
// CIR_FLAT: cir.br ^bb4
31+
// CIR_FLAT: ^bb4: // pred: ^bb3
32+
// CIR_FLAT: %[[SEL:.*]] = cir.eh.selector %[[EH]]
3133
} catch (int idx) {
3234
z = 98;
3335
idx++;

0 commit comments

Comments
 (0)