Newer
Older
else
break;
}
if (v == dep) {
// If this load depends directly on an allocation, there isn't
// anything stored there; therefore, we can optimize this load
// to undef.
MD.removeInstruction(L);
L->replaceAllUsesWith(UndefValue::get(L->getType()));
toErase.push_back(L);
deletedLoad = true;
NumGVNLoad++;
}
}
Owen Anderson
committed
if (!deletedLoad)
last = L;
return deletedLoad;
}
Owen Anderson
committed
/// processInstruction - When calculating availability, handle an instruction
Owen Anderson
committed
/// by inserting it into the appropriate sets
Chris Lattner
committed
bool GVN::processInstruction(Instruction *I, ValueNumberedSet &currAvail,
DenseMap<Value*, LoadInst*> &lastSeenLoad,
SmallVectorImpl<Instruction*> &toErase) {
if (LoadInst* L = dyn_cast<LoadInst>(I))
Owen Anderson
committed
return processLoad(L, lastSeenLoad, toErase);
Chris Lattner
committed
Owen Anderson
committed
// Allocations are always uniquely numbered, so we can save time and memory
// by fast failing them.
if (isa<AllocationInst>(I))
return false;
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;
}