Coverage Report

Created: 2023-03-01 07:33

/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_