random cleanups, no functionality change.

llvm-svn: 60779
This commit is contained in:
Chris Lattner 2008-12-09 19:21:47 +00:00
parent 2e41b0e6e7
commit 0a5a8d54a9
1 changed files with 26 additions and 14 deletions

View File

@ -802,21 +802,28 @@ Value *GVN::GetValueForBlock(BasicBlock *BB, LoadInst* orig,
if (!DT->isReachableFromEntry(BB)) if (!DT->isReachableFromEntry(BB))
return Phis[BB] = UndefValue::get(orig->getType()); return Phis[BB] = UndefValue::get(orig->getType());
BasicBlock* singlePred = BB->getSinglePredecessor(); if (BasicBlock *Pred = BB->getSinglePredecessor()) {
if (singlePred) { Value *ret = GetValueForBlock(Pred, orig, Phis);
Value *ret = GetValueForBlock(singlePred, orig, Phis);
Phis[BB] = ret; Phis[BB] = ret;
return ret; return ret;
} }
// Get the number of predecessors of this block so we can reserve space later.
// If there is already a PHI in it, use the #preds from it, otherwise count.
// Getting it from the PHI is constant time.
unsigned NumPreds;
if (PHINode *ExistingPN = dyn_cast<PHINode>(BB->begin()))
NumPreds = ExistingPN->getNumIncomingValues();
else
NumPreds = std::distance(pred_begin(BB), pred_end(BB));
// Otherwise, the idom is the loop, so we need to insert a PHI node. Do so // Otherwise, the idom is the loop, so we need to insert a PHI node. Do so
// now, then get values to fill in the incoming values for the PHI. // now, then get values to fill in the incoming values for the PHI.
PHINode *PN = PHINode::Create(orig->getType(), orig->getName()+".rle", PHINode *PN = PHINode::Create(orig->getType(), orig->getName()+".rle",
BB->begin()); BB->begin());
PN->reserveOperandSpace(std::distance(pred_begin(BB), pred_end(BB))); PN->reserveOperandSpace(NumPreds);
if (Phis.count(BB) == 0) Phis.insert(std::make_pair(BB, PN));
Phis.insert(std::make_pair(BB, PN));
// Fill in the incoming values for the block. // Fill in the incoming values for the block.
for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) { for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) {
@ -1147,11 +1154,8 @@ bool GVN::processLoad(LoadInst *L, SmallVectorImpl<Instruction*> &toErase) {
return false; return false;
// If it is defined in another block, try harder. // If it is defined in another block, try harder.
if (dep.isNonLocal()) { if (dep.isNonLocal())
if (L->getParent() == &L->getParent()->getParent()->getEntryBlock())
return false;
return processNonLocalLoad(L, toErase); return processNonLocalLoad(L, toErase);
}
Instruction *DepInst = dep.getInst(); Instruction *DepInst = dep.getInst();
if (StoreInst *DepSI = dyn_cast<StoreInst>(DepInst)) { if (StoreInst *DepSI = dyn_cast<StoreInst>(DepInst)) {
@ -1243,8 +1247,7 @@ bool GVN::processInstruction(Instruction *I,
if (constVal) { if (constVal) {
for (PhiMapType::iterator PI = phiMap.begin(), PE = phiMap.end(); for (PhiMapType::iterator PI = phiMap.begin(), PE = phiMap.end();
PI != PE; ++PI) PI != PE; ++PI)
if (PI->second.count(p)) PI->second.erase(p);
PI->second.erase(p);
p->replaceAllUsesWith(constVal); p->replaceAllUsesWith(constVal);
toErase.push_back(p); toErase.push_back(p);
@ -1296,9 +1299,13 @@ bool GVN::runOnFunction(Function& F) {
changed |= removedBlock; changed |= removedBlock;
} }
unsigned Iteration = 0;
while (shouldContinue) { while (shouldContinue) {
DEBUG(cerr << "GVN iteration: " << Iteration << "\n");
shouldContinue = iterateOnFunction(F); shouldContinue = iterateOnFunction(F);
changed |= shouldContinue; changed |= shouldContinue;
++Iteration;
} }
if (EnablePRE) { if (EnablePRE) {
@ -1308,6 +1315,10 @@ bool GVN::runOnFunction(Function& F) {
changed |= PREChanged; changed |= PREChanged;
} }
} }
// FIXME: Should perform GVN again after PRE does something. PRE can move
// computations into blocks where they become fully redundant. Note that
// we can't do this until PRE's critical edge splitting updates memdep.
// Actually, when this happens, we should just fully integrate PRE into GVN.
cleanupGlobalSets(); cleanupGlobalSets();
@ -1317,6 +1328,8 @@ bool GVN::runOnFunction(Function& F) {
bool GVN::processBlock(DomTreeNode* DTN) { bool GVN::processBlock(DomTreeNode* DTN) {
BasicBlock* BB = DTN->getBlock(); BasicBlock* BB = DTN->getBlock();
// FIXME: Kill off toErase by doing erasing eagerly in a helper function (and
// incrementing BI before processing an instruction).
SmallVector<Instruction*, 8> toErase; SmallVector<Instruction*, 8> toErase;
bool changed_function = false; bool changed_function = false;
@ -1348,13 +1361,12 @@ bool GVN::processBlock(DomTreeNode* DTN) {
MD->removeInstruction(*I); MD->removeInstruction(*I);
(*I)->eraseFromParent(); (*I)->eraseFromParent();
} }
toErase.clear();
if (AtStart) if (AtStart)
BI = BB->begin(); BI = BB->begin();
else else
++BI; ++BI;
toErase.clear();
} }
return changed_function; return changed_function;