OSDN Git Service

Fix three bugs:
authorChris Lattner <sabre@nondot.org>
Sat, 30 Oct 2004 05:41:23 +0000 (05:41 +0000)
committerChris Lattner <sabre@nondot.org>
Sat, 30 Oct 2004 05:41:23 +0000 (05:41 +0000)
 1. Calls to external global VARIABLES should not be treated as a call to an
    external function
 2. Efficiently deleting an element from a vector by using std::swap with
    the back, then pop_back is NOT a good way to keep the vector sorted.
 3. Our hope of having stuff get deleted by making them redundant just won't
    work.  In particular, if we have three calls in sequence that should be
    merged: A, B, C   first we unify B into A.  To be sure that they appeared
    identical (so B would be erased) we set B = A.  On the next step, we
    unified C into A and set C = A.  Unfortunately, this is no guarantee that
    C = B, so we would fail to delete the dead call.  Switch to a more
    explicit scheme.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@17357 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/DataStructure/DataStructure.cpp

index 6ddf576..bd5c560 100644 (file)
@@ -1491,7 +1491,7 @@ static inline void killIfUselessEdge(DSNodeHandle &Edge) {
 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())
+    if (Globals[i]->isExternal() && isa<Function>(Globals[i]))
       return true;
   return false;
 }
@@ -1507,6 +1507,9 @@ static void removeIdenticalCalls(std::vector<DSCallSite> &Calls) {
   Function *LastCalleeFunc = 0;
   unsigned NumDuplicateCalls = 0;
   bool LastCalleeContainsExternalFunction = false;
+
+  std::vector<unsigned> CallsToDelete;
+
   for (unsigned i = 0; i != Calls.size(); ++i) {
     DSCallSite &CS = Calls[i];
 
@@ -1518,9 +1521,7 @@ static void removeIdenticalCalls(std::vector<DSCallSite> &Calls) {
 #ifndef NDEBUG
       std::cerr << "WARNING: Useless call site found.\n";
 #endif
-      CS.swap(Calls.back());
-      Calls.pop_back();
-      --i;
+      CallsToDelete.push_back(i);
     } else {
       // If the return value or any arguments point to a void node with no
       // information at all in it, and the call node is the only node to point
@@ -1563,11 +1564,8 @@ static void removeIdenticalCalls(std::vector<DSCallSite> &Calls) {
           DSCallSite &OCS = Calls[i-1];
           OCS.mergeWith(CS);
           
-          // The node will now be eliminated as a duplicate!
-          if (CS.getNumPtrArgs() < OCS.getNumPtrArgs())
-            CS = OCS;
-          else if (CS.getNumPtrArgs() > OCS.getNumPtrArgs())
-            OCS = CS;
+          // No need to keep this call anymore.
+          CallsToDelete.push_back(i);
         }
 #endif
       } else {
@@ -1583,6 +1581,11 @@ static void removeIdenticalCalls(std::vector<DSCallSite> &Calls) {
     }
   }
 #endif
+
+  unsigned NumDeleted = 0;
+  for (unsigned i = 0, e = CallsToDelete.size(); i != e; ++i)
+    Calls.erase(Calls.begin()+CallsToDelete[i]-NumDeleted++);
+
   Calls.erase(std::unique(Calls.begin(), Calls.end()), Calls.end());
 
   // Track the number of call nodes merged away...