diff options
Diffstat (limited to 'lib/Transforms')
-rw-r--r-- | lib/Transforms/IPO/Inliner.cpp | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/lib/Transforms/IPO/Inliner.cpp b/lib/Transforms/IPO/Inliner.cpp index d5967fb11c..9b8e0a1fc4 100644 --- a/lib/Transforms/IPO/Inliner.cpp +++ b/lib/Transforms/IPO/Inliner.cpp @@ -293,10 +293,12 @@ bool Inliner::runOnSCC(std::vector<CallGraphNode*> &SCC) { // If we inlined the last possible call site to the function, delete the // function body now. - if (Callee->use_empty() && - (Callee->hasLocalLinkage() || - Callee->hasAvailableExternallyLinkage()) && - !SCCFunctions.count(Callee)) { + if (Callee->use_empty() && Callee->hasLocalLinkage() && + !SCCFunctions.count(Callee) && + // The function may be apparently dead, but if there are indirect + // callgraph references to the node, we cannot delete it yet, this + // could invalidate the CGSCC iterator. + CG[Callee]->getNumReferences() == 0) { DEBUG(errs() << " -> Deleting dead function: " << Callee->getName() << "\n"); CallGraphNode *CalleeNode = CG[Callee]; @@ -353,7 +355,7 @@ bool Inliner::removeDeadFunctions(CallGraph &CG, // from the program. Insert the dead ones in the FunctionsToRemove set. for (CallGraph::iterator I = CG.begin(), E = CG.end(); I != E; ++I) { CallGraphNode *CGN = I->second; - if (CGN == 0 || CGN->getFunction() == 0) + if (CGN->getFunction() == 0) continue; Function *F = CGN->getFunction(); @@ -364,7 +366,8 @@ bool Inliner::removeDeadFunctions(CallGraph &CG, if (DNR && DNR->count(F)) continue; - if (!F->hasLinkOnceLinkage() && !F->hasLocalLinkage()) + if (!F->hasLinkOnceLinkage() && !F->hasLocalLinkage() && + !F->hasAvailableExternallyLinkage()) continue; if (!F->use_empty()) continue; |