llvm.org GIT mirror llvm / 4846f4b
Extricate the "reverse" support from the depth-first iterator. This is really a crappy form of post-order traversal which really does not belong here. While we are at it, improve documentation and use a vector instead of a stack. This improves the post dominator analysis pass by ~5%, and probably also helps other passes as well. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@9084 91177308-0d34-0410-b5e6-96231b3b80d8 Chris Lattner 16 years ago
2 changed file(s) with 76 addition(s) and 110 deletion(s). Raw diff Collapse all Expand all
0 //===- Support/DepthFirstIterator.h - Depth First iterator ------*- C++ -*-===//
11 //
22 // This file builds on the Support/GraphTraits.h file to build generic depth
3 // first graph iterator.
3 // first graph iterator. This file exposes the following functions/types:
4 //
5 // df_begin/df_end/df_iterator
6 // * Normal depth-first iteration - visit a node and then all of its children.
7 //
8 // idf_begin/idf_end/idf_iterator
9 // * Depth-first iteration on the 'inverse' graph.
410 //
511 //===----------------------------------------------------------------------===//
612
915
1016 #include "Support/GraphTraits.h"
1117 #include "Support/iterator"
12 #include <stack>
18 #include <vector>
1319 #include
1420
1521 // Generic Depth First Iterator
2329 std::set Visited; // All of the blocks visited so far...
2430 // VisitStack - Used to maintain the ordering. Top = current block
2531 // First element is node pointer, second is the 'next child' to visit
26 std::stack > VisitStack;
27 const bool Reverse; // Iterate over children before self?
32 std::vector > VisitStack;
2833 private:
29 void reverseEnterNode() {
30 std::pair &Top = VisitStack.top();
31 NodeType *Node = Top.first;
32 ChildItTy &It = Top.second;
33 for (; It != GT::child_end(Node); ++It) {
34 NodeType *Child = *It;
35 if (!Visited.count(Child)) {
36 Visited.insert(Child);
37 VisitStack.push(std::make_pair(Child, GT::child_begin(Child)));
38 reverseEnterNode();
39 return;
40 }
41 }
42 }
43
44 inline df_iterator(NodeType *Node, bool reverse) : Reverse(reverse) {
34 inline df_iterator(NodeType *Node) {
4535 Visited.insert(Node);
46 VisitStack.push(std::make_pair(Node, GT::child_begin(Node)));
47 if (Reverse) reverseEnterNode();
36 VisitStack.push_back(std::make_pair(Node, GT::child_begin(Node)));
4837 }
4938 inline df_iterator() { /* End is when stack is empty */ }
5039
5342 typedef df_iterator _Self;
5443
5544 // Provide static begin and end methods as our public "constructors"
56 static inline _Self begin(GraphT G, bool Reverse = false) {
57 return _Self(GT::getEntryNode(G), Reverse);
45 static inline _Self begin(GraphT G) {
46 return _Self(GT::getEntryNode(G));
5847 }
5948 static inline _Self end(GraphT G) { return _Self(); }
6049
6150
6251 inline bool operator==(const _Self& x) const {
63 return VisitStack == x.VisitStack;
52 return VisitStack.size() == x.VisitStack.size() &&
53 VisitStack == x.VisitStack;
6454 }
6555 inline bool operator!=(const _Self& x) const { return !operator==(x); }
6656
6757 inline pointer operator*() const {
68 return VisitStack.top().first;
58 return VisitStack.back().first;
6959 }
7060
7161 // This is a nonstandard operator-> that dereferences the pointer an extra
7565 inline NodeType *operator->() const { return operator*(); }
7666
7767 inline _Self& operator++() { // Preincrement
78 if (Reverse) { // Reverse Depth First Iterator
79 if (VisitStack.top().second == GT::child_end(VisitStack.top().first))
80 VisitStack.pop();
81 if (!VisitStack.empty())
82 reverseEnterNode();
83 } else { // Normal Depth First Iterator
84 do {
85 std::pair &Top = VisitStack.top();
86 NodeType *Node = Top.first;
87 ChildItTy &It = Top.second;
88
89 while (It != GT::child_end(Node)) {
90 NodeType *Next = *It++;
91 if (!Visited.count(Next)) { // Has our next sibling been visited?
92 // No, do it now.
93 Visited.insert(Next);
94 VisitStack.push(std::make_pair(Next, GT::child_begin(Next)));
95 return *this;
96 }
97 }
98
99 // Oops, ran out of successors... go up a level on the stack.
100 VisitStack.pop();
101 } while (!VisitStack.empty());
102 }
68 do {
69 std::pair &Top = VisitStack.back();
70 NodeType *Node = Top.first;
71 ChildItTy &It = Top.second;
72
73 while (It != GT::child_end(Node)) {
74 NodeType *Next = *It++;
75 if (!Visited.count(Next)) { // Has our next sibling been visited?
76 // No, do it now.
77 Visited.insert(Next);
78 VisitStack.push_back(std::make_pair(Next, GT::child_begin(Next)));
79 return *this;
80 }
81 }
82
83 // Oops, ran out of successors... go up a level on the stack.
84 VisitStack.pop_back();
85 } while (!VisitStack.empty());
10386 return *this;
10487 }
10588
120103 // Provide global constructors that automatically figure out correct types...
121104 //
122105 template
123 df_iterator df_begin(T G, bool Reverse = false) {
124 return df_iterator::begin(G, Reverse);
106 df_iterator df_begin(T G) {
107 return df_iterator::begin(G);
125108 }
126109
127110 template
136119 };
137120
138121 template
139 idf_iterator idf_begin(T G, bool Reverse = false) {
140 return idf_iterator::begin(G, Reverse);
122 idf_iterator idf_begin(T G) {
123 return idf_iterator::begin(G);
141124 }
142125
143126 template
0 //===- Support/DepthFirstIterator.h - Depth First iterator ------*- C++ -*-===//
11 //
22 // This file builds on the Support/GraphTraits.h file to build generic depth
3 // first graph iterator.
3 // first graph iterator. This file exposes the following functions/types:
4 //
5 // df_begin/df_end/df_iterator
6 // * Normal depth-first iteration - visit a node and then all of its children.
7 //
8 // idf_begin/idf_end/idf_iterator
9 // * Depth-first iteration on the 'inverse' graph.
410 //
511 //===----------------------------------------------------------------------===//
612
915
1016 #include "Support/GraphTraits.h"
1117 #include "Support/iterator"
12 #include <stack>
18 #include <vector>
1319 #include
1420
1521 // Generic Depth First Iterator
2329 std::set Visited; // All of the blocks visited so far...
2430 // VisitStack - Used to maintain the ordering. Top = current block
2531 // First element is node pointer, second is the 'next child' to visit
26 std::stack > VisitStack;
27 const bool Reverse; // Iterate over children before self?
32 std::vector > VisitStack;
2833 private:
29 void reverseEnterNode() {
30 std::pair &Top = VisitStack.top();
31 NodeType *Node = Top.first;
32 ChildItTy &It = Top.second;
33 for (; It != GT::child_end(Node); ++It) {
34 NodeType *Child = *It;
35 if (!Visited.count(Child)) {
36 Visited.insert(Child);
37 VisitStack.push(std::make_pair(Child, GT::child_begin(Child)));
38 reverseEnterNode();
39 return;
40 }
41 }
42 }
43
44 inline df_iterator(NodeType *Node, bool reverse) : Reverse(reverse) {
34 inline df_iterator(NodeType *Node) {
4535 Visited.insert(Node);
46 VisitStack.push(std::make_pair(Node, GT::child_begin(Node)));
47 if (Reverse) reverseEnterNode();
36 VisitStack.push_back(std::make_pair(Node, GT::child_begin(Node)));
4837 }
4938 inline df_iterator() { /* End is when stack is empty */ }
5039
5342 typedef df_iterator _Self;
5443
5544 // Provide static begin and end methods as our public "constructors"
56 static inline _Self begin(GraphT G, bool Reverse = false) {
57 return _Self(GT::getEntryNode(G), Reverse);
45 static inline _Self begin(GraphT G) {
46 return _Self(GT::getEntryNode(G));
5847 }
5948 static inline _Self end(GraphT G) { return _Self(); }
6049
6150
6251 inline bool operator==(const _Self& x) const {
63 return VisitStack == x.VisitStack;
52 return VisitStack.size() == x.VisitStack.size() &&
53 VisitStack == x.VisitStack;
6454 }
6555 inline bool operator!=(const _Self& x) const { return !operator==(x); }
6656
6757 inline pointer operator*() const {
68 return VisitStack.top().first;
58 return VisitStack.back().first;
6959 }
7060
7161 // This is a nonstandard operator-> that dereferences the pointer an extra
7565 inline NodeType *operator->() const { return operator*(); }
7666
7767 inline _Self& operator++() { // Preincrement
78 if (Reverse) { // Reverse Depth First Iterator
79 if (VisitStack.top().second == GT::child_end(VisitStack.top().first))
80 VisitStack.pop();
81 if (!VisitStack.empty())
82 reverseEnterNode();
83 } else { // Normal Depth First Iterator
84 do {
85 std::pair &Top = VisitStack.top();
86 NodeType *Node = Top.first;
87 ChildItTy &It = Top.second;
88
89 while (It != GT::child_end(Node)) {
90 NodeType *Next = *It++;
91 if (!Visited.count(Next)) { // Has our next sibling been visited?
92 // No, do it now.
93 Visited.insert(Next);
94 VisitStack.push(std::make_pair(Next, GT::child_begin(Next)));
95 return *this;
96 }
97 }
98
99 // Oops, ran out of successors... go up a level on the stack.
100 VisitStack.pop();
101 } while (!VisitStack.empty());
102 }
68 do {
69 std::pair &Top = VisitStack.back();
70 NodeType *Node = Top.first;
71 ChildItTy &It = Top.second;
72
73 while (It != GT::child_end(Node)) {
74 NodeType *Next = *It++;
75 if (!Visited.count(Next)) { // Has our next sibling been visited?
76 // No, do it now.
77 Visited.insert(Next);
78 VisitStack.push_back(std::make_pair(Next, GT::child_begin(Next)));
79 return *this;
80 }
81 }
82
83 // Oops, ran out of successors... go up a level on the stack.
84 VisitStack.pop_back();
85 } while (!VisitStack.empty());
10386 return *this;
10487 }
10588
120103 // Provide global constructors that automatically figure out correct types...
121104 //
122105 template
123 df_iterator df_begin(T G, bool Reverse = false) {
124 return df_iterator::begin(G, Reverse);
106 df_iterator df_begin(T G) {
107 return df_iterator::begin(G);
125108 }
126109
127110 template
136119 };
137120
138121 template
139 idf_iterator idf_begin(T G, bool Reverse = false) {
140 return idf_iterator::begin(G, Reverse);
122 idf_iterator idf_begin(T G) {
123 return idf_iterator::begin(G);
141124 }
142125
143126 template