diff --git a/lib/Analysis/LoadValueNumbering.cpp b/lib/Analysis/LoadValueNumbering.cpp index 2c2b136d2df..354eb8d5602 100644 --- a/lib/Analysis/LoadValueNumbering.cpp +++ b/lib/Analysis/LoadValueNumbering.cpp @@ -284,43 +284,13 @@ void LoadVN::getEqualNumberNodes(Value *V, if (LI->isVolatile()) return getAnalysis().getEqualNumberNodes(V, RetVals); - Value *PointerSource = LI->getOperand(0); + Value *LoadPtr = LI->getOperand(0); BasicBlock *LoadBB = LI->getParent(); Function *F = LoadBB->getParent(); - - // Now that we know the set of equivalent source pointers for the load - // instruction, look to see if there are any load or store candidates that are - // identical. - // - std::map > CandidateLoads; - std::map > CandidateStores; - - for (Value::use_iterator UI = PointerSource->use_begin(), - UE = PointerSource->use_end(); UI != UE; ++UI) - if (LoadInst *Cand = dyn_cast(*UI)) {// Is a load of source? - if (Cand->getParent()->getParent() == F && // In the same function? - Cand != LI && !Cand->isVolatile()) // Not LI itself? - CandidateLoads[Cand->getParent()].push_back(Cand); // Got one... - } else if (StoreInst *Cand = dyn_cast(*UI)) { - if (Cand->getParent()->getParent() == F && !Cand->isVolatile() && - Cand->getOperand(1) == PointerSource) // It's a store THROUGH the ptr. - CandidateStores[Cand->getParent()].push_back(Cand); - } - - // Get alias analysis & dominators. - AliasAnalysis &AA = getAnalysis(); - DominatorSet &DomSetInfo = getAnalysis(); - Value *LoadPtr = LI->getOperand(0); + // Find out how many bytes of memory are loaded by the load instruction... unsigned LoadSize = getAnalysis().getTypeSize(LI->getType()); - - // Find all of the candidate loads and stores that are in the same block as - // the defining instruction. - std::set Instrs; - Instrs.insert(CandidateLoads[LoadBB].begin(), CandidateLoads[LoadBB].end()); - CandidateLoads.erase(LoadBB); - Instrs.insert(CandidateStores[LoadBB].begin(), CandidateStores[LoadBB].end()); - CandidateStores.erase(LoadBB); + AliasAnalysis &AA = getAnalysis(); // Figure out if the load is invalidated from the entry of the block it is in // until the actual instruction. This scans the block backwards from LI. If @@ -332,27 +302,26 @@ void LoadVN::getEqualNumberNodes(Value *V, // If this instruction is a candidate load before LI, we know there are no // invalidating instructions between it and LI, so they have the same value // number. - if (isa(I) && cast(I)->getOperand(0) == PointerSource) { + if (isa(I) && cast(I)->getOperand(0) == LoadPtr) { RetVals.push_back(I); - Instrs.erase(I); - } else if (AllocationInst *AI = dyn_cast(I)) { + } else if (I == LoadPtr) { // If we run into an allocation of the value being loaded, then the // contents are not initialized. - if ((Value*)AI == PointerSource) { - LoadInvalidatedInBBBefore = true; + if (isa(I)) RetVals.push_back(UndefValue::get(LI->getType())); - break; - } + + // Otherwise, since this is the definition of what we are loading, this + // loaded value cannot occur before this block. + LoadInvalidatedInBBBefore = true; + break; } if (AA.getModRefInfo(I, LoadPtr, LoadSize) & AliasAnalysis::Mod) { // If the invalidating instruction is a store, and its in our candidate // set, then we can do store-load forwarding: the load has the same value // # as the stored value. - if (isa(I) && I->getOperand(1) == PointerSource) { - Instrs.erase(I); + if (isa(I) && I->getOperand(1) == LoadPtr) RetVals.push_back(I->getOperand(0)); - } LoadInvalidatedInBBBefore = true; break; @@ -367,10 +336,8 @@ void LoadVN::getEqualNumberNodes(Value *V, for (BasicBlock::iterator I = LI->getNext(); I != LoadBB->end(); ++I) { // If this instruction is a load, then this instruction returns the same // value as LI. - if (isa(I) && cast(I)->getOperand(0) == PointerSource) { + if (isa(I) && cast(I)->getOperand(0) == LoadPtr) RetVals.push_back(I); - Instrs.erase(I); - } if (AA.getModRefInfo(I, LoadPtr, LoadSize) & AliasAnalysis::Mod) { LoadInvalidatedInBBAfter = true; @@ -378,6 +345,43 @@ void LoadVN::getEqualNumberNodes(Value *V, } } + // If the pointer is clobbered on entry and on exit to the function, there is + // no need to do any global analysis at all. + if (LoadInvalidatedInBBBefore && LoadInvalidatedInBBAfter) + return; + + // Now that we know the set of equivalent source pointers for the load + // instruction, look to see if there are any load or store candidates that are + // identical. + // + std::map > CandidateLoads; + std::map > CandidateStores; + + for (Value::use_iterator UI = LoadPtr->use_begin(), UE = LoadPtr->use_end(); + UI != UE; ++UI) + if (LoadInst *Cand = dyn_cast(*UI)) {// Is a load of source? + if (Cand->getParent()->getParent() == F && // In the same function? + // Not in LI's block? + Cand->getParent() != LoadBB && !Cand->isVolatile()) + CandidateLoads[Cand->getParent()].push_back(Cand); // Got one... + } else if (StoreInst *Cand = dyn_cast(*UI)) { + if (Cand->getParent()->getParent() == F && !Cand->isVolatile() && + Cand->getParent() != LoadBB && + Cand->getOperand(1) == LoadPtr) // It's a store THROUGH the ptr. + CandidateStores[Cand->getParent()].push_back(Cand); + } + + // Get dominators. + DominatorSet &DomSetInfo = getAnalysis(); + + // Find all of the candidate loads and stores that are in the same block as + // the defining instruction. + std::set Instrs; + Instrs.insert(CandidateLoads[LoadBB].begin(), CandidateLoads[LoadBB].end()); + CandidateLoads.erase(LoadBB); + Instrs.insert(CandidateStores[LoadBB].begin(), CandidateStores[LoadBB].end()); + CandidateStores.erase(LoadBB); + // If there is anything left in the Instrs set, it could not possibly equal // LI. Instrs.clear();