llir-opt  0.0.1
Low-Level Post-Link Optimiser for OCaml and C
ref.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 "core/adt/hash.h"
8 #include "core/type.h"
9 
10 class Use;
11 class User;
12 class Value;
13 class Inst;
14 class Global;
15 
16 
17 
21 template <typename T>
22 class RefBase {
23 public:
24  T *Get() const { return inst_; }
25  T *operator->() const { return inst_; }
26  T &operator*() const { return *inst_; }
27 
28  unsigned Index() const { return index_; }
29 
30  template <typename U = T>
31  typename std::enable_if<std::is_base_of<Inst, U>::value, Type>::type
32  GetType() const
33  {
34  return inst_->GetType(index_);
35  }
36 
37  operator bool() const { return inst_ != nullptr; }
38 
39  bool operator==(const RefBase<T> &that) const
40  {
41  return inst_ == that.inst_ && index_ == that.index_;
42  }
43 
44  bool operator!=(const RefBase<T> &that) const
45  {
46  return !(*this == that);
47  }
48 
49 protected:
50  RefBase(T *inst, unsigned index) : inst_(inst), index_(index) {}
51 
52 protected:
54  T *inst_;
56  unsigned index_;
57 };
58 
62 template <typename T>
63 class Ref : public RefBase<T> {
64 public:
65  Ref() : RefBase<T>(nullptr, 0) {}
66  Ref(T &inst, unsigned idx = 0) : RefBase<T>(&inst, idx) {}
67  Ref(T *inst, unsigned idx = 0) : RefBase<T>(inst, idx) {}
68 
69  template
70  < typename U
71  , class = typename std::enable_if<std::is_base_of<U, T>::value>::type
72  >
73  operator Ref<U>() const
74  {
75  return Ref<U>(static_cast<U *>(this->inst_), this->index_);
76  }
77 };
78 
82 template <typename T>
83 class ConstRef : public RefBase<const T> {
84 public:
85  ConstRef() : RefBase<const T>(nullptr, 0) {}
86  ConstRef(const T &inst, unsigned idx = 0) : RefBase<const T>(&inst, idx) {}
87  ConstRef(const T *inst, unsigned idx = 0) : RefBase<const T>(inst, idx) {}
88  ConstRef(const Ref<T> &ref) : RefBase<const T>(ref.Get(), ref.Index()) {}
89 
90  template
91  < typename U
92  , class = typename std::enable_if<std::is_base_of<U, T>::value>::type
93  >
94  operator ConstRef<U>() const
95  {
96  return {static_cast<const U *>(this->inst_), this->index_};
97  }
98 };
99 
103 template<typename T>
104 struct std::hash<Ref<T>> {
105  std::size_t operator()(const Ref<T> &ref) const
106  {
107  size_t hash = 0;
108  ::hash_combine(hash, ref.Get());
109  ::hash_combine(hash, ref.Index());
110  return hash;
111  }
112 };
113 
117 template<typename T>
118 struct std::hash<ConstRef<T>> {
119  std::size_t operator()(const ConstRef<T> &ref) const
120  {
121  size_t hash = 0;
122  ::hash_combine(hash, ref.Get());
123  ::hash_combine(hash, ref.Index());
124  return hash;
125  }
126 };
127 
Use
Definition: use.h:18
Inst
Definition: inst.h:53
ConstRef
Definition: ref.h:83
Value
Definition: value.h:22
RefBase::inst_
T * inst_
Instruction pointed to.
Definition: ref.h:54
RefBase::index_
unsigned index_
Index of the return value in the instruction.
Definition: ref.h:56
Ref
Definition: ref.h:63
RefBase
Definition: ref.h:22
User
Definition: user.h:20
Global
Definition: global.h:23