llir-opt  0.0.1
Low-Level Post-Link Optimiser for OCaml and C
value.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 <iterator>
8 
9 #include <llvm/ADT/ArrayRef.h>
10 #include <llvm/ADT/iterator.h>
11 #include <llvm/ADT/iterator_range.h>
12 
13 #include "core/use.h"
14 
15 template<typename T> class Ref;
16 
17 
18 
22 class Value {
23 public:
24  template<typename T>
25  using forward_it = std::iterator<std::forward_iterator_tag, T>;
26 
30  template <typename UseT>
31  class use_iterator_impl : public forward_it<UseT *> {
32  public:
33  use_iterator_impl() : u_(nullptr) {}
34 
35  bool operator==(const use_iterator_impl &that) const { return u_ == that.u_; }
36  bool operator!=(const use_iterator_impl &that) const { return !(*this == that); }
37 
38  use_iterator_impl &operator++() {
39  assert(u_ && "Cannot increment end iterator!");
40  u_ = u_->getNext();
41  return *this;
42  }
43 
44  use_iterator_impl operator++(int) {
45  auto tmp = *this;
46  ++*this;
47  return tmp;
48  }
49 
50  UseT &operator*() const {
51  assert(u_ && "Cannot dereference end iterator!");
52  return *u_;
53  }
54 
55  UseT *operator->() const { return &operator*(); }
56 
57  operator use_iterator_impl<const UseT>() const {
59  }
60 
61  private:
62  explicit use_iterator_impl(UseT *u) : u_(u) {}
63 
64  private:
65  friend class Value;
66  UseT *u_;
67  };
68 
72  template <typename UserTy>
73  class user_iterator_impl : public forward_it<UserTy *> {
74  public:
75  user_iterator_impl() = default;
76 
77  bool operator==(const user_iterator_impl &that) const
78  {
79  return UI == that.UI;
80  }
81 
82  bool operator!=(const user_iterator_impl &that) const
83  {
84  return !(*this == that);
85  }
86 
88  bool atEnd() const { return *this == user_iterator_impl(); }
89 
90  // Pre-increment
91  user_iterator_impl &operator++()
92  {
93  ++UI;
94  return *this;
95  }
96 
97  // Post-increment
98  user_iterator_impl operator++(int)
99  {
100  auto tmp = *this;
101  ++*this;
102  return tmp;
103  }
104 
105  // Retrieve a pointer to the current User.
106  UserTy *operator*() const {
107  return UI->getUser();
108  }
109 
110  UserTy *operator->() const { return operator*(); }
111 
112  operator user_iterator_impl<const UserTy>() const {
113  return user_iterator_impl<const UserTy>(*UI);
114  }
115 
116  Use &getUse() const { return *UI; }
117 
118  private:
119  explicit user_iterator_impl(Use *U) : UI(U) {}
120 
121  private:
122  use_iterator_impl<Use> UI;
123  friend class Value;
124  };
125 
126  using use_iterator = use_iterator_impl<Use>;
127  using const_use_iterator = use_iterator_impl<const Use>;
128  using user_iterator = user_iterator_impl<User>;
129  using const_user_iterator = user_iterator_impl<const User>;
130 
131 public:
133  enum class Kind {
134  INST,
135  GLOBAL,
136  EXPR,
137  CONST,
138  };
139 
141  Value(Kind kind) : kind_(kind), users_(nullptr) { }
143  Value(const Value &) = delete;
145  Value(Value &&) = delete;
146 
148  virtual ~Value();
149 
151  Kind GetKind() const { return kind_; }
153  bool Is(Kind kind) const { return GetKind() == kind; }
155  bool IsConstant() const;
156 
158  virtual void replaceAllUsesWith(Value *v);
160  virtual void replaceAllUsesWith(Ref<Value> v);
161 
162  // Iterator over use sites.
163  size_t use_size() const { return std::distance(use_begin(), use_end()); }
164  bool use_empty() const { return users_ == nullptr; }
165  use_iterator use_begin() { return use_iterator(users_); }
166  const_use_iterator use_begin() const { return const_use_iterator(users_); }
167  use_iterator use_end() { return use_iterator(); }
168  const_use_iterator use_end() const { return const_use_iterator(); }
169  llvm::iterator_range<use_iterator> uses();
170  llvm::iterator_range<const_use_iterator> uses() const;
171 
172  // Iterator over users.
173  bool user_empty() const { return users_ == nullptr; }
174  user_iterator user_begin() { return user_iterator(users_); }
175  const_user_iterator user_begin() const { return const_user_iterator(users_); }
176  user_iterator user_end() { return user_iterator(); }
177  const_user_iterator user_end() const { return const_user_iterator(); }
178  llvm::iterator_range<user_iterator> users();
179  llvm::iterator_range<const_user_iterator> users() const;
180 
182  void operator = (const Value &) = delete;
184  void operator = (Value &&) = delete;
185 
186 private:
188  friend class Use;
190  Kind kind_;
192  Use *users_;
193 };
194 
Use
Definition: use.h:18
Value::operator=
void operator=(const Value &)=delete
Do not allow assignments.
Value
Definition: value.h:22
Value::replaceAllUsesWith
virtual void replaceAllUsesWith(Value *v)
Replaces all uses of this value.
Definition: value.cpp:34
Value::GetKind
Kind GetKind() const
Returns the value kind.
Definition: value.h:151
Value::~Value
virtual ~Value()
Destroy the value.
Definition: value.cpp:12
Value::use_iterator_impl
Definition: value.h:31
Value::user_iterator_impl
Definition: value.h:73
Value::Kind
Kind
Enumeration of value types.
Definition: value.h:133
Value::Value
Value(Kind kind)
Constructs a new value.
Definition: value.h:141
Use::getUser
User * getUser() const
Returns the user attached to this use.
Definition: use.h:41
Value::user_iterator_impl::atEnd
bool atEnd() const
Returns true if this iterator is equal to user_end() on the value.
Definition: value.h:88
Ref
Definition: ref.h:63
Value::IsConstant
bool IsConstant() const
Checks whether the value is a compile-time constant.
Definition: value.cpp:18
Value::Is
bool Is(Kind kind) const
Checks if the value is of a specific kind.
Definition: value.h:153