Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
14 | pmbaty | 1 | //===- llvm/User.h - User class definition ----------------------*- C++ -*-===// |
2 | // |
||
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
||
4 | // See https://llvm.org/LICENSE.txt for license information. |
||
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
||
6 | // |
||
7 | //===----------------------------------------------------------------------===// |
||
8 | // |
||
9 | // This class defines the interface that one who uses a Value must implement. |
||
10 | // Each instance of the Value class keeps track of what User's have handles |
||
11 | // to it. |
||
12 | // |
||
13 | // * Instructions are the largest class of Users. |
||
14 | // * Constants may be users of other constants (think arrays and stuff) |
||
15 | // |
||
16 | //===----------------------------------------------------------------------===// |
||
17 | |||
18 | #ifndef LLVM_IR_USER_H |
||
19 | #define LLVM_IR_USER_H |
||
20 | |||
21 | #include "llvm/ADT/iterator.h" |
||
22 | #include "llvm/ADT/iterator_range.h" |
||
23 | #include "llvm/IR/Use.h" |
||
24 | #include "llvm/IR/Value.h" |
||
25 | #include "llvm/Support/Casting.h" |
||
26 | #include "llvm/Support/Compiler.h" |
||
27 | #include "llvm/Support/ErrorHandling.h" |
||
28 | #include <cassert> |
||
29 | #include <cstddef> |
||
30 | #include <cstdint> |
||
31 | #include <iterator> |
||
32 | |||
33 | namespace llvm { |
||
34 | |||
35 | template <typename T> class ArrayRef; |
||
36 | template <typename T> class MutableArrayRef; |
||
37 | |||
38 | /// Compile-time customization of User operands. |
||
39 | /// |
||
40 | /// Customizes operand-related allocators and accessors. |
||
41 | template <class> |
||
42 | struct OperandTraits; |
||
43 | |||
44 | class User : public Value { |
||
45 | template <unsigned> |
||
46 | friend struct HungoffOperandTraits; |
||
47 | |||
48 | LLVM_ATTRIBUTE_ALWAYS_INLINE static void * |
||
49 | allocateFixedOperandUser(size_t, unsigned, unsigned); |
||
50 | |||
51 | protected: |
||
52 | /// Allocate a User with an operand pointer co-allocated. |
||
53 | /// |
||
54 | /// This is used for subclasses which need to allocate a variable number |
||
55 | /// of operands, ie, 'hung off uses'. |
||
56 | void *operator new(size_t Size); |
||
57 | |||
58 | /// Allocate a User with the operands co-allocated. |
||
59 | /// |
||
60 | /// This is used for subclasses which have a fixed number of operands. |
||
61 | void *operator new(size_t Size, unsigned Us); |
||
62 | |||
63 | /// Allocate a User with the operands co-allocated. If DescBytes is non-zero |
||
64 | /// then allocate an additional DescBytes bytes before the operands. These |
||
65 | /// bytes can be accessed by calling getDescriptor. |
||
66 | /// |
||
67 | /// DescBytes needs to be divisible by sizeof(void *). The allocated |
||
68 | /// descriptor, if any, is aligned to sizeof(void *) bytes. |
||
69 | /// |
||
70 | /// This is used for subclasses which have a fixed number of operands. |
||
71 | void *operator new(size_t Size, unsigned Us, unsigned DescBytes); |
||
72 | |||
73 | User(Type *ty, unsigned vty, Use *, unsigned NumOps) |
||
74 | : Value(ty, vty) { |
||
75 | assert(NumOps < (1u << NumUserOperandsBits) && "Too many operands"); |
||
76 | NumUserOperands = NumOps; |
||
77 | // If we have hung off uses, then the operand list should initially be |
||
78 | // null. |
||
79 | assert((!HasHungOffUses || !getOperandList()) && |
||
80 | "Error in initializing hung off uses for User"); |
||
81 | } |
||
82 | |||
83 | /// Allocate the array of Uses, followed by a pointer |
||
84 | /// (with bottom bit set) to the User. |
||
85 | /// \param IsPhi identifies callers which are phi nodes and which need |
||
86 | /// N BasicBlock* allocated along with N |
||
87 | void allocHungoffUses(unsigned N, bool IsPhi = false); |
||
88 | |||
89 | /// Grow the number of hung off uses. Note that allocHungoffUses |
||
90 | /// should be called if there are no uses. |
||
91 | void growHungoffUses(unsigned N, bool IsPhi = false); |
||
92 | |||
93 | protected: |
||
94 | ~User() = default; // Use deleteValue() to delete a generic Instruction. |
||
95 | |||
96 | public: |
||
97 | User(const User &) = delete; |
||
98 | |||
99 | /// Free memory allocated for User and Use objects. |
||
100 | void operator delete(void *Usr); |
||
101 | /// Placement delete - required by std, called if the ctor throws. |
||
102 | void operator delete(void *Usr, unsigned) { |
||
103 | // Note: If a subclass manipulates the information which is required to calculate the |
||
104 | // Usr memory pointer, e.g. NumUserOperands, the operator delete of that subclass has |
||
105 | // to restore the changed information to the original value, since the dtor of that class |
||
106 | // is not called if the ctor fails. |
||
107 | User::operator delete(Usr); |
||
108 | |||
109 | #ifndef LLVM_ENABLE_EXCEPTIONS |
||
110 | llvm_unreachable("Constructor throws?"); |
||
111 | #endif |
||
112 | } |
||
113 | /// Placement delete - required by std, called if the ctor throws. |
||
114 | void operator delete(void *Usr, unsigned, unsigned) { |
||
115 | // Note: If a subclass manipulates the information which is required to calculate the |
||
116 | // Usr memory pointer, e.g. NumUserOperands, the operator delete of that subclass has |
||
117 | // to restore the changed information to the original value, since the dtor of that class |
||
118 | // is not called if the ctor fails. |
||
119 | User::operator delete(Usr); |
||
120 | |||
121 | #ifndef LLVM_ENABLE_EXCEPTIONS |
||
122 | llvm_unreachable("Constructor throws?"); |
||
123 | #endif |
||
124 | } |
||
125 | |||
126 | protected: |
||
127 | template <int Idx, typename U> static Use &OpFrom(const U *that) { |
||
128 | return Idx < 0 |
||
129 | ? OperandTraits<U>::op_end(const_cast<U*>(that))[Idx] |
||
130 | : OperandTraits<U>::op_begin(const_cast<U*>(that))[Idx]; |
||
131 | } |
||
132 | |||
133 | template <int Idx> Use &Op() { |
||
134 | return OpFrom<Idx>(this); |
||
135 | } |
||
136 | template <int Idx> const Use &Op() const { |
||
137 | return OpFrom<Idx>(this); |
||
138 | } |
||
139 | |||
140 | private: |
||
141 | const Use *getHungOffOperands() const { |
||
142 | return *(reinterpret_cast<const Use *const *>(this) - 1); |
||
143 | } |
||
144 | |||
145 | Use *&getHungOffOperands() { return *(reinterpret_cast<Use **>(this) - 1); } |
||
146 | |||
147 | const Use *getIntrusiveOperands() const { |
||
148 | return reinterpret_cast<const Use *>(this) - NumUserOperands; |
||
149 | } |
||
150 | |||
151 | Use *getIntrusiveOperands() { |
||
152 | return reinterpret_cast<Use *>(this) - NumUserOperands; |
||
153 | } |
||
154 | |||
155 | void setOperandList(Use *NewList) { |
||
156 | assert(HasHungOffUses && |
||
157 | "Setting operand list only required for hung off uses"); |
||
158 | getHungOffOperands() = NewList; |
||
159 | } |
||
160 | |||
161 | public: |
||
162 | const Use *getOperandList() const { |
||
163 | return HasHungOffUses ? getHungOffOperands() : getIntrusiveOperands(); |
||
164 | } |
||
165 | Use *getOperandList() { |
||
166 | return const_cast<Use *>(static_cast<const User *>(this)->getOperandList()); |
||
167 | } |
||
168 | |||
169 | Value *getOperand(unsigned i) const { |
||
170 | assert(i < NumUserOperands && "getOperand() out of range!"); |
||
171 | return getOperandList()[i]; |
||
172 | } |
||
173 | |||
174 | void setOperand(unsigned i, Value *Val) { |
||
175 | assert(i < NumUserOperands && "setOperand() out of range!"); |
||
176 | assert((!isa<Constant>((const Value*)this) || |
||
177 | isa<GlobalValue>((const Value*)this)) && |
||
178 | "Cannot mutate a constant with setOperand!"); |
||
179 | getOperandList()[i] = Val; |
||
180 | } |
||
181 | |||
182 | const Use &getOperandUse(unsigned i) const { |
||
183 | assert(i < NumUserOperands && "getOperandUse() out of range!"); |
||
184 | return getOperandList()[i]; |
||
185 | } |
||
186 | Use &getOperandUse(unsigned i) { |
||
187 | assert(i < NumUserOperands && "getOperandUse() out of range!"); |
||
188 | return getOperandList()[i]; |
||
189 | } |
||
190 | |||
191 | unsigned getNumOperands() const { return NumUserOperands; } |
||
192 | |||
193 | /// Returns the descriptor co-allocated with this User instance. |
||
194 | ArrayRef<const uint8_t> getDescriptor() const; |
||
195 | |||
196 | /// Returns the descriptor co-allocated with this User instance. |
||
197 | MutableArrayRef<uint8_t> getDescriptor(); |
||
198 | |||
199 | /// Set the number of operands on a GlobalVariable. |
||
200 | /// |
||
201 | /// GlobalVariable always allocates space for a single operands, but |
||
202 | /// doesn't always use it. |
||
203 | /// |
||
204 | /// FIXME: As that the number of operands is used to find the start of |
||
205 | /// the allocated memory in operator delete, we need to always think we have |
||
206 | /// 1 operand before delete. |
||
207 | void setGlobalVariableNumOperands(unsigned NumOps) { |
||
208 | assert(NumOps <= 1 && "GlobalVariable can only have 0 or 1 operands"); |
||
209 | NumUserOperands = NumOps; |
||
210 | } |
||
211 | |||
212 | /// Subclasses with hung off uses need to manage the operand count |
||
213 | /// themselves. In these instances, the operand count isn't used to find the |
||
214 | /// OperandList, so there's no issue in having the operand count change. |
||
215 | void setNumHungOffUseOperands(unsigned NumOps) { |
||
216 | assert(HasHungOffUses && "Must have hung off uses to use this method"); |
||
217 | assert(NumOps < (1u << NumUserOperandsBits) && "Too many operands"); |
||
218 | NumUserOperands = NumOps; |
||
219 | } |
||
220 | |||
221 | /// A droppable user is a user for which uses can be dropped without affecting |
||
222 | /// correctness and should be dropped rather than preventing a transformation |
||
223 | /// from happening. |
||
224 | bool isDroppable() const; |
||
225 | |||
226 | // --------------------------------------------------------------------------- |
||
227 | // Operand Iterator interface... |
||
228 | // |
||
229 | using op_iterator = Use*; |
||
230 | using const_op_iterator = const Use*; |
||
231 | using op_range = iterator_range<op_iterator>; |
||
232 | using const_op_range = iterator_range<const_op_iterator>; |
||
233 | |||
234 | op_iterator op_begin() { return getOperandList(); } |
||
235 | const_op_iterator op_begin() const { return getOperandList(); } |
||
236 | op_iterator op_end() { |
||
237 | return getOperandList() + NumUserOperands; |
||
238 | } |
||
239 | const_op_iterator op_end() const { |
||
240 | return getOperandList() + NumUserOperands; |
||
241 | } |
||
242 | op_range operands() { |
||
243 | return op_range(op_begin(), op_end()); |
||
244 | } |
||
245 | const_op_range operands() const { |
||
246 | return const_op_range(op_begin(), op_end()); |
||
247 | } |
||
248 | |||
249 | /// Iterator for directly iterating over the operand Values. |
||
250 | struct value_op_iterator |
||
251 | : iterator_adaptor_base<value_op_iterator, op_iterator, |
||
252 | std::random_access_iterator_tag, Value *, |
||
253 | ptrdiff_t, Value *, Value *> { |
||
254 | explicit value_op_iterator(Use *U = nullptr) : iterator_adaptor_base(U) {} |
||
255 | |||
256 | Value *operator*() const { return *I; } |
||
257 | Value *operator->() const { return operator*(); } |
||
258 | }; |
||
259 | |||
260 | value_op_iterator value_op_begin() { |
||
261 | return value_op_iterator(op_begin()); |
||
262 | } |
||
263 | value_op_iterator value_op_end() { |
||
264 | return value_op_iterator(op_end()); |
||
265 | } |
||
266 | iterator_range<value_op_iterator> operand_values() { |
||
267 | return make_range(value_op_begin(), value_op_end()); |
||
268 | } |
||
269 | |||
270 | struct const_value_op_iterator |
||
271 | : iterator_adaptor_base<const_value_op_iterator, const_op_iterator, |
||
272 | std::random_access_iterator_tag, const Value *, |
||
273 | ptrdiff_t, const Value *, const Value *> { |
||
274 | explicit const_value_op_iterator(const Use *U = nullptr) : |
||
275 | iterator_adaptor_base(U) {} |
||
276 | |||
277 | const Value *operator*() const { return *I; } |
||
278 | const Value *operator->() const { return operator*(); } |
||
279 | }; |
||
280 | |||
281 | const_value_op_iterator value_op_begin() const { |
||
282 | return const_value_op_iterator(op_begin()); |
||
283 | } |
||
284 | const_value_op_iterator value_op_end() const { |
||
285 | return const_value_op_iterator(op_end()); |
||
286 | } |
||
287 | iterator_range<const_value_op_iterator> operand_values() const { |
||
288 | return make_range(value_op_begin(), value_op_end()); |
||
289 | } |
||
290 | |||
291 | /// Drop all references to operands. |
||
292 | /// |
||
293 | /// This function is in charge of "letting go" of all objects that this User |
||
294 | /// refers to. This allows one to 'delete' a whole class at a time, even |
||
295 | /// though there may be circular references... First all references are |
||
296 | /// dropped, and all use counts go to zero. Then everything is deleted for |
||
297 | /// real. Note that no operations are valid on an object that has "dropped |
||
298 | /// all references", except operator delete. |
||
299 | void dropAllReferences() { |
||
300 | for (Use &U : operands()) |
||
301 | U.set(nullptr); |
||
302 | } |
||
303 | |||
304 | /// Replace uses of one Value with another. |
||
305 | /// |
||
306 | /// Replaces all references to the "From" definition with references to the |
||
307 | /// "To" definition. Returns whether any uses were replaced. |
||
308 | bool replaceUsesOfWith(Value *From, Value *To); |
||
309 | |||
310 | // Methods for support type inquiry through isa, cast, and dyn_cast: |
||
311 | static bool classof(const Value *V) { |
||
312 | return isa<Instruction>(V) || isa<Constant>(V); |
||
313 | } |
||
314 | }; |
||
315 | |||
316 | // Either Use objects, or a Use pointer can be prepended to User. |
||
317 | static_assert(alignof(Use) >= alignof(User), |
||
318 | "Alignment is insufficient after objects prepended to User"); |
||
319 | static_assert(alignof(Use *) >= alignof(User), |
||
320 | "Alignment is insufficient after objects prepended to User"); |
||
321 | |||
322 | template<> struct simplify_type<User::op_iterator> { |
||
323 | using SimpleType = Value*; |
||
324 | |||
325 | static SimpleType getSimplifiedValue(User::op_iterator &Val) { |
||
326 | return Val->get(); |
||
327 | } |
||
328 | }; |
||
329 | template<> struct simplify_type<User::const_op_iterator> { |
||
330 | using SimpleType = /*const*/ Value*; |
||
331 | |||
332 | static SimpleType getSimplifiedValue(User::const_op_iterator &Val) { |
||
333 | return Val->get(); |
||
334 | } |
||
335 | }; |
||
336 | |||
337 | } // end namespace llvm |
||
338 | |||
339 | #endif // LLVM_IR_USER_H |