Delete trivial landing pads that just continue unwinding the caught

exception.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@139117 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Duncan Sands 2011-09-05 12:57:57 +00:00
parent dabc280672
commit ad99ef8bf5
2 changed files with 71 additions and 0 deletions

View File

@ -63,6 +63,7 @@ class SimplifyCFGOpt {
bool FoldValueComparisonIntoPredecessors(TerminatorInst *TI,
IRBuilder<> &Builder);
bool SimplifyResume(ResumeInst *RI, IRBuilder<> &Builder);
bool SimplifyReturn(ReturnInst *RI, IRBuilder<> &Builder);
bool SimplifyUnwind(UnwindInst *UI, IRBuilder<> &Builder);
bool SimplifyUnreachable(UnreachableInst *UI);
@ -2138,6 +2139,52 @@ static bool SimplifyBranchOnICmpChain(BranchInst *BI, const TargetData *TD,
return true;
}
bool SimplifyCFGOpt::SimplifyResume(ResumeInst *RI, IRBuilder<> &Builder) {
// If this is a trivial landing pad that just continues unwinding the caught
// exception then zap the landing pad, turning its invokes into calls.
BasicBlock *BB = RI->getParent();
LandingPadInst *LPInst = dyn_cast<LandingPadInst>(BB->getFirstNonPHI());
if (RI->getValue() != LPInst)
// Not a landing pad, or the resume is not unwinding the exception that
// caused control to branch here.
return false;
// Check that there are no other instructions except for debug intrinsics.
BasicBlock::iterator I = LPInst, E = RI;
while (++I != E)
if (!isa<DbgInfoIntrinsic>(I))
return false;
// Turn all invokes that unwind here into calls and delete the basic block.
for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB); PI != PE;) {
InvokeInst *II = cast<InvokeInst>((*PI++)->getTerminator());
SmallVector<Value*, 8> Args(II->op_begin(), II->op_end() - 3);
// Insert a call instruction before the invoke.
CallInst *Call = CallInst::Create(II->getCalledValue(), Args, "", II);
Call->takeName(II);
Call->setCallingConv(II->getCallingConv());
Call->setAttributes(II->getAttributes());
Call->setDebugLoc(II->getDebugLoc());
// Anything that used the value produced by the invoke instruction now uses
// the value produced by the call instruction. Note that we do this even
// for void functions and calls with no uses so that the callgraph edge is
// updated.
II->replaceAllUsesWith(Call);
BB->removePredecessor(II->getParent());
// Insert a branch to the normal destination right before the invoke.
BranchInst::Create(II->getNormalDest(), II);
// Finally, delete the invoke instruction!
II->eraseFromParent();
}
// The landingpad is now unreachable. Zap it.
BB->eraseFromParent();
return true;
}
bool SimplifyCFGOpt::SimplifyReturn(ReturnInst *RI, IRBuilder<> &Builder) {
BasicBlock *BB = RI->getParent();
if (!BB->getFirstNonPHIOrDbg()->isTerminator()) return false;
@ -2836,6 +2883,8 @@ bool SimplifyCFGOpt::run(BasicBlock *BB) {
} else {
if (SimplifyCondBranch(BI, Builder)) return true;
}
} else if (ResumeInst *RI = dyn_cast<ResumeInst>(BB->getTerminator())) {
if (SimplifyResume(RI, Builder)) return true;
} else if (ReturnInst *RI = dyn_cast<ReturnInst>(BB->getTerminator())) {
if (SimplifyReturn(RI, Builder)) return true;
} else if (SwitchInst *SI = dyn_cast<SwitchInst>(BB->getTerminator())) {

View File

@ -0,0 +1,22 @@
; RUN: opt < %s -simplifycfg -S | FileCheck %s
; CHECK-NOT: invoke
; CHECK-NOT: landingpad
declare void @bar()
define i32 @foo() {
entry:
invoke void @bar()
to label %return unwind label %lpad
return:
ret i32 0
lpad:
%lp = landingpad { i8*, i32 } personality i32 (i32, i64, i8*, i8*)* @__gxx_personality_v0
cleanup
resume { i8*, i32 } %lp
}
declare i32 @__gxx_personality_v0(i32, i64, i8*, i8*)