summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis/DataStructure/DataStructure.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2004-10-30 05:41:23 +0000
committerChris Lattner <sabre@nondot.org>2004-10-30 05:41:23 +0000
commit8aa0bafe1a3075864fae60ec63e2f76f278b5ed1 (patch)
tree0ee0067f5c3fba612ebb49a97fa616b53f072dff /llvm/lib/Analysis/DataStructure/DataStructure.cpp
parentbc740090a9101a6254e8de3e8a3791a88f1cd1e7 (diff)
downloadbcm5719-llvm-8aa0bafe1a3075864fae60ec63e2f76f278b5ed1.tar.gz
bcm5719-llvm-8aa0bafe1a3075864fae60ec63e2f76f278b5ed1.zip
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. llvm-svn: 17357
Diffstat (limited to 'llvm/lib/Analysis/DataStructure/DataStructure.cpp')
-rw-r--r--llvm/lib/Analysis/DataStructure/DataStructure.cpp21
1 files changed, 12 insertions, 9 deletions
diff --git a/llvm/lib/Analysis/DataStructure/DataStructure.cpp b/llvm/lib/Analysis/DataStructure/DataStructure.cpp
index 6ddf576dd51..bd5c5607cf2 100644
--- a/llvm/lib/Analysis/DataStructure/DataStructure.cpp
+++ b/llvm/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<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...
OpenPOWER on IntegriCloud