Jlm
Loading...
Searching...
No Matches
aggregation.hpp
Go to the documentation of this file.
1/*
2 * Copyright 2017 Nico Reißmann <nico.reissmann@gmail.com>
3 * See COPYING for terms of redistribution.
4 */
5
6#ifndef JLM_LLVM_IR_AGGREGATION_HPP
7#define JLM_LLVM_IR_AGGREGATION_HPP
8
10
11#include <memory>
12
13namespace jlm::llvm
14{
15
16class ControlFlowGraph;
17
19{
20 using iterator =
23 const AggregationNode,
24 std::vector<std::unique_ptr<AggregationNode>>::const_iterator>;
25
26public:
27 virtual ~AggregationNode() noexcept;
28
30 : index_(0),
31 parent_(nullptr)
32 {}
33
34 AggregationNode(const AggregationNode & other) = delete;
35
36 AggregationNode(AggregationNode && other) = delete;
37
39 operator=(const AggregationNode & other) = delete;
40
42 operator=(AggregationNode && other) = delete;
43
44 inline iterator
45 begin() noexcept
46 {
47 return iterator(children_.begin());
48 }
49
50 inline const_iterator
51 begin() const noexcept
52 {
53 return const_iterator(children_.begin());
54 }
55
56 inline iterator
57 end() noexcept
58 {
59 return iterator(children_.end());
60 }
61
62 inline const_iterator
63 end() const noexcept
64 {
65 return const_iterator(children_.end());
66 }
67
68 inline size_t
69 nchildren() const noexcept
70 {
71 return children_.size();
72 }
73
74 inline void
75 add_child(std::unique_ptr<AggregationNode> child)
76 {
77 size_t index = nchildren();
78 children_.emplace_back(std::move(child));
79 children_[index]->parent_ = this;
80 children_[index]->index_ = index;
81 }
82
83 inline AggregationNode *
84 child(size_t n) const noexcept
85 {
86 JLM_ASSERT(n < nchildren());
87 return children_[n].get();
88 }
89
91 parent() noexcept
92 {
93 JLM_ASSERT(parent_->child(index_) == this);
94 return parent_;
95 }
96
97 const AggregationNode *
98 parent() const noexcept
99 {
100 JLM_ASSERT(parent_->child(index_) == this);
101 return parent_;
102 }
103
104 size_t
105 index() const noexcept
106 {
107 JLM_ASSERT(parent()->child(index_) == this);
108 return index_;
109 }
110
114 size_t
115 nnodes() const noexcept
116 {
117 size_t n = 1;
118 for (auto & child : children_)
119 n += child->nnodes();
120
121 return n;
122 }
123
124 virtual std::string
125 debug_string() const = 0;
126
146 static void
148
149private:
150 void
152 {
153 children_.clear();
154 }
155
156 size_t index_;
158 std::vector<std::unique_ptr<AggregationNode>> children_;
159};
160
161template<class T>
162static inline bool
163is(const AggregationNode * node)
164{
165 static_assert(
166 std::is_base_of<AggregationNode, T>::value,
167 "Template parameter T must be derived from jlm::AggregationNode");
168
169 return dynamic_cast<const T *>(node) != nullptr;
170}
171
173{
176
177public:
178 ~EntryAggregationNode() noexcept override;
179
180 explicit EntryAggregationNode(const std::vector<llvm::Argument *> & arguments)
182 {}
183
185 begin() const;
186
188 end() const;
189
190 const llvm::Argument *
191 argument(size_t index) const noexcept
192 {
194 return arguments_[index];
195 }
196
197 size_t
198 narguments() const noexcept
199 {
200 return arguments_.size();
201 }
202
203 [[nodiscard]] std::string
204 debug_string() const override;
205
206 static std::unique_ptr<AggregationNode>
207 create(const std::vector<llvm::Argument *> & arguments)
208 {
209 return std::make_unique<EntryAggregationNode>(arguments);
210 }
211
212private:
213 std::vector<llvm::Argument *> arguments_;
214};
215
217{
218 typedef std::vector<const Variable *>::const_iterator const_iterator;
219
220public:
221 ~ExitAggregationNode() noexcept override;
222
223 explicit ExitAggregationNode(const std::vector<const Variable *> & results)
224 : results_(results)
225 {}
226
228 begin() const
229 {
230 return results_.begin();
231 }
232
234 end() const
235 {
236 return results_.end();
237 }
238
239 const Variable *
240 result(size_t index) const noexcept
241 {
243 return results_[index];
244 }
245
246 size_t
247 nresults() const noexcept
248 {
249 return results_.size();
250 }
251
252 [[nodiscard]] std::string
253 debug_string() const override;
254
255 static inline std::unique_ptr<AggregationNode>
256 create(const std::vector<const Variable *> & results)
257 {
258 return std::make_unique<ExitAggregationNode>(results);
259 }
260
261private:
262 std::vector<const Variable *> results_;
263};
264
266{
267public:
268 ~BasicBlockAggregationNode() noexcept override;
269
271
273 : bb_(std::move(bb))
274 {}
275
276 [[nodiscard]] std::string
277 debug_string() const override;
278
280 tacs() const noexcept
281 {
282 return bb_;
283 }
284
285 static std::unique_ptr<AggregationNode>
287 {
288 return std::make_unique<BasicBlockAggregationNode>();
289 }
290
291 static std::unique_ptr<AggregationNode>
293 {
294 return std::make_unique<BasicBlockAggregationNode>(std::move(bb));
295 }
296
297private:
299};
300
302{
303public:
304 ~LinearAggregationNode() noexcept override;
305
306 LinearAggregationNode(std::unique_ptr<AggregationNode> n1, std::unique_ptr<AggregationNode> n2)
307 {
308 add_child(std::move(n1));
309 add_child(std::move(n2));
310 }
311
312 [[nodiscard]] std::string
313 debug_string() const override;
314
315 static std::unique_ptr<AggregationNode>
316 create(std::unique_ptr<AggregationNode> n1, std::unique_ptr<AggregationNode> n2)
317 {
318 return std::make_unique<LinearAggregationNode>(std::move(n1), std::move(n2));
319 }
320};
321
323{
324public:
325 ~BranchAggregationNode() noexcept override;
326
328
329 [[nodiscard]] std::string
330 debug_string() const override;
331
332 static inline std::unique_ptr<AggregationNode>
334 {
335 return std::make_unique<BranchAggregationNode>();
336 }
337};
338
340{
341public:
342 ~LoopAggregationNode() noexcept override;
343
344 explicit LoopAggregationNode(std::unique_ptr<AggregationNode> body)
345 {
346 add_child(std::move(body));
347 }
348
349 [[nodiscard]] std::string
350 debug_string() const override;
351
352 static inline std::unique_ptr<AggregationNode>
353 create(std::unique_ptr<AggregationNode> body)
354 {
355 return std::make_unique<LoopAggregationNode>(std::move(body));
356 }
357};
358
396std::unique_ptr<AggregationNode>
397aggregate(ControlFlowGraph & cfg);
398
399size_t
400ntacs(const AggregationNode & root);
401
402}
403
404#endif
util::HashSet< rvsdg::Output * > arguments
const_iterator end() const noexcept
virtual ~AggregationNode() noexcept
AggregationNode(const AggregationNode &other)=delete
AggregationNode(AggregationNode &&other)=delete
iterator begin() noexcept
AggregationNode & operator=(AggregationNode &&other)=delete
AggregationNode * parent() noexcept
virtual std::string debug_string() const =0
iterator end() noexcept
size_t nchildren() const noexcept
util::PtrIterator< AggregationNode, std::vector< std::unique_ptr< AggregationNode > >::iterator > iterator
AggregationNode * parent_
AggregationNode * child(size_t n) const noexcept
size_t nnodes() const noexcept
const_iterator begin() const noexcept
AggregationNode & operator=(const AggregationNode &other)=delete
void add_child(std::unique_ptr< AggregationNode > child)
size_t index() const noexcept
static void normalize(AggregationNode &node)
util::PtrIterator< const AggregationNode, std::vector< std::unique_ptr< AggregationNode > >::const_iterator > const_iterator
const AggregationNode * parent() const noexcept
std::vector< std::unique_ptr< AggregationNode > > children_
Function argument.
Definition cfg.hpp:28
static std::unique_ptr< AggregationNode > create()
static std::unique_ptr< AggregationNode > create(ThreeAddressCodeList &&bb)
std::string debug_string() const override
const ThreeAddressCodeList & tacs() const noexcept
~BasicBlockAggregationNode() noexcept override
static std::unique_ptr< AggregationNode > create()
~BranchAggregationNode() noexcept override
std::string debug_string() const override
const llvm::Argument * argument(size_t index) const noexcept
std::vector< llvm::Argument * > arguments_
constiterator end() const
static std::unique_ptr< AggregationNode > create(const std::vector< llvm::Argument * > &arguments)
size_t narguments() const noexcept
constiterator begin() const
std::string debug_string() const override
util::PtrIterator< const llvm::Argument, std::vector< llvm::Argument * >::const_iterator > constiterator
~EntryAggregationNode() noexcept override
std::vector< const Variable * > results_
const Variable * result(size_t index) const noexcept
static std::unique_ptr< AggregationNode > create(const std::vector< const Variable * > &results)
std::vector< constVariable * >::const_iterator const_iterator
~ExitAggregationNode() noexcept override
const_iterator end() const
const_iterator begin() const
std::string debug_string() const override
size_t nresults() const noexcept
std::string debug_string() const override
static std::unique_ptr< AggregationNode > create(std::unique_ptr< AggregationNode > n1, std::unique_ptr< AggregationNode > n2)
~LinearAggregationNode() noexcept override
std::string debug_string() const override
~LoopAggregationNode() noexcept override
static std::unique_ptr< AggregationNode > create(std::unique_ptr< AggregationNode > body)
#define JLM_ASSERT(x)
Definition common.hpp:16
Global memory state passed between functions.
static ControlFlowGraphNode * aggregate(ControlFlowGraphNode *, ControlFlowGraphNode *, AggregationMap &)
size_t ntacs(const AggregationNode &root)
static bool is(const AggregationNode *node)