llvm.org GIT mirror llvm / 9061e99
add support for "external" depth first iterators, which store the 'visited' set outside of the iterator itself. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@9090 91177308-0d34-0410-b5e6-96231b3b80d8 Chris Lattner 16 years ago
2 changed file(s) with 198 addition(s) and 22 deletion(s). Raw diff Collapse all Expand all
77 //
88 // idf_begin/idf_end/idf_iterator
99 // * Depth-first iteration on the 'inverse' graph.
10 //
11 // df_ext_begin/df_ext_end/df_ext_iterator
12 // * Normal depth-first iteration - visit a node and then all of its children.
13 // This iterator stores the 'visited' set in an external set, which allows
14 // it to be more efficient, and allows external clients to use the set for
15 // other purposes.
16 //
17 // idf_ext_begin/idf_ext_end/idf_ext_iterator
18 // * Depth-first iteration on the 'inverse' graph.
19 // This iterator stores the 'visited' set in an external set, which allows
20 // it to be more efficient, and allows external clients to use the set for
21 // other purposes.
1022 //
1123 //===----------------------------------------------------------------------===//
1224
1830 #include
1931 #include
2032
33 // df_iterator_storage - A private class which is used to figure out where to
34 // store the visited set.
35 template // Non-external set
36 class df_iterator_storage {
37 public:
38 SetType Visited;
39 };
40
41 template
42 class df_iterator_storage {
43 public:
44 df_iterator_storage(SetType &VSet) : Visited(VSet) {}
45 df_iterator_storage(const df_iterator_storage &S) : Visited(S.Visited) {}
46 SetType &Visited;
47 };
48
49
2150 // Generic Depth First Iterator
22 template >
23 class df_iterator : public forward_iterator {
51 template
52 std::set::NodeType*>,
53 bool ExtStorage = false, class GT = GraphTraits >
54 class df_iterator : public forward_iterator,
55 public df_iterator_storage {
2456 typedef forward_iterator super;
2557
2658 typedef typename GT::NodeType NodeType;
2759 typedef typename GT::ChildIteratorType ChildItTy;
2860
29 std::set Visited; // All of the blocks visited so far...
3061 // VisitStack - Used to maintain the ordering. Top = current block
3162 // First element is node pointer, second is the 'next child' to visit
3263 std::vector > VisitStack;
3364 private:
3465 inline df_iterator(NodeType *Node) {
35 Visited.insert(Node);
66 this->Visited.insert(Node);
3667 VisitStack.push_back(std::make_pair(Node, GT::child_begin(Node)));
3768 }
3869 inline df_iterator() { /* End is when stack is empty */ }
70
71 inline df_iterator(NodeType *Node, SetType &S)
72 : df_iterator_storage(S) {
73 if (!S.count(Node)) {
74 this->Visited.insert(Node);
75 VisitStack.push_back(std::make_pair(Node, GT::child_begin(Node)));
76 }
77 }
78 inline df_iterator(SetType &S)
79 : df_iterator_storage(S) {
80 // End is when stack is empty
81 }
3982
4083 public:
4184 typedef typename super::pointer pointer;
42 typedef df_iteratorGT> _Self;
85 typedef df_iteratorSetType, ExtStorage, GT> _Self;
4386
4487 // Provide static begin and end methods as our public "constructors"
4588 static inline _Self begin(GraphT G) {
4790 }
4891 static inline _Self end(GraphT G) { return _Self(); }
4992
93 // Static begin and end methods as our public ctors for external iterators
94 static inline _Self begin(GraphT G, SetType &S) {
95 return _Self(GT::getEntryNode(G), S);
96 }
97 static inline _Self end(GraphT G, SetType &S) { return _Self(S); }
5098
5199 inline bool operator==(const _Self& x) const {
52100 return VisitStack.size() == x.VisitStack.size() &&
72120
73121 while (It != GT::child_end(Node)) {
74122 NodeType *Next = *It++;
75 if (!Visited.count(Next)) { // Has our next sibling been visited?
123 if (!this->Visited.count(Next)) { // Has our next sibling been visited?
76124 // No, do it now.
77 Visited.insert(Next);
125 this->Visited.insert(Next);
78126 VisitStack.push_back(std::make_pair(Next, GT::child_begin(Next)));
79127 return *this;
80128 }
95143 // nodes that a depth first iteration did not find: ie unreachable nodes.
96144 //
97145 inline bool nodeVisited(NodeType *Node) const {
98 return Visited.count(Node) != 0;
146 return this->Visited.count(Node) != 0;
99147 }
100148 };
101149
112160 return df_iterator::end(G);
113161 }
114162
163 // Provide global definitions of external depth first iterators...
164 template
165 struct df_ext_iterator : public df_iterator {
166 df_ext_iterator(const df_iterator &V)
167 : df_iterator(V) {}
168 };
169
170 template
171 df_ext_iterator df_ext_begin(T G, SetTy &S) {
172 return df_ext_iterator::begin(G, S);
173 }
174
175 template
176 df_ext_iterator df_ext_end(T G, SetTy &S) {
177 return df_ext_iterator::end(G, S);
178 }
179
180
115181 // Provide global definitions of inverse depth first iterators...
116 template
117 struct idf_iterator : public df_iterator > {
118 idf_iterator(const df_iterator > &V) :df_iterator >(V){}
182 template ::NodeType*>,
183 bool External = false>
184 struct idf_iterator : public df_iterator, SetTy, External> {
185 idf_iterator(const df_iterator, SetTy, External> &V)
186 : df_iterator, SetTy, External>(V) {}
119187 };
120188
121189 template
128196 return idf_iterator::end(G);
129197 }
130198
199 // Provide global definitions of external inverse depth first iterators...
200 template ::NodeType*> >
201 struct idf_ext_iterator : public idf_iterator {
202 idf_ext_iterator(const idf_iterator &V)
203 : idf_iterator(V) {}
204 idf_ext_iterator(const df_iterator, SetTy, true> &V)
205 : idf_iterator(V) {}
206 };
207
208 template
209 idf_ext_iterator idf_ext_begin(T G, SetTy &S) {
210 return idf_ext_iterator::begin(G, S);
211 }
212
213 template
214 idf_ext_iterator idf_ext_end(T G, SetTy &S) {
215 return idf_ext_iterator::end(G, S);
216 }
217
218
131219 #endif
77 //
88 // idf_begin/idf_end/idf_iterator
99 // * Depth-first iteration on the 'inverse' graph.
10 //
11 // df_ext_begin/df_ext_end/df_ext_iterator
12 // * Normal depth-first iteration - visit a node and then all of its children.
13 // This iterator stores the 'visited' set in an external set, which allows
14 // it to be more efficient, and allows external clients to use the set for
15 // other purposes.
16 //
17 // idf_ext_begin/idf_ext_end/idf_ext_iterator
18 // * Depth-first iteration on the 'inverse' graph.
19 // This iterator stores the 'visited' set in an external set, which allows
20 // it to be more efficient, and allows external clients to use the set for
21 // other purposes.
1022 //
1123 //===----------------------------------------------------------------------===//
1224
1830 #include
1931 #include
2032
33 // df_iterator_storage - A private class which is used to figure out where to
34 // store the visited set.
35 template // Non-external set
36 class df_iterator_storage {
37 public:
38 SetType Visited;
39 };
40
41 template
42 class df_iterator_storage {
43 public:
44 df_iterator_storage(SetType &VSet) : Visited(VSet) {}
45 df_iterator_storage(const df_iterator_storage &S) : Visited(S.Visited) {}
46 SetType &Visited;
47 };
48
49
2150 // Generic Depth First Iterator
22 template >
23 class df_iterator : public forward_iterator {
51 template
52 std::set::NodeType*>,
53 bool ExtStorage = false, class GT = GraphTraits >
54 class df_iterator : public forward_iterator,
55 public df_iterator_storage {
2456 typedef forward_iterator super;
2557
2658 typedef typename GT::NodeType NodeType;
2759 typedef typename GT::ChildIteratorType ChildItTy;
2860
29 std::set Visited; // All of the blocks visited so far...
3061 // VisitStack - Used to maintain the ordering. Top = current block
3162 // First element is node pointer, second is the 'next child' to visit
3263 std::vector > VisitStack;
3364 private:
3465 inline df_iterator(NodeType *Node) {
35 Visited.insert(Node);
66 this->Visited.insert(Node);
3667 VisitStack.push_back(std::make_pair(Node, GT::child_begin(Node)));
3768 }
3869 inline df_iterator() { /* End is when stack is empty */ }
70
71 inline df_iterator(NodeType *Node, SetType &S)
72 : df_iterator_storage(S) {
73 if (!S.count(Node)) {
74 this->Visited.insert(Node);
75 VisitStack.push_back(std::make_pair(Node, GT::child_begin(Node)));
76 }
77 }
78 inline df_iterator(SetType &S)
79 : df_iterator_storage(S) {
80 // End is when stack is empty
81 }
3982
4083 public:
4184 typedef typename super::pointer pointer;
42 typedef df_iteratorGT> _Self;
85 typedef df_iteratorSetType, ExtStorage, GT> _Self;
4386
4487 // Provide static begin and end methods as our public "constructors"
4588 static inline _Self begin(GraphT G) {
4790 }
4891 static inline _Self end(GraphT G) { return _Self(); }
4992
93 // Static begin and end methods as our public ctors for external iterators
94 static inline _Self begin(GraphT G, SetType &S) {
95 return _Self(GT::getEntryNode(G), S);
96 }
97 static inline _Self end(GraphT G, SetType &S) { return _Self(S); }
5098
5199 inline bool operator==(const _Self& x) const {
52100 return VisitStack.size() == x.VisitStack.size() &&
72120
73121 while (It != GT::child_end(Node)) {
74122 NodeType *Next = *It++;
75 if (!Visited.count(Next)) { // Has our next sibling been visited?
123 if (!this->Visited.count(Next)) { // Has our next sibling been visited?
76124 // No, do it now.
77 Visited.insert(Next);
125 this->Visited.insert(Next);
78126 VisitStack.push_back(std::make_pair(Next, GT::child_begin(Next)));
79127 return *this;
80128 }
95143 // nodes that a depth first iteration did not find: ie unreachable nodes.
96144 //
97145 inline bool nodeVisited(NodeType *Node) const {
98 return Visited.count(Node) != 0;
146 return this->Visited.count(Node) != 0;
99147 }
100148 };
101149
112160 return df_iterator::end(G);
113161 }
114162
163 // Provide global definitions of external depth first iterators...
164 template
165 struct df_ext_iterator : public df_iterator {
166 df_ext_iterator(const df_iterator &V)
167 : df_iterator(V) {}
168 };
169
170 template
171 df_ext_iterator df_ext_begin(T G, SetTy &S) {
172 return df_ext_iterator::begin(G, S);
173 }
174
175 template
176 df_ext_iterator df_ext_end(T G, SetTy &S) {
177 return df_ext_iterator::end(G, S);
178 }
179
180
115181 // Provide global definitions of inverse depth first iterators...
116 template
117 struct idf_iterator : public df_iterator > {
118 idf_iterator(const df_iterator > &V) :df_iterator >(V){}
182 template ::NodeType*>,
183 bool External = false>
184 struct idf_iterator : public df_iterator, SetTy, External> {
185 idf_iterator(const df_iterator, SetTy, External> &V)
186 : df_iterator, SetTy, External>(V) {}
119187 };
120188
121189 template
128196 return idf_iterator::end(G);
129197 }
130198
199 // Provide global definitions of external inverse depth first iterators...
200 template ::NodeType*> >
201 struct idf_ext_iterator : public idf_iterator {
202 idf_ext_iterator(const idf_iterator &V)
203 : idf_iterator(V) {}
204 idf_ext_iterator(const df_iterator, SetTy, true> &V)
205 : idf_iterator(V) {}
206 };
207
208 template
209 idf_ext_iterator idf_ext_begin(T G, SetTy &S) {
210 return idf_ext_iterator::begin(G, S);
211 }
212
213 template
214 idf_ext_iterator idf_ext_end(T G, SetTy &S) {
215 return idf_ext_iterator::end(G, S);
216 }
217
218
131219 #endif