X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FADT%2FSCCIterator.h;h=e28f4caa5d76993668b45eacb9fc8de76e8ad839;hb=d6a2aab53e3c4fcd53399cfa6f66d62913e53663;hp=cf137cd473404e91fdd1a750220dbaa1de73cdd8;hpb=b2109ce97881269a610fa4afbcbca350e975174d;p=oota-llvm.git diff --git a/include/llvm/ADT/SCCIterator.h b/include/llvm/ADT/SCCIterator.h index cf137cd4734..e28f4caa5d7 100644 --- a/include/llvm/ADT/SCCIterator.h +++ b/include/llvm/ADT/SCCIterator.h @@ -1,30 +1,32 @@ -//===-- Support/SCCIterator.h - SCC iterator --------------------*- C++ -*-===// -// +//===-- Support/SCCIterator.h - Strongly Connected Comp. Iter. --*- C++ -*-===// +// // The LLVM Compiler Infrastructure // -// This file was developed by the LLVM research group and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. -// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// //===----------------------------------------------------------------------===// // -// This builds on the Support/GraphTraits.h file to find the strongly connected +// This builds on the llvm/ADT/GraphTraits.h file to find the strongly connected // components (SCCs) of a graph in O(N+E) time using Tarjan's DFS algorithm. // // The SCC iterator has the important property that if a node in SCC S1 has an // edge to a node in SCC S2, then it visits S1 *after* S2. -// +// // To visit S1 *before* S2, use the scc_iterator on the Inverse graph. // (NOTE: This requires some simple wrappers and is not supported yet.) // //===----------------------------------------------------------------------===// -#ifndef SUPPORT_SCCITERATOR_H -#define SUPPORT_SCCITERATOR_H +#ifndef LLVM_ADT_SCCITERATOR_H +#define LLVM_ADT_SCCITERATOR_H -#include "Support/GraphTraits.h" -#include "Support/iterator" -#include +#include "llvm/ADT/GraphTraits.h" +#include "llvm/ADT/iterator.h" #include +#include + +namespace llvm { //===----------------------------------------------------------------------===// /// @@ -68,64 +70,59 @@ class scc_iterator nodeVisitNumbers[N] = visitNum; SCCNodeStack.push_back(N); MinVisitNumStack.push_back(visitNum); - VisitStack.push_back(make_pair(N, GT::child_begin(N))); - //DEBUG(std::cerr << "TarjanSCC: Node " << N << - // " : visitNum = " << visitNum << "\n"); + VisitStack.push_back(std::make_pair(N, GT::child_begin(N))); + //DOUT << "TarjanSCC: Node " << N << + // " : visitNum = " << visitNum << "\n"; } // The stack-based DFS traversal; defined below. void DFSVisitChildren() { assert(!VisitStack.empty()); - while (VisitStack.back().second != GT::child_end(VisitStack.back().first)) - { // TOS has at least one more child so continue DFS - NodeType *childN = *VisitStack.back().second++; - if (nodeVisitNumbers.find(childN) == nodeVisitNumbers.end()) - { // this node has never been seen - DFSVisitOne(childN); - } - else - { - unsigned childNum = nodeVisitNumbers[childN]; - if (MinVisitNumStack.back() > childNum) - MinVisitNumStack.back() = childNum; - } + while (VisitStack.back().second != GT::child_end(VisitStack.back().first)) { + // 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 + DFSVisitOne(childN); + } else { + unsigned childNum = nodeVisitNumbers[childN]; + if (MinVisitNumStack.back() > childNum) + MinVisitNumStack.back() = childNum; } + } } // Compute the next SCC using the DFS traversal. void GetNextSCC() { assert(VisitStack.size() == MinVisitNumStack.size()); CurrentSCC.clear(); // Prepare to compute the next SCC - while (! VisitStack.empty()) - { - DFSVisitChildren(); - - assert(VisitStack.back().second == - GT::child_end(VisitStack.back().first)); - NodeType* visitingN = VisitStack.back().first; - unsigned minVisitNum = MinVisitNumStack.back(); - VisitStack.pop_back(); - MinVisitNumStack.pop_back(); - if (! MinVisitNumStack.empty() && MinVisitNumStack.back() > minVisitNum) - MinVisitNumStack.back() = minVisitNum; - - //DEBUG(std::cerr << "TarjanSCC: Popped node " << visitingN << - // " : 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()] = ~0UL; - } while (CurrentSCC.back() != visitingN); - return; - } - } + while (!VisitStack.empty()) { + DFSVisitChildren(); + assert(VisitStack.back().second ==GT::child_end(VisitStack.back().first)); + NodeType* visitingN = VisitStack.back().first; + unsigned minVisitNum = MinVisitNumStack.back(); + VisitStack.pop_back(); + MinVisitNumStack.pop_back(); + if (!MinVisitNumStack.empty() && MinVisitNumStack.back() > minVisitNum) + MinVisitNumStack.back() = minVisitNum; + + //DOUT << "TarjanSCC: Popped node " << visitingN << + // " : 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; + } + } } inline scc_iterator(NodeType *entryN) : visitNum(0) { @@ -147,7 +144,7 @@ public: return CurrentSCC.empty(); } - inline bool operator==(const _Self& x) const { + inline bool operator==(const _Self& x) const { return VisitStack == x.VisitStack && CurrentSCC == x.CurrentSCC; } inline bool operator!=(const _Self& x) const { return !operator==(x); } @@ -155,18 +152,18 @@ public: // Iterator traversal: forward iteration only inline _Self& operator++() { // Preincrement GetNextSCC(); - return *this; + return *this; } inline _Self operator++(int) { // Postincrement - _Self tmp = *this; ++*this; return tmp; + _Self tmp = *this; ++*this; return tmp; } // Retrieve a reference to the current SCC - inline const SccTy &operator*() const { + inline const SccTy &operator*() const { assert(!CurrentSCC.empty() && "Dereferencing END SCC iterator!"); return CurrentSCC; } - inline SccTy &operator*() { + inline SccTy &operator*() { assert(!CurrentSCC.empty() && "Dereferencing END SCC iterator!"); return CurrentSCC; } @@ -197,4 +194,6 @@ scc_iterator scc_end(T G) { return scc_iterator::end(G); } +} // End llvm namespace + #endif