From 6688d617978b338f96d27c6d73a396fbd2bf8e9c Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 28 Oct 2009 03:44:30 +0000 Subject: [PATCH] Rewrite SelectionDAG::isPredecessorOf to be iterative instead of recursive to avoid consuming extraordinary amounts of stack space when processing tall graphs. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@85369 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 37 ++++++++++------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 37736c04ab4..139eec3c2f8 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -5307,31 +5307,26 @@ bool SDValue::reachesChainWithoutSideEffects(SDValue Dest, return false; } - -static void findPredecessor(SDNode *N, const SDNode *P, bool &found, - SmallPtrSet &Visited) { - if (found || !Visited.insert(N)) - return; - - for (unsigned i = 0, e = N->getNumOperands(); !found && i != e; ++i) { - SDNode *Op = N->getOperand(i).getNode(); - if (Op == P) { - found = true; - return; - } - findPredecessor(Op, P, found, Visited); - } -} - /// isPredecessorOf - Return true if this node is a predecessor of N. This node -/// is either an operand of N or it can be reached by recursively traversing -/// up the operands. +/// is either an operand of N or it can be reached by traversing up the operands. /// NOTE: this is an expensive method. Use it carefully. bool SDNode::isPredecessorOf(SDNode *N) const { SmallPtrSet Visited; - bool found = false; - findPredecessor(N, this, found, Visited); - return found; + SmallVector Worklist; + Worklist.push_back(N); + + do { + N = Worklist.pop_back_val(); + for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { + SDNode *Op = N->getOperand(i).getNode(); + if (Op == this) + return true; + if (Visited.insert(Op)) + Worklist.push_back(Op); + } + } while (!Worklist.empty()); + + return false; } uint64_t SDNode::getConstantOperandVal(unsigned Num) const { -- 2.34.1