Skip to content

Commit b365964

Browse files
committed
[CIR][CIRGen] cir.try: handle trivial ones and fix crash
OG codegen does not generate any exception related content when there are not calls happening inside the try block. For now we mimic OG and do the same, until we see a concrete use case that would have used emitting this code.
1 parent 5d9732a commit b365964

File tree

4 files changed

+52
-5
lines changed

4 files changed

+52
-5
lines changed

clang/lib/CIR/CodeGen/CIRGenCleanup.h

+1-2
Original file line numberDiff line numberDiff line change
@@ -206,8 +206,7 @@ class EHCatchScope : public EHScope {
206206
// 'takeHandler' or some such function which removes ownership from the
207207
// EHCatchScope object if the handlers should live longer than EHCatchScope.
208208
void clearHandlerBlocks() {
209-
for (unsigned I = 0, N = getNumHandlers(); I != N; ++I)
210-
delete getHandler(I).Block;
209+
// The blocks are owned by CatchOp, nothing to delete.
211210
}
212211

213212
typedef const Handler *iterator;

clang/lib/CIR/CodeGen/CIRGenException.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ mlir::Block *CIRGenFunction::getEHResumeBlock(bool isCleanup) {
257257
// pointer but only use it to denote we're tracking things, but there
258258
// shouldn't be any changes to that block after work done in this function.
259259
auto catchOp = currLexScope->getExceptionInfo().catchOp;
260-
assert(catchOp.getNumRegions() && "expected at least one region");
260+
assert(catchOp && catchOp.getNumRegions() && "expected at least one region");
261261
auto &fallbackRegion = catchOp.getRegion(catchOp.getNumRegions() - 1);
262262

263263
auto *resumeBlock = &fallbackRegion.getBlocks().back();
@@ -510,6 +510,7 @@ void CIRGenFunction::exitCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock) {
510510
if (!CatchScope.hasEHBranches()) {
511511
CatchScope.clearHandlerBlocks();
512512
EHStack.popCatch();
513+
currLexScope->getExceptionInfo().catchOp->erase();
513514
return;
514515
}
515516

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

+25-2
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,28 @@ struct RemoveEmptySwitch : public OpRewritePattern<SwitchOp> {
8383
}
8484
};
8585

86+
struct RemoveTrivialTry : public OpRewritePattern<TryOp> {
87+
using OpRewritePattern<TryOp>::OpRewritePattern;
88+
89+
LogicalResult match(TryOp op) const final {
90+
return success(op.getResult().use_empty() && op.getBody().hasOneBlock());
91+
}
92+
93+
void rewrite(TryOp op, PatternRewriter &rewriter) const final {
94+
// Move try body to the parent.
95+
assert(op.getBody().hasOneBlock());
96+
97+
Block *parentBlock = op.getOperation()->getBlock();
98+
mlir::Block *tryBody = &op.getBody().getBlocks().front();
99+
YieldOp y = dyn_cast<YieldOp>(tryBody->getTerminator());
100+
assert(y && "expected well wrapped up try block");
101+
y->erase();
102+
103+
rewriter.inlineBlockBefore(tryBody, parentBlock, Block::iterator(op));
104+
rewriter.eraseOp(op);
105+
}
106+
};
107+
86108
//===----------------------------------------------------------------------===//
87109
// MergeCleanupsPass
88110
//===----------------------------------------------------------------------===//
@@ -106,7 +128,8 @@ void populateMergeCleanupPatterns(RewritePatternSet &patterns) {
106128
patterns.add<
107129
RemoveRedundantBranches,
108130
RemoveEmptyScope,
109-
RemoveEmptySwitch
131+
RemoveEmptySwitch,
132+
RemoveTrivialTry
110133
>(patterns.getContext());
111134
// clang-format on
112135
}
@@ -121,7 +144,7 @@ void MergeCleanupsPass::runOnOperation() {
121144
getOperation()->walk([&](Operation *op) {
122145
// CastOp here is to perform a manual `fold` in
123146
// applyOpPatternsAndFold
124-
if (isa<BrOp, BrCondOp, ScopeOp, SwitchOp, CastOp>(op))
147+
if (isa<BrOp, BrCondOp, ScopeOp, SwitchOp, CastOp, TryOp>(op))
125148
ops.push_back(op);
126149
});
127150

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

+24
Original file line numberDiff line numberDiff line change
@@ -83,5 +83,29 @@ unsigned long long tc3() {
8383
z = 100;
8484
}
8585

86+
return z;
87+
}
88+
89+
// CIR: cir.func @_Z3tc4v()
90+
unsigned long long tc4() {
91+
int x = 50, y = 3;
92+
unsigned long long z;
93+
94+
// CIR-NOT: cir.try
95+
try {
96+
int a = 4;
97+
a++;
98+
99+
// CIR: cir.scope {
100+
// CIR: cir.alloca !s32i, !cir.ptr<!s32i>, ["a", init]
101+
// CIR-NOT: cir.alloca !cir.ptr<!cir.eh.info>
102+
// CIR: cir.const #cir.int<4> : !s32i
103+
// CIR: cir.unary(inc,
104+
// CIR: cir.store %11, %8 : !s32i, !cir.ptr<!s32i>
105+
} catch (int idx) {
106+
z = 98;
107+
idx++;
108+
}
109+
86110
return z;
87111
}

0 commit comments

Comments
 (0)