17 #define DEBUG_TYPE "prune-eh"
33 STATISTIC(NumRemoved,
"Number of invokes removed");
34 STATISTIC(NumUnreach,
"Number of noreturn calls optimized");
53 "Remove unused exception handling info",
false,
false)
56 "Remove unused exception handling
info",
false, false)
64 bool MadeChange =
false;
75 MadeChange |= SimplifyFunction(
F);
84 bool SCCMightUnwind =
false, SCCMightReturn =
false;
86 (!SCCMightUnwind || !SCCMightReturn) &&
I != E; ++
I) {
89 SCCMightUnwind =
true;
90 SCCMightReturn =
true;
95 bool CheckUnwind = !SCCMightUnwind && !F->
doesNotThrow();
98 if (!CheckUnwind && !CheckReturn)
104 if (CheckUnwind && isa<ResumeInst>(BB->getTerminator())) {
106 SCCMightUnwind =
true;
107 }
else if (CheckReturn && isa<ReturnInst>(BB->getTerminator())) {
108 SCCMightReturn =
true;
113 if (CheckUnwind && !SCCMightUnwind)
115 if (
CallInst *CI = dyn_cast<CallInst>(
I)) {
116 if (CI->doesNotThrow()) {
118 }
else if (
Function *Callee = CI->getCalledFunction()) {
122 if (!SCCNodes.
count(CalleeNode)) {
123 SCCMightUnwind =
true;
128 SCCMightUnwind =
true;
132 if (SCCMightUnwind && SCCMightReturn)
break;
138 if (!SCCMightUnwind || !SCCMightReturn)
150 F->
getContext(), AttributeSet::FunctionIndex, NewAttributes);
162 if (
Function *F = (*I)->getFunction())
163 MadeChange |= SimplifyFunction(F);
173 bool PruneEH::SimplifyFunction(
Function *F) {
174 bool MadeChange =
false;
176 if (
InvokeInst *II = dyn_cast<InvokeInst>(BB->getTerminator()))
177 if (II->doesNotThrow()) {
182 Call->setCallingConv(II->getCallingConv());
183 Call->setAttributes(II->getAttributes());
184 Call->setDebugLoc(II->getDebugLoc());
190 II->replaceAllUsesWith(Call);
191 BasicBlock *UnwindBlock = II->getUnwindDest();
199 BB->getInstList().pop_back();
203 DeleteBasicBlock(UnwindBlock);
210 if (
CallInst *CI = dyn_cast<CallInst>(
I++))
211 if (CI->doesNotReturn() && !isa<UnreachableInst>(
I)) {
222 DeleteBasicBlock(New);
235 void PruneEH::DeleteBasicBlock(
BasicBlock *BB) {
237 CallGraph &CG = getAnalysis<CallGraph>();
242 if (
CallInst *CI = dyn_cast<CallInst>(
I)) {
243 if (!isa<IntrinsicInst>(
I))
244 CGN->removeCallEdgeFor(CI);
245 }
else if (
InvokeInst *II = dyn_cast<InvokeInst>(
I))
246 CGN->removeCallEdgeFor(II);
254 for (
unsigned i = 0, e = Succs.size(); i != e; ++i)
255 Succs[i]->removePredecessor(BB);
void removePredecessor(BasicBlock *Pred, bool DontDeleteUselessPHIs=false)
Notify the BasicBlock that the predecessor Pred is no longer able to reach it.
static PassRegistry * getPassRegistry()
LLVMContext & getContext() const
std::vector< CallGraphNode * >::const_iterator iterator
const Function * getParent() const
Return the enclosing method, or null if none.
STATISTIC(NumRemoved,"Number of invokes removed")
AttrBuilder & addAttribute(Attribute::AttrKind Val)
Add an attribute to the builder.
void initializePruneEHPass(PassRegistry &)
#define INITIALIZE_PASS_DEPENDENCY(depName)
bool doesNotThrow() const
Determine if the function cannot unwind.
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
static BranchInst * Create(BasicBlock *IfTrue, Instruction *InsertBefore=0)
INITIALIZE_PASS_BEGIN(PruneEH,"prune-eh","Remove unused exception handling info", false, false) INITIALIZE_PASS_END(PruneEH
ID
LLVM Calling Convention Representation.
Interval::succ_iterator succ_begin(Interval *I)
bool count(PtrType Ptr) const
count - Return true if the specified pointer is in the set.
Interval::succ_iterator succ_end(Interval *I)
LLVM Basic Block Representation.
static bool mayBeOverridden(LinkageTypes Linkage)
Interval::pred_iterator pred_begin(Interval *I)
bool doesNotReturn() const
Determine if the function cannot return.
const InstListType & getInstList() const
Return the underlying instruction list container.
Interval::pred_iterator pred_end(Interval *I)
Function doesn't unwind stack.
Mark the function as not returning.
static UndefValue * get(Type *T)
static CallInst * Create(Value *Func, ArrayRef< Value * > Args, const Twine &NameStr="", Instruction *InsertBefore=0)
void eraseFromParent()
Unlink 'this' from the containing function and delete it.
AttributeSet getAttributes() const
Return the attribute list for this Function.
bool isDeclaration() const
BasicBlock * splitBasicBlock(iterator I, const Twine &BBName="")
Split the basic block into two basic blocks at the specified instruction.
Pass * createPruneEHPass()
CallGraphSCC - This is a single SCC that a CallGraphSCCPass is run on.
void addAttributes(unsigned i, AttributeSet attrs)
adds the attributes to the list of attributes.
AttributeSet getFnAttributes() const
The function attributes are returned.