From 857eb0697f79d3a25d55876fa0d7f4481ff0be67 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 30 Oct 2004 05:41:23 +0000 Subject: [PATCH] Fix three bugs: 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 | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/lib/Analysis/DataStructure/DataStructure.cpp b/lib/Analysis/DataStructure/DataStructure.cpp index 6ddf576dd51..bd5c5607cf2 100644 --- a/lib/Analysis/DataStructure/DataStructure.cpp +++ b/lib/Analysis/DataStructure/DataStructure.cpp @@ -1491,7 +1491,7 @@ static inline void killIfUselessEdge(DSNodeHandle &Edge) { static inline bool nodeContainsExternalFunction(const DSNode *N) { const std::vector &Globals = N->getGlobals(); for (unsigned i = 0, e = Globals.size(); i != e; ++i) - if (Globals[i]->isExternal()) + if (Globals[i]->isExternal() && isa(Globals[i])) return true; return false; } @@ -1507,6 +1507,9 @@ static void removeIdenticalCalls(std::vector &Calls) { Function *LastCalleeFunc = 0; unsigned NumDuplicateCalls = 0; bool LastCalleeContainsExternalFunction = false; + + std::vector CallsToDelete; + for (unsigned i = 0; i != Calls.size(); ++i) { DSCallSite &CS = Calls[i]; @@ -1518,9 +1521,7 @@ static void removeIdenticalCalls(std::vector &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 &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 &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... -- 2.11.0