[llvm-commits] CVS: llvm/lib/Transforms/IPO/Inliner.cpp Inliner.h

Chris Lattner lattner at cs.uiuc.edu
Tue Apr 20 17:07:02 PDT 2004


Changes in directory llvm/lib/Transforms/IPO:

Inliner.cpp updated: 1.10 -> 1.11
Inliner.h updated: 1.5 -> 1.6

---
Log message:

REALLY fix PR324: http://llvm.cs.uiuc.edu/PR324 : don't delete linkonce functions until after the SCC traversal
is done, which avoids invalidating iterators in the SCC traversal routines


---
Diffs of the changes:  (+33 -7)

Index: llvm/lib/Transforms/IPO/Inliner.cpp
diff -u llvm/lib/Transforms/IPO/Inliner.cpp:1.10 llvm/lib/Transforms/IPO/Inliner.cpp:1.11
--- llvm/lib/Transforms/IPO/Inliner.cpp:1.10	Tue Apr 20 15:20:59 2004
+++ llvm/lib/Transforms/IPO/Inliner.cpp	Tue Apr 20 17:06:53 2004
@@ -117,7 +117,7 @@
           // 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 @@
             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 @@
   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;
+}


Index: llvm/lib/Transforms/IPO/Inliner.h
diff -u llvm/lib/Transforms/IPO/Inliner.h:1.5 llvm/lib/Transforms/IPO/Inliner.h:1.6
--- llvm/lib/Transforms/IPO/Inliner.h:1.5	Thu Apr  8 01:34:31 2004
+++ llvm/lib/Transforms/IPO/Inliner.h	Tue Apr 20 17:06:53 2004
@@ -35,6 +35,11 @@
   // 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.
   ///





More information about the llvm-commits mailing list