mirror of
https://github.com/RPCS3/llvm.git
synced 2025-04-01 21:03:54 +00:00
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:
parent
62c3a95051
commit
857eb0697f
@ -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...
|
||||
|
Loading…
x
Reference in New Issue
Block a user