Jlm
Loading...
Searching...
No Matches
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
16namespace jlm::tooling
17{
18
19class Command;
20
24class CommandGraph final
25{
26public:
27 class Edge;
28 class Node;
29
30 ~CommandGraph() = default;
31
33
34 CommandGraph(const CommandGraph &) = delete;
35
37
39 operator=(const CommandGraph &) = delete;
40
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
82private:
85 std::unordered_set<std::unique_ptr<Node>> Nodes_;
86};
87
94{
95public:
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
113private:
116};
117
122{
125
128
129public:
131
132private:
133 Node(const CommandGraph & commandGraph, std::unique_ptr<Command> command);
134
135public:
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
188private:
190 std::unique_ptr<Command> Command_;
191 std::unordered_set<Edge *> IncomingEdges_;
192 std::unordered_set<std::unique_ptr<Edge>> OutgoingEdges_;
193};
194
198{
199public:
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
206private:
207 friend Node;
208
209 explicit IncomingEdgeConstIterator(const std::unordered_set<Edge *>::const_iterator & it)
210 : it_(it)
211 {}
212
213public:
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 *
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
260private:
261 std::unordered_set<Edge *>::const_iterator it_;
262};
263
267{
268public:
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
275private:
276 friend Node;
277
279 const std::unordered_set<std::unique_ptr<Edge>>::const_iterator & it)
280 : it_(it)
281 {}
282
283public:
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 *
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
330private:
331 std::unordered_set<std::unique_ptr<Edge>>::const_iterator it_;
332};
333
334}
335
336#endif
Node & GetSink() const noexcept
Node & GetSource() const noexcept
Edge(Node &source, Node &sink)
Command graph node incoming edge const iterator.
IncomingEdgeConstIterator(const std::unordered_set< Edge * >::const_iterator &it)
bool operator!=(const IncomingEdgeConstIterator &other) const
bool operator==(const IncomingEdgeConstIterator &other) const
std::unordered_set< Edge * >::const_iterator it_
Command graph node outgoing edge const iterator.
OutgoingEdgeConstIterator(const std::unordered_set< std::unique_ptr< Edge > >::const_iterator &it)
bool operator!=(const OutgoingEdgeConstIterator &other) const
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_
Node & operator=(Node &&)=delete
Node & operator=(const Node &)=delete
size_t NumOutgoingEdges() const noexcept
IncomingEdgeConstRange IncomingEdges() const
std::unordered_set< std::unique_ptr< Edge > > OutgoingEdges_
util::IteratorRange< OutgoingEdgeConstIterator > OutgoingEdgeConstRange
util::IteratorRange< IncomingEdgeConstIterator > IncomingEdgeConstRange
const CommandGraph & GetCommandGraph() const noexcept
Command & GetCommand() const noexcept
size_t NumIncomingEdges() const noexcept
std::unique_ptr< Command > Command_
CommandGraph & operator=(CommandGraph &&)=delete
Node & GetEntryNode() const noexcept
static std::unique_ptr< CommandGraph > Create()
static std::vector< CommandGraph::Node * > SortNodesTopological(const CommandGraph &commandGraph)
Node & GetExitNode() const noexcept
Node & AddNode(std::unique_ptr< Node > node)
size_t NumNodes() const noexcept
std::unordered_set< std::unique_ptr< Node > > Nodes_
CommandGraph(CommandGraph &&)=delete
CommandGraph & operator=(const CommandGraph &)=delete
CommandGraph(const CommandGraph &)=delete
Command class.
Definition Command.hpp:31
#define JLM_ASSERT(x)
Definition common.hpp:16