diff --git a/include/Support/DepthFirstIterator.h b/include/Support/DepthFirstIterator.h index 967a0e145ac..10ef3f378c8 100644 --- a/include/Support/DepthFirstIterator.h +++ b/include/Support/DepthFirstIterator.h @@ -1,7 +1,13 @@ //===- Support/DepthFirstIterator.h - Depth First iterator ------*- C++ -*-===// // // This file builds on the Support/GraphTraits.h file to build generic depth -// first graph iterator. +// first graph iterator. This file exposes the following functions/types: +// +// df_begin/df_end/df_iterator +// * Normal depth-first iteration - visit a node and then all of its children. +// +// idf_begin/idf_end/idf_iterator +// * Depth-first iteration on the 'inverse' graph. // //===----------------------------------------------------------------------===// @@ -10,7 +16,7 @@ #include "Support/GraphTraits.h" #include "Support/iterator" -#include +#include #include // Generic Depth First Iterator @@ -24,28 +30,11 @@ class df_iterator : public forward_iterator { std::set Visited; // All of the blocks visited so far... // VisitStack - Used to maintain the ordering. Top = current block // First element is node pointer, second is the 'next child' to visit - std::stack > VisitStack; - const bool Reverse; // Iterate over children before self? + std::vector > VisitStack; private: - void reverseEnterNode() { - std::pair &Top = VisitStack.top(); - NodeType *Node = Top.first; - ChildItTy &It = Top.second; - for (; It != GT::child_end(Node); ++It) { - NodeType *Child = *It; - if (!Visited.count(Child)) { - Visited.insert(Child); - VisitStack.push(std::make_pair(Child, GT::child_begin(Child))); - reverseEnterNode(); - return; - } - } - } - - inline df_iterator(NodeType *Node, bool reverse) : Reverse(reverse) { + inline df_iterator(NodeType *Node) { Visited.insert(Node); - VisitStack.push(std::make_pair(Node, GT::child_begin(Node))); - if (Reverse) reverseEnterNode(); + VisitStack.push_back(std::make_pair(Node, GT::child_begin(Node))); } inline df_iterator() { /* End is when stack is empty */ } @@ -54,19 +43,20 @@ public: typedef df_iterator _Self; // Provide static begin and end methods as our public "constructors" - static inline _Self begin(GraphT G, bool Reverse = false) { - return _Self(GT::getEntryNode(G), Reverse); + static inline _Self begin(GraphT G) { + return _Self(GT::getEntryNode(G)); } static inline _Self end(GraphT G) { return _Self(); } inline bool operator==(const _Self& x) const { - return VisitStack == x.VisitStack; + return VisitStack.size() == x.VisitStack.size() && + VisitStack == x.VisitStack; } inline bool operator!=(const _Self& x) const { return !operator==(x); } inline pointer operator*() const { - return VisitStack.top().first; + return VisitStack.back().first; } // This is a nonstandard operator-> that dereferences the pointer an extra @@ -76,31 +66,24 @@ public: inline NodeType *operator->() const { return operator*(); } inline _Self& operator++() { // Preincrement - if (Reverse) { // Reverse Depth First Iterator - if (VisitStack.top().second == GT::child_end(VisitStack.top().first)) - VisitStack.pop(); - if (!VisitStack.empty()) - reverseEnterNode(); - } else { // Normal Depth First Iterator - do { - std::pair &Top = VisitStack.top(); - NodeType *Node = Top.first; - ChildItTy &It = Top.second; - - while (It != GT::child_end(Node)) { - NodeType *Next = *It++; - if (!Visited.count(Next)) { // Has our next sibling been visited? - // No, do it now. - Visited.insert(Next); - VisitStack.push(std::make_pair(Next, GT::child_begin(Next))); - return *this; - } - } - - // Oops, ran out of successors... go up a level on the stack. - VisitStack.pop(); - } while (!VisitStack.empty()); - } + do { + std::pair &Top = VisitStack.back(); + NodeType *Node = Top.first; + ChildItTy &It = Top.second; + + while (It != GT::child_end(Node)) { + NodeType *Next = *It++; + if (!Visited.count(Next)) { // Has our next sibling been visited? + // No, do it now. + Visited.insert(Next); + VisitStack.push_back(std::make_pair(Next, GT::child_begin(Next))); + return *this; + } + } + + // Oops, ran out of successors... go up a level on the stack. + VisitStack.pop_back(); + } while (!VisitStack.empty()); return *this; } @@ -121,8 +104,8 @@ public: // Provide global constructors that automatically figure out correct types... // template -df_iterator df_begin(T G, bool Reverse = false) { - return df_iterator::begin(G, Reverse); +df_iterator df_begin(T G) { + return df_iterator::begin(G); } template @@ -137,8 +120,8 @@ struct idf_iterator : public df_iterator > { }; template -idf_iterator idf_begin(T G, bool Reverse = false) { - return idf_iterator::begin(G, Reverse); +idf_iterator idf_begin(T G) { + return idf_iterator::begin(G); } template