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
This commit is contained in:
Chris Lattner 2004-10-30 05:41:23 +00:00
parent 62c3a95051
commit 857eb0697f

View 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...