Coverage Report

Created: 2026-08-14 06:34

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/spirv-tools/source/opt/tree_iterator.h
Line
Count
Source
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
63.5k
  explicit inline TreeDFIterator(NodePtr top_node) : current_(top_node) {
57
63.5k
    if (current_ && current_->begin() != current_->end())
58
31.7k
      parent_iterators_.emplace(make_pair(current_, current_->begin()));
59
63.5k
  }
spvtools::opt::TreeDFIterator<spvtools::opt::DominatorTreeNode>::TreeDFIterator(spvtools::opt::DominatorTreeNode*)
Line
Count
Source
56
63.5k
  explicit inline TreeDFIterator(NodePtr top_node) : current_(top_node) {
57
63.5k
    if (current_ && current_->begin() != current_->end())
58
31.7k
      parent_iterators_.emplace(make_pair(current_, current_->begin()));
59
63.5k
  }
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
31.7k
  inline TreeDFIterator() : TreeDFIterator(nullptr) {}
spvtools::opt::TreeDFIterator<spvtools::opt::DominatorTreeNode>::TreeDFIterator()
Line
Count
Source
62
31.7k
  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.45M
  bool operator==(const TreeDFIterator& x) const {
65
1.45M
    return current_ == x.current_;
66
1.45M
  }
spvtools::opt::TreeDFIterator<spvtools::opt::DominatorTreeNode>::operator==(spvtools::opt::TreeDFIterator<spvtools::opt::DominatorTreeNode> const&) const
Line
Count
Source
64
1.45M
  bool operator==(const TreeDFIterator& x) const {
65
1.45M
    return current_ == x.current_;
66
1.45M
  }
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.45M
  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.45M
  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.42M
  reference operator*() const { return *current_; }
spvtools::opt::TreeDFIterator<spvtools::opt::DominatorTreeNode>::operator*() const
Line
Count
Source
70
1.42M
  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.42M
  TreeDFIterator& operator++() {
75
1.42M
    MoveToNextNode();
76
1.42M
    return *this;
77
1.42M
  }
spvtools::opt::TreeDFIterator<spvtools::opt::DominatorTreeNode>::operator++()
Line
Count
Source
74
1.42M
  TreeDFIterator& operator++() {
75
1.42M
    MoveToNextNode();
76
1.42M
    return *this;
77
1.42M
  }
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.42M
  inline void MoveToNextNode() {
92
1.42M
    if (!current_) return;
93
1.42M
    if (parent_iterators_.empty()) {
94
31.7k
      current_ = nullptr;
95
31.7k
      return;
96
31.7k
    }
97
1.39M
    std::pair<NodePtr, NodeIterator>& next_it = parent_iterators_.top();
98
    // Set the new node.
99
1.39M
    current_ = *next_it.second;
100
    // Update the iterator for the next child.
101
1.39M
    ++next_it.second;
102
    // If we finished with node, pop it.
103
1.39M
    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.39M
    if (current_->begin() != current_->end())
106
814k
      parent_iterators_.emplace(make_pair(current_, current_->begin()));
107
1.39M
  }
spvtools::opt::TreeDFIterator<spvtools::opt::DominatorTreeNode>::MoveToNextNode()
Line
Count
Source
91
1.42M
  inline void MoveToNextNode() {
92
1.42M
    if (!current_) return;
93
1.42M
    if (parent_iterators_.empty()) {
94
31.7k
      current_ = nullptr;
95
31.7k
      return;
96
31.7k
    }
97
1.39M
    std::pair<NodePtr, NodeIterator>& next_it = parent_iterators_.top();
98
    // Set the new node.
99
1.39M
    current_ = *next_it.second;
100
    // Update the iterator for the next child.
101
1.39M
    ++next_it.second;
102
    // If we finished with node, pop it.
103
1.39M
    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.39M
    if (current_->begin() != current_->end())
106
814k
      parent_iterators_.emplace(make_pair(current_, current_->begin()));
107
1.39M
  }
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
37.5k
  static inline PostOrderTreeDFIterator begin(NodePtr top_node) {
151
37.5k
    return PostOrderTreeDFIterator(top_node);
152
37.5k
  }
spvtools::opt::PostOrderTreeDFIterator<spvtools::opt::DominatorTreeNode>::begin(spvtools::opt::DominatorTreeNode*)
Line
Count
Source
150
18.7k
  static inline PostOrderTreeDFIterator begin(NodePtr top_node) {
151
18.7k
    return PostOrderTreeDFIterator(top_node);
152
18.7k
  }
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
18.7k
  static inline PostOrderTreeDFIterator begin(NodePtr top_node) {
151
18.7k
    return PostOrderTreeDFIterator(top_node);
152
18.7k
  }
