[llvm-commits] CVS: llvm/lib/Analysis/DataStructure/DataStructure.cpp

Chris Lattner lattner at cs.uiuc.edu
Tue Mar 22 15:55:08 PST 2005



Changes in directory llvm/lib/Analysis/DataStructure:

DataStructure.cpp updated: 1.226 -> 1.227
---
Log message:

Several changes here:
1. Increase max node size from 64->256 to avoid collapsing an important
   structure in 181.mcf
2. If we have multiple calls to an indirect call node with an indirect
   callee, fold these call nodes together, to avoid DSA turning apoc into
   a flaming fireball of death when analyzing 176.gcc.
  With this change, 176.gcc now takes ~7s to analyze for loc+bu+td, with 
  5.7s of that in the BU pass.


---
Diffs of the changes:  (+42 -19)

 DataStructure.cpp |   61 +++++++++++++++++++++++++++++++++++++-----------------
 1 files changed, 42 insertions(+), 19 deletions(-)


Index: llvm/lib/Analysis/DataStructure/DataStructure.cpp
diff -u llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.226 llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.227
--- llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.226	Mon Mar 21 19:42:59 2005
+++ llvm/lib/Analysis/DataStructure/DataStructure.cpp	Tue Mar 22 17:54:52 2005
@@ -39,7 +39,7 @@
   Statistic<> NumTrivialGlobalDNE("dsa", "Number of globals trivially removed");
 };
 
-#if 1
+#if 0
 #define TIME_REGION(VARNAME, DESC) \
    NamedRegionTimer VARNAME(DESC)
 #else
@@ -467,7 +467,7 @@
     // collapse it.  This can occur for fortran common blocks, which have stupid
     // things like { [100000000 x double], [1000000 x double] }.
     unsigned NumFields = (NewTySize+DS::PointerSize-1) >> DS::PointerShift;
-    if (NumFields > 64) {
+    if (NumFields > 256) {
       foldNodeCompletely();
       return true;
     }
@@ -509,7 +509,7 @@
     // collapse it.  This can occur for fortran common blocks, which have stupid
     // things like { [100000000 x double], [1000000 x double] }.
     unsigned NumFields = (NewTySize+DS::PointerSize-1) >> DS::PointerShift;
-    if (NumFields > 64) {
+    if (NumFields > 256) {
       foldNodeCompletely();
       return true;
     }
@@ -1574,22 +1574,20 @@
         Edge.setTo(0, 0);  // Kill the edge!
 }
 
-#if 0
 static inline bool nodeContainsExternalFunction(const DSNode *N) {
-  const std::vector<GlobalValue*> &Globals = N->getGlobals();
-  for (unsigned i = 0, e = Globals.size(); i != e; ++i)
-    if (Globals[i]->isExternal() && isa<Function>(Globals[i]))
-      return true;
+  std::vector<Function*> Funcs;
+  N->addFullFunctionList(Funcs);
+  for (unsigned i = 0, e = Funcs.size(); i != e; ++i)
+    if (Funcs[i]->isExternal()) return true;
   return false;
 }
-#endif
 
 static void removeIdenticalCalls(std::list<DSCallSite> &Calls) {
   // Remove trivially identical function calls
   Calls.sort();  // Sort by callee as primary key!
 
   // Scan the call list cleaning it up as necessary...
-  DSNode   *LastCalleeNode = 0;
+  DSNodeHandle LastCalleeNode;
   Function *LastCalleeFunc = 0;
   unsigned NumDuplicateCalls = 0;
   bool LastCalleeContainsExternalFunction = false;
@@ -1600,17 +1598,41 @@
     DSCallSite &CS = *I;
     std::list<DSCallSite>::iterator OldIt = I++;
 
-    // If the Callee is a useless edge, this must be an unreachable call site,
-    // eliminate it.
-    if (CS.isIndirectCall() && CS.getCalleeNode()->getNumReferrers() == 1 &&
-        CS.getCalleeNode()->isComplete() &&
-        CS.getCalleeNode()->getGlobalsList().empty()) {  // No useful info?
+    if (!CS.isIndirectCall()) {
+      LastCalleeNode = 0;
+    } else {
+      DSNode *Callee = CS.getCalleeNode();
+
+      // If the Callee is a useless edge, this must be an unreachable call site,
+      // eliminate it.
+      if (Callee->getNumReferrers() == 1 && Callee->isComplete() &&
+          Callee->getGlobalsList().empty()) {  // No useful info?
 #ifndef NDEBUG
-      std::cerr << "WARNING: Useless call site found.\n";
+        std::cerr << "WARNING: Useless call site found.\n";
 #endif
-      Calls.erase(OldIt);
-      ++NumDeleted;
-      continue;
+        Calls.erase(OldIt);
+        ++NumDeleted;
+        continue;
+      }
+
+      // If the last call site in the list has the same callee as this one, and
+      // if the callee contains an external function, it will never be
+      // resolvable, just merge the call sites.
+      if (!LastCalleeNode.isNull() && LastCalleeNode.getNode() == Callee) {
+        LastCalleeContainsExternalFunction =
+          nodeContainsExternalFunction(Callee);
+
+        std::list<DSCallSite>::iterator PrevIt = OldIt;
+        --PrevIt;
+        PrevIt->mergeWith(CS);
+
+        // No need to keep this call anymore.
+        Calls.erase(OldIt);
+        ++NumDeleted;
+        continue;
+      } else {
+        LastCalleeNode = Callee;
+      }
     }
 
     // If the return value or any arguments point to a void node with no
@@ -1676,6 +1698,7 @@
 #endif
 
     if (I != Calls.end() && CS == *I) {
+      LastCalleeNode = 0;
       Calls.erase(OldIt);
       ++NumDeleted;
       continue;






More information about the llvm-commits mailing list