Skip to content

Commit 7c24e59

Browse files
committed
[CIR][CIRGen][NFCI] Exceptions: change getEHDispatchBlock to create blocks inside calls
getEHDispatchBlock result isn't really used to track anything just yet, so this change isn't supposed to affect anything. This is building block for having a cleanup per call.
1 parent fd3ba1d commit 7c24e59

File tree

5 files changed

+41
-8
lines changed

5 files changed

+41
-8
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -893,7 +893,7 @@ def ConditionOp : CIR_Op<"condition", [
893893
def YieldOp : CIR_Op<"yield", [ReturnLike, Terminator,
894894
ParentOneOf<["IfOp", "ScopeOp", "SwitchOp", "WhileOp", "ForOp", "AwaitOp",
895895
"TernaryOp", "GlobalOp", "DoWhileOp", "TryOp", "ArrayCtor",
896-
"ArrayDtor"]>]> {
896+
"ArrayDtor", "CallOp"]>]> {
897897
let summary = "Represents the default branching behaviour of a region";
898898
let description = [{
899899
The `cir.yield` operation terminates regions on different CIR operations,

clang/lib/CIR/CodeGen/CIRGenCall.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,8 +505,10 @@ buildCallLikeOp(CIRGenFunction &CGF, mlir::Location callLoc,
505505
}
506506
callOpWithExceptions->setAttr("extra_attrs", extraFnAttrs);
507507

508+
CGF.callWithExceptionCtx = callOpWithExceptions;
508509
auto *invokeDest = CGF.getInvokeDest(tryOp);
509510
(void)invokeDest;
511+
CGF.callWithExceptionCtx = nullptr;
510512

511513
if (tryOp.getSynthetic()) {
512514
builder.create<mlir::cir::YieldOp>(tryOp.getLoc());

clang/lib/CIR/CodeGen/CIRGenException.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -742,7 +742,9 @@ mlir::Operation *CIRGenFunction::buildLandingPad(mlir::cir::TryOp tryOp) {
742742
// landing pad by generating a branch to the dispatch block. In CIR the same
743743
// function is called to gather some state, but this block info it's not
744744
// useful per-se.
745-
(void)getEHDispatchBlock(EHStack.getInnermostEHScope(), tryOp);
745+
mlir::Block *dispatch =
746+
getEHDispatchBlock(EHStack.getInnermostEHScope(), tryOp);
747+
(void)dispatch;
746748
}
747749

748750
return tryOp;
@@ -789,9 +791,12 @@ CIRGenFunction::getEHDispatchBlock(EHScopeStack::stable_iterator si,
789791

790792
case EHScope::Cleanup: {
791793
assert(tryOp && "expected cir.try available");
792-
llvm::MutableArrayRef<mlir::Region> regions = tryOp.getCatchRegions();
793-
assert(regions.size() == 1 && "expected only one region");
794-
dispatchBlock = &regions[0].getBlocks().back();
794+
assert(callWithExceptionCtx && "expected call information");
795+
{
796+
mlir::OpBuilder::InsertionGuard guard(getBuilder());
797+
dispatchBlock = builder.createBlock(&callWithExceptionCtx.getCleanup());
798+
builder.createYield(callWithExceptionCtx.getLoc());
799+
}
795800
break;
796801
}
797802

clang/lib/CIR/CodeGen/CIRGenFunction.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1748,6 +1748,7 @@ class CIRGenFunction : public CIRGenTypeCache {
17481748
};
17491749

17501750
/// Emits try/catch information for the current EH stack.
1751+
mlir::cir::CallOp callWithExceptionCtx = nullptr;
17511752
mlir::Operation *buildLandingPad(mlir::cir::TryOp tryOp);
17521753
mlir::Block *getEHResumeBlock(bool isCleanup, mlir::cir::TryOp tryOp);
17531754
mlir::Block *getEHDispatchBlock(EHScopeStack::stable_iterator scope,

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

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,30 @@ struct RemoveTrivialTry : public OpRewritePattern<TryOp> {
111111
}
112112
};
113113

114+
// Remove call exception with empty cleanups
115+
struct SimplifyCallOp : public OpRewritePattern<CallOp> {
116+
using OpRewritePattern<CallOp>::OpRewritePattern;
117+
118+
LogicalResult match(CallOp op) const final {
119+
// Applicable to cir.call exception ... clean { cir.yield }
120+
mlir::Region *r = &op.getCleanup();
121+
if (r->empty() || !r->hasOneBlock())
122+
return failure();
123+
124+
mlir::Block *b = &r->getBlocks().back();
125+
if (&b->back() != &b->front())
126+
return failure();
127+
128+
return success(isa<YieldOp>(&b->getOperations().back()));
129+
}
130+
131+
void rewrite(CallOp op, PatternRewriter &rewriter) const final {
132+
mlir::Block *b = &op.getCleanup().back();
133+
rewriter.eraseOp(&b->back());
134+
rewriter.eraseBlock(b);
135+
}
136+
};
137+
114138
/// Simplify suitable ternary operations into select operations.
115139
///
116140
/// For now we only simplify those ternary operations whose true and false
@@ -255,7 +279,8 @@ void populateMergeCleanupPatterns(RewritePatternSet &patterns) {
255279
RemoveEmptySwitch,
256280
RemoveTrivialTry,
257281
SimplifyTernary,
258-
SimplifySelect
282+
SimplifySelect,
283+
SimplifyCallOp
259284
>(patterns.getContext());
260285
// clang-format on
261286
}
@@ -271,8 +296,8 @@ void CIRSimplifyPass::runOnOperation() {
271296
// CastOp here is to perform a manual `fold` in
272297
// applyOpPatternsAndFold
273298
if (isa<BrOp, BrCondOp, ScopeOp, SwitchOp, CastOp, TryOp, UnaryOp,
274-
TernaryOp, SelectOp, ComplexCreateOp, ComplexRealOp, ComplexImagOp>(
275-
op))
299+
TernaryOp, SelectOp, ComplexCreateOp, ComplexRealOp, ComplexImagOp,
300+
CallOp>(op))
276301
ops.push_back(op);
277302
});
278303

0 commit comments

Comments
 (0)