mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 20:23:11 +01:00
Move EliminateDuplicatePHINodes() from SimplifyCFG.cpp to Local.cpp
llvm-svn: 90324
This commit is contained in:
parent
e70972f8d5
commit
ccb304105a
@ -603,3 +603,65 @@ bool llvm::OnlyUsedByDbgInfoIntrinsics(Instruction *I,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// EliminateDuplicatePHINodes - Check for and eliminate duplicate PHI
|
||||||
|
/// nodes in this block. This doesn't try to be clever about PHI nodes
|
||||||
|
/// which differ only in the order of the incoming values, but instcombine
|
||||||
|
/// orders them so it usually won't matter.
|
||||||
|
///
|
||||||
|
bool llvm::EliminateDuplicatePHINodes(BasicBlock *BB) {
|
||||||
|
bool Changed = false;
|
||||||
|
|
||||||
|
// This implementation doesn't currently consider undef operands
|
||||||
|
// specially. Theroetically, two phis which are identical except for
|
||||||
|
// one having an undef where the other doesn't could be collapsed.
|
||||||
|
|
||||||
|
// Map from PHI hash values to PHI nodes. If multiple PHIs have
|
||||||
|
// the same hash value, the element is the first PHI in the
|
||||||
|
// linked list in CollisionMap.
|
||||||
|
DenseMap<uintptr_t, PHINode *> HashMap;
|
||||||
|
|
||||||
|
// Maintain linked lists of PHI nodes with common hash values.
|
||||||
|
DenseMap<PHINode *, PHINode *> CollisionMap;
|
||||||
|
|
||||||
|
// Examine each PHI.
|
||||||
|
for (BasicBlock::iterator I = BB->begin();
|
||||||
|
PHINode *PN = dyn_cast<PHINode>(I++); ) {
|
||||||
|
// Compute a hash value on the operands. Instcombine will likely have sorted
|
||||||
|
// them, which helps expose duplicates, but we have to check all the
|
||||||
|
// operands to be safe in case instcombine hasn't run.
|
||||||
|
uintptr_t Hash = 0;
|
||||||
|
for (User::op_iterator I = PN->op_begin(), E = PN->op_end(); I != E; ++I) {
|
||||||
|
// This hash algorithm is quite weak as hash functions go, but it seems
|
||||||
|
// to do a good enough job for this particular purpose, and is very quick.
|
||||||
|
Hash ^= reinterpret_cast<uintptr_t>(static_cast<Value *>(*I));
|
||||||
|
Hash = (Hash << 7) | (Hash >> (sizeof(uintptr_t) * CHAR_BIT - 7));
|
||||||
|
}
|
||||||
|
// If we've never seen this hash value before, it's a unique PHI.
|
||||||
|
std::pair<DenseMap<uintptr_t, PHINode *>::iterator, bool> Pair =
|
||||||
|
HashMap.insert(std::make_pair(Hash, PN));
|
||||||
|
if (Pair.second) continue;
|
||||||
|
// Otherwise it's either a duplicate or a hash collision.
|
||||||
|
for (PHINode *OtherPN = Pair.first->second; ; ) {
|
||||||
|
if (OtherPN->isIdenticalTo(PN)) {
|
||||||
|
// A duplicate. Replace this PHI with its duplicate.
|
||||||
|
PN->replaceAllUsesWith(OtherPN);
|
||||||
|
PN->eraseFromParent();
|
||||||
|
Changed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// A non-duplicate hash collision.
|
||||||
|
DenseMap<PHINode *, PHINode *>::iterator I = CollisionMap.find(OtherPN);
|
||||||
|
if (I == CollisionMap.end()) {
|
||||||
|
// Set this PHI to be the head of the linked list of colliding PHIs.
|
||||||
|
PHINode *Old = Pair.first->second;
|
||||||
|
Pair.first->second = PN;
|
||||||
|
CollisionMap[PN] = Old;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Procede to the next PHI in the list.
|
||||||
|
OtherPN = I->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Changed;
|
||||||
|
}
|
||||||
|
@ -1589,69 +1589,6 @@ static bool SimplifyCondBranchToCondBranch(BranchInst *PBI, BranchInst *BI) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// EliminateDuplicatePHINodes - Check for and eliminate duplicate PHI
|
|
||||||
/// nodes in this block. This doesn't try to be clever about PHI nodes
|
|
||||||
/// which differ only in the order of the incoming values, but instcombine
|
|
||||||
/// orders them so it usually won't matter.
|
|
||||||
///
|
|
||||||
bool llvm::EliminateDuplicatePHINodes(BasicBlock *BB) {
|
|
||||||
bool Changed = false;
|
|
||||||
|
|
||||||
// This implementation doesn't currently consider undef operands
|
|
||||||
// specially. Theroetically, two phis which are identical except for
|
|
||||||
// one having an undef where the other doesn't could be collapsed.
|
|
||||||
|
|
||||||
// Map from PHI hash values to PHI nodes. If multiple PHIs have
|
|
||||||
// the same hash value, the element is the first PHI in the
|
|
||||||
// linked list in CollisionMap.
|
|
||||||
DenseMap<uintptr_t, PHINode *> HashMap;
|
|
||||||
|
|
||||||
// Maintain linked lists of PHI nodes with common hash values.
|
|
||||||
DenseMap<PHINode *, PHINode *> CollisionMap;
|
|
||||||
|
|
||||||
// Examine each PHI.
|
|
||||||
for (BasicBlock::iterator I = BB->begin();
|
|
||||||
PHINode *PN = dyn_cast<PHINode>(I++); ) {
|
|
||||||
// Compute a hash value on the operands. Instcombine will likely have sorted
|
|
||||||
// them, which helps expose duplicates, but we have to check all the
|
|
||||||
// operands to be safe in case instcombine hasn't run.
|
|
||||||
uintptr_t Hash = 0;
|
|
||||||
for (User::op_iterator I = PN->op_begin(), E = PN->op_end(); I != E; ++I) {
|
|
||||||
// This hash algorithm is quite weak as hash functions go, but it seems
|
|
||||||
// to do a good enough job for this particular purpose, and is very quick.
|
|
||||||
Hash ^= reinterpret_cast<uintptr_t>(static_cast<Value *>(*I));
|
|
||||||
Hash = (Hash << 7) | (Hash >> (sizeof(uintptr_t) * CHAR_BIT - 7));
|
|
||||||
}
|
|
||||||
// If we've never seen this hash value before, it's a unique PHI.
|
|
||||||
std::pair<DenseMap<uintptr_t, PHINode *>::iterator, bool> Pair =
|
|
||||||
HashMap.insert(std::make_pair(Hash, PN));
|
|
||||||
if (Pair.second) continue;
|
|
||||||
// Otherwise it's either a duplicate or a hash collision.
|
|
||||||
for (PHINode *OtherPN = Pair.first->second; ; ) {
|
|
||||||
if (OtherPN->isIdenticalTo(PN)) {
|
|
||||||
// A duplicate. Replace this PHI with its duplicate.
|
|
||||||
PN->replaceAllUsesWith(OtherPN);
|
|
||||||
PN->eraseFromParent();
|
|
||||||
Changed = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// A non-duplicate hash collision.
|
|
||||||
DenseMap<PHINode *, PHINode *>::iterator I = CollisionMap.find(OtherPN);
|
|
||||||
if (I == CollisionMap.end()) {
|
|
||||||
// Set this PHI to be the head of the linked list of colliding PHIs.
|
|
||||||
PHINode *Old = Pair.first->second;
|
|
||||||
Pair.first->second = PN;
|
|
||||||
CollisionMap[PN] = Old;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// Procede to the next PHI in the list.
|
|
||||||
OtherPN = I->second;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Changed;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// SimplifyCFG - This function is used to do simplification of a CFG. For
|
/// SimplifyCFG - This function is used to do simplification of a CFG. For
|
||||||
/// example, it adjusts branches to branches to eliminate the extra hop, it
|
/// example, it adjusts branches to branches to eliminate the extra hop, it
|
||||||
/// eliminates unreachable basic blocks, and does other "peephole" optimization
|
/// eliminates unreachable basic blocks, and does other "peephole" optimization
|
||||||
|
Loading…
Reference in New Issue
Block a user