/src/spirv-tools/source/opt/tree_iterator.h
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright (c) 2017 Google Inc. |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | | // you may not use this file except in compliance with the License. |
5 | | // You may obtain a copy of the License at |
6 | | // |
7 | | // http://www.apache.org/licenses/LICENSE-2.0 |
8 | | // |
9 | | // Unless required by applicable law or agreed to in writing, software |
10 | | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | | // See the License for the specific language governing permissions and |
13 | | // limitations under the License. |
14 | | |
15 | | #ifndef SOURCE_OPT_TREE_ITERATOR_H_ |
16 | | #define SOURCE_OPT_TREE_ITERATOR_H_ |
17 | | |
18 | | #include <stack> |
19 | | #include <type_traits> |
20 | | #include <utility> |
21 | | |
22 | | namespace spvtools { |
23 | | namespace opt { |
24 | | |
25 | | // Helper class to iterate over a tree in a depth first order. |
26 | | // The class assumes the data structure is a tree, tree node type implements a |
27 | | // forward iterator. |
28 | | // At each step, the iterator holds the pointer to the current node and state of |
29 | | // the walk. |
30 | | // The state is recorded by stacking the iteration position of the node |
31 | | // children. To move to the next node, the iterator: |
32 | | // - Looks at the top of the stack; |
33 | | // - Sets the node behind the iterator as the current node; |
34 | | // - Increments the iterator if it has more children to visit, pops otherwise; |
35 | | // - If the current node has children, the children iterator is pushed into the |
36 | | // stack. |
37 | | template <typename NodeTy> |
38 | | class TreeDFIterator { |
39 | | static_assert(!std::is_pointer<NodeTy>::value && |
40 | | !std::is_reference<NodeTy>::value, |
41 | | "NodeTy should be a class"); |
42 | | // Type alias to keep track of the const qualifier. |
43 | | using NodeIterator = |
44 | | typename std::conditional<std::is_const<NodeTy>::value, |
45 | | typename NodeTy::const_iterator, |
46 | | typename NodeTy::iterator>::type; |
47 | | |
48 | | // Type alias to keep track of the const qualifier. |
49 | | using NodePtr = NodeTy*; |
50 | | |
51 | | public: |
52 | | // Standard iterator interface. |
53 | | using reference = NodeTy&; |
54 | | using value_type = NodeTy; |
55 | | |
56 | 48.0k | explicit inline TreeDFIterator(NodePtr top_node) : current_(top_node) { |
57 | 48.0k | if (current_ && current_->begin() != current_->end()) |
58 | 24.0k | parent_iterators_.emplace(make_pair(current_, current_->begin())); |
59 | 48.0k | } spvtools::opt::TreeDFIterator<spvtools::opt::DominatorTreeNode>::TreeDFIterator(spvtools::opt::DominatorTreeNode*) Line | Count | Source | 56 | 48.0k | explicit inline TreeDFIterator(NodePtr top_node) : current_(top_node) { | 57 | 48.0k | if (current_ && current_->begin() != current_->end()) | 58 | 24.0k | parent_iterators_.emplace(make_pair(current_, current_->begin())); | 59 | 48.0k | } |
Unexecuted instantiation: spvtools::opt::TreeDFIterator<spvtools::opt::DominatorTreeNode const>::TreeDFIterator(spvtools::opt::DominatorTreeNode const*) Unexecuted instantiation: spvtools::opt::TreeDFIterator<spvtools::opt::Loop>::TreeDFIterator(spvtools::opt::Loop*) Unexecuted instantiation: spvtools::opt::TreeDFIterator<spvtools::opt::SENode const>::TreeDFIterator(spvtools::opt::SENode const*) Unexecuted instantiation: spvtools::opt::TreeDFIterator<spvtools::opt::SENode>::TreeDFIterator(spvtools::opt::SENode*) |
60 | | |
61 | | // end() iterator. |
62 | 24.0k | inline TreeDFIterator() : TreeDFIterator(nullptr) {} spvtools::opt::TreeDFIterator<spvtools::opt::DominatorTreeNode>::TreeDFIterator() Line | Count | Source | 62 | 24.0k | inline TreeDFIterator() : TreeDFIterator(nullptr) {} |
Unexecuted instantiation: spvtools::opt::TreeDFIterator<spvtools::opt::DominatorTreeNode const>::TreeDFIterator() Unexecuted instantiation: spvtools::opt::TreeDFIterator<spvtools::opt::Loop>::TreeDFIterator() Unexecuted instantiation: spvtools::opt::TreeDFIterator<spvtools::opt::SENode const>::TreeDFIterator() Unexecuted instantiation: spvtools::opt::TreeDFIterator<spvtools::opt::SENode>::TreeDFIterator() |
63 | | |
64 | 1.12M | bool operator==(const TreeDFIterator& x) const { |
65 | 1.12M | return current_ == x.current_; |
66 | 1.12M | } spvtools::opt::TreeDFIterator<spvtools::opt::DominatorTreeNode>::operator==(spvtools::opt::TreeDFIterator<spvtools::opt::DominatorTreeNode> const&) const Line | Count | Source | 64 | 1.12M | bool operator==(const TreeDFIterator& x) const { | 65 | 1.12M | return current_ == x.current_; | 66 | 1.12M | } |
Unexecuted instantiation: spvtools::opt::TreeDFIterator<spvtools::opt::DominatorTreeNode const>::operator==(spvtools::opt::TreeDFIterator<spvtools::opt::DominatorTreeNode const> const&) const Unexecuted instantiation: spvtools::opt::TreeDFIterator<spvtools::opt::Loop>::operator==(spvtools::opt::TreeDFIterator<spvtools::opt::Loop> const&) const Unexecuted instantiation: spvtools::opt::TreeDFIterator<spvtools::opt::SENode const>::operator==(spvtools::opt::TreeDFIterator<spvtools::opt::SENode const> const&) const Unexecuted instantiation: spvtools::opt::TreeDFIterator<spvtools::opt::SENode>::operator==(spvtools::opt::TreeDFIterator<spvtools::opt::SENode> const&) const |
67 | | |
68 | 1.12M | bool operator!=(const TreeDFIterator& x) const { return !(*this == x); } spvtools::opt::TreeDFIterator<spvtools::opt::DominatorTreeNode>::operator!=(spvtools::opt::TreeDFIterator<spvtools::opt::DominatorTreeNode> const&) const Line | Count | Source | 68 | 1.12M | bool operator!=(const TreeDFIterator& x) const { return !(*this == x); } |
Unexecuted instantiation: spvtools::opt::TreeDFIterator<spvtools::opt::DominatorTreeNode const>::operator!=(spvtools::opt::TreeDFIterator<spvtools::opt::DominatorTreeNode const> const&) const Unexecuted instantiation: spvtools::opt::TreeDFIterator<spvtools::opt::Loop>::operator!=(spvtools::opt::TreeDFIterator<spvtools::opt::Loop> const&) const Unexecuted instantiation: spvtools::opt::TreeDFIterator<spvtools::opt::SENode const>::operator!=(spvtools::opt::TreeDFIterator<spvtools::opt::SENode const> const&) const Unexecuted instantiation: spvtools::opt::TreeDFIterator<spvtools::opt::SENode>::operator!=(spvtools::opt::TreeDFIterator<spvtools::opt::SENode> const&) const |
69 | | |
70 | 1.10M | reference operator*() const { return *current_; } spvtools::opt::TreeDFIterator<spvtools::opt::DominatorTreeNode>::operator*() const Line | Count | Source | 70 | 1.10M | reference operator*() const { return *current_; } |
Unexecuted instantiation: spvtools::opt::TreeDFIterator<spvtools::opt::DominatorTreeNode const>::operator*() const Unexecuted instantiation: spvtools::opt::TreeDFIterator<spvtools::opt::Loop>::operator*() const |
71 | | |
72 | 0 | NodePtr operator->() const { return current_; } Unexecuted instantiation: spvtools::opt::TreeDFIterator<spvtools::opt::DominatorTreeNode>::operator->() const Unexecuted instantiation: spvtools::opt::TreeDFIterator<spvtools::opt::SENode const>::operator->() const Unexecuted instantiation: spvtools::opt::TreeDFIterator<spvtools::opt::SENode>::operator->() const |
73 | | |
74 | 1.10M | TreeDFIterator& operator++() { |
75 | 1.10M | MoveToNextNode(); |
76 | 1.10M | return *this; |
77 | 1.10M | } spvtools::opt::TreeDFIterator<spvtools::opt::DominatorTreeNode>::operator++() Line | Count | Source | 74 | 1.10M | TreeDFIterator& operator++() { | 75 | 1.10M | MoveToNextNode(); | 76 | 1.10M | return *this; | 77 | 1.10M | } |
Unexecuted instantiation: spvtools::opt::TreeDFIterator<spvtools::opt::DominatorTreeNode const>::operator++() Unexecuted instantiation: spvtools::opt::TreeDFIterator<spvtools::opt::Loop>::operator++() Unexecuted instantiation: spvtools::opt::TreeDFIterator<spvtools::opt::Loop const>::operator++() Unexecuted instantiation: spvtools::opt::TreeDFIterator<spvtools::opt::SENode const>::operator++() Unexecuted instantiation: spvtools::opt::TreeDFIterator<spvtools::opt::SENode>::operator++() |
78 | | |
79 | | TreeDFIterator operator++(int) { |
80 | | TreeDFIterator tmp = *this; |
81 | | ++*this; |
82 | | return tmp; |
83 | | } |
84 | | |
85 | | private: |
86 | | // Moves the iterator to the next node in the tree. |
87 | | // If we are at the end, do nothing, otherwise |
88 | | // if our current node has children, use the children iterator and push the |
89 | | // current node into the stack. |
90 | | // If we reach the end of the local iterator, pop it. |
91 | 1.10M | inline void MoveToNextNode() { |
92 | 1.10M | if (!current_) return; |
93 | 1.10M | if (parent_iterators_.empty()) { |
94 | 24.0k | current_ = nullptr; |
95 | 24.0k | return; |
96 | 24.0k | } |
97 | 1.07M | std::pair<NodePtr, NodeIterator>& next_it = parent_iterators_.top(); |
98 | | // Set the new node. |
99 | 1.07M | current_ = *next_it.second; |
100 | | // Update the iterator for the next child. |
101 | 1.07M | ++next_it.second; |
102 | | // If we finished with node, pop it. |
103 | 1.07M | if (next_it.first->end() == next_it.second) parent_iterators_.pop(); |
104 | | // If our current node is not a leaf, store the iteration state for later. |
105 | 1.07M | if (current_->begin() != current_->end()) |
106 | 660k | parent_iterators_.emplace(make_pair(current_, current_->begin())); |
107 | 1.07M | } spvtools::opt::TreeDFIterator<spvtools::opt::DominatorTreeNode>::MoveToNextNode() Line | Count | Source | 91 | 1.10M | inline void MoveToNextNode() { | 92 | 1.10M | if (!current_) return; | 93 | 1.10M | if (parent_iterators_.empty()) { | 94 | 24.0k | current_ = nullptr; | 95 | 24.0k | return; | 96 | 24.0k | } | 97 | 1.07M | std::pair<NodePtr, NodeIterator>& next_it = parent_iterators_.top(); | 98 | | // Set the new node. | 99 | 1.07M | current_ = *next_it.second; | 100 | | // Update the iterator for the next child. | 101 | 1.07M | ++next_it.second; | 102 | | // If we finished with node, pop it. | 103 | 1.07M | if (next_it.first->end() == next_it.second) parent_iterators_.pop(); | 104 | | // If our current node is not a leaf, store the iteration state for later. | 105 | 1.07M | if (current_->begin() != current_->end()) | 106 | 660k | parent_iterators_.emplace(make_pair(current_, current_->begin())); | 107 | 1.07M | } |
Unexecuted instantiation: spvtools::opt::TreeDFIterator<spvtools::opt::DominatorTreeNode const>::MoveToNextNode() Unexecuted instantiation: spvtools::opt::TreeDFIterator<spvtools::opt::Loop>::MoveToNextNode() Unexecuted instantiation: spvtools::opt::TreeDFIterator<spvtools::opt::Loop const>::MoveToNextNode() Unexecuted instantiation: spvtools::opt::TreeDFIterator<spvtools::opt::SENode const>::MoveToNextNode() Unexecuted instantiation: spvtools::opt::TreeDFIterator<spvtools::opt::SENode>::MoveToNextNode() |
108 | | |
109 | | // The current node of the tree. |
110 | | NodePtr current_; |
111 | | // State of the tree walk: each pair contains the parent node (which has been |
112 | | // already visited) and the iterator of the next children to visit. |
113 | | // When all the children has been visited, we pop the entry, get the next |
114 | | // child and push back the pair if the children iterator is not end(). |
115 | | std::stack<std::pair<NodePtr, NodeIterator>> parent_iterators_; |
116 | | }; |
117 | | |
118 | | // Helper class to iterate over a tree in a depth first post-order. |
119 | | // The class assumes the data structure is a tree, tree node type implements a |
120 | | // forward iterator. |
121 | | // At each step, the iterator holds the pointer to the current node and state of |
122 | | // the walk. |
123 | | // The state is recorded by stacking the iteration position of the node |
124 | | // children. To move to the next node, the iterator: |
125 | | // - Looks at the top of the stack; |
126 | | // - If the children iterator has reach the end, then the node become the |
127 | | // current one and we pop the stack; |
128 | | // - Otherwise, we save the child and increment the iterator; |
129 | | // - We walk the child sub-tree until we find a leaf, stacking all non-leaves |
130 | | // states (pair of node pointer and child iterator) as we walk it. |
131 | | template <typename NodeTy> |
132 | | class PostOrderTreeDFIterator { |
133 | | static_assert(!std::is_pointer<NodeTy>::value && |
134 | | !std::is_reference<NodeTy>::value, |
135 | | "NodeTy should be a class"); |
136 | | // Type alias to keep track of the const qualifier. |
137 | | using NodeIterator = |
138 | | typename std::conditional<std::is_const<NodeTy>::value, |
139 | | typename NodeTy::const_iterator, |
140 | | typename NodeTy::iterator>::type; |
141 | | |
142 | | // Type alias to keep track of the const qualifier. |
143 | | using NodePtr = NodeTy*; |
144 | | |
145 | | public: |
146 | | // Standard iterator interface. |
147 | | using reference = NodeTy&; |
148 | | using value_type = NodeTy; |
149 | | |
150 | 22.1k | static inline PostOrderTreeDFIterator begin(NodePtr top_node) { |
151 | 22.1k | return PostOrderTreeDFIterator(top_node); |
152 | 22.1k | } spvtools::opt::PostOrderTreeDFIterator<spvtools::opt::DominatorTreeNode>::begin(spvtools::opt::DominatorTreeNode*) Line | Count | Source | 150 | 11.0k | static inline PostOrderTreeDFIterator begin(NodePtr top_node) { | 151 | 11.0k | return PostOrderTreeDFIterator(top_node); | 152 | 11.0k | } |
Unexecuted instantiation: spvtools::opt::PostOrderTreeDFIterator<spvtools::opt::DominatorTreeNode const>::begin(spvtools::opt::DominatorTreeNode const*) spvtools::opt::PostOrderTreeDFIterator<spvtools::opt::Loop>::begin(spvtools::opt::Loop*) Line | Count | Source | 150 | 11.0k | static inline PostOrderTreeDFIterator begin(NodePtr top_node) { | 151 | 11.0k | return PostOrderTreeDFIterator(top_node); | 152 | 11.0k | } |
Unexecuted instantiation: spvtools::opt::PostOrderTreeDFIterator<spvtools::opt::Loop const>::begin(spvtools::opt::Loop const*) |
153 | | |
154 | 22.1k | static inline PostOrderTreeDFIterator end(NodePtr sentinel_node) { |
155 | 22.1k | return PostOrderTreeDFIterator(sentinel_node, false); |
156 | 22.1k | } spvtools::opt::PostOrderTreeDFIterator<spvtools::opt::DominatorTreeNode>::end(spvtools::opt::DominatorTreeNode*) Line | Count | Source | 154 | 11.0k | static inline PostOrderTreeDFIterator end(NodePtr sentinel_node) { | 155 | 11.0k | return PostOrderTreeDFIterator(sentinel_node, false); | 156 | 11.0k | } |
Unexecuted instantiation: spvtools::opt::PostOrderTreeDFIterator<spvtools::opt::DominatorTreeNode const>::end(spvtools::opt::DominatorTreeNode const*) spvtools::opt::PostOrderTreeDFIterator<spvtools::opt::Loop>::end(spvtools::opt::Loop*) Line | Count | Source | 154 | 11.0k | static inline PostOrderTreeDFIterator end(NodePtr sentinel_node) { | 155 | 11.0k | return PostOrderTreeDFIterator(sentinel_node, false); | 156 | 11.0k | } |
Unexecuted instantiation: spvtools::opt::PostOrderTreeDFIterator<spvtools::opt::Loop const>::end(spvtools::opt::Loop const*) |
157 | | |
158 | 317k | bool operator==(const PostOrderTreeDFIterator& x) const { |
159 | 317k | return current_ == x.current_; |
160 | 317k | } spvtools::opt::PostOrderTreeDFIterator<spvtools::opt::DominatorTreeNode>::operator==(spvtools::opt::PostOrderTreeDFIterator<spvtools::opt::DominatorTreeNode> const&) const Line | Count | Source | 158 | 282k | bool operator==(const PostOrderTreeDFIterator& x) const { | 159 | 282k | return current_ == x.current_; | 160 | 282k | } |
spvtools::opt::PostOrderTreeDFIterator<spvtools::opt::Loop>::operator==(spvtools::opt::PostOrderTreeDFIterator<spvtools::opt::Loop> const&) const Line | Count | Source | 158 | 35.0k | bool operator==(const PostOrderTreeDFIterator& x) const { | 159 | 35.0k | return current_ == x.current_; | 160 | 35.0k | } |
|
161 | | |
162 | 317k | bool operator!=(const PostOrderTreeDFIterator& x) const { |
163 | 317k | return !(*this == x); |
164 | 317k | } spvtools::opt::PostOrderTreeDFIterator<spvtools::opt::DominatorTreeNode>::operator!=(spvtools::opt::PostOrderTreeDFIterator<spvtools::opt::DominatorTreeNode> const&) const Line | Count | Source | 162 | 282k | bool operator!=(const PostOrderTreeDFIterator& x) const { | 163 | 282k | return !(*this == x); | 164 | 282k | } |
spvtools::opt::PostOrderTreeDFIterator<spvtools::opt::Loop>::operator!=(spvtools::opt::PostOrderTreeDFIterator<spvtools::opt::Loop> const&) const Line | Count | Source | 162 | 35.0k | bool operator!=(const PostOrderTreeDFIterator& x) const { | 163 | 35.0k | return !(*this == x); | 164 | 35.0k | } |
|
165 | | |
166 | 295k | reference operator*() const { return *current_; } spvtools::opt::PostOrderTreeDFIterator<spvtools::opt::DominatorTreeNode>::operator*() const Line | Count | Source | 166 | 271k | reference operator*() const { return *current_; } |
spvtools::opt::PostOrderTreeDFIterator<spvtools::opt::Loop>::operator*() const Line | Count | Source | 166 | 24.0k | reference operator*() const { return *current_; } |
|
167 | | |
168 | | NodePtr operator->() const { return current_; } |
169 | | |
170 | 295k | PostOrderTreeDFIterator& operator++() { |
171 | 295k | MoveToNextNode(); |
172 | 295k | return *this; |
173 | 295k | } spvtools::opt::PostOrderTreeDFIterator<spvtools::opt::DominatorTreeNode>::operator++() Line | Count | Source | 170 | 271k | PostOrderTreeDFIterator& operator++() { | 171 | 271k | MoveToNextNode(); | 172 | 271k | return *this; | 173 | 271k | } |
spvtools::opt::PostOrderTreeDFIterator<spvtools::opt::Loop>::operator++() Line | Count | Source | 170 | 24.0k | PostOrderTreeDFIterator& operator++() { | 171 | 24.0k | MoveToNextNode(); | 172 | 24.0k | return *this; | 173 | 24.0k | } |
|
174 | | |
175 | | PostOrderTreeDFIterator operator++(int) { |
176 | | PostOrderTreeDFIterator tmp = *this; |
177 | | ++*this; |
178 | | return tmp; |
179 | | } |
180 | | |
181 | | private: |
182 | | explicit inline PostOrderTreeDFIterator(NodePtr top_node) |
183 | 22.1k | : current_(top_node) { |
184 | 22.1k | if (current_) WalkToLeaf(); |
185 | 22.1k | } spvtools::opt::PostOrderTreeDFIterator<spvtools::opt::DominatorTreeNode>::PostOrderTreeDFIterator(spvtools::opt::DominatorTreeNode*) Line | Count | Source | 183 | 11.0k | : current_(top_node) { | 184 | 11.0k | if (current_) WalkToLeaf(); | 185 | 11.0k | } |
spvtools::opt::PostOrderTreeDFIterator<spvtools::opt::Loop>::PostOrderTreeDFIterator(spvtools::opt::Loop*) Line | Count | Source | 183 | 11.0k | : current_(top_node) { | 184 | 11.0k | if (current_) WalkToLeaf(); | 185 | 11.0k | } |
|
186 | | |
187 | | // Constructor for the "end()" iterator. |
188 | | // |end_sentinel| is the value that acts as end value (can be null). The bool |
189 | | // parameters is to distinguish from the start() Ctor. |
190 | | inline PostOrderTreeDFIterator(NodePtr sentinel_node, bool) |
191 | 22.1k | : current_(sentinel_node) {} spvtools::opt::PostOrderTreeDFIterator<spvtools::opt::DominatorTreeNode>::PostOrderTreeDFIterator(spvtools::opt::DominatorTreeNode*, bool) Line | Count | Source | 191 | 11.0k | : current_(sentinel_node) {} |
spvtools::opt::PostOrderTreeDFIterator<spvtools::opt::Loop>::PostOrderTreeDFIterator(spvtools::opt::Loop*, bool) Line | Count | Source | 191 | 11.0k | : current_(sentinel_node) {} |
|
192 | | |
193 | | // Moves the iterator to the next node in the tree. |
194 | | // If we are at the end, do nothing, otherwise |
195 | | // if our current node has children, use the children iterator and push the |
196 | | // current node into the stack. |
197 | | // If we reach the end of the local iterator, pop it. |
198 | 295k | inline void MoveToNextNode() { |
199 | 295k | if (!current_) return; |
200 | 295k | if (parent_iterators_.empty()) { |
201 | 0 | current_ = nullptr; |
202 | 0 | return; |
203 | 0 | } |
204 | 295k | std::pair<NodePtr, NodeIterator>& next_it = parent_iterators_.top(); |
205 | | // If we visited all children, the current node is the top of the stack. |
206 | 295k | if (next_it.second == next_it.first->end()) { |
207 | | // Set the new node. |
208 | 190k | current_ = next_it.first; |
209 | 190k | parent_iterators_.pop(); |
210 | 190k | return; |
211 | 190k | } |
212 | | // We have more children to visit, set the current node to the first child |
213 | | // and dive to leaf. |
214 | 104k | current_ = *next_it.second; |
215 | | // Update the iterator for the next child (avoid unneeded pop). |
216 | 104k | ++next_it.second; |
217 | 104k | WalkToLeaf(); |
218 | 104k | } spvtools::opt::PostOrderTreeDFIterator<spvtools::opt::DominatorTreeNode>::MoveToNextNode() Line | Count | Source | 198 | 271k | inline void MoveToNextNode() { | 199 | 271k | if (!current_) return; | 200 | 271k | if (parent_iterators_.empty()) { | 201 | 0 | current_ = nullptr; | 202 | 0 | return; | 203 | 0 | } | 204 | 271k | std::pair<NodePtr, NodeIterator>& next_it = parent_iterators_.top(); | 205 | | // If we visited all children, the current node is the top of the stack. | 206 | 271k | if (next_it.second == next_it.first->end()) { | 207 | | // Set the new node. | 208 | 180k | current_ = next_it.first; | 209 | 180k | parent_iterators_.pop(); | 210 | 180k | return; | 211 | 180k | } | 212 | | // We have more children to visit, set the current node to the first child | 213 | | // and dive to leaf. | 214 | 91.1k | current_ = *next_it.second; | 215 | | // Update the iterator for the next child (avoid unneeded pop). | 216 | 91.1k | ++next_it.second; | 217 | 91.1k | WalkToLeaf(); | 218 | 91.1k | } |
spvtools::opt::PostOrderTreeDFIterator<spvtools::opt::Loop>::MoveToNextNode() Line | Count | Source | 198 | 24.0k | inline void MoveToNextNode() { | 199 | 24.0k | if (!current_) return; | 200 | 24.0k | if (parent_iterators_.empty()) { | 201 | 0 | current_ = nullptr; | 202 | 0 | return; | 203 | 0 | } | 204 | 24.0k | std::pair<NodePtr, NodeIterator>& next_it = parent_iterators_.top(); | 205 | | // If we visited all children, the current node is the top of the stack. | 206 | 24.0k | if (next_it.second == next_it.first->end()) { | 207 | | // Set the new node. | 208 | 10.2k | current_ = next_it.first; | 209 | 10.2k | parent_iterators_.pop(); | 210 | 10.2k | return; | 211 | 10.2k | } | 212 | | // We have more children to visit, set the current node to the first child | 213 | | // and dive to leaf. | 214 | 13.7k | current_ = *next_it.second; | 215 | | // Update the iterator for the next child (avoid unneeded pop). | 216 | 13.7k | ++next_it.second; | 217 | 13.7k | WalkToLeaf(); | 218 | 13.7k | } |
|
219 | | |
220 | | // Moves the iterator to the next node in the tree. |
221 | | // If we are at the end, do nothing, otherwise |
222 | | // if our current node has children, use the children iterator and push the |
223 | | // current node into the stack. |
224 | | // If we reach the end of the local iterator, pop it. |
225 | 127k | inline void WalkToLeaf() { |
226 | 317k | while (current_->begin() != current_->end()) { |
227 | 190k | NodeIterator next = ++current_->begin(); |
228 | 190k | parent_iterators_.emplace(make_pair(current_, next)); |
229 | | // Set the first child as the new node. |
230 | 190k | current_ = *current_->begin(); |
231 | 190k | } |
232 | 127k | } spvtools::opt::PostOrderTreeDFIterator<spvtools::opt::DominatorTreeNode>::WalkToLeaf() Line | Count | Source | 225 | 102k | inline void WalkToLeaf() { | 226 | 282k | while (current_->begin() != current_->end()) { | 227 | 180k | NodeIterator next = ++current_->begin(); | 228 | 180k | parent_iterators_.emplace(make_pair(current_, next)); | 229 | | // Set the first child as the new node. | 230 | 180k | current_ = *current_->begin(); | 231 | 180k | } | 232 | 102k | } |
Unexecuted instantiation: spvtools::opt::PostOrderTreeDFIterator<spvtools::opt::DominatorTreeNode const>::WalkToLeaf() spvtools::opt::PostOrderTreeDFIterator<spvtools::opt::Loop>::WalkToLeaf() Line | Count | Source | 225 | 24.8k | inline void WalkToLeaf() { | 226 | 35.0k | while (current_->begin() != current_->end()) { | 227 | 10.2k | NodeIterator next = ++current_->begin(); | 228 | 10.2k | parent_iterators_.emplace(make_pair(current_, next)); | 229 | | // Set the first child as the new node. | 230 | 10.2k | current_ = *current_->begin(); | 231 | 10.2k | } | 232 | 24.8k | } |
Unexecuted instantiation: spvtools::opt::PostOrderTreeDFIterator<spvtools::opt::Loop const>::WalkToLeaf() |
233 | | |
234 | | // The current node of the tree. |
235 | | NodePtr current_; |
236 | | // State of the tree walk: each pair contains the parent node and the iterator |
237 | | // of the next children to visit. |
238 | | // When all the children has been visited, we pop the first entry and the |
239 | | // parent node become the current node. |
240 | | std::stack<std::pair<NodePtr, NodeIterator>> parent_iterators_; |
241 | | }; |
242 | | |
243 | | } // namespace opt |
244 | | } // namespace spvtools |
245 | | |
246 | | #endif // SOURCE_OPT_TREE_ITERATOR_H_ |