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