34 #define DEBUG_TYPE "prune-eh" 36 STATISTIC(NumRemoved,
"Number of invokes removed");
37 STATISTIC(NumUnreach,
"Number of noreturn calls optimized");
56 "Remove unused exception handling info",
false,
false)
59 "Remove unused exception handling
info",
false, false)
65 bool MadeChange =
false;
85 bool SCCMightUnwind =
false, SCCMightReturn =
false;
87 (!SCCMightUnwind || !SCCMightReturn) &&
I !=
E; ++
I) {
90 SCCMightUnwind =
true;
91 SCCMightReturn =
true;
96 bool CheckUnwind = !SCCMightUnwind && !F->
doesNotThrow();
102 bool CheckReturnViaAsm = CheckReturn &&
106 if (!CheckUnwind && !CheckReturn)
111 if (CheckUnwind && TI->
mayThrow()) {
112 SCCMightUnwind =
true;
113 }
else if (CheckReturn && isa<ReturnInst>(TI)) {
114 SCCMightReturn =
true;
118 if ((!CheckUnwind || SCCMightUnwind) &&
119 (!CheckReturnViaAsm || SCCMightReturn))
124 if (CheckUnwind && !SCCMightUnwind &&
I.mayThrow()) {
125 bool InstMightUnwind =
true;
126 if (
const auto *CI = dyn_cast<CallInst>(&
I)) {
131 if (SCCNodes.
count(CalleeNode) > 0)
132 InstMightUnwind =
false;
135 SCCMightUnwind |= InstMightUnwind;
137 if (CheckReturnViaAsm && !SCCMightReturn)
139 if (
const auto *IA = dyn_cast<InlineAsm>(ICS.getCalledValue()))
140 if (IA->hasSideEffects())
141 SCCMightReturn =
true;
144 if (SCCMightUnwind && SCCMightReturn)
151 if (!SCCMightUnwind || !SCCMightReturn)
181 CallGraph &CG = getAnalysis<CallGraphWrapperPass>().getCallGraph();
190 bool MadeChange =
false;
192 if (
InvokeInst *II = dyn_cast<InvokeInst>(BB->getTerminator()))
194 BasicBlock *UnwindBlock = II->getUnwindDest();
206 if (
CallInst *CI = dyn_cast<CallInst>(
I++))
207 if (CI->doesNotReturn() && !isa<UnreachableInst>(
I)) {
215 BB->getInstList().pop_back();
240 if (
I->getType()->isTokenTy()) {
264 for (
unsigned i = 0, e = Succs.size(); i != e; ++i)
265 Succs[i]->removePredecessor(BB);
Pass interface - Implemented by all 'passes'.
bool isIntrinsic() const
isIntrinsic - Returns true if the function's name starts with "llvm.".
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
This class represents lattice values for constants.
static bool runImpl(CallGraphSCC &SCC, CallGraph &CG)
This class represents a function call, abstracting a target machine's calling convention.
bool isTerminator() const
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
STATISTIC(NumFunctions, "Total number of functions")
A node in the call graph for a module.
iterator begin()
Instruction iterator methods.
void initializePruneEHPass(PassRegistry &)
#define INITIALIZE_PASS_DEPENDENCY(depName)
unsigned changeToUnreachable(Instruction *I, bool UseLLVMTrap, bool PreserveLCSSA=false, DomTreeUpdater *DTU=nullptr)
Insert an unreachable instruction before the specified instruction, making it and the rest of the cod...
static bool SimplifyFunction(Function *F, CallGraph &CG)
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 ...
static void DeleteBasicBlock(BasicBlock *BB, CallGraph &CG)
DeleteBasicBlock - remove the specified basic block from the program, updating the callgraph to refle...
amdgpu Simplify well known AMD library false Value * Callee
Interval::succ_iterator succ_end(Interval *I)
The ModulePass which wraps up a CallGraph and the logic to build it.
bool isLeaf(ID id)
Returns true if the intrinsic is a leaf, i.e.
LLVM Basic Block Representation.
This function has undefined behavior.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
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 mayThrow() const
Return true if this instruction may throw an exception.
bool doesNotReturn() const
Determine if the function cannot return.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
bool pred_empty(const BasicBlock *BB)
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
bool doesNotThrow() const
Determine if the function cannot unwind.
Iterator for intrusive lists based on ilist_node.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
Intrinsic::ID getIntrinsicID() const LLVM_READONLY
getIntrinsicID - This method returns the ID number of the specified function, or Intrinsic::not_intri...
void removeUnwindEdge(BasicBlock *BB, DomTreeUpdater *DTU=nullptr)
Replace 'BB's terminator with one that does not have an unwind successor block.
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
The basic data container for the call graph of a Module of IR.
bool hasExactDefinition() const
Return true if this global has an exact defintion.
Establish a view to a call site for examination.
const Function * getParent() const
Return the enclosing method, or null if none.
std::vector< CallGraphNode * >::const_iterator iterator
SymbolTableList< BasicBlock >::iterator eraseFromParent()
Unlink 'this' from the containing function and delete it.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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.
void addFnAttr(Attribute::AttrKind Kind)
Add function attributes to this function.
INITIALIZE_PASS_BEGIN(PruneEH, "prune-eh", "Remove unused exception handling info", false, false) INITIALIZE_PASS_END(PruneEH