Index: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp =================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp @@ -57,6 +57,11 @@ cl::desc("The number of instructions to scan in a block in memory " "dependency analysis (default = 100)")); +static cl::opt BlockNumberLimit( + "memdep-block-number-limit", cl::Hidden, cl::init(1000), + cl::desc("The number of blocks to scan during memory " + "dependency analysis (default = 1000)")); + // Limit on the number of memdep results to process. static const unsigned int NumResultsLimit = 100; @@ -1246,6 +1251,8 @@ // won't get any reuse from currently inserted values, because we don't // revisit blocks after we insert info for them. unsigned NumSortedEntries = Cache->size(); + unsigned WorklistEntries = BlockNumberLimit; + bool GotWorklistLimit = false; DEBUG(AssertSorted(*Cache)); while (!Worklist.empty()) { @@ -1324,6 +1331,15 @@ goto PredTranslationFailure; } } + if (NewBlocks.size() > WorklistEntries) { + // Make sure to clean up the Visited map before continuing on to + // PredTranslationFailure. + for (unsigned i = 0; i < NewBlocks.size(); i++) + Visited.erase(NewBlocks[i]); + GotWorklistLimit = true; + goto PredTranslationFailure; + } + WorklistEntries -= NewBlocks.size(); Worklist.append(NewBlocks.begin(), NewBlocks.end()); continue; } @@ -1469,18 +1485,22 @@ if (SkipFirstBlock) return true; - for (NonLocalDepInfo::reverse_iterator I = Cache->rbegin(); ; ++I) { - assert(I != Cache->rend() && "Didn't find current block??"); - if (I->getBB() != BB) + bool foundBlock = false; + for (NonLocalDepEntry &I: llvm::reverse(*Cache)) { + if (I.getBB() != BB) continue; - assert((I->getResult().isNonLocal() || !DT->isReachableFromEntry(BB)) && + assert((GotWorklistLimit || I.getResult().isNonLocal() || \ + !DT->isReachableFromEntry(BB)) && "Should only be here with transparent block"); - I->setResult(MemDepResult::getUnknown()); - Result.push_back(NonLocalDepResult(I->getBB(), I->getResult(), + foundBlock = true; + I.setResult(MemDepResult::getUnknown()); + Result.push_back(NonLocalDepResult(I.getBB(), I.getResult(), Pointer.getAddr())); break; } + (void)foundBlock; + assert((foundBlock || GotWorklistLimit) && "Current block not in cache?"); } // Okay, we're done now. If we added new values to the cache, re-sort it.