Handle the situation where CodeGenPrepare removes a reference to a BB that has

the last invoke instruction in the function. This also removes the last landing
pad in an function. This is fine, but with SjLj EH code, we've already placed a
bunch of code in the 'entry' block, which expects the landing pad to stick
around.

When we get to the situation where CGP has removed the last landing pad, go
ahead and nuke the SjLj instructions from the 'entry' block.
<rdar://problem/12721258>


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@168930 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Bill Wendling 2012-11-29 19:38:06 +00:00
parent b53b791efd
commit 7360116048
2 changed files with 98 additions and 0 deletions

View File

@ -22,6 +22,7 @@
#include "llvm/InlineAsm.h"
#include "llvm/Instructions.h"
#include "llvm/IntrinsicInst.h"
#include "llvm/Module.h"
#include "llvm/Pass.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallSet.h"
@ -183,8 +184,12 @@ bool CodeGenPrepare::runOnFunction(Function &F) {
if (!DisableBranchOpts) {
MadeChange = false;
SmallPtrSet<BasicBlock*, 8> WorkList;
SmallPtrSet<BasicBlock*, 8> LPadList;
SmallVector<BasicBlock*, 8> ReturnList;
for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
SmallVector<BasicBlock*, 2> Successors(succ_begin(BB), succ_end(BB));
if (BB->isLandingPad()) LPadList.insert(BB);
if (isa<ReturnInst>(BB->getTerminator())) ReturnList.push_back(BB);
MadeChange |= ConstantFoldTerminator(BB, true);
if (!MadeChange) continue;
@ -195,9 +200,11 @@ bool CodeGenPrepare::runOnFunction(Function &F) {
}
// Delete the dead blocks and any of their dead successors.
bool HadLPads = !LPadList.empty();
while (!WorkList.empty()) {
BasicBlock *BB = *WorkList.begin();
WorkList.erase(BB);
LPadList.erase(BB);
SmallVector<BasicBlock*, 2> Successors(succ_begin(BB), succ_end(BB));
DeleteDeadBlock(BB);
@ -208,6 +215,74 @@ bool CodeGenPrepare::runOnFunction(Function &F) {
WorkList.insert(*II);
}
if (HadLPads && LPadList.empty()) {
// All of the landing pads were removed. Get rid of the SjLj EH context
// code.
Module *M = F.getParent();
// These functions must exist if we have SjLj EH code to clean up.
Constant *RegisterFn = M->getFunction("_Unwind_SjLj_Register");
Constant *UnregisterFn = M->getFunction("_Unwind_SjLj_Unregister");
if (RegisterFn) {
Constant *LSDAAddrFn =
Intrinsic::getDeclaration(M, Intrinsic::eh_sjlj_lsda);
Constant *FrameAddrFn =
Intrinsic::getDeclaration(M, Intrinsic::frameaddress);
Constant *StackAddrFn =
Intrinsic::getDeclaration(M, Intrinsic::stacksave);
Constant *BuiltinSetjmpFn =
Intrinsic::getDeclaration(M, Intrinsic::eh_sjlj_setjmp);
Constant *FuncCtxFn =
Intrinsic::getDeclaration(M, Intrinsic::eh_sjlj_functioncontext);
BasicBlock &Entry = F.getEntryBlock();
SmallVector<Instruction*, 8> DeadInsts;
for (BasicBlock::iterator I = Entry.begin(), E = Entry.end();
I != E; ++I) {
if (CallInst *CI = dyn_cast<CallInst>(I)) {
Value *Callee = CI->getCalledValue();
bool IsDead = true;
if (Callee != LSDAAddrFn && Callee != FrameAddrFn &&
Callee != StackAddrFn && Callee != BuiltinSetjmpFn &&
Callee != FuncCtxFn && Callee != RegisterFn)
IsDead = false;
if (IsDead) {
Type *Ty = CI->getType();
if (!Ty->isVoidTy())
CI->replaceAllUsesWith(UndefValue::get(Ty));
DeadInsts.push_back(CI);
}
}
}
// Find and remove the unregister calls.
for (SmallVectorImpl<BasicBlock*>::iterator I = ReturnList.begin(),
E = ReturnList.end(); I != E; ++I) {
BasicBlock *BB = *I;
typedef BasicBlock::InstListType::reverse_iterator reverse_iterator;
for (reverse_iterator II = BB->getInstList().rbegin(),
IE = BB->getInstList().rend(); II != IE; ++II) {
if (CallInst *CI = dyn_cast<CallInst>(&*II)) {
Value *Callee = CI->getCalledValue();
if (Callee == UnregisterFn) {
DeadInsts.push_back(CI);
break;
}
}
}
}
// Kill the dead instructions.
for (SmallVectorImpl<Instruction*>::iterator I = DeadInsts.begin(),
E = DeadInsts.end(); I != E; ++I)
(*I)->eraseFromParent();
}
}
// Merge pairs of basic blocks with unconditional branches, connected by
// a single edge.
if (EverMadeChange || MadeChange)

View File

@ -69,3 +69,26 @@ bb:
store <4 x float> %tmp154, <4 x float>* undef, align 16
ret void
}
; <rdar://problem/12721258>
%A = type { %B }
%B = type { i32 }
define void @_Z3Foov() ssp {
entry:
br i1 true, label %exit, label %false
false:
invoke void undef(%A* undef)
to label %exit unwind label %lpad
lpad:
%0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_sj0 to i8*)
catch i8* null
unreachable
exit:
ret void
}
declare i32 @__gxx_personality_sj0(...)