diff --git a/include/llvm/Analysis/MemoryDependenceAnalysis.h b/include/llvm/Analysis/MemoryDependenceAnalysis.h index 7546eda862d..ac6ffb642b8 100644 --- a/include/llvm/Analysis/MemoryDependenceAnalysis.h +++ b/include/llvm/Analysis/MemoryDependenceAnalysis.h @@ -43,9 +43,8 @@ class MemoryDependenceAnalysis : public FunctionPass { Instruction* getCallSiteDependency(CallSite C, Instruction* start, bool local = true); - bool nonLocalHelper(Instruction* query, BasicBlock* block, - DenseMap& resp, - SmallPtrSet& visited); + void nonLocalHelper(Instruction* query, BasicBlock* block, + DenseMap& resp); public: static Instruction* NonLocal; @@ -74,7 +73,7 @@ class MemoryDependenceAnalysis : public FunctionPass { Instruction* getDependency(Instruction* query, Instruction* start = 0, BasicBlock* block = 0); - bool getNonLocalDependency(Instruction* query, + void getNonLocalDependency(Instruction* query, DenseMap& resp); /// removeInstruction - Remove an instruction from the dependence analysis, diff --git a/lib/Analysis/MemoryDependenceAnalysis.cpp b/lib/Analysis/MemoryDependenceAnalysis.cpp index 5a8cb7bfaa7..a280fffb59b 100644 --- a/lib/Analysis/MemoryDependenceAnalysis.cpp +++ b/lib/Analysis/MemoryDependenceAnalysis.cpp @@ -101,63 +101,62 @@ Instruction* MemoryDependenceAnalysis::getCallSiteDependency(CallSite C, Instruc return NonLocal; } -bool MemoryDependenceAnalysis::nonLocalHelper(Instruction* query, +void MemoryDependenceAnalysis::nonLocalHelper(Instruction* query, BasicBlock* block, - DenseMap& resp, - SmallPtrSet& visited) { - if (resp.count(block)) - return resp[block] != None; + DenseMap& resp) { + SmallPtrSet visited; + SmallVector stack; + stack.push_back(block); - Instruction* localDep = getDependency(query, 0, block); - if (localDep != NonLocal) { - resp.insert(std::make_pair(block, localDep)); - return true; + while (!stack.empty()) { + BasicBlock* BB = stack.back(); + + visited.insert(BB); + + if (resp.count(BB)) { + stack.pop_back(); + continue; + } + + if (BB != block) { + Instruction* localDep = getDependency(query, 0, BB); + if (localDep != NonLocal) { + resp.insert(std::make_pair(BB, localDep)); + continue; + } + } + + bool predOnStack = false; + bool inserted = false; + for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB); + PI != PE; ++PI) + if (!visited.count(*PI)) { + stack.push_back(*PI); + inserted = true; + } else + predOnStack = true; + + if (inserted) + continue; + else if (!inserted && !predOnStack) { + resp.insert(std::make_pair(BB, None)); + } else if (!inserted && predOnStack){ + resp.insert(std::make_pair(BB, NonLocal)); + } + + stack.pop_back(); } - - visited.insert(block); - - bool inserted = false; - bool predOnStack = false; - for (pred_iterator PI = pred_begin(block), PE = pred_end(block); - PI != PE; ++PI) - if (!visited.count(*PI)) - inserted |= nonLocalHelper(query, *PI, resp, visited); - else - predOnStack = true; - - visited.erase(block); - - if (!inserted && !predOnStack) - resp.insert(std::make_pair(block, None)); - else if (inserted && predOnStack) - resp.insert(std::make_pair(block, NonLocal)); - - return inserted; } -bool MemoryDependenceAnalysis::getNonLocalDependency(Instruction* query, +void MemoryDependenceAnalysis::getNonLocalDependency(Instruction* query, DenseMap& resp) { Instruction* localDep = getDependency(query); if (localDep != NonLocal) { resp.insert(std::make_pair(query->getParent(), localDep)); - return true; + return; } - bool inserted = false; - SmallPtrSet visited; - visited.insert(query->getParent()); - - BasicBlock* parent = query->getParent(); - for (pred_iterator PI = pred_begin(parent), PE = pred_end(parent); - PI != PE; ++PI) { - if (!visited.count(*PI)) - inserted |= nonLocalHelper(query, *PI, resp, visited); - } - - if (!inserted) - resp.insert(std::make_pair(query->getParent(), None)); - - return inserted; + nonLocalHelper(query, query->getParent(), resp); } /// getDependency - Return the instruction on which a memory operation diff --git a/lib/Transforms/Scalar/GVN.cpp b/lib/Transforms/Scalar/GVN.cpp index 3d04fc4fd81..e39e2eb16af 100644 --- a/lib/Transforms/Scalar/GVN.cpp +++ b/lib/Transforms/Scalar/GVN.cpp @@ -721,8 +721,9 @@ Value *GVN::GetValueForBlock(BasicBlock *BB, LoadInst* orig, Value *&V = Phis[BB]; if (V) return V; - if (std::distance(pred_begin(BB), pred_end(BB)) == 1) - return V = GetValueForBlock(*pred_begin(BB), orig, Phis); + BasicBlock* singlePred = BB->getSinglePredecessor(); + if (singlePred) + return V = GetValueForBlock(singlePred, orig, Phis); // 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. @@ -750,6 +751,16 @@ Value *GVN::GetValueForBlock(BasicBlock *BB, LoadInst* orig, MD.removeInstruction(PN); PN->replaceAllUsesWith(first); + + SmallVector toRemove; + for (DenseMap::iterator I = Phis.begin(), + E = Phis.end(); I != E; ++I) + if (I->second == PN) + toRemove.push_back(I->first); + for (SmallVector::iterator I = toRemove.begin(), + E= toRemove.end(); I != E; ++I) + Phis[*I] = first; + PN->eraseFromParent(); Phis[BB] = first; @@ -764,9 +775,7 @@ bool GVN::processNonLocalLoad(LoadInst* L, SmallVector& toErase MemoryDependenceAnalysis& MD = getAnalysis(); DenseMap deps; - bool ret = MD.getNonLocalDependency(L, deps); - if (!ret) - return false; + MD.getNonLocalDependency(L, deps); DenseMap repl; for (DenseMap::iterator I = deps.begin(), E = deps.end();