Jlm
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 
13 namespace jlm::llvm
14 {
15 
16 class ControlFlowGraph;
17 
19 {
20  using iterator =
23  const AggregationNode,
24  std::vector<std::unique_ptr<AggregationNode>>::const_iterator>;
25 
26 public:
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
147  normalize(AggregationNode & node);
148 
149 private:
150  void
152  {
153  children_.clear();
154  }
155 
156  size_t index_;
158  std::vector<std::unique_ptr<AggregationNode>> children_;
159 };
160 
161 template<class T>
162 static inline bool
163 is(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 
177 public:
178  ~EntryAggregationNode() noexcept override;
179 
180  explicit EntryAggregationNode(const std::vector<llvm::Argument *> & arguments)
181  : arguments_(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 
212 private:
213  std::vector<llvm::Argument *> arguments_;
214 };
215 
217 {
218  typedef std::vector<const Variable *>::const_iterator const_iterator;
219 
220 public:
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 
261 private:
262  std::vector<const Variable *> results_;
263 };
264 
266 {
267 public:
268  ~BasicBlockAggregationNode() noexcept override;
269 
271 
273  : bb_(std::move(bb))
274  {}
275 
276  [[nodiscard]] std::string
277  debug_string() const override;
278 
279  const ThreeAddressCodeList &
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 
297 private:
299 };
300 
302 {
303 public:
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 {
324 public:
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 {
341 public:
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 
396 std::unique_ptr<AggregationNode>
397 aggregate(ControlFlowGraph & cfg);
398 
399 size_t
400 ntacs(const AggregationNode & root);
401 
402 }
403 
404 #endif
const_iterator end() const noexcept
Definition: aggregation.hpp:63
virtual ~AggregationNode() noexcept
AggregationNode(const AggregationNode &other)=delete
AggregationNode(AggregationNode &&other)=delete
AggregationNode & operator=(const AggregationNode &other)=delete
iterator begin() noexcept
Definition: aggregation.hpp:45
const AggregationNode * parent() const noexcept
Definition: aggregation.hpp:98
virtual std::string debug_string() const =0
iterator end() noexcept
Definition: aggregation.hpp:57
size_t nchildren() const noexcept
Definition: aggregation.hpp:69
util::PtrIterator< AggregationNode, std::vector< std::unique_ptr< AggregationNode > >::iterator > iterator
Definition: aggregation.hpp:21
AggregationNode * parent_
AggregationNode & operator=(AggregationNode &&other)=delete
size_t nnodes() const noexcept
const_iterator begin() const noexcept
Definition: aggregation.hpp:51
void add_child(std::unique_ptr< AggregationNode > child)
Definition: aggregation.hpp:75
size_t index() const noexcept
static void normalize(AggregationNode &node)
Definition: aggregation.cpp:19
AggregationNode * parent() noexcept
Definition: aggregation.hpp:91
util::PtrIterator< const AggregationNode, std::vector< std::unique_ptr< AggregationNode > >::const_iterator > const_iterator
Definition: aggregation.hpp:24
AggregationNode * child(size_t n) const noexcept
Definition: aggregation.hpp:84
std::vector< std::unique_ptr< AggregationNode > > children_
Function argument.
Definition: cfg.hpp:27
const ThreeAddressCodeList & tacs() const noexcept
static std::unique_ptr< AggregationNode > create(ThreeAddressCodeList &&bb)
std::string debug_string() const override
Definition: aggregation.cpp:89
static std::unique_ptr< AggregationNode > create()
~BasicBlockAggregationNode() noexcept override
static std::unique_ptr< AggregationNode > create()
~BranchAggregationNode() noexcept override
std::string debug_string() const override
std::vector< llvm::Argument * > arguments_
const llvm::Argument * argument(size_t index) const noexcept
constiterator end() const
Definition: aggregation.cpp:67
size_t narguments() const noexcept
constiterator begin() const
Definition: aggregation.cpp:61
std::string debug_string() const override
Definition: aggregation.cpp:73
util::PtrIterator< const llvm::Argument, std::vector< llvm::Argument * >::const_iterator > constiterator
static std::unique_ptr< AggregationNode > create(const std::vector< llvm::Argument * > &arguments)
~EntryAggregationNode() noexcept override
std::vector< const Variable * > results_
std::vector< const Variable * >::const_iterator const_iterator
const Variable * result(size_t index) const noexcept
static std::unique_ptr< AggregationNode > create(const std::vector< const Variable * > &results)
~ExitAggregationNode() noexcept override
const_iterator end() const
const_iterator begin() const
std::string debug_string() const override
Definition: aggregation.cpp:81
size_t nresults() const noexcept
std::string debug_string() const override
Definition: aggregation.cpp:97
~LinearAggregationNode() noexcept override
static std::unique_ptr< AggregationNode > create(std::unique_ptr< AggregationNode > n1, std::unique_ptr< AggregationNode > n2)
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)