Unexecuted instantiation: spvtools::opt::PostOrderTreeDFIterator<spvtools::opt::Loop const>::begin(spvtools::opt::Loop const*)
153
154
37.5k
  static inline PostOrderTreeDFIterator end(NodePtr sentinel_node) {
155
37.5k
    return PostOrderTreeDFIterator(sentinel_node, false);
156
37.5k
  }
spvtools::opt::PostOrderTreeDFIterator<spvtools::opt::DominatorTreeNode>::end(spvtools::opt::DominatorTreeNode*)
Line
Count
Source
154
18.7k
  static inline PostOrderTreeDFIterator end(NodePtr sentinel_node) {
155
18.7k
    return PostOrderTreeDFIterator(sentinel_node, false);
156
18.7k
  }
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
18.7k
  static inline PostOrderTreeDFIterator end(NodePtr sentinel_node) {
155
18.7k
    return PostOrderTreeDFIterator(sentinel_node, false);
156
18.7k
  }
Unexecuted instantiation: spvtools::opt::PostOrderTreeDFIterator<spvtools::opt::Loop const>::end(spvtools::opt::Loop const*)
157
158
469k
  bool operator==(const PostOrderTreeDFIterator& x) const {
159
469k
    return current_ == x.current_;
160
469k
  }
spvtools::opt::PostOrderTreeDFIterator<spvtools::opt::DominatorTreeNode>::operator==(spvtools::opt::PostOrderTreeDFIterator<spvtools::opt::DominatorTreeNode> const&) const
Line
Count
Source
158
418k
  bool operator==(const PostOrderTreeDFIterator& x) const {
159
418k
    return current_ == x.current_;
160
418k
  }
spvtools::opt::PostOrderTreeDFIterator<spvtools::opt::Loop>::operator==(spvtools::opt::PostOrderTreeDFIterator<spvtools::opt::Loop> const&) const
Line
Count
Source
158
50.5k
  bool operator==(const PostOrderTreeDFIterator& x) const {
159
50.5k
    return current_ == x.current_;
160
50.5k
  }
161
162
469k
  bool operator!=(const PostOrderTreeDFIterator& x) const {
163
469k
    return !(*this == x);
164
469k
  }
spvtools::opt::PostOrderTreeDFIterator<spvtools::opt::DominatorTreeNode>::operator!=(spvtools::opt::PostOrderTreeDFIterator<spvtools::opt::DominatorTreeNode> const&) const
Line
Count
Source
162
418k
  bool operator!=(const PostOrderTreeDFIterator& x) const {
163
418k
    return !(*this == x);
164
418k
  }
spvtools::opt::PostOrderTreeDFIterator<spvtools::opt::Loop>::operator!=(spvtools::opt::PostOrderTreeDFIterator<spvtools::opt::Loop> const&) const
Line
Count
Source
162
50.5k
  bool operator!=(const PostOrderTreeDFIterator& x) const {
163
50.5k
    return !(*this == x);
164
50.5k
  }
165
166
431k
  reference operator*() const { return *current_; }
spvtools::opt::PostOrderTreeDFIterator<spvtools::opt::DominatorTreeNode>::operator*() const
Line
Count
Source
166
399k
  reference operator*() const { return *current_; }
spvtools::opt::PostOrderTreeDFIterator<spvtools::opt::Loop>::operator*() const
Line
Count
Source
166
31.7k
  reference operator*() const { return *current_; }
167
168
  NodePtr operator->() const { return current_; }
169
170
431k
  PostOrderTreeDFIterator& operator++() {
171
431k
    MoveToNextNode();
172
431k
    return *this;
173
431k
  }
spvtools::opt::PostOrderTreeDFIterator<spvtools::opt::DominatorTreeNode>::operator++()
Line
Count
Source
170
399k
  PostOrderTreeDFIterator& operator++() {
171
399k
    MoveToNextNode();
172
399k
    return *this;
173
399k
  }
spvtools::opt::PostOrderTreeDFIterator<spvtools::opt::Loop>::operator++()
Line
Count
Source
170
31.7k
  PostOrderTreeDFIterator& operator++() {
171
31.7k
    MoveToNextNode();
172
31.7k
    return *this;
173
31.7k
  }
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
37.5k
      : current_(top_node) {
184
37.5k
    if (current_) WalkToLeaf();
185
37.5k
  }
spvtools::opt::PostOrderTreeDFIterator<spvtools::opt::DominatorTreeNode>::PostOrderTreeDFIterator(spvtools::opt::DominatorTreeNode*)
Line
Count
Source
183
18.7k
      : current_(top_node) {
184
18.7k
    if (current_) WalkToLeaf();
185
18.7k
  }
spvtools::opt::PostOrderTreeDFIterator<spvtools::opt::Loop>::PostOrderTreeDFIterator(spvtools::opt::Loop*)
Line
Count
Source
183
18.7k
      : current_(top_node) {
184
18.7k
    if (current_) WalkToLeaf();
185
18.7k
  }
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
37.5k
      : current_(sentinel_node) {}
