llir-opt  0.0.1
Low-Level Post-Link Optimiser for OCaml and C
annot.h
1 // This file if part of the llir-opt project.
2 // Licensing information can be found in the LICENSE file.
3 // (C) 2018 Nandor Licker. All rights reserved.
4 
5 #pragma once
6 
7 #include <llvm/ADT/ilist_node.h>
8 #include <llvm/ADT/ilist.h>
9 #include <llvm/ADT/iterator_range.h>
10 
11 
15 class Annot : public llvm::ilist_node<Annot> {
16 public:
17  enum class Kind {
18  PROBABILITY = 0,
19  CAML_FRAME = 1,
20  CXX_LSDA = 2,
21  };
22 
23 public:
25  Annot(Kind kind) : kind_(kind) {}
26 
28  bool Is(Kind kind) const { return GetKind() == kind; }
30  Kind GetKind() const { return kind_; }
31 
33  bool operator==(const Annot &annot) const;
34 
35 private:
37  Kind kind_;
38 };
39 
43 class Probability final : public Annot {
44 public:
45  static constexpr Annot::Kind kAnnotKind = Kind::PROBABILITY;
46 
47 public:
49  Probability(uint32_t n, uint32_t d);
50 
52  uint32_t GetNumerator() const { return n_; };
54  uint32_t GetDenumerator() const { return d_; }
55 
57  bool operator==(const Probability &that) const;
58 
59 private:
61  uint32_t n_;
63  uint32_t d_;
64 };
65 
69 class AnnotSet {
70 private:
72  using AnnotListType = llvm::ilist<Annot>;
73 
74 public:
76  using iterator = AnnotListType::iterator;
77  using const_iterator = AnnotListType::const_iterator;
78 
79 public:
81  AnnotSet();
83  AnnotSet(AnnotSet &&that);
85  AnnotSet(const AnnotSet &that);
86 
88  ~AnnotSet();
89 
93  template<typename T>
94  bool Has() const
95  {
96  for (auto &annot : annots_) {
97  if (annot.Is(T::kAnnotKind)) {
98  return true;
99  }
100  }
101  return false;
102  }
103 
109  template<typename T, typename... Args>
110  bool Set(Args&&... args)
111  {
112  for (auto &annot : annots_) {
113  if (annot.Is(T::kAnnotKind)) {
114  return false;
115  }
116  }
117 
118  annots_.push_back(new T(std::move(args)...));
119  return true;
120  }
121 
125  template<typename T>
126  bool Clear()
127  {
128  for (auto it = annots_.begin(); it != annots_.end(); ) {
129  auto jt = it++;
130  if (jt->Is(T::kAnnotKind)) {
131  annots_.erase(jt);
132  return true;
133  }
134  }
135  return false;
136  }
137 
141  template<typename T>
142  const T *Get() const
143  {
144  for (auto it = annots_.begin(); it != annots_.end(); ++it) {
145  if (it->Is(T::kAnnotKind)) {
146  return static_cast<const T *>(&*it);
147  }
148  }
149  return nullptr;
150  }
151 
155  template<typename T>
157  {
158  AnnotSet that;
159  for (auto &annot : annots_) {
160  if (!annot.Is(T::kAnnotKind)) {
161  that.Add(annot);
162  }
163  }
164  return that;
165  }
166 
170  bool Add(const Annot &annot);
171 
173  bool operator == (const AnnotSet &that) const;
175  bool operator != (const AnnotSet &that) const { return !(*this == that); }
176 
178  AnnotSet &operator=(AnnotSet &&that);
179 
181  size_t size() const { return annots_.size(); }
183  bool empty() const { return annots_.empty(); }
185  iterator begin() { return annots_.begin(); }
187  iterator end() { return annots_.end(); }
189  const_iterator begin() const { return annots_.begin(); }
191  const_iterator end() const { return annots_.end(); }
192 
193 private:
195  AnnotListType annots_;
196 };
197 
201 class CamlFrame final : public Annot {
202 public:
203  static constexpr Annot::Kind kAnnotKind = Kind::CAML_FRAME;
204 
205 public:
207  struct DebugInfo {
209  int64_t Location;
211  std::string File;
213  std::string Definition;
214 
216  bool operator==(const DebugInfo &that) const {
217  if (Location != that.Location) {
218  return false;
219  }
220  if (File != that.File) {
221  return false;
222  }
223  if (Definition != that.Definition) {
224  return false;
225  }
226  return true;
227  }
228  };
229 
231  using DebugInfos = std::vector<DebugInfo>;
232 
234  using const_alloc_iterator = std::vector<size_t>::const_iterator;
236  using const_debug_infos_iterator = std::vector<DebugInfos>::const_iterator;
237 
238 public:
240  CamlFrame() : Annot(Kind::CAML_FRAME) {}
242  CamlFrame(
243  std::vector<size_t> &&allocs,
244  std::vector<DebugInfos> &&debug_infos
245  );
246 
248  size_t alloc_size() const { return allocs_.size(); }
250  llvm::iterator_range<const_alloc_iterator> allocs() const
251  {
252  return { allocs_.begin(), allocs_.end() };
253  }
254 
256  size_t debug_info_size() const { return debug_infos_.size(); }
258  llvm::iterator_range<const_debug_infos_iterator> debug_infos() const
259  {
260  return { debug_infos_.begin(), debug_infos_.end() };
261  }
262 
264  bool operator==(const CamlFrame &annot) const;
265 
266 private:
268  std::vector<size_t> allocs_;
270  std::vector<DebugInfos> debug_infos_;
271 };
272 
276 class CxxLSDA final : public Annot {
277 public:
278  static constexpr Annot::Kind kAnnotKind = Kind::CXX_LSDA;
279 
281  using const_type_iterator = std::vector<std::string>::const_iterator;
282 
283 public:
284  CxxLSDA(
285  bool cleanup,
286  bool catchAll,
287  std::vector<std::string> &&catches,
288  std::vector<std::string> &&filters)
289  : Annot(Kind::CXX_LSDA)
290  , cleanup_(cleanup)
291  , catchAll_(catchAll)
292  , catches_(std::move(catches))
293  , filters_(std::move(filters))
294  {
295  }
296 
298  bool IsCleanup() const { return cleanup_; }
300  bool IsCatchAll() const { return catchAll_; }
301 
303  size_t catch_size() const { return catches_.size(); }
305  llvm::iterator_range<const_type_iterator> catches() const
306  {
307  return { catches_.begin(), catches_.end() };
308  }
309 
311  size_t filter_size() const { return filters_.size(); }
313  llvm::iterator_range<const_type_iterator> filters() const
314  {
315  return { filters_.begin(), filters_.end() };
316  }
317 
318 private:
320  bool cleanup_;
322  bool catchAll_;
324  std::vector<std::string> catches_;
326  std::vector<std::string> filters_;
327 };
CamlFrame::debug_infos
llvm::iterator_range< const_debug_infos_iterator > debug_infos() const
Iterator over debug information bundles.
Definition: annot.h:258
CxxLSDA::catches
llvm::iterator_range< const_type_iterator > catches() const
Iterator over catches.
Definition: annot.h:305
Probability::operator==
bool operator==(const Probability &that) const
Checks if two annotations are equal.
Definition: annot.cpp:140
AnnotSet::AnnotSet
AnnotSet()
Creats a new, empty annotation set.
Definition: annot.cpp:32
AnnotSet::operator==
bool operator==(const AnnotSet &that) const
Compares two annotations sets for equality.
Definition: annot.cpp:80
AnnotSet::operator!=
bool operator!=(const AnnotSet &that) const
Compares two annotations sets for inequality.
Definition: annot.h:175
CamlFrame::DebugInfos
std::vector< DebugInfo > DebugInfos
Debug information bundle.
Definition: annot.h:231
AnnotSet::Has
bool Has() const
Definition: annot.h:94
CamlFrame::DebugInfo
Debug information.
Definition: annot.h:207
CxxLSDA::filter_size
size_t filter_size() const
Returns the number of filters.
Definition: annot.h:311
AnnotSet::empty
bool empty() const
Checks if there are any annotations set.
Definition: annot.h:183
Probability::Probability
Probability(uint32_t n, uint32_t d)
Constructs an annotation carrying a probability.
Definition: annot.cpp:133
CamlFrame::DebugInfo::operator==
bool operator==(const DebugInfo &that) const
Compares two debug info objects.
Definition: annot.h:216
CamlFrame::DebugInfo::Location
int64_t Location
Packed location information.
Definition: annot.h:209
CxxLSDA::IsCatchAll
bool IsCatchAll() const
Checks whether the frame is a catch-all frame.
Definition: annot.h:300
CxxLSDA::filters
llvm::iterator_range< const_type_iterator > filters() const
Iterator over filters.
Definition: annot.h:313
CamlFrame::allocs
llvm::iterator_range< const_alloc_iterator > allocs() const
Iterator over allocations.
Definition: annot.h:250
AnnotSet
Definition: annot.h:69
AnnotSet::Add
bool Add(const Annot &annot)
Definition: annot.cpp:66
AnnotSet::size
size_t size() const
Returns the number of set annotations.
Definition: annot.h:181
CxxLSDA::IsCleanup
bool IsCleanup() const
Checks whether the frame is a cleanup frame.
Definition: annot.h:298
CxxLSDA
Definition: annot.h:276
Annot::operator==
bool operator==(const Annot &annot) const
Checks if two annotations are equal.
Definition: annot.cpp:12
CamlFrame::const_debug_infos_iterator
std::vector< DebugInfos >::const_iterator const_debug_infos_iterator
Iterator over debug infos.
Definition: annot.h:236
AnnotSet::~AnnotSet
~AnnotSet()
Destroys the annotation set.
Definition: annot.cpp:61
AnnotSet::Clear
bool Clear()
Definition: annot.h:126
AnnotSet::end
iterator end()
Iterator past the last annotation.
Definition: annot.h:187
AnnotSet::operator=
AnnotSet & operator=(AnnotSet &&that)
Assigns annotation from a different set.
Definition: annot.cpp:110
AnnotSet::end
const_iterator end() const
Constant iterator past the last annotation.
Definition: annot.h:191
Probability
Definition: annot.h:43
CxxLSDA::catch_size
size_t catch_size() const
Returns the number of catches.
Definition: annot.h:303
Annot::Is
bool Is(Kind kind) const
Checks if the annotation is of a given kind.
Definition: annot.h:28
AnnotSet::begin
const_iterator begin() const
Constant iterator to the first annotation.
Definition: annot.h:189
CamlFrame
Definition: annot.h:201
Annot::GetKind
Kind GetKind() const
Returns the annotation kind.
Definition: annot.h:30
AnnotSet::Set
bool Set(Args &&... args)
Definition: annot.h:110
CamlFrame::alloc_size
size_t alloc_size() const
Returns the number of allocations.
Definition: annot.h:248
Probability::GetNumerator
uint32_t GetNumerator() const
Returns the numerator.
Definition: annot.h:52
AnnotSet::Without
AnnotSet Without() const
Definition: annot.h:156
Probability::GetDenumerator
uint32_t GetDenumerator() const
Returns the denominator.
Definition: annot.h:54
CamlFrame::debug_info_size
size_t debug_info_size() const
Returns the number of debug infos.
Definition: annot.h:256
CamlFrame::DebugInfo::Definition
std::string Definition
Name of the definition.
Definition: annot.h:213
CamlFrame::DebugInfo::File
std::string File
Name of the originating file.
Definition: annot.h:211
CxxLSDA::const_type_iterator
std::vector< std::string >::const_iterator const_type_iterator
Iterator over type IDs.
Definition: annot.h:281
CamlFrame::CamlFrame
CamlFrame()
Constructs an annotation without debug info.
Definition: annot.h:240
Annot
Definition: annot.h:15
CamlFrame::operator==
bool operator==(const CamlFrame &annot) const
Checks if two annotations are equal.
Definition: annot.cpp:127
AnnotSet::begin
iterator begin()
Iterator to the first annotation.
Definition: annot.h:185
AnnotSet::iterator
AnnotListType::iterator iterator
Iterator over the annotations.
Definition: annot.h:76
Annot::Annot
Annot(Kind kind)
Creates a new annotation.
Definition: annot.h:25
CamlFrame::const_alloc_iterator
std::vector< size_t >::const_iterator const_alloc_iterator
Iterator over allocations.
Definition: annot.h:234
AnnotSet::Get
const T * Get() const
Definition: annot.h:142