Jlm
traverser.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2010 2011 2012 2015 Helge Bahmann <hcb@chaoticmind.net>
3  * Copyright 2014 Nico Reißmann <nico.reissmann@gmail.com>
4  * See COPYING for terms of redistribution.
5  */
6 
7 #ifndef JLM_RVSDG_TRAVERSER_HPP
8 #define JLM_RVSDG_TRAVERSER_HPP
9 
10 #include <jlm/rvsdg/region.hpp>
11 
12 #include <list>
13 #include <unordered_map>
14 
15 namespace jlm::rvsdg
16 {
17 
18 class Graph;
19 class Input;
20 class Node;
21 class Output;
22 class Region;
23 
24 namespace detail
25 {
26 
27 enum class TraversalNodeState : uint8_t
28 {
29  // Nodes that are not ready to be visited
30  ahead = 0,
31  // Nodes that are ready to be visited
32  frontier = 1,
33  // Nodes that have been visited
34  behind = 2
35 };
36 
41 template<typename NodeType>
42 class TraversalTracker final
43 {
44 public:
46  bool
47  isNodeVisited(NodeType * node) const;
48 
50  void
51  checkNodeActivation(NodeType * node, std::size_t threshold);
52 
54  void
55  checkNodeDeactivation(NodeType * node, std::size_t threshold);
56 
58  void
59  checkMarkNodeVisitedIfFrontier(NodeType * node);
60 
62  void
63  incActivationCount(NodeType * node, std::size_t threshold);
64 
66  void
67  decActivationCount(NodeType * node, std::size_t threshold);
68 
70  void
71  removeNode(NodeType * node);
72 
73  NodeType *
74  peek();
75 
76 private:
77  using FrontierList = std::list<NodeType *>;
78 
79  struct State
80  {
82  uint32_t activationCount = 0;
83  typename FrontierList::iterator pos = {};
84  };
85 
86  std::unordered_map<NodeType *, State> states_;
88 };
89 
90 template<typename Traverser, typename NodeType>
92 {
93 public:
94  using iterator_category = std::input_iterator_tag;
95  using value_type = NodeType *;
96  using difference_type = ssize_t;
97  using pointer = value_type *;
98  using reference = value_type &;
99 
100  constexpr TraverserIterator(Traverser & traverser, NodeType * node) noexcept
101  : traverser_(traverser),
102  node_(node)
103  {}
104 
105  const TraverserIterator &
106  operator++() noexcept
107  {
108  node_ = traverser_.next();
109  return *this;
110  }
111 
112  bool
113  operator==(const TraverserIterator & other) const noexcept
114  {
115  return &traverser_ == &other.traverser_ && node_ == other.node_;
116  }
117 
118  bool
119  operator!=(const TraverserIterator & other) const noexcept
120  {
121  return !(*this == other);
122  }
123 
124  reference
125  operator*() noexcept
126  {
127  return node_;
128  }
129 
130  pointer
131  operator->() noexcept
132  {
133  return &node_;
134  }
135 
136 private:
137  Traverser & traverser_;
138  NodeType * node_;
139 };
140 
145 template<typename Traverser>
146 class ForwardingObserver final : public RegionObserver
147 {
148 public:
149  ~ForwardingObserver() noexcept override;
150 
151  ForwardingObserver(const Region & region, Traverser & traverser);
152 
153  void
154  onNodeCreate(Node * node) override;
155 
156  void
157  onNodeDestroy(Node * node) override;
158 
159  void
160  onInputCreate(Input * input) override;
161 
162  void
163  onInputChange(Input * input, Output * oldOrigin, Output * newOrigin) override;
164 
165  void
166  onInputDestroy(Input * input) override;
167 
168 private:
169  Traverser & traverser_;
170 };
171 
180 template<bool IsConst>
182 {
183 public:
184  using NodeType = std::conditional_t<IsConst, const Node, Node>;
185  using RegionType = std::conditional_t<IsConst, const Region, Region>;
188 
190 
192 
193  explicit TopDownTraverserGeneric(RegionType * region);
194 
195  NodeType *
196  next();
197 
198  iterator
199  begin()
200  {
201  return iterator(*this, next());
202  }
203 
204  iterator
205  end()
206  {
207  return iterator(*this, nullptr);
208  }
209 
210 private:
211  bool
212  isOutputActivated(const Output & output) const;
213 
214  void
215  markAsVisited(NodeType & node);
216 
217  void
218  onNodeCreate(NodeType * node);
219 
220  void
221  onNodeDestroy(NodeType * node);
222 
223  void
224  onInputCreate(Input * input);
225 
226  void
227  onInputChange(Input * in, Output * old_origin, Output * new_origin);
228 
229  void
230  onInputDestroy(Input * input);
231 
234  // Any node with Id >= this cutoff was created after traversal began and will be skipped
235  Node::Id nodeIdCutoff_;
236 };
237 
246 template<bool IsConst>
248 {
249 public:
250  using NodeType = std::conditional_t<IsConst, const Node, Node>;
251  using RegionType = std::conditional_t<IsConst, const Region, Region>;
254 
256 
258 
259  explicit BottomUpTraverserGeneric(RegionType * region);
260 
261  NodeType *
262  next();
263 
264  iterator
265  begin()
266  {
267  return iterator(*this, next());
268  }
269 
270  iterator
271  end()
272  {
273  return iterator(*this, nullptr);
274  }
275 
276 private:
277  bool
278  isInputActivated(const Input & input) const;
279 
280  void
281  markAsVisited(NodeType & node);
282 
283  void
284  onNodeCreate(NodeType * node);
285 
286  void
287  onNodeDestroy(NodeType * node);
288 
289  void
290  onInputCreate(Input * input);
291 
292  void
293  onInputChange(Input * input, Output * oldOrigin, Output * newOrigin);
294 
295  void
296  onInputDestroy(Input * input);
297 
300 };
301 
302 }
303 
309 
315 
321 
327 
328 }
329 
330 #endif
uint64_t Id
Definition: node.hpp:583
Proxy object to observe changes to a region.
Definition: region.hpp:783
Represent acyclic RVSDG subgraphs.
Definition: region.hpp:213
std::conditional_t< IsConst, const Node, Node > NodeType
Definition: traverser.hpp:250
TraversalTracker< NodeType > tracker_
Definition: traverser.hpp:298
std::conditional_t< IsConst, const Region, Region > RegionType
Definition: traverser.hpp:251
void onNodeDestroy(Node *node) override
Definition: traverser.cpp:48
void onInputCreate(Input *input) override
Definition: traverser.cpp:55
void onInputChange(Input *input, Output *oldOrigin, Output *newOrigin) override
Definition: traverser.cpp:62
void onNodeCreate(Node *node) override
Definition: traverser.cpp:41
void onInputDestroy(Input *input) override
Definition: traverser.cpp:69
TraversalTracker< NodeType > tracker_
Definition: traverser.hpp:232
std::conditional_t< IsConst, const Node, Node > NodeType
Definition: traverser.hpp:184
std::conditional_t< IsConst, const Region, Region > RegionType
Definition: traverser.hpp:185
void checkMarkNodeVisitedIfFrontier(NodeType *node)
Marks a node visited if it is currently ready for visiting.
Definition: traverser.cpp:451
std::list< NodeType * > FrontierList
Definition: traverser.hpp:77
bool isNodeVisited(NodeType *node) const
Determines whether node has been visited already.
Definition: traverser.cpp:417
void decActivationCount(NodeType *node, std::size_t threshold)
Decrements activation count; removes from frontier if threshold is no longer met.
Definition: traverser.cpp:473
void incActivationCount(NodeType *node, std::size_t threshold)
Increments activation count; adds to frontier if threshold is met.
Definition: traverser.cpp:464
void checkNodeActivation(NodeType *node, std::size_t threshold)
Checks activation count whether node is ready for visiting.
Definition: traverser.cpp:425
void checkNodeDeactivation(NodeType *node, std::size_t threshold)
Checks activation count whether node is no longer ready for visiting.
Definition: traverser.cpp:438
std::unordered_map< NodeType *, State > states_
Definition: traverser.hpp:86
void removeNode(NodeType *node)
Removes any state associated with the given node.
Definition: traverser.cpp:482
constexpr TraverserIterator(Traverser &traverser, NodeType *node) noexcept
Definition: traverser.hpp:100
bool operator==(const TraverserIterator &other) const noexcept
Definition: traverser.hpp:113
bool operator!=(const TraverserIterator &other) const noexcept
Definition: traverser.hpp:119
const TraverserIterator & operator++() noexcept
Definition: traverser.hpp:106
std::input_iterator_tag iterator_category
Definition: traverser.hpp:94