From 9eef1c75a5e18f310aa9124a752c85ad7596c7a1 Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Wed, 15 Jun 2011 23:59:25 +0000 Subject: [PATCH] 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 --- lib/Analysis/MemoryDependenceAnalysis.cpp | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/lib/Analysis/MemoryDependenceAnalysis.cpp b/lib/Analysis/MemoryDependenceAnalysis.cpp index ed638ff1c0f..bba4482f4da 100644 --- a/lib/Analysis/MemoryDependenceAnalysis.cpp +++ b/lib/Analysis/MemoryDependenceAnalysis.cpp @@ -47,6 +47,11 @@ STATISTIC(NumUncacheNonLocalPtr, STATISTIC(NumCacheCompleteNonLocalPtr, "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; // Register this pass... @@ -180,8 +185,16 @@ AliasAnalysis::ModRefResult GetLocation(const Instruction *Inst, MemDepResult MemoryDependenceAnalysis:: getCallSiteDependencyFrom(CallSite CS, bool isReadOnlyCall, BasicBlock::iterator ScanIt, BasicBlock *BB) { + unsigned Limit = BlockScanLimit; + // Walk backwards through the block, looking for dependencies 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; // 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; int64_t MemLocOffset = 0; - + + unsigned Limit = BlockScanLimit; + // Walk backwards through the basic block, looking for dependencies. 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; if (IntrinsicInst *II = dyn_cast(Inst)) {