llir-opt  0.0.1
Low-Level Post-Link Optimiser for OCaml and C
user.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/value.h"
14 
15 
16 
20 class User : public Value {
21 public:
22  using op_iterator = Use *;
23  using const_op_iterator = const Use *;
24  using op_range = llvm::iterator_range<op_iterator>;
25  using const_op_range = llvm::iterator_range<const_op_iterator>;
26 
27  struct value_op_iterator : llvm::iterator_adaptor_base
28  < value_op_iterator
29  , op_iterator
30  , std::random_access_iterator_tag
31  , Ref<Value>
32  , ptrdiff_t
33  , Ref<Value>
34  , Ref<Value>>
35  {
36  explicit value_op_iterator(Use *U = nullptr)
37  : iterator_adaptor_base(U)
38  {
39  }
40 
41  Ref<Value> operator*() const { return *I; }
42  Ref<Value> operator->() const { return *I; }
43  };
44 
45  struct const_value_op_iterator : llvm::iterator_adaptor_base
46  < const_value_op_iterator
47  , const_op_iterator
48  , std::random_access_iterator_tag
49  , ConstRef<Value>
50  , ptrdiff_t
51  , ConstRef<Value>
52  , ConstRef<Value>>
53  {
54  explicit const_value_op_iterator(const Use *U = nullptr)
55  : iterator_adaptor_base(U)
56  {
57  }
58 
59  ConstRef<Value> operator*() const { return *I; }
60  ConstRef<Value> operator->() const { return *I; }
61  };
62 
63  using value_op_range = llvm::iterator_range<value_op_iterator>;
64  using const_value_op_range = llvm::iterator_range<const_value_op_iterator>;
65 
66  template <typename T>
67  struct conv_op_iterator : llvm::iterator_adaptor_base
68  < conv_op_iterator<T>
69  , value_op_iterator
70  , std::random_access_iterator_tag
71  , Ref<T>
72  , ptrdiff_t
73  , Ref<T>
74  , Ref<T>
75  >
76  {
78  : llvm::iterator_adaptor_base
81  , std::random_access_iterator_tag
82  , Ref<T>
83  , ptrdiff_t
84  , Ref<T>
85  , Ref<T>
86  >(it)
87  {
88  }
89 
90  Ref<T> operator*() const;
91  Ref<T> operator->() const;
92  };
93 
94  template <typename T>
95  struct const_conv_op_iterator : llvm::iterator_adaptor_base
96  < const_conv_op_iterator<T>
97  , const_value_op_iterator
98  , std::random_access_iterator_tag
99  , ConstRef<T>
100  , ptrdiff_t
101  , ConstRef<T>
102  , ConstRef<T>
103  >
104  {
106  : llvm::iterator_adaptor_base
109  , std::random_access_iterator_tag
110  , ConstRef<T>
111  , ptrdiff_t
112  , ConstRef<T>
113  , ConstRef<T>
114  >(it)
115  {
116  }
117 
118  ConstRef<T> operator*() const;
119  ConstRef<T> operator->() const;
120  };
121 
122  template<typename T>
123  using conv_op_range = llvm::iterator_range<conv_op_iterator<T>>;
124  template<typename T>
125  using const_conv_op_range = llvm::iterator_range<const_conv_op_iterator<T>>;
126 
127  template <typename T>
128  struct unref_iterator : llvm::iterator_adaptor_base
129  < unref_iterator<T>
130  , value_op_iterator
131  , std::random_access_iterator_tag
132  , T *
133  , ptrdiff_t
134  , T *
135  , T *
136  >
137  {
139  : llvm::iterator_adaptor_base
142  , std::random_access_iterator_tag
143  , T *
144  , ptrdiff_t
145  , T *
146  , T *
147  >(it)
148  {
149  }
150 
151  T *operator*() const { return static_cast<T *>((*this->I).Get()); }
152  T *operator->() const { return static_cast<T *>((*this->I).Get()); }
153  };
154 
155  template <typename T>
156  struct const_unref_iterator : llvm::iterator_adaptor_base
157  < const_unref_iterator<T>
158  , const_value_op_iterator
159  , std::random_access_iterator_tag
160  , const T*
161  , ptrdiff_t
162  , const T*
163  , const T*
164  >
165  {
167  : llvm::iterator_adaptor_base
170  , std::random_access_iterator_tag
171  , const T*
172  , ptrdiff_t
173  , const T*
174  , const T*
175  >(it)
176  {
177  }
178 
179  const T *operator*() const { return static_cast<const T *>((*this->I).Get()); }
180  const T *operator->() const { return static_cast<const T *>((*this->I).Get()); }
181  };
182 
183  template<typename T>
184  using unref_range = llvm::iterator_range<unref_iterator<T>>;
185  template<typename T>
186  using const_unref_range = llvm::iterator_range<const_unref_iterator<T>>;
187 
188 public:
190  User(Kind kind, unsigned numOps);
191 
193  virtual ~User();
194 
195  // Returns the number of operands.
196  size_t size() const { return numOps_; }
197 
198  // Iterators over uses.
199  op_iterator op_begin() { return uses_; }
200  op_iterator op_end() { return uses_ + numOps_; }
201  op_range operands();
202  const_op_iterator op_begin() const { return uses_; }
203  const_op_iterator op_end() const { return uses_ + numOps_; }
204  const_op_range operands() const;
205 
206  // Iterators over values.
207  value_op_iterator value_op_begin();
208  value_op_iterator value_op_end();
209  value_op_range operand_values();
210  const_value_op_iterator value_op_begin() const;
211  const_value_op_iterator value_op_end() const;
212  const_value_op_range operand_values() const;
213 
214 protected:
216  template <int I>
217  void Set(Ref<Value> val)
218  {
219  (I < 0 ? op_end() : op_begin())[I] = val;
220  }
221 
223  void Set(int i, Ref<Value> val)
224  {
225  (i < 0 ? op_end() : op_begin())[i] = val;
226  }
227 
229  template <int I>
231  {
232  return static_cast<Ref<Value>>((I < 0 ? op_end() : op_begin())[I]);
233  }
234 
237  {
238  return static_cast<Ref<Value>>((i < 0 ? op_end() : op_begin())[i]);
239  }
240 
242  template <int I>
244  {
245  return static_cast<ConstRef<Value>>((I < 0 ? op_end() : op_begin())[I]);
246  }
247 
249  ConstRef<Value> Get(int i) const
250  {
251  return static_cast<ConstRef<Value>>((i < 0 ? op_end() : op_begin())[i]);
252  }
253 
254 protected:
256  void resizeUses(unsigned n);
257 
258 protected:
260  unsigned numOps_;
263 };
User::Get
Ref< Value > Get()
Accessor for an operand.
Definition: user.h:230
Use
Definition: use.h:18
ConstRef
Definition: ref.h:83
User::Get
ConstRef< Value > Get(int i) const
Accessor for an operand.
Definition: user.h:249
Value
Definition: value.h:22
User::const_unref_iterator
Definition: user.h:156
User::uses_
Use * uses_
Head of the use list.
Definition: user.h:262
User::unref_iterator
Definition: user.h:128
User::numOps_
unsigned numOps_
Number of operands.
Definition: user.h:260
User::const_value_op_iterator
Definition: user.h:45
User::Set
void Set(int i, Ref< Value > val)
Setter for an operand.
Definition: user.h:223
User::const_conv_op_iterator
Definition: user.h:95
User::User
User(Kind kind, unsigned numOps)
Creates a new user.
Definition: user.cpp:43
Value::Kind
Kind
Enumeration of value types.
Definition: value.h:133
User::Get
Ref< Value > Get(int i)
Accessor for an operand.
Definition: user.h:236
User::resizeUses
void resizeUses(unsigned n)
Grows the operand list.
Definition: user.cpp:114
User::~User
virtual ~User()
Cleans up after the use.
Definition: user.cpp:57
Ref< Value >
User::conv_op_iterator
Definition: user.h:67
User
Definition: user.h:20
User::value_op_iterator
Definition: user.h:27
User::Set
void Set(Ref< Value > val)
Setter for an operand.
Definition: user.h:217
User::Get
ConstRef< Value > Get() const
Accessor for an operand.
Definition: user.h:243