Newer
Older
Owen Anderson
committed
unsigned num = VN.lookup_or_add(I);
Owen Anderson
committed
if (PHINode* p = dyn_cast<PHINode>(I)) {
Value* constVal = CollapsePhi(p);
Owen Anderson
committed
if (constVal) {
for (PhiMapType::iterator PI = phiMap.begin(), PE = phiMap.end();
PI != PE; ++PI)
if (PI->second.count(p))
PI->second.erase(p);
Owen Anderson
committed
p->replaceAllUsesWith(constVal);
toErase.push_back(p);
Owen Anderson
committed
}
// Perform value-number based elimination
Owen Anderson
committed
} else if (currAvail.test(num)) {
Owen Anderson
committed
Value* repl = find_leader(currAvail, num);
Owen Anderson
committed
// Remove it!
MemoryDependenceAnalysis& MD = getAnalysis<MemoryDependenceAnalysis>();
MD.removeInstruction(I);
Owen Anderson
committed
Owen Anderson
committed
I->replaceAllUsesWith(repl);
toErase.push_back(I);
return true;
} else if (!I->isTerminator()) {
currAvail.set(num);
currAvail.insert(I);
}
return false;
}
// GVN::runOnFunction - This is the main transformation entry point for a
// function.
//
VN.setAliasAnalysis(&getAnalysis<AliasAnalysis>());
VN.setMemDep(&getAnalysis<MemoryDependenceAnalysis>());
VN.setDomTree(&getAnalysis<DominatorTree>());
bool changed = false;
bool shouldContinue = true;
while (shouldContinue) {
shouldContinue = iterateOnFunction(F);
changed |= shouldContinue;
}
return changed;
}
// GVN::iterateOnFunction - Executes one iteration of GVN
bool GVN::iterateOnFunction(Function &F) {
Owen Anderson
committed
// Clean out global sets from any previous functions
VN.clear();
availableOut.clear();
Owen Anderson
committed
bool changed_function = false;
DominatorTree &DT = getAnalysis<DominatorTree>();
SmallVector<Instruction*, 8> toErase;
DenseMap<Value*, LoadInst*> lastSeenLoad;
Owen Anderson
committed
DenseMap<DomTreeNode*, size_t> numChildrenVisited;
Owen Anderson
committed
// Top-down walk of the dominator tree
for (df_iterator<DomTreeNode*> DI = df_begin(DT.getRootNode()),
E = df_end(DT.getRootNode()); DI != E; ++DI) {
Owen Anderson
committed
// Get the set to update for this block
ValueNumberedSet& currAvail = availableOut[DI->getBlock()];
lastSeenLoad.clear();
Owen Anderson
committed
BasicBlock* BB = DI->getBlock();
// A block inherits AVAIL_OUT from its dominator
Owen Anderson
committed
if (DI->getIDom() != 0) {
Owen Anderson
committed
currAvail = availableOut[DI->getIDom()->getBlock()];
Owen Anderson
committed
numChildrenVisited[DI->getIDom()]++;
if (numChildrenVisited[DI->getIDom()] == DI->getIDom()->getNumChildren()) {
availableOut.erase(DI->getIDom()->getBlock());
numChildrenVisited.erase(DI->getIDom());
}
}
Owen Anderson
committed
for (BasicBlock::iterator BI = BB->begin(), BE = BB->end();
BI != BE;) {
changed_function |= processInstruction(BI, currAvail,
lastSeenLoad, toErase);
if (toErase.empty()) {
++BI;
continue;
}
// If we need some instructions deleted, do it now.
NumGVNInstr += toErase.size();
// Avoid iterator invalidation.
bool AtStart = BI == BB->begin();
if (!AtStart)
--BI;
Owen Anderson
committed
for (SmallVector<Instruction*, 4>::iterator I = toErase.begin(),
(*I)->eraseFromParent();
Owen Anderson
committed
if (AtStart)
BI = BB->begin();
else
++BI;
Owen Anderson
committed
}
}
return changed_function;
}