mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-30 06:40:53 +00:00
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:
parent
519c63cdeb
commit
9eef1c75a5
@ -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)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user