X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTransforms%2FScalar%2FGVN.cpp;h=edd11e8e493b0dff793a18e7c4c49f80e1799925;hb=a37226af81bf10ba9f23ef065d8efc58877d3dc3;hp=1f3ecfa2b195152bdabe57bbaed930ae905a626e;hpb=4b55c3b0f17cdf548e45899ba069e454c6342bf1;p=oota-llvm.git diff --git a/lib/Transforms/Scalar/GVN.cpp b/lib/Transforms/Scalar/GVN.cpp index 1f3ecfa2b19..edd11e8e493 100644 --- a/lib/Transforms/Scalar/GVN.cpp +++ b/lib/Transforms/Scalar/GVN.cpp @@ -642,6 +642,10 @@ namespace { DenseMap availableOut; + typedef DenseMap > PhiMapType; + PhiMapType phiMap; + + // This transformation requires dominator postdominator info virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesCFG(); @@ -726,21 +730,23 @@ Value *GVN::GetValueForBlock(BasicBlock *BB, LoadInst* orig, bool top_level) { // If we have already computed this value, return the previously computed val. - Value *V = Phis[BB]; - if (V && ! top_level) return V; + DenseMap::iterator V = Phis.find(BB); + if (V != Phis.end() && !top_level) return V->second; BasicBlock* singlePred = BB->getSinglePredecessor(); if (singlePred) { - V = GetValueForBlock(singlePred, orig, Phis); - Phis[BB] = V; - return V; + Value *ret = GetValueForBlock(singlePred, orig, Phis); + Phis[BB] = ret; + return ret; } // 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. PHINode *PN = new PHINode(orig->getType(), orig->getName()+".rle", BB->begin()); PN->reserveOperandSpace(std::distance(pred_begin(BB), pred_end(BB))); - Phis[BB] = PN; + + if (Phis.count(BB) == 0) + Phis.insert(std::make_pair(BB, PN)); bool all_same = true; Value* first = 0; @@ -778,6 +784,7 @@ Value *GVN::GetValueForBlock(BasicBlock *BB, LoadInst* orig, return first; } + phiMap[orig->getPointerOperand()].insert(PN); return PN; } @@ -789,6 +796,7 @@ bool GVN::processNonLocalLoad(LoadInst* L, MD.getNonLocalDependency(L, deps); DenseMap repl; + for (DenseMap::iterator I = deps.begin(), E = deps.end(); I != E; ++I) if (I->second == MemoryDependenceAnalysis::None) { @@ -797,24 +805,40 @@ bool GVN::processNonLocalLoad(LoadInst* L, continue; }else if (StoreInst* S = dyn_cast(I->second)) { if (S->getPointerOperand() == L->getPointerOperand()) - repl.insert(std::make_pair(I->first, S->getOperand(0))); + repl[I->first] = S->getOperand(0); else return false; } else if (LoadInst* LD = dyn_cast(I->second)) { if (LD->getPointerOperand() == L->getPointerOperand()) - repl.insert(std::make_pair(I->first, LD)); + repl[I->first] = LD; else return false; } else { return false; } + SmallPtrSet& p = phiMap[L->getPointerOperand()]; + for (SmallPtrSet::iterator I = p.begin(), E = p.end(); + I != E; ++I) { + if ((*I)->getParent() == L->getParent()) { + MD.removeInstruction(L); + L->replaceAllUsesWith(*I); + toErase.push_back(L); + NumGVNLoad++; + + return true; + } else { + repl.insert(std::make_pair((*I)->getParent(), *I)); + } + } + SmallPtrSet visited; Value* v = GetValueForBlock(L->getParent(), L, repl, true); MD.removeInstruction(L); L->replaceAllUsesWith(v); toErase.push_back(L); + NumGVNLoad++; return true; } @@ -915,6 +939,7 @@ bool GVN::runOnFunction(Function &F) { // Clean out global sets from any previous functions VN.clear(); availableOut.clear(); + phiMap.clear(); bool changed_function = false;