Use cached information that has already been computed to make clean() simpler and faster. This is a small speedup on most cases.

llvm-svn: 37761
This commit is contained in:
Owen Anderson 2007-06-27 17:38:29 +00:00
parent 59e5e118ac
commit 7dae8efcf2
1 changed files with 31 additions and 52 deletions

View File

@ -429,7 +429,7 @@ namespace {
// Helper fuctions // Helper fuctions
// FIXME: eliminate or document these better // FIXME: eliminate or document these better
void dump(const SmallPtrSet<Value*, 32>& s) const; void dump(const SmallPtrSet<Value*, 32>& s) const;
void clean(SmallPtrSet<Value*, 32>& set); void clean(SmallPtrSet<Value*, 32>& set, BitVector& presentInSet);
Value* find_leader(SmallPtrSet<Value*, 32>& vals, Value* find_leader(SmallPtrSet<Value*, 32>& vals,
uint32_t v); uint32_t v);
Value* phi_translate(Value* V, BasicBlock* pred, BasicBlock* succ); Value* phi_translate(Value* V, BasicBlock* pred, BasicBlock* succ);
@ -671,7 +671,7 @@ bool GVNPRE::dependsOnInvoke(Value* V) {
/// clean - Remove all non-opaque values from the set whose operands are not /// clean - Remove all non-opaque values from the set whose operands are not
/// themselves in the set, as well as all values that depend on invokes (see /// themselves in the set, as well as all values that depend on invokes (see
/// above) /// above)
void GVNPRE::clean(SmallPtrSet<Value*, 32>& set) { void GVNPRE::clean(SmallPtrSet<Value*, 32>& set, BitVector& presentInSet) {
std::vector<Value*> worklist; std::vector<Value*> worklist;
worklist.reserve(set.size()); worklist.reserve(set.size());
topo_sort(set, worklist); topo_sort(set, worklist);
@ -685,69 +685,43 @@ void GVNPRE::clean(SmallPtrSet<Value*, 32>& set) {
User* U = cast<User>(v); User* U = cast<User>(v);
bool lhsValid = !isa<Instruction>(U->getOperand(0)); bool lhsValid = !isa<Instruction>(U->getOperand(0));
if (!lhsValid) lhsValid |= presentInSet.test(VN.lookup(U->getOperand(0)));
for (SmallPtrSet<Value*, 32>::iterator I = set.begin(), E = set.end();
I != E; ++I)
if (VN.lookup(*I) == VN.lookup(U->getOperand(0))) {
lhsValid = true;
break;
}
if (lhsValid) if (lhsValid)
lhsValid = !dependsOnInvoke(U->getOperand(0)); lhsValid = !dependsOnInvoke(U->getOperand(0));
bool rhsValid = !isa<Instruction>(U->getOperand(1)); bool rhsValid = !isa<Instruction>(U->getOperand(1));
if (!rhsValid) rhsValid |= presentInSet.test(VN.lookup(U->getOperand(1)));
for (SmallPtrSet<Value*, 32>::iterator I = set.begin(), E = set.end();
I != E; ++I)
if (VN.lookup(*I) == VN.lookup(U->getOperand(1))) {
rhsValid = true;
break;
}
if (rhsValid) if (rhsValid)
rhsValid = !dependsOnInvoke(U->getOperand(1)); rhsValid = !dependsOnInvoke(U->getOperand(1));
if (!lhsValid || !rhsValid) if (!lhsValid || !rhsValid) {
set.erase(U); set.erase(U);
presentInSet.flip(VN.lookup(U));
}
// Handle ternary ops // Handle ternary ops
} else if (isa<ShuffleVectorInst>(v) || isa<InsertElementInst>(v)) { } else if (isa<ShuffleVectorInst>(v) || isa<InsertElementInst>(v)) {
User* U = cast<User>(v); User* U = cast<User>(v);
bool lhsValid = !isa<Instruction>(U->getOperand(0)); bool lhsValid = !isa<Instruction>(U->getOperand(0));
if (!lhsValid) lhsValid |= presentInSet.test(VN.lookup(U->getOperand(0)));
for (SmallPtrSet<Value*, 32>::iterator I = set.begin(), E = set.end();
I != E; ++I)
if (VN.lookup(*I) == VN.lookup(U->getOperand(0))) {
lhsValid = true;
break;
}
if (lhsValid) if (lhsValid)
lhsValid = !dependsOnInvoke(U->getOperand(0)); lhsValid = !dependsOnInvoke(U->getOperand(0));
bool rhsValid = !isa<Instruction>(U->getOperand(1)); bool rhsValid = !isa<Instruction>(U->getOperand(1));
if (!rhsValid) rhsValid |= presentInSet.test(VN.lookup(U->getOperand(1)));
for (SmallPtrSet<Value*, 32>::iterator I = set.begin(), E = set.end();
I != E; ++I)
if (VN.lookup(*I) == VN.lookup(U->getOperand(1))) {
rhsValid = true;
break;
}
if (rhsValid) if (rhsValid)
rhsValid = !dependsOnInvoke(U->getOperand(1)); rhsValid = !dependsOnInvoke(U->getOperand(1));
bool thirdValid = !isa<Instruction>(U->getOperand(2)); bool thirdValid = !isa<Instruction>(U->getOperand(2));
if (!thirdValid) thirdValid |= presentInSet.test(VN.lookup(U->getOperand(2)));
for (SmallPtrSet<Value*, 32>::iterator I = set.begin(), E = set.end();
I != E; ++I)
if (VN.lookup(*I) == VN.lookup(U->getOperand(2))) {
thirdValid = true;
break;
}
if (thirdValid) if (thirdValid)
thirdValid = !dependsOnInvoke(U->getOperand(2)); thirdValid = !dependsOnInvoke(U->getOperand(2));
if (!lhsValid || !rhsValid || !thirdValid) if (!lhsValid || !rhsValid || !thirdValid) {
set.erase(U); set.erase(U);
presentInSet.flip(VN.lookup(U));
}
} }
} }
} }
@ -1042,17 +1016,18 @@ unsigned GVNPRE::buildsets_anticin(BasicBlock* BB,
if (defer) if (defer)
return 0; return 0;
anticIn.clear(); anticIn.clear();
BitVector numbers(VN.size()); BitVector numbers(VN.size());
for (SmallPtrSet<Value*, 32>::iterator I = anticOut.begin(), for (SmallPtrSet<Value*, 32>::iterator I = anticOut.begin(),
E = anticOut.end(); I != E; ++I) { E = anticOut.end(); I != E; ++I) {
anticIn.insert(*I);
unsigned num = VN.lookup_or_add(*I); unsigned num = VN.lookup_or_add(*I);
numbers.resize(VN.size()); numbers.resize(VN.size());
numbers.set(num);
if (isa<Instruction>(*I)) {
anticIn.insert(*I);
numbers.set(num);
}
} }
for (SmallPtrSet<Value*, 32>::iterator I = currExps.begin(), for (SmallPtrSet<Value*, 32>::iterator I = currExps.begin(),
E = currExps.end(); I != E; ++I) { E = currExps.end(); I != E; ++I) {
@ -1063,19 +1038,17 @@ unsigned GVNPRE::buildsets_anticin(BasicBlock* BB,
} }
for (SmallPtrSet<Value*, 32>::iterator I = currTemps.begin(), for (SmallPtrSet<Value*, 32>::iterator I = currTemps.begin(),
E = currTemps.end(); I != E; ++I) E = currTemps.end(); I != E; ++I) {
anticIn.erase(*I); anticIn.erase(*I);
numbers.flip(VN.lookup(*I));
}
clean(anticIn); clean(anticIn, numbers);
anticOut.clear();
if (old != anticIn.size()) { if (old != anticIn.size())
DOUT << "OLD: " << old << "\n";
DOUT << "NEW: " << anticIn.size() << "\n";
DOUT << "ANTIC_OUT: " << anticOut.size() << "\n";
anticOut.clear();
return 2; return 2;
} else else
anticOut.clear();
return 1; return 1;
} }
@ -1392,6 +1365,12 @@ bool GVNPRE::runOnFunction(Function &F) {
// This phase calculates the AVAIL_OUT and ANTIC_IN sets // This phase calculates the AVAIL_OUT and ANTIC_IN sets
buildsets(F); buildsets(F);
for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI) {
DOUT << "ANTIC_IN: " << FI->getName() << "\n";
dump(anticipatedIn[FI]);
DOUT << "\n\n";
}
// Phase 2: Insert // Phase 2: Insert
// This phase inserts values to make partially redundant values // This phase inserts values to make partially redundant values
// fully redundant // fully redundant