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 |