mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-04 17:56:53 +00:00
Completely rewrite support for the Value::use_* list. Now, all operations on
this list (except use_size()) are constant time. Before the killUse method (used whenever something stopped using a value) was linear time, and thus very very slow for large programs. This speeds GCCAS up _substantially_ on large programs: almost 2x for 176.gcc: 176.gcc: 77.07s -> 37.38s 177.mesa: 7.59s -> 5.57s 252.eon: 21.02s -> 19.52s (*) 253.perlbmk: 11.40s -> 13.05s 254.gap: 7.25s -> 7.42s 252.eon would speed up a whole lot more, but optimization time is being dominated by the inlining pass, which needs to be fixed. llvm-svn: 9160
This commit is contained in:
parent
0493113344
commit
09ef1749f7
@ -35,7 +35,7 @@ Value::~Value() {
|
||||
//
|
||||
if (Uses.begin() != Uses.end()) {
|
||||
std::cerr << "While deleting: " << *Ty << "%" << Name << "\n";
|
||||
for (use_const_iterator I = Uses.begin(); I != Uses.end(); ++I)
|
||||
for (use_const_iterator I = Uses.begin(), E = Uses.end(); I != E; ++I)
|
||||
std::cerr << "Use still stuck around after Def is destroyed:"
|
||||
<< **I << "\n";
|
||||
}
|
||||
@ -47,25 +47,6 @@ Value::~Value() {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Value::replaceAllUsesWith(Value *New) {
|
||||
assert(New && "Value::replaceAllUsesWith(<null>) is invalid!");
|
||||
assert(New != this && "this->replaceAllUsesWith(this) is NOT valid!");
|
||||
assert(New->getType() == getType() &&
|
||||
"replaceAllUses of value with new value of different type!");
|
||||
while (!Uses.empty()) {
|
||||
User *Use = Uses.back();
|
||||
// Must handle Constants specially, we cannot call replaceUsesOfWith on a
|
||||
// constant!
|
||||
if (Constant *C = dyn_cast<Constant>(Use)) {
|
||||
C->replaceUsesOfWithOnConstant(this, New);
|
||||
} else {
|
||||
Use->replaceUsesOfWith(this, New);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// uncheckedReplaceAllUsesWith - This is exactly the same as replaceAllUsesWith,
|
||||
// except that it doesn't have all of the asserts. The asserts fail because we
|
||||
// are half-way done resolving types, which causes some types to exist as two
|
||||
@ -74,31 +55,24 @@ void Value::replaceAllUsesWith(Value *New) {
|
||||
//
|
||||
void Value::uncheckedReplaceAllUsesWith(Value *New) {
|
||||
while (!Uses.empty()) {
|
||||
User *Use = Uses.back();
|
||||
Use &U = Uses.back();
|
||||
// Must handle Constants specially, we cannot call replaceUsesOfWith on a
|
||||
// constant!
|
||||
if (Constant *C = dyn_cast<Constant>(Use)) {
|
||||
C->replaceUsesOfWithOnConstant(this, New, true);
|
||||
if (Constant *C = dyn_cast<Constant>(U.getUser())) {
|
||||
C->replaceUsesOfWithOnConstant(this, New);
|
||||
} else {
|
||||
Use->replaceUsesOfWith(this, New);
|
||||
U.set(New);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Value::replaceAllUsesWith(Value *New) {
|
||||
assert(New && "Value::replaceAllUsesWith(<null>) is invalid!");
|
||||
assert(New != this && "this->replaceAllUsesWith(this) is NOT valid!");
|
||||
assert(New->getType() == getType() &&
|
||||
"replaceAllUses of value with new value of different type!");
|
||||
|
||||
void Value::killUse(User *U) {
|
||||
assert(U != 0 && "Null users are not allowed!");
|
||||
unsigned i;
|
||||
|
||||
// Scan backwards through the uses list looking for the user. We do this
|
||||
// because vectors like to be accessed on the end. This is incredibly
|
||||
// important from a performance perspective.
|
||||
for (i = Uses.size()-1; Uses[i] != U; --i)
|
||||
/* empty */;
|
||||
|
||||
assert(i < Uses.size() && "Use not in uses list!!");
|
||||
Uses[i] = Uses.back();
|
||||
Uses.pop_back();
|
||||
uncheckedReplaceAllUsesWith(New);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
Loading…
Reference in New Issue
Block a user