Go to the documentation of this file.
34 #define DEBUG_TYPE "prune-eh"
36 STATISTIC(NumRemoved,
"Number of invokes removed");
37 STATISTIC(NumUnreach,
"Number of noreturn calls optimized");
55 "Remove unused exception handling info",
false,
false)
64 for (
auto *
F : Functions)
67 bool MadeChange =
false;
81 bool SCCMightUnwind =
false, SCCMightReturn =
false;
83 if (!
F->hasExactDefinition()) {
84 SCCMightUnwind |= !
F->doesNotThrow();
85 SCCMightReturn |= !
F->doesNotReturn();
87 bool CheckUnwind = !SCCMightUnwind && !
F->doesNotThrow();
88 bool CheckReturn = !SCCMightReturn && !
F->doesNotReturn();
93 bool CheckReturnViaAsm = CheckReturn &&
94 F->hasFnAttribute(Attribute::Naked) &&
95 F->hasFnAttribute(Attribute::NoInline);
97 if (!CheckUnwind && !CheckReturn)
102 if (CheckUnwind && TI->
mayThrow()) {
103 SCCMightUnwind =
true;
104 }
else if (CheckReturn && isa<ReturnInst>(TI)) {
105 SCCMightReturn =
true;
109 if ((!CheckUnwind || SCCMightUnwind) &&
110 (!CheckReturnViaAsm || SCCMightReturn))
115 if (CheckUnwind && !SCCMightUnwind &&
I.mayThrow()) {
116 bool InstMightUnwind =
true;
117 if (
const auto *CI = dyn_cast<CallInst>(&
I)) {
121 if (Functions.contains(
Callee))
122 InstMightUnwind =
false;
125 SCCMightUnwind |= InstMightUnwind;
127 if (CheckReturnViaAsm && !SCCMightReturn)
128 if (
const auto *CB = dyn_cast<CallBase>(&
I))
129 if (
const auto *IA = dyn_cast<InlineAsm>(CB->getCalledOperand()))
130 if (IA->hasSideEffects())
131 SCCMightReturn =
true;
134 if (SCCMightUnwind && SCCMightReturn)
140 if (!SCCMightUnwind || !SCCMightReturn)
142 if (!SCCMightUnwind && !
F->hasFnAttribute(Attribute::NoUnwind)) {
143 F->addFnAttr(Attribute::NoUnwind);
147 if (!SCCMightReturn && !
F->hasFnAttribute(Attribute::NoReturn)) {
148 F->addFnAttr(Attribute::NoReturn);
167 for (
auto &
N :
SCC) {
168 if (
auto *
F =
N->getFunction())
171 CallGraph &CG = getAnalysis<CallGraphWrapperPass>().getCallGraph();
174 return runImpl(CGU, Functions);
182 bool MadeChange =
false;
184 if (
InvokeInst *II = dyn_cast<InvokeInst>(
BB->getTerminator()))
186 BasicBlock *UnwindBlock = II->getUnwindDest();
198 if (
CallInst *CI = dyn_cast<CallInst>(
I++))
199 if (CI->doesNotReturn() && !CI->isMustTailCall() &&
200 !isa<UnreachableInst>(
I)) {
208 BB->getInstList().pop_back();
232 if (
I->getType()->isTokenTy()) {
237 if (
auto *Call = dyn_cast<CallBase>(&*
I)) {
241 else if (!
Callee->isIntrinsic())
256 for (
unsigned i = 0,
e = Succs.size();
i !=
e; ++
i)
257 Succs[
i]->removePredecessor(
BB);
259 BB->eraseFromParent();
Wrapper to unify "old style" CallGraph and "new style" LazyCallGraph.
bool isTerminator() const
This is an optimization pass for GlobalISel generic memory operations.
InstListType::iterator iterator
Instruction iterators...
static void DeleteBasicBlock(BasicBlock *BB, CallGraphUpdater &CGU)
DeleteBasicBlock - remove the specified basic block from the program, updating the callgraph to refle...
Interval::succ_iterator succ_end(Interval *I)
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
Pass * createPruneEHPass()
createPruneEHPass - Return a new pass object which transforms invoke instructions into calls,...
The basic data container for the call graph of a Module of IR.
static bool SimplifyFunction(Function *F, CallGraphUpdater &CGU)
void prune(LinkGraph &G)
Removes dead symbols/blocks/addressables.
bool mayThrow() const
Return true if this instruction may throw an exception.
LLVM Basic Block Representation.
CallGraphSCC - This is a single SCC that a CallGraphSCCPass is run on.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
void removeCallSite(CallBase &CS)
Remove the call site CS from the call graph.
STATISTIC(NumFunctions, "Total number of functions")
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
void removeUnwindEdge(BasicBlock *BB, DomTreeUpdater *DTU=nullptr)
Replace 'BB's terminator with one that does not have an unwind successor block.
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
bool canSimplifyInvokeNoUnwind(const Function *F)
The ModulePass which wraps up a CallGraph and the logic to build it.
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...
void initializePruneEHPass(PassRegistry &)
bool isLeaf(ID id)
Returns true if the intrinsic is a leaf, i.e.
static bool runImpl(CallGraphUpdater &CGU, SetVector< Function * > &Functions)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool insert(const value_type &X)
Insert a new element into the SetVector.
bool pred_empty(const BasicBlock *BB)
amdgpu Simplify well known AMD library false FunctionCallee Callee
INITIALIZE_PASS_BEGIN(PruneEH, "prune-eh", "Remove unused exception handling info", false, false) INITIALIZE_PASS_END(PruneEH
unsigned changeToUnreachable(Instruction *I, bool PreserveLCSSA=false, DomTreeUpdater *DTU=nullptr, MemorySSAUpdater *MSSAU=nullptr)
Insert an unreachable instruction before the specified instruction, making it and the rest of the cod...
Pass interface - Implemented by all 'passes'.
This class represents a function call, abstracting a target machine's calling convention.
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM BB
This function has undefined behavior.
void initialize(CallGraph &CG, CallGraphSCC &SCC)
Initializers for usage outside of a CGSCC pass, inside a CGSCC pass in the old and new pass manager (...
BasicBlockListType::iterator iterator