Add an early bailout to IsValueFullyAvailableInBlock from deeply nested blocks.

The limit is set to an arbitrary 1000 recursion depth to avoid stack overflow
issues. <rdar://problem/11286839>.

llvm-svn: 155722
This commit is contained in:
Mon P Wang 2012-04-27 18:09:28 +00:00
parent 1ccecdb2fd
commit 6120cfb8cd
1 changed files with 12 additions and 3 deletions

View File

@ -59,6 +59,11 @@ static cl::opt<bool> EnablePRE("enable-pre",
cl::init(true), cl::Hidden); cl::init(true), cl::Hidden);
static cl::opt<bool> EnableLoadPRE("enable-load-pre", cl::init(true)); static cl::opt<bool> EnableLoadPRE("enable-load-pre", cl::init(true));
// Maximum allowed recursion depth.
static cl::opt<int>
MaxRecurseDepth("max-recurse-depth", cl::Hidden, cl::init(1000), cl::ZeroOrMore,
cl::desc("Max recurse depth (default = 1000)"));
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// ValueTable Class // ValueTable Class
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@ -647,7 +652,11 @@ void GVN::dump(DenseMap<uint32_t, Value*>& d) {
/// 3) we are speculating for this block and have used that to speculate for /// 3) we are speculating for this block and have used that to speculate for
/// other blocks. /// other blocks.
static bool IsValueFullyAvailableInBlock(BasicBlock *BB, static bool IsValueFullyAvailableInBlock(BasicBlock *BB,
DenseMap<BasicBlock*, char> &FullyAvailableBlocks) { DenseMap<BasicBlock*, char> &FullyAvailableBlocks,
uint32_t RecurseDepth) {
if (RecurseDepth > MaxRecurseDepth)
return false;
// Optimistically assume that the block is fully available and check to see // Optimistically assume that the block is fully available and check to see
// if we already know about this block in one lookup. // if we already know about this block in one lookup.
std::pair<DenseMap<BasicBlock*, char>::iterator, char> IV = std::pair<DenseMap<BasicBlock*, char>::iterator, char> IV =
@ -673,7 +682,7 @@ static bool IsValueFullyAvailableInBlock(BasicBlock *BB,
// If the value isn't fully available in one of our predecessors, then it // If the value isn't fully available in one of our predecessors, then it
// isn't fully available in this block either. Undo our previous // isn't fully available in this block either. Undo our previous
// optimistic assumption and bail out. // optimistic assumption and bail out.
if (!IsValueFullyAvailableInBlock(*PI, FullyAvailableBlocks)) if (!IsValueFullyAvailableInBlock(*PI, FullyAvailableBlocks,RecurseDepth+1))
goto SpeculationFailure; goto SpeculationFailure;
return true; return true;
@ -1570,7 +1579,7 @@ bool GVN::processNonLocalLoad(LoadInst *LI) {
for (pred_iterator PI = pred_begin(LoadBB), E = pred_end(LoadBB); for (pred_iterator PI = pred_begin(LoadBB), E = pred_end(LoadBB);
PI != E; ++PI) { PI != E; ++PI) {
BasicBlock *Pred = *PI; BasicBlock *Pred = *PI;
if (IsValueFullyAvailableInBlock(Pred, FullyAvailableBlocks)) { if (IsValueFullyAvailableInBlock(Pred, FullyAvailableBlocks, 0)) {
continue; continue;
} }
PredLoads[Pred] = 0; PredLoads[Pred] = 0;