35 #define DEBUG_TYPE "prune-eh"
37 STATISTIC(NumRemoved,
"Number of invokes removed");
38 STATISTIC(NumUnreach,
"Number of noreturn calls optimized");
57 "Remove unused exception handling info",
false,
false)
60 "Remove unused exception handling
info",
false, false)
67 CallGraph &CG = getAnalysis<CallGraphWrapperPass>().getCallGraph();
68 bool MadeChange =
false;
79 MadeChange |= SimplifyFunction(
F);
88 bool SCCMightUnwind =
false, SCCMightReturn =
false;
90 (!SCCMightUnwind || !SCCMightReturn) &&
I != E; ++
I) {
93 SCCMightUnwind =
true;
94 SCCMightReturn =
true;
99 bool CheckUnwind = !SCCMightUnwind && !F->
doesNotThrow();
105 bool CheckReturnViaAsm = CheckReturn &&
109 if (!CheckUnwind && !CheckReturn)
114 if (CheckUnwind && TI->
mayThrow()) {
115 SCCMightUnwind =
true;
116 }
else if (CheckReturn && isa<ReturnInst>(TI)) {
117 SCCMightReturn =
true;
121 if ((!CheckUnwind || SCCMightUnwind) &&
122 (!CheckReturnViaAsm || SCCMightReturn))
127 if (CheckUnwind && !SCCMightUnwind &&
I.mayThrow()) {
128 bool InstMightUnwind =
true;
129 if (
const auto *CI = dyn_cast<CallInst>(&
I)) {
130 if (
Function *Callee = CI->getCalledFunction()) {
134 if (SCCNodes.
count(CalleeNode) > 0)
135 InstMightUnwind =
false;
138 SCCMightUnwind |= InstMightUnwind;
140 if (CheckReturnViaAsm && !SCCMightReturn)
142 if (
const auto *IA = dyn_cast<InlineAsm>(ICS.getCalledValue()))
143 if (IA->hasSideEffects())
144 SCCMightReturn =
true;
147 if (SCCMightUnwind && SCCMightReturn)
154 if (!SCCMightUnwind || !SCCMightReturn)
178 if (
Function *F = (*I)->getFunction())
179 MadeChange |= SimplifyFunction(F);
189 bool PruneEH::SimplifyFunction(
Function *F) {
190 bool MadeChange =
false;
192 if (
InvokeInst *II = dyn_cast<InvokeInst>(BB->getTerminator()))
198 Call->setCallingConv(II->getCallingConv());
199 Call->setAttributes(II->getAttributes());
200 Call->setDebugLoc(II->getDebugLoc());
206 II->replaceAllUsesWith(Call);
207 BasicBlock *UnwindBlock = II->getUnwindDest();
215 BB->getInstList().pop_back();
219 DeleteBasicBlock(UnwindBlock);
226 if (
CallInst *CI = dyn_cast<CallInst>(
I++))
227 if (CI->doesNotReturn() && !isa<UnreachableInst>(
I)) {
238 DeleteBasicBlock(New);
251 void PruneEH::DeleteBasicBlock(
BasicBlock *BB) {
253 CallGraph &CG = getAnalysis<CallGraphWrapperPass>().getCallGraph();
258 if (
CallInst *CI = dyn_cast<CallInst>(
I)) {
259 if (!isa<IntrinsicInst>(
I))
261 }
else if (
InvokeInst *II = dyn_cast<InvokeInst>(
I))
270 for (
unsigned i = 0, e = Succs.size(); i != e; ++i)
271 Succs[i]->removePredecessor(BB);
Pass interface - Implemented by all 'passes'.
void removePredecessor(BasicBlock *Pred, bool DontDeleteUselessPHIs=false)
Notify the BasicBlock that the predecessor Pred is no longer able to reach it.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
STATISTIC(NumFunctions,"Total number of functions")
std::vector< CallGraphNode * >::const_iterator iterator
CallInst - This class represents a function call, abstracting a target machine's calling convention...
size_type count(PtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
const Function * getParent() const
Return the enclosing method, or null if none.
AttrBuilder & addAttribute(Attribute::AttrKind Val)
Add an attribute to the builder.
A node in the call graph for a module.
iterator begin()
Instruction iterator methods.
void initializePruneEHPass(PassRegistry &)
#define INITIALIZE_PASS_DEPENDENCY(depName)
bool doesNotThrow() const
Determine if the function cannot unwind.
static CallInst * Create(Value *Func, ArrayRef< Value * > Args, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
INITIALIZE_PASS_BEGIN(PruneEH,"prune-eh","Remove unused exception handling info", false, false) INITIALIZE_PASS_END(PruneEH
bool canSimplifyInvokeNoUnwind(const Function *F)
Interval::succ_iterator succ_begin(Interval *I)
succ_begin/succ_end - define methods so that Intervals may be used just like BasicBlocks can with the...
This file provides interfaces used to build and manipulate a call graph, which is a very useful tool ...
Interval::succ_iterator succ_end(Interval *I)
Subclasses of this class are all able to terminate a basic block.
The ModulePass which wraps up a CallGraph and the logic to build it.
LLVM Basic Block Representation.
static bool mayBeOverridden(LinkageTypes Linkage)
Whether the definition of this global may be replaced by something non-equivalent at link time...
UnreachableInst - This function has undefined behavior.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool doesNotReturn() const
Determine if the function cannot return.
const InstListType & getInstList() const
Return the underlying instruction list container.
Function doesn't unwind stack.
bool pred_empty(const BasicBlock *BB)
Mark the function as not returning.
static UndefValue * get(Type *T)
get() - Static factory methods - Return an 'undef' object of the specified type.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
static BranchInst * Create(BasicBlock *IfTrue, Instruction *InsertBefore=nullptr)
AttributeSet getAttributes() const
Return the attribute list for this Function.
bool mayThrow() const
mayThrow - Return true if this instruction may throw an exception.
The basic data container for the call graph of a Module of IR.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
ImmutableCallSite - establish a view to a call site for examination.
iplist< BasicBlock >::iterator eraseFromParent()
Unlink 'this' from the containing function and delete it.
BasicBlock * splitBasicBlock(iterator I, const Twine &BBName="")
Split the basic block into two basic blocks at the specified instruction.
Pass * createPruneEHPass()
createPruneEHPass - Return a new pass object which transforms invoke instructions into calls...
CallGraphSCC - This is a single SCC that a CallGraphSCCPass is run on.
void removeCallEdgeFor(CallSite CS)
Removes the edge in the node for the specified call site.
InvokeInst - Invoke instruction.
void addAttributes(unsigned i, AttributeSet attrs)
adds the attributes to the list of attributes.
AttributeSet getFnAttributes() const
The function attributes are returned.