diff options
Diffstat (limited to 'include/llvm/ADT/SCCIterator.h')
-rw-r--r-- | include/llvm/ADT/SCCIterator.h | 68 |
1 files changed, 39 insertions, 29 deletions
diff --git a/include/llvm/ADT/SCCIterator.h b/include/llvm/ADT/SCCIterator.h index d38ce4c..c49d599 100644 --- a/include/llvm/ADT/SCCIterator.h +++ b/include/llvm/ADT/SCCIterator.h @@ -66,7 +66,7 @@ class scc_iterator std::vector<unsigned> MinVisitNumStack; // A single "visit" within the non-recursive DFS traversal. - void DFSVisitOne(NodeType* N) { + void DFSVisitOne(NodeType *N) { ++visitNum; // Global counter for the visit order nodeVisitNumbers[N] = visitNum; SCCNodeStack.push_back(N); @@ -83,13 +83,14 @@ class scc_iterator // TOS has at least one more child so continue DFS NodeType *childN = *VisitStack.back().second++; if (!nodeVisitNumbers.count(childN)) { - // this node has never been seen + // this node has never been seen. DFSVisitOne(childN); - } else { - unsigned childNum = nodeVisitNumbers[childN]; - if (MinVisitNumStack.back() > childNum) - MinVisitNumStack.back() = childNum; + continue; } + + unsigned childNum = nodeVisitNumbers[childN]; + if (MinVisitNumStack.back() > childNum) + MinVisitNumStack.back() = childNum; } } @@ -100,7 +101,7 @@ class scc_iterator while (!VisitStack.empty()) { DFSVisitChildren(); assert(VisitStack.back().second ==GT::child_end(VisitStack.back().first)); - NodeType* visitingN = VisitStack.back().first; + NodeType *visitingN = VisitStack.back().first; unsigned minVisitNum = MinVisitNumStack.back(); VisitStack.pop_back(); MinVisitNumStack.pop_back(); @@ -111,18 +112,19 @@ class scc_iterator // " : minVisitNum = " << minVisitNum << "; Node visit num = " << // nodeVisitNumbers[visitingN] << "\n"; - if (minVisitNum == nodeVisitNumbers[visitingN]) { - // A full SCC is on the SCCNodeStack! It includes all nodes below - // visitingN on the stack. Copy those nodes to CurrentSCC, - // reset their minVisit values, and return (this suspends - // the DFS traversal till the next ++). - do { - CurrentSCC.push_back(SCCNodeStack.back()); - SCCNodeStack.pop_back(); - nodeVisitNumbers[CurrentSCC.back()] = ~0U; - } while (CurrentSCC.back() != visitingN); - return; - } + if (minVisitNum != nodeVisitNumbers[visitingN]) + continue; + + // A full SCC is on the SCCNodeStack! It includes all nodes below + // visitingN on the stack. Copy those nodes to CurrentSCC, + // reset their minVisit values, and return (this suspends + // the DFS traversal till the next ++). + do { + CurrentSCC.push_back(SCCNodeStack.back()); + SCCNodeStack.pop_back(); + nodeVisitNumbers[CurrentSCC.back()] = ~0U; + } while (CurrentSCC.back() != visitingN); + return; } } @@ -136,11 +138,11 @@ public: typedef scc_iterator<GraphT, GT> _Self; // Provide static "constructors"... - static inline _Self begin(const GraphT& G) { return _Self(GT::getEntryNode(G)); } - static inline _Self end (const GraphT& G) { return _Self(); } + static inline _Self begin(const GraphT &G){return _Self(GT::getEntryNode(G));} + static inline _Self end (const GraphT &G) { return _Self(); } - // Direct loop termination test (I.fini() is more efficient than I == end()) - inline bool fini() const { + // Direct loop termination test: I.isAtEnd() is more efficient than I == end() + inline bool isAtEnd() const { assert(!CurrentSCC.empty() || VisitStack.empty()); return CurrentSCC.empty(); } @@ -181,28 +183,36 @@ public: return true; return false; } + + /// ReplaceNode - This informs the scc_iterator that the specified Old node + /// has been deleted, and New is to be used in its place. + void ReplaceNode(NodeType *Old, NodeType *New) { + assert(nodeVisitNumbers.count(Old) && "Old not in scc_iterator?"); + nodeVisitNumbers[New] = nodeVisitNumbers[Old]; + nodeVisitNumbers.erase(Old); + } }; // Global constructor for the SCC iterator. template <class T> -scc_iterator<T> scc_begin(const T& G) { +scc_iterator<T> scc_begin(const T &G) { return scc_iterator<T>::begin(G); } template <class T> -scc_iterator<T> scc_end(const T& G) { +scc_iterator<T> scc_end(const T &G) { return scc_iterator<T>::end(G); } template <class T> -scc_iterator<Inverse<T> > scc_begin(const Inverse<T>& G) { - return scc_iterator<Inverse<T> >::begin(G); +scc_iterator<Inverse<T> > scc_begin(const Inverse<T> &G) { + return scc_iterator<Inverse<T> >::begin(G); } template <class T> -scc_iterator<Inverse<T> > scc_end(const Inverse<T>& G) { - return scc_iterator<Inverse<T> >::end(G); +scc_iterator<Inverse<T> > scc_end(const Inverse<T> &G) { + return scc_iterator<Inverse<T> >::end(G); } } // End llvm namespace |