spvtools::opt::PostOrderTreeDFIterator<spvtools::opt::DominatorTreeNode>::PostOrderTreeDFIterator(spvtools::opt::DominatorTreeNode*, bool)
Line
Count
Source
191
18.7k
      : current_(sentinel_node) {}
spvtools::opt::PostOrderTreeDFIterator<spvtools::opt::Loop>::PostOrderTreeDFIterator(spvtools::opt::Loop*, bool)
Line
Count
Source
191
18.7k
      : 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
431k
  inline void MoveToNextNode() {
199
431k
    if (!current_) return;
200
431k
    if (parent_iterators_.empty()) {
201
0
      current_ = nullptr;
202
0
      return;
203
0
    }
204
431k
    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
431k
    if (next_it.second == next_it.first->end()) {
207
      // Set the new node.
208
276k
      current_ = next_it.first;
209
276k
      parent_iterators_.pop();
210
276k
      return;
211
276k
    }
212
    // We have more children to visit, set the current node to the first child
213
    // and dive to leaf.
214
154k
    current_ = *next_it.second;
215
    // Update the iterator for the next child (avoid unneeded pop).
216
154k
    ++next_it.second;
217
154k
    WalkToLeaf();
218
154k
  }
spvtools::opt::PostOrderTreeDFIterator<spvtools::opt::DominatorTreeNode>::MoveToNextNode()
Line
Count
Source
198
399k
  inline void MoveToNextNode() {
199
399k
    if (!current_) return;
200
399k
    if (parent_iterators_.empty()) {
201
0
      current_ = nullptr;
202
0
      return;
203
0
    }
204
399k
    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
399k
    if (next_it.second == next_it.first->end()) {
207
      // Set the new node.
208
263k
      current_ = next_it.first;
209
263k
      parent_iterators_.pop();
210
263k
      return;
211
263k
    }
212
    // We have more children to visit, set the current node to the first child
213
    // and dive to leaf.
214
136k
    current_ = *next_it.second;
215
    // Update the iterator for the next child (avoid unneeded pop).
216
136k
    ++next_it.second;
217
136k
    WalkToLeaf();
218
136k
  }
spvtools::opt::PostOrderTreeDFIterator<spvtools::opt::Loop>::MoveToNextNode()
Line
Count
Source
198
31.7k
  inline void MoveToNextNode() {
199
31.7k
    if (!current_) return;
200
31.7k
    if (parent_iterators_.empty()) {
201
0
      current_ = nullptr;
202
0
      return;
203
0
    }
204
31.7k
    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
31.7k
    if (next_it.second == next_it.first->end()) {
207
      // Set the new node.
208
13.8k
      current_ = next_it.first;
209
13.8k
      parent_iterators_.pop();
210
13.8k
      return;
211
13.8k
    }
212
    // We have more children to visit, set the current node to the first child
213
    // and dive to leaf.
214
17.9k
    current_ = *next_it.second;
215
    // Update the iterator for the next child (avoid unneeded pop).
216
17.9k
    ++next_it.second;
217
17.9k
    WalkToLeaf();
218
17.9k
  }
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
192k
  inline void WalkToLeaf() {
226
469k
    while (current_->begin() != current_->end()) {
227
276k
      NodeIterator next = ++current_->begin();
228
276k
      parent_iterators_.emplace(make_pair(current_, next));
229
      // Set the first child as the new node.
230
276k
      current_ = *current_->begin();
231
276k
    }
232
192k
  }
spvtools::opt::PostOrderTreeDFIterator<spvtools::opt::DominatorTreeNode>::WalkToLeaf()
Line
Count
Source
225
155k
  inline void WalkToLeaf() {
226
418k
    while (current_->begin() != current_->end()) {
227
263k
      NodeIterator next = ++current_->begin();
228
263k
      parent_iterators_.emplace(make_pair(current_, next));
229
      // Set the first child as the new node.
230
263k
      current_ = *current_->begin();
231
263k
    }
232
155k
  }
Unexecuted instantiation: spvtools::opt::PostOrderTreeDFIterator<spvtools::opt::DominatorTreeNode const>::WalkToLeaf()
spvtools::opt::PostOrderTreeDFIterator<spvtools::opt::Loop>::WalkToLeaf()
Line
Count
Source
225
36.7k
  inline void WalkToLeaf() {
226
50.5k
    while (current_->begin() != current_->end()) {
227
13.8k
      NodeIterator next = ++current_->begin();
228
13.8k
      parent_iterators_.emplace(make_pair(current_, next));
229
      // Set the first child as the new node.
230
13.8k
      current_ = *current_->begin();
231
13.8k
    }
232
36.7k
  }
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_