Newer
Older
Owen Anderson
committed
// Create a PHI to make the value available in this block.
pred_iterator PB = pred_begin(CurrentBlock), PE = pred_end(CurrentBlock);
PHINode* Phi = PHINode::Create(CurInst->getType(), std::distance(PB, PE),
Chris Lattner
committed
CurInst->getName() + ".pre-phi",
Owen Anderson
committed
CurrentBlock->begin());
for (pred_iterator PI = PB; PI != PE; ++PI) {
BasicBlock *P = *PI;
Phi->addIncoming(predMap[P], P);
}
Owen Anderson
committed
addToLeaderTable(ValNo, Phi, CurrentBlock);
Chris Lattner
committed
CurInst->replaceAllUsesWith(Phi);
Owen Anderson
committed
if (Phi->getType()->isPointerTy()) {
// Because we have added a PHI-use of the pointer value, it has now
// "escaped" from alias analysis' perspective. We need to inform
// AA of this.
for (unsigned ii = 0, ee = Phi->getNumIncomingValues(); ii != ee; ++ii)
VN.getAliasAnalysis()->addEscapingUse(Phi->getOperandUse(2*ii));
if (MD)
MD->invalidateCachedPointerInfo(Phi);
}
Chris Lattner
committed
VN.erase(CurInst);
Owen Anderson
committed
removeFromLeaderTable(ValNo, CurInst, CurrentBlock);
DEBUG(dbgs() << "GVN PRE removed: " << *CurInst << '\n');
if (MD) MD->removeInstruction(CurInst);
Chris Lattner
committed
CurInst->eraseFromParent();
Chris Lattner
committed
Changed = true;
Owen Anderson
committed
}
}
if (splitCriticalEdges())
Changed = true;
return Changed;
}
/// splitCriticalEdges - Split critical edges found during the previous
/// iteration that may enable further optimization.
bool GVN::splitCriticalEdges() {
if (toSplit.empty())
return false;
do {
std::pair<TerminatorInst*, unsigned> Edge = toSplit.pop_back_val();
SplitCriticalEdge(Edge.first, Edge.second, this);
} while (!toSplit.empty());
if (MD) MD->invalidateCachedPredecessors();
Owen Anderson
committed
}
/// iterateOnFunction - Executes one iteration of GVN
Owen Anderson
committed
Owen Anderson
committed
// Top-down walk of the dominator tree
#if 0
// Needed for value numbering with phi construction to work.
Owen Anderson
committed
ReversePostOrderTraversal<Function*> RPOT(&F);
for (ReversePostOrderTraversal<Function*>::rpo_iterator RI = RPOT.begin(),
RE = RPOT.end(); RI != RE; ++RI)
Changed |= processBlock(*RI);
#else
for (df_iterator<DomTreeNode*> DI = df_begin(DT->getRootNode()),
DE = df_end(DT->getRootNode()); DI != DE; ++DI)
Changed |= processBlock(DI->getBlock());
#endif
Owen Anderson
committed
}
void GVN::cleanupGlobalSets() {
VN.clear();
Owen Anderson
committed
TableAllocator.Reset();
Bill Wendling
committed
/// verifyRemoved - Verify that the specified instruction does not occur in our
/// internal data structures.
void GVN::verifyRemoved(const Instruction *Inst) const {
VN.verifyRemoved(Inst);
// Walk through the value number scope to make sure the instruction isn't
// ferreted away in it.
Owen Anderson
committed
for (DenseMap<uint32_t, LeaderTableEntry>::const_iterator
I = LeaderTable.begin(), E = LeaderTable.end(); I != E; ++I) {
Owen Anderson
committed
const LeaderTableEntry *Node = &I->second;
Owen Anderson
committed
assert(Node->Val != Inst && "Inst still in value numbering scope!");
Owen Anderson
committed
Owen Anderson
committed
while (Node->Next) {
Node = Node->Next;
assert(Node->Val != Inst && "Inst still in value numbering scope!");
}
}