Skip to content

Commit

Permalink
[CIR][CIRGen] cir.try: handle trivial ones and fix crash
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
bcardosolopes committed Jul 13, 2024
1 parent 5d9732a commit b365964
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 5 deletions.
3 changes: 1 addition & 2 deletions clang/lib/CIR/CodeGen/CIRGenCleanup.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,7 @@ class EHCatchScope : public EHScope {
// 'takeHandler' or some such function which removes ownership from the
// EHCatchScope object if the handlers should live longer than EHCatchScope.
void clearHandlerBlocks() {
for (unsigned I = 0, N = getNumHandlers(); I != N; ++I)
delete getHandler(I).Block;
// The blocks are owned by CatchOp, nothing to delete.
}

typedef const Handler *iterator;
Expand Down
3 changes: 2 additions & 1 deletion clang/lib/CIR/CodeGen/CIRGenException.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ mlir::Block *CIRGenFunction::getEHResumeBlock(bool isCleanup) {
// pointer but only use it to denote we're tracking things, but there
// shouldn't be any changes to that block after work done in this function.
auto catchOp = currLexScope->getExceptionInfo().catchOp;
assert(catchOp.getNumRegions() && "expected at least one region");
assert(catchOp && catchOp.getNumRegions() && "expected at least one region");
auto &fallbackRegion = catchOp.getRegion(catchOp.getNumRegions() - 1);

auto *resumeBlock = &fallbackRegion.getBlocks().back();
Expand Down Expand Up @@ -510,6 +510,7 @@ void CIRGenFunction::exitCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock) {
if (!CatchScope.hasEHBranches()) {
CatchScope.clearHandlerBlocks();
EHStack.popCatch();
currLexScope->getExceptionInfo().catchOp->erase();
return;
}

Expand Down
27 changes: 25 additions & 2 deletions clang/lib/CIR/Dialect/Transforms/MergeCleanups.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,28 @@ struct RemoveEmptySwitch : public OpRewritePattern<SwitchOp> {
}
};

struct RemoveTrivialTry : public OpRewritePattern<TryOp> {
using OpRewritePattern<TryOp>::OpRewritePattern;

LogicalResult match(TryOp op) const final {
return success(op.getResult().use_empty() && op.getBody().hasOneBlock());
}

void rewrite(TryOp op, PatternRewriter &rewriter) const final {
// Move try body to the parent.
assert(op.getBody().hasOneBlock());

Block *parentBlock = op.getOperation()->getBlock();
mlir::Block *tryBody = &op.getBody().getBlocks().front();
YieldOp y = dyn_cast<YieldOp>(tryBody->getTerminator());
assert(y && "expected well wrapped up try block");
y->erase();

rewriter.inlineBlockBefore(tryBody, parentBlock, Block::iterator(op));
rewriter.eraseOp(op);
}
};

//===----------------------------------------------------------------------===//
// MergeCleanupsPass
//===----------------------------------------------------------------------===//
Expand All @@ -106,7 +128,8 @@ void populateMergeCleanupPatterns(RewritePatternSet &patterns) {
patterns.add<
RemoveRedundantBranches,
RemoveEmptyScope,
RemoveEmptySwitch
RemoveEmptySwitch,
RemoveTrivialTry
>(patterns.getContext());
// clang-format on
}
Expand All @@ -121,7 +144,7 @@ void MergeCleanupsPass::runOnOperation() {
getOperation()->walk([&](Operation *op) {
// CastOp here is to perform a manual `fold` in
// applyOpPatternsAndFold
if (isa<BrOp, BrCondOp, ScopeOp, SwitchOp, CastOp>(op))
if (isa<BrOp, BrCondOp, ScopeOp, SwitchOp, CastOp, TryOp>(op))
ops.push_back(op);
});

Expand Down
24 changes: 24 additions & 0 deletions clang/test/CIR/CodeGen/try-catch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,5 +83,29 @@ unsigned long long tc3() {
z = 100;
}

return z;
}

// CIR: cir.func @_Z3tc4v()
unsigned long long tc4() {
int x = 50, y = 3;
unsigned long long z;

// CIR-NOT: cir.try
try {
int a = 4;
a++;

// CIR: cir.scope {
// CIR: cir.alloca !s32i, !cir.ptr<!s32i>, ["a", init]
// CIR-NOT: cir.alloca !cir.ptr<!cir.eh.info>
// CIR: cir.const #cir.int<4> : !s32i
// CIR: cir.unary(inc,
// CIR: cir.store %11, %8 : !s32i, !cir.ptr<!s32i>
} catch (int idx) {
z = 98;
idx++;
}

return z;
}

0 comments on commit b365964

Please sign in to comment.