Jlm
Annotation.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_ANNOTATION_HPP
7 #define JLM_LLVM_IR_ANNOTATION_HPP
8 
9 #include <jlm/util/common.hpp>
11 
12 #include <algorithm>
13 #include <memory>
14 #include <unordered_map>
15 #include <unordered_set>
16 
17 namespace jlm::llvm
18 {
19 
20 class AggregationNode;
21 class Variable;
22 
23 class VariableSet final
24 {
25 
26  class ConstIterator final
27  {
28  public:
29  using iterator_category = std::forward_iterator_tag;
30  using value_type = const llvm::Variable *;
31  using difference_type = std::ptrdiff_t;
32  using pointer = const llvm::Variable **;
33  using reference = const llvm::Variable *&;
34 
35  explicit ConstIterator(const std::unordered_set<const llvm::Variable *>::const_iterator & it)
36  : It_(it)
37  {}
38 
39  public:
40  const llvm::Variable &
41  GetVariable() const noexcept
42  {
43  return **It_;
44  }
45 
46  const llvm::Variable &
47  operator*() const
48  {
49  return GetVariable();
50  }
51 
52  const llvm::Variable *
53  operator->() const
54  {
55  return &GetVariable();
56  }
57 
60  {
61  ++It_;
62  return *this;
63  }
64 
67  {
68  ConstIterator tmp = *this;
69  ++*this;
70  return tmp;
71  }
72 
73  bool
74  operator==(const ConstIterator & other) const
75  {
76  return It_ == other.It_;
77  }
78 
79  bool
80  operator!=(const ConstIterator & other) const
81  {
82  return !operator==(other);
83  }
84 
85  private:
86  std::unordered_set<const llvm::Variable *>::const_iterator It_;
87  };
88 
90 
91 public:
92  VariableSet() = default;
93 
94  VariableSet(std::initializer_list<const Variable *> init)
95  : Set_(init)
96  {}
97 
99  Variables() const noexcept
100  {
101  return { ConstIterator(Set_.begin()), ConstIterator(Set_.end()) };
102  }
103 
104  bool
105  Contains(const Variable & v) const
106  {
107  return Set_.find(&v) != Set_.end();
108  }
109 
110  bool
111  Contains(const VariableSet & variableSet) const
112  {
113  if (variableSet.Size() > Size())
114  return false;
115 
116  return std::all_of(
117  variableSet.Set_.begin(),
118  variableSet.Set_.end(),
119  [&](const Variable * v)
120  {
121  return Contains(*v);
122  });
123  }
124 
125  size_t
126  Size() const noexcept
127  {
128  return Set_.size();
129  }
130 
131  void
132  Insert(const Variable & v)
133  {
134  Set_.insert(&v);
135  }
136 
137  void
138  Insert(const VariableSet & variableSet)
139  {
140  Set_.insert(variableSet.Set_.begin(), variableSet.Set_.end());
141  }
142 
143  void
144  Remove(const Variable & v)
145  {
146  Set_.erase(&v);
147  }
148 
149  void
150  Remove(const VariableSet & variableSet)
151  {
152  for (auto & v : variableSet.Variables())
153  Remove(v);
154  }
155 
156  void
157  Intersect(const VariableSet & variableSet)
158  {
159  for (auto it = Set_.begin(); it != Set_.end();)
160  {
161  if (!variableSet.Contains(**it))
162  it = Set_.erase(it);
163  else
164  it++;
165  }
166  }
167 
168  bool
169  operator==(const VariableSet & other) const
170  {
171  if (Size() != other.Size())
172  return false;
173 
174  return std::all_of(
175  Set_.begin(),
176  Set_.end(),
177  [&](const Variable * v)
178  {
179  return Contains(*v);
180  });
181  }
182 
183  bool
184  operator!=(const VariableSet & other) const
185  {
186  return !(*this == other);
187  }
188 
189  std::string
190  DebugString() const noexcept;
191 
192 private:
193  std::unordered_set<const Variable *> Set_;
194 };
195 
197 {
198 public:
199  virtual ~AnnotationSet() noexcept;
200 
201  AnnotationSet(VariableSet readSet, VariableSet allWriteSet, VariableSet fullWriteSet)
202  : ReadSet_(std::move(readSet)),
203  AllWriteSet_(std::move(allWriteSet)),
204  FullWriteSet_(std::move(fullWriteSet))
205  {}
206 
207  AnnotationSet(const AnnotationSet &) = delete;
208 
209  AnnotationSet(AnnotationSet &&) noexcept = delete;
210 
211  AnnotationSet &
212  operator=(const AnnotationSet &) = delete;
213 
214  AnnotationSet &
215  operator=(AnnotationSet &&) = delete;
216 
217  const VariableSet &
218  ReadSet() const noexcept
219  {
220  return ReadSet_;
221  }
222 
223  const VariableSet &
224  AllWriteSet() const noexcept
225  {
226  return AllWriteSet_;
227  }
228 
229  const VariableSet &
230  FullWriteSet() const noexcept
231  {
232  return FullWriteSet_;
233  }
234 
235  virtual bool
236  operator==(const AnnotationSet & other) const
237  {
238  return ReadSet_ == other.ReadSet_ && AllWriteSet_ == other.AllWriteSet_
239  && FullWriteSet_ == other.FullWriteSet_;
240  }
241 
242  bool
243  operator!=(const AnnotationSet & other) const
244  {
245  return !(*this == other);
246  }
247 
248  virtual std::string
249  DebugString() const noexcept = 0;
250 
251 private:
252  VariableSet ReadSet_;
253  VariableSet AllWriteSet_;
254  VariableSet FullWriteSet_;
255 };
256 
257 class EntryAnnotationSet final : public AnnotationSet
258 {
259 public:
260  ~EntryAnnotationSet() noexcept override;
261 
262  EntryAnnotationSet(VariableSet readSet, VariableSet allWriteSet, VariableSet fullWriteSet)
263  : AnnotationSet(std::move(readSet), std::move(allWriteSet), std::move(fullWriteSet))
264  {}
265 
267  VariableSet readSet,
268  VariableSet allWriteSet,
269  VariableSet fullWriteSet,
270  VariableSet topSet)
271  : AnnotationSet(std::move(readSet), std::move(allWriteSet), std::move(fullWriteSet)),
272  TopSet_(std::move(topSet))
273  {}
274 
275  static std::unique_ptr<EntryAnnotationSet>
276  Create(VariableSet readSet, VariableSet allWriteSet, VariableSet fullWriteSet)
277  {
278  return std::make_unique<EntryAnnotationSet>(
279  std::move(readSet),
280  std::move(allWriteSet),
281  std::move(fullWriteSet));
282  }
283 
284  std::string
285  DebugString() const noexcept override;
286 
287  bool
288  operator==(const AnnotationSet & other) const override;
289 
290  VariableSet TopSet_;
291 };
292 
293 class ExitAnnotationSet final : public AnnotationSet
294 {
295 public:
296  ~ExitAnnotationSet() noexcept override;
297 
298  ExitAnnotationSet(VariableSet readSet, VariableSet allWriteSet, VariableSet fullWriteSet)
299  : AnnotationSet(std::move(readSet), std::move(allWriteSet), std::move(fullWriteSet))
300  {}
301 
302  static std::unique_ptr<ExitAnnotationSet>
303  Create(VariableSet readSet, VariableSet allWriteSet, VariableSet fullWriteSet)
304  {
305  return std::make_unique<ExitAnnotationSet>(
306  std::move(readSet),
307  std::move(allWriteSet),
308  std::move(fullWriteSet));
309  }
310 
311  std::string
312  DebugString() const noexcept override;
313 
314  bool
315  operator==(const AnnotationSet & other) const override;
316 };
317 
319 {
320 public:
321  ~BasicBlockAnnotationSet() noexcept override;
322 
323  BasicBlockAnnotationSet(VariableSet readSet, VariableSet allWriteSet, VariableSet fullWriteSet)
324  : AnnotationSet(std::move(readSet), std::move(allWriteSet), std::move(fullWriteSet))
325  {}
326 
327  static std::unique_ptr<BasicBlockAnnotationSet>
328  Create(VariableSet readSet, VariableSet allWriteSet, VariableSet fullWriteSet)
329  {
330  return std::make_unique<BasicBlockAnnotationSet>(
331  std::move(readSet),
332  std::move(allWriteSet),
333  std::move(fullWriteSet));
334  }
335 
336  std::string
337  DebugString() const noexcept override;
338 
339  bool
340  operator==(const AnnotationSet & other) const override;
341 };
342 
343 class LinearAnnotationSet final : public AnnotationSet
344 {
345 public:
346  ~LinearAnnotationSet() noexcept override;
347 
348  LinearAnnotationSet(VariableSet readSet, VariableSet allWriteSet, VariableSet fullWriteSet)
349  : AnnotationSet(std::move(readSet), std::move(allWriteSet), std::move(fullWriteSet))
350  {}
351 
352  static std::unique_ptr<LinearAnnotationSet>
353  Create(VariableSet readSet, VariableSet allWriteSet, VariableSet fullWriteSet)
354  {
355  return std::make_unique<LinearAnnotationSet>(
356  std::move(readSet),
357  std::move(allWriteSet),
358  std::move(fullWriteSet));
359  }
360 
361  std::string
362  DebugString() const noexcept override;
363 
364  bool
365  operator==(const AnnotationSet & other) const override;
366 };
367 
368 class BranchAnnotationSet final : public AnnotationSet
369 {
370 public:
371  ~BranchAnnotationSet() noexcept override;
372 
373  BranchAnnotationSet(VariableSet readSet, VariableSet allWriteSet, VariableSet fullWriteSet)
374  : AnnotationSet(std::move(readSet), std::move(allWriteSet), std::move(fullWriteSet))
375  {}
376 
378  VariableSet readSet,
379  VariableSet allWriteSet,
380  VariableSet fullWriteSet,
381  VariableSet inputVariables,
382  VariableSet outputVariables)
383  : AnnotationSet(std::move(readSet), std::move(allWriteSet), std::move(fullWriteSet)),
384  InputVariables_(std::move(inputVariables)),
385  OutputVariables_(std::move(outputVariables))
386  {}
387 
388  static std::unique_ptr<BranchAnnotationSet>
389  Create(VariableSet readSet, VariableSet allWriteSet, VariableSet fullWriteSet)
390  {
391  return std::make_unique<BranchAnnotationSet>(
392  std::move(readSet),
393  std::move(allWriteSet),
394  std::move(fullWriteSet));
395  }
396 
397  std::string
398  DebugString() const noexcept override;
399 
400  bool
401  operator==(const AnnotationSet & other) const override;
402 
403  const VariableSet &
404  InputVariables() const noexcept
405  {
406  return InputVariables_;
407  }
408 
409  void
410  SetInputVariables(VariableSet inputVariables) noexcept
411  {
412  InputVariables_ = std::move(inputVariables);
413  }
414 
415  const VariableSet &
416  OutputVariables() const noexcept
417  {
418  return OutputVariables_;
419  }
420 
421  void
422  SetOutputVariables(VariableSet outputVariables) noexcept
423  {
424  OutputVariables_ = std::move(outputVariables);
425  }
426 
427 private:
430 };
431 
432 class LoopAnnotationSet final : public AnnotationSet
433 {
434 public:
435  ~LoopAnnotationSet() noexcept override;
436 
437  LoopAnnotationSet(VariableSet readSet, VariableSet allWriteSet, VariableSet fullWriteSet)
438  : AnnotationSet(std::move(readSet), std::move(allWriteSet), std::move(fullWriteSet))
439  {}
440 
442  VariableSet readSet,
443  VariableSet allWriteSet,
444  VariableSet fullWriteSet,
445  VariableSet loopVariables)
446  : AnnotationSet(std::move(readSet), std::move(allWriteSet), std::move(fullWriteSet)),
447  LoopVariables_(std::move(loopVariables))
448  {}
449 
450  static std::unique_ptr<LoopAnnotationSet>
451  Create(VariableSet readSet, VariableSet allWriteSet, VariableSet fullWriteSet)
452  {
453  return std::make_unique<LoopAnnotationSet>(
454  std::move(readSet),
455  std::move(allWriteSet),
456  std::move(fullWriteSet));
457  }
458 
459  std::string
460  DebugString() const noexcept override;
461 
462  bool
463  operator==(const AnnotationSet & other) const override;
464 
465  const VariableSet &
466  LoopVariables() const noexcept
467  {
468  return LoopVariables_;
469  }
470 
471  void
472  SetLoopVariables(VariableSet loopVariables) noexcept
473  {
474  LoopVariables_ = std::move(loopVariables);
475  }
476 
477 private:
479 };
480 
481 class AnnotationMap final
482 {
483 public:
484  AnnotationMap() = default;
485 
486  AnnotationMap(const AnnotationMap &) = delete;
487 
488  AnnotationMap(AnnotationMap &&) noexcept = delete;
489 
490  AnnotationMap &
491  operator=(const AnnotationMap &) = delete;
492 
493  AnnotationMap &
494  operator=(AnnotationMap &&) noexcept = delete;
495 
496  bool
497  Contains(const AggregationNode & aggregationNode) const noexcept
498  {
499  return Map_.find(&aggregationNode) != Map_.end();
500  }
501 
502  template<class T>
503  T &
504  Lookup(const AggregationNode & aggregationNode) const noexcept
505  {
506  JLM_ASSERT(Contains(aggregationNode));
507  auto & demandSet = Map_.find(&aggregationNode)->second;
508  return *jlm::util::assertedCast<T>(demandSet.get());
509  }
510 
511  void
512  Insert(const AggregationNode & aggregationNode, std::unique_ptr<AnnotationSet> annotationSet)
513  {
514  JLM_ASSERT(!Contains(aggregationNode));
515  Map_[&aggregationNode] = std::move(annotationSet);
516  }
517 
518  static std::unique_ptr<AnnotationMap>
520  {
521  return std::make_unique<AnnotationMap>();
522  }
523 
524 private:
525  std::unordered_map<const AggregationNode *, std::unique_ptr<AnnotationSet>> Map_;
526 };
527 
528 std::unique_ptr<AnnotationMap>
529 Annotate(const AggregationNode & aggregationTreeRoot);
530 
531 }
532 
533 #endif
std::unordered_map< const AggregationNode *, std::unique_ptr< AnnotationSet > > Map_
Definition: Annotation.hpp:525
T & Lookup(const AggregationNode &aggregationNode) const noexcept
Definition: Annotation.hpp:504
AnnotationMap(const AnnotationMap &)=delete
static std::unique_ptr< AnnotationMap > Create()
Definition: Annotation.hpp:519
void Insert(const AggregationNode &aggregationNode, std::unique_ptr< AnnotationSet > annotationSet)
Definition: Annotation.hpp:512
AnnotationMap(AnnotationMap &&) noexcept=delete
virtual ~AnnotationSet() noexcept
const VariableSet & FullWriteSet() const noexcept
Definition: Annotation.hpp:230
const VariableSet & AllWriteSet() const noexcept
Definition: Annotation.hpp:224
AnnotationSet(const AnnotationSet &)=delete
virtual bool operator==(const AnnotationSet &other) const
Definition: Annotation.hpp:236
virtual std::string DebugString() const noexcept=0
bool operator!=(const AnnotationSet &other) const
Definition: Annotation.hpp:243
AnnotationSet(AnnotationSet &&) noexcept=delete
~BasicBlockAnnotationSet() noexcept override
static std::unique_ptr< BasicBlockAnnotationSet > Create(VariableSet readSet, VariableSet allWriteSet, VariableSet fullWriteSet)
Definition: Annotation.hpp:328
void SetInputVariables(VariableSet inputVariables) noexcept
Definition: Annotation.hpp:410
void SetOutputVariables(VariableSet outputVariables) noexcept
Definition: Annotation.hpp:422
BranchAnnotationSet(VariableSet readSet, VariableSet allWriteSet, VariableSet fullWriteSet, VariableSet inputVariables, VariableSet outputVariables)
Definition: Annotation.hpp:377
static std::unique_ptr< BranchAnnotationSet > Create(VariableSet readSet, VariableSet allWriteSet, VariableSet fullWriteSet)
Definition: Annotation.hpp:389
const VariableSet & OutputVariables() const noexcept
Definition: Annotation.hpp:416
~BranchAnnotationSet() noexcept override
static std::unique_ptr< EntryAnnotationSet > Create(VariableSet readSet, VariableSet allWriteSet, VariableSet fullWriteSet)
Definition: Annotation.hpp:276
~EntryAnnotationSet() noexcept override
EntryAnnotationSet(VariableSet readSet, VariableSet allWriteSet, VariableSet fullWriteSet, VariableSet topSet)
Definition: Annotation.hpp:266
~ExitAnnotationSet() noexcept override
static std::unique_ptr< ExitAnnotationSet > Create(VariableSet readSet, VariableSet allWriteSet, VariableSet fullWriteSet)
Definition: Annotation.hpp:303
~LinearAnnotationSet() noexcept override
static std::unique_ptr< LinearAnnotationSet > Create(VariableSet readSet, VariableSet allWriteSet, VariableSet fullWriteSet)
Definition: Annotation.hpp:353
~LoopAnnotationSet() noexcept override
void SetLoopVariables(VariableSet loopVariables) noexcept
Definition: Annotation.hpp:472
static std::unique_ptr< LoopAnnotationSet > Create(VariableSet readSet, VariableSet allWriteSet, VariableSet fullWriteSet)
Definition: Annotation.hpp:451
LoopAnnotationSet(VariableSet readSet, VariableSet allWriteSet, VariableSet fullWriteSet, VariableSet loopVariables)
Definition: Annotation.hpp:441
bool operator!=(const ConstIterator &other) const
Definition: Annotation.hpp:80
const llvm::Variable * operator->() const
Definition: Annotation.hpp:53
const llvm::Variable & GetVariable() const noexcept
Definition: Annotation.hpp:41
const llvm::Variable & operator*() const
Definition: Annotation.hpp:47
std::forward_iterator_tag iterator_category
Definition: Annotation.hpp:29
ConstIterator(const std::unordered_set< const llvm::Variable * >::const_iterator &it)
Definition: Annotation.hpp:35
std::unordered_set< const llvm::Variable * >::const_iterator It_
Definition: Annotation.hpp:86
bool operator==(const ConstIterator &other) const
Definition: Annotation.hpp:74
bool Contains(const VariableSet &variableSet) const
Definition: Annotation.hpp:111
util::IteratorRange< ConstIterator > ConstRange
Definition: Annotation.hpp:89
void Remove(const VariableSet &variableSet)
Definition: Annotation.hpp:150
void Insert(const Variable &v)
Definition: Annotation.hpp:132
std::string DebugString() const noexcept
Definition: Annotation.cpp:17
VariableSet(std::initializer_list< const Variable * > init)
Definition: Annotation.hpp:94
bool operator!=(const VariableSet &other) const
Definition: Annotation.hpp:184
std::unordered_set< const Variable * > Set_
Definition: Annotation.hpp:193
size_t Size() const noexcept
Definition: Annotation.hpp:126
bool Contains(const Variable &v) const
Definition: Annotation.hpp:105
void Insert(const VariableSet &variableSet)
Definition: Annotation.hpp:138
ConstRange Variables() const noexcept
Definition: Annotation.hpp:99
void Remove(const Variable &v)
Definition: Annotation.hpp:144
void Intersect(const VariableSet &variableSet)
Definition: Annotation.hpp:157
bool operator==(const VariableSet &other) const
Definition: Annotation.hpp:169
#define JLM_ASSERT(x)
Definition: common.hpp:16
Global memory state passed between functions.
std::unique_ptr< AnnotationMap > Annotate(const AggregationNode &aggregationTreeRoot)
Definition: Annotation.cpp:492