Add a limit to the number of instructions memdep will scan in a single block. This prevents (at least in some cases) O(N^2) runtime in passes like DSE.

The limit in this patch is probably too high, but it is enough to stop DSE from going completely insane on a testcase I have (which has a single block with around 50,000 non-aliasing stores in it).

rdar://9471075

llvm-svn: 133111
This commit is contained in:
Eli Friedman 2011-06-15 23:59:25 +00:00
parent 519c63cdeb
commit 9eef1c75a5

View File

@ -47,6 +47,11 @@ STATISTIC(NumUncacheNonLocalPtr,
STATISTIC(NumCacheCompleteNonLocalPtr, STATISTIC(NumCacheCompleteNonLocalPtr,
"Number of block queries that were completely cached"); "Number of block queries that were completely cached");
// Limit for the number of instructions to scan in a block.
// FIXME: Figure out what a sane value is for this.
// (500 is relatively insane.)
static const int BlockScanLimit = 500;
char MemoryDependenceAnalysis::ID = 0; char MemoryDependenceAnalysis::ID = 0;
// Register this pass... // Register this pass...
@ -180,8 +185,16 @@ AliasAnalysis::ModRefResult GetLocation(const Instruction *Inst,
MemDepResult MemoryDependenceAnalysis:: MemDepResult MemoryDependenceAnalysis::
getCallSiteDependencyFrom(CallSite CS, bool isReadOnlyCall, getCallSiteDependencyFrom(CallSite CS, bool isReadOnlyCall,
BasicBlock::iterator ScanIt, BasicBlock *BB) { BasicBlock::iterator ScanIt, BasicBlock *BB) {
unsigned Limit = BlockScanLimit;
// Walk backwards through the block, looking for dependencies // Walk backwards through the block, looking for dependencies
while (ScanIt != BB->begin()) { while (ScanIt != BB->begin()) {
// Limit the amount of scanning we do so we don't end up with quadratic
// running time on extreme testcases.
--Limit;
if (!Limit)
return MemDepResult::getUnknown();
Instruction *Inst = --ScanIt; Instruction *Inst = --ScanIt;
// If this inst is a memory op, get the pointer it accessed // If this inst is a memory op, get the pointer it accessed
@ -322,9 +335,17 @@ getPointerDependencyFrom(const AliasAnalysis::Location &MemLoc, bool isLoad,
const Value *MemLocBase = 0; const Value *MemLocBase = 0;
int64_t MemLocOffset = 0; int64_t MemLocOffset = 0;
unsigned Limit = BlockScanLimit;
// Walk backwards through the basic block, looking for dependencies. // Walk backwards through the basic block, looking for dependencies.
while (ScanIt != BB->begin()) { while (ScanIt != BB->begin()) {
// Limit the amount of scanning we do so we don't end up with quadratic
// running time on extreme testcases.
--Limit;
if (!Limit)
return MemDepResult::getUnknown();
Instruction *Inst = --ScanIt; Instruction *Inst = --ScanIt;
if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(Inst)) { if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(Inst)) {