Jlm
CommandGraph.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2018 Nico Reißmann <nico.reissmann@gmail.com>
3  * See COPYING for terms of redistribution.
4  */
5 
6 #ifndef JLM_TOOLING_COMMANDGRAPH_HPP
7 #define JLM_TOOLING_COMMANDGRAPH_HPP
8 
9 #include <jlm/util/common.hpp>
11 
12 #include <memory>
13 #include <unordered_set>
14 #include <vector>
15 
16 namespace jlm::tooling
17 {
18 
19 class Command;
20 
24 class CommandGraph final
25 {
26 public:
27  class Edge;
28  class Node;
29 
30  ~CommandGraph() = default;
31 
32  CommandGraph();
33 
34  CommandGraph(const CommandGraph &) = delete;
35 
36  CommandGraph(CommandGraph &&) = delete;
37 
38  CommandGraph &
39  operator=(const CommandGraph &) = delete;
40 
41  CommandGraph &
42  operator=(CommandGraph &&) = delete;
43 
44  Node &
45  GetEntryNode() const noexcept
46  {
47  return *EntryNode_;
48  }
49 
50  Node &
51  GetExitNode() const noexcept
52  {
53  return *ExitNode_;
54  }
55 
56  size_t
57  NumNodes() const noexcept
58  {
59  return Nodes_.size();
60  }
61 
62  Node &
63  AddNode(std::unique_ptr<Node> node)
64  {
65  auto pointer = node.get();
66  Nodes_.insert(std::move(node));
67  return *pointer;
68  }
69 
70  void
71  Run() const;
72 
73  static std::vector<CommandGraph::Node *>
74  SortNodesTopological(const CommandGraph & commandGraph);
75 
76  static std::unique_ptr<CommandGraph>
78  {
79  return std::make_unique<CommandGraph>();
80  }
81 
82 private:
85  std::unordered_set<std::unique_ptr<Node>> Nodes_;
86 };
87 
93 class CommandGraph::Edge final
94 {
95 public:
96  Edge(Node & source, Node & sink)
97  : Sink_(&sink),
98  Source_(&source)
99  {}
100 
101  [[nodiscard]] Node &
102  GetSource() const noexcept
103  {
104  return *Source_;
105  }
106 
107  [[nodiscard]] Node &
108  GetSink() const noexcept
109  {
110  return *Sink_;
111  }
112 
113 private:
116 };
117 
122 {
125 
128 
129 public:
130  ~Node();
131 
132 private:
133  Node(const CommandGraph & commandGraph, std::unique_ptr<Command> command);
134 
135 public:
136  Node(const Node &) = delete;
137 
138  Node(Node &&) = delete;
139 
140  Node &
141  operator=(const Node &) = delete;
142 
143  Node &
144  operator=(Node &&) = delete;
145 
146  const CommandGraph &
147  GetCommandGraph() const noexcept
148  {
149  return CommandGraph_;
150  }
151 
152  Command &
153  GetCommand() const noexcept
154  {
155  return *Command_;
156  }
157 
158  size_t
159  NumIncomingEdges() const noexcept
160  {
161  return IncomingEdges_.size();
162  }
163 
164  size_t
165  NumOutgoingEdges() const noexcept
166  {
167  return OutgoingEdges_.size();
168  }
169 
171  IncomingEdges() const;
172 
174  OutgoingEdges() const;
175 
176  void
177  AddEdge(Node & sink)
178  {
179  std::unique_ptr<Edge> edge(new Edge(*this, sink));
180  auto pointer = edge.get();
181  OutgoingEdges_.insert(std::move(edge));
182  sink.IncomingEdges_.insert(pointer);
183  }
184 
185  static Node &
186  Create(CommandGraph & commandGraph, std::unique_ptr<Command> command);
187 
188 private:
190  std::unique_ptr<Command> Command_;
191  std::unordered_set<Edge *> IncomingEdges_;
192  std::unordered_set<std::unique_ptr<Edge>> OutgoingEdges_;
193 };
194 
198 {
199 public:
200  using iterator_category = std::forward_iterator_tag;
201  using value_type = Edge *;
202  using difference_type = std::ptrdiff_t;
203  using pointer = Edge **;
204  using reference = Edge *&;
205 
206 private:
207  friend Node;
208 
209  explicit IncomingEdgeConstIterator(const std::unordered_set<Edge *>::const_iterator & it)
210  : it_(it)
211  {}
212 
213 public:
214  [[nodiscard]] const Edge *
215  GetEdge() const noexcept
216  {
217  return *it_;
218  }
219 
220  const Edge &
221  operator*() const
222  {
223  JLM_ASSERT(GetEdge() != nullptr);
224  return *GetEdge();
225  }
226 
227  const Edge *
228  operator->() const
229  {
230  return GetEdge();
231  }
232 
235  {
236  ++it_;
237  return *this;
238  }
239 
242  {
243  IncomingEdgeConstIterator tmp = *this;
244  ++*this;
245  return tmp;
246  }
247 
248  bool
250  {
251  return it_ == other.it_;
252  }
253 
254  bool
256  {
257  return !operator==(other);
258  }
259 
260 private:
261  std::unordered_set<Edge *>::const_iterator it_;
262 };
263 
267 {
268 public:
269  using iterator_category = std::forward_iterator_tag;
270  using value_type = Edge *;
271  using difference_type = std::ptrdiff_t;
272  using pointer = Edge **;
273  using reference = Edge *&;
274 
275 private:
276  friend Node;
277 
279  const std::unordered_set<std::unique_ptr<Edge>>::const_iterator & it)
280  : it_(it)
281  {}
282 
283 public:
284  [[nodiscard]] const Edge *
285  GetEdge() const noexcept
286  {
287  return it_->get();
288  }
289 
290  const Edge &
291  operator*() const
292  {
293  JLM_ASSERT(GetEdge() != nullptr);
294  return *GetEdge();
295  }
296 
297  const Edge *
298  operator->() const
299  {
300  return GetEdge();
301  }
302 
305  {
306  ++it_;
307  return *this;
308  }
309 
312  {
313  OutgoingEdgeConstIterator tmp = *this;
314  ++*this;
315  return tmp;
316  }
317 
318  bool
320  {
321  return it_ == other.it_;
322  }
323 
324  bool
326  {
327  return !operator==(other);
328  }
329 
330 private:
331  std::unordered_set<std::unique_ptr<Edge>>::const_iterator it_;
332 };
333 
334 }
335 
336 #endif
Edge(Node &source, Node &sink)
Node & GetSink() const noexcept
Node & GetSource() const noexcept
Command graph node incoming edge const iterator.
std::unordered_set< Edge * >::const_iterator it_
IncomingEdgeConstIterator(const std::unordered_set< Edge * >::const_iterator &it)
bool operator!=(const IncomingEdgeConstIterator &other) const
bool operator==(const IncomingEdgeConstIterator &other) const
Command graph node outgoing edge const iterator.
bool operator!=(const OutgoingEdgeConstIterator &other) const
OutgoingEdgeConstIterator(const std::unordered_set< std::unique_ptr< Edge >>::const_iterator &it)
std::unordered_set< std::unique_ptr< Edge > >::const_iterator it_
bool operator==(const OutgoingEdgeConstIterator &other) const
OutgoingEdgeConstRange OutgoingEdges() const
const CommandGraph & CommandGraph_
std::unordered_set< Edge * > IncomingEdges_
static Node & Create(CommandGraph &commandGraph, std::unique_ptr< Command > command)
size_t NumOutgoingEdges() const noexcept
IncomingEdgeConstRange IncomingEdges() const
std::unordered_set< std::unique_ptr< Edge > > OutgoingEdges_
util::IteratorRange< OutgoingEdgeConstIterator > OutgoingEdgeConstRange
Node(const CommandGraph &commandGraph, std::unique_ptr< Command > command)
util::IteratorRange< IncomingEdgeConstIterator > IncomingEdgeConstRange
const CommandGraph & GetCommandGraph() const noexcept
Node & operator=(const Node &)=delete
size_t NumIncomingEdges() const noexcept
std::unique_ptr< Command > Command_
Node & operator=(Node &&)=delete
Command & GetCommand() const noexcept
static std::unique_ptr< CommandGraph > Create()
static std::vector< CommandGraph::Node * > SortNodesTopological(const CommandGraph &commandGraph)
size_t NumNodes() const noexcept
CommandGraph & operator=(const CommandGraph &)=delete
std::unordered_set< std::unique_ptr< Node > > Nodes_
CommandGraph(CommandGraph &&)=delete
Node & GetEntryNode() const noexcept
Node & AddNode(std::unique_ptr< Node > node)
Node & GetExitNode() const noexcept
CommandGraph(const CommandGraph &)=delete
CommandGraph & operator=(CommandGraph &&)=delete
Command class.
Definition: Command.hpp:30
#define JLM_ASSERT(x)
Definition: common.hpp:16
std::string Edge(jlm::rvsdg::Output *output, jlm::rvsdg::Input *input, std::unordered_map< rvsdg::Output *, ViewColors > &tailLabel, bool back_edge=false)
Definition: view.cpp:172