diff options
| author | Chris Lattner <sabre@nondot.org> | 2004-04-20 22:06:53 +0000 | 
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2004-04-20 22:06:53 +0000 | 
| commit | c87784f1fcd52e052f4540a90684a410c05532d2 (patch) | |
| tree | 3d049d17e57f414fef0a6c2a2cec7da7aa24e367 /llvm/lib/Transforms | |
| parent | 99504890b76878a5f8965029622a80436c32e4f5 (diff) | |
| download | bcm5719-llvm-c87784f1fcd52e052f4540a90684a410c05532d2.tar.gz bcm5719-llvm-c87784f1fcd52e052f4540a90684a410c05532d2.zip | |
REALLY fix PR324: don't delete linkonce functions until after the SCC traversal
is done, which avoids invalidating iterators in the SCC traversal routines
llvm-svn: 13088
Diffstat (limited to 'llvm/lib/Transforms')
| -rw-r--r-- | llvm/lib/Transforms/IPO/Inliner.cpp | 35 | ||||
| -rw-r--r-- | llvm/lib/Transforms/IPO/Inliner.h | 5 | 
2 files changed, 33 insertions, 7 deletions
| diff --git a/llvm/lib/Transforms/IPO/Inliner.cpp b/llvm/lib/Transforms/IPO/Inliner.cpp index 0684c28697e..17e8001c5b5 100644 --- a/llvm/lib/Transforms/IPO/Inliner.cpp +++ b/llvm/lib/Transforms/IPO/Inliner.cpp @@ -117,7 +117,7 @@ bool Inliner::runOnSCC(const 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 != Caller && -              (Callee->hasInternalLinkage() || Callee->hasLinkOnceLinkage())) { +              Callee->hasInternalLinkage()) {              DEBUG(std::cerr << "    -> Deleting dead function: "                              << Callee->getName() << "\n");              SCCFunctions.erase(Callee);    // Remove function from this SCC. @@ -126,12 +126,6 @@ bool Inliner::runOnSCC(const std::vector<CallGraphNode*> &SCC) {              while (CalleeNode->begin() != CalleeNode->end())                CalleeNode->removeCallEdgeTo(*(CalleeNode->end()-1)); -            // If the function has external linkage (basically if it's a -            // linkonce function) remove the edge from the external node to the -            // callee node. -            if (!Callee->hasInternalLinkage()) -              CG.getExternalCallingNode()->removeCallEdgeTo(CalleeNode); -              // Removing the node for callee from the call graph and delete it.              delete CG.removeFunctionFromModule(CalleeNode);              ++NumDeleted; @@ -145,3 +139,30 @@ bool Inliner::runOnSCC(const std::vector<CallGraphNode*> &SCC) {    return Changed;  } +// doFinalization - Remove now-dead linkonce functions at the end of +// processing to avoid breaking the SCC traversal. +bool Inliner::doFinalization(CallGraph &CG) { +  bool Changed = false; +  for (CallGraph::iterator I = CG.begin(), E = CG.end(); I != E; ) { +    CallGraphNode *CGN = (++I)->second; +    Function *F = CGN ? CGN->getFunction() : 0; +    if (F && (F->hasLinkOnceLinkage() || F->hasInternalLinkage()) && +        F->use_empty()) { +      // Remove any call graph edges from the callee to its callees. +      while (CGN->begin() != CGN->end()) +        CGN->removeCallEdgeTo(*(CGN->end()-1)); +       +      // If the function has external linkage (basically if it's a +      // linkonce function) remove the edge from the external node to the +      // callee node. +      if (!F->hasInternalLinkage()) +        CG.getExternalCallingNode()->removeCallEdgeTo(CGN); +       +      // Removing the node for callee from the call graph and delete it. +      delete CG.removeFunctionFromModule(CGN); +      ++NumDeleted; +      Changed = true; +    } +  } +  return Changed; +} diff --git a/llvm/lib/Transforms/IPO/Inliner.h b/llvm/lib/Transforms/IPO/Inliner.h index b63fe2ac05c..45d5db726c0 100644 --- a/llvm/lib/Transforms/IPO/Inliner.h +++ b/llvm/lib/Transforms/IPO/Inliner.h @@ -35,6 +35,11 @@ struct Inliner : public CallGraphSCCPass {    // Pass class.    virtual bool runOnSCC(const std::vector<CallGraphNode *> &SCC); +  // doFinalization - Remove now-dead linkonce functions at the end of +  // processing to avoid breaking the SCC traversal. +  virtual bool doFinalization(CallGraph &CG); + +    /// This method returns the value specified by the -inline-threshold value,    /// specified on the command line.  This is typically not directly needed.    /// | 

