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 friend struct HungoffOperandTraits; 46 template <class ConstantClass> friend struct ConstantAggrKeyType; 47 48 LLVM_ATTRIBUTE_ALWAYS_INLINE static void * 49 allocateFixedOperandUser(size_t, unsigned, unsigned); 50 51 protected: 52 // Disable the default operator new, as all subclasses must use one of the 53 // custom operators below depending on how they store their operands. 54 void *operator new(size_t Size) = delete; 55 56 /// Indicates this User has operands "hung off" in another allocation. 57 struct HungOffOperandsAllocMarker {}; 58 59 /// Indicates this User has operands co-allocated. 60 struct IntrusiveOperandsAllocMarker { 61 /// The number of operands for this User. 62 const unsigned NumOps; 63 }; 64 65 /// Indicates this User has operands and a descriptor co-allocated . 66 struct IntrusiveOperandsAndDescriptorAllocMarker { 67 /// The number of operands for this User. 68 const unsigned NumOps; 69 /// The number of bytes to allocate for the descriptor. Must be divisible by 70 /// `sizeof(void *)`. 71 const unsigned DescBytes; 72 }; 73 74 /// Information about how a User object was allocated, to be passed into the 75 /// User constructor. 76 /// 77 /// DO NOT USE DIRECTLY. Use one of the `AllocMarker` structs instead, they 78 /// call all be implicitly converted to `AllocInfo`. 79 struct AllocInfo { 80 public: 81 const unsigned NumOps : NumUserOperandsBits; 82 const bool HasHungOffUses : 1; 83 const bool HasDescriptor : 1; 84 85 AllocInfo() = delete; 86 87 constexpr AllocInfo(const HungOffOperandsAllocMarker) 88 : NumOps(0), HasHungOffUses(true), HasDescriptor(false) {} 89 90 constexpr AllocInfo(const IntrusiveOperandsAllocMarker Alloc) 91 : NumOps(Alloc.NumOps), HasHungOffUses(false), HasDescriptor(false) {} 92 93 constexpr AllocInfo(const IntrusiveOperandsAndDescriptorAllocMarker Alloc) 94 : NumOps(Alloc.NumOps), HasHungOffUses(false), 95 HasDescriptor(Alloc.DescBytes != 0) {} 96 }; 97 98 /// Allocate a User with an operand pointer co-allocated. 99 /// 100 /// This is used for subclasses which need to allocate a variable number 101 /// of operands, ie, 'hung off uses'. 102 void *operator new(size_t Size, HungOffOperandsAllocMarker); 103 104 /// Allocate a User with the operands co-allocated. 105 /// 106 /// This is used for subclasses which have a fixed number of operands. 107 void *operator new(size_t Size, IntrusiveOperandsAllocMarker allocTrait); 108 109 /// Allocate a User with the operands co-allocated. If DescBytes is non-zero 110 /// then allocate an additional DescBytes bytes before the operands. These 111 /// bytes can be accessed by calling getDescriptor. 112 void *operator new(size_t Size, 113 IntrusiveOperandsAndDescriptorAllocMarker allocTrait); 114 115 User(Type *ty, unsigned vty, AllocInfo AllocInfo) : Value(ty, vty) { 116 assert(AllocInfo.NumOps < (1u << NumUserOperandsBits) && 117 "Too many operands"); 118 NumUserOperands = AllocInfo.NumOps; 119 assert((!AllocInfo.HasDescriptor || !AllocInfo.HasHungOffUses) && 120 "Cannot have both hung off uses and a descriptor"); 121 HasHungOffUses = AllocInfo.HasHungOffUses; 122 HasDescriptor = AllocInfo.HasDescriptor; 123 // If we have hung off uses, then the operand list should initially be 124 // null. 125 assert((!AllocInfo.HasHungOffUses || !getOperandList()) && 126 "Error in initializing hung off uses for User"); 127 } 128 129 /// Allocate the array of Uses, followed by a pointer 130 /// (with bottom bit set) to the User. 131 /// \param IsPhi identifies callers which are phi nodes and which need 132 /// N BasicBlock* allocated along with N 133 void allocHungoffUses(unsigned N, bool IsPhi = false); 134 135 /// Grow the number of hung off uses. Note that allocHungoffUses 136 /// should be called if there are no uses. 137 void growHungoffUses(unsigned N, bool IsPhi = false); 138 139 protected: 140 ~User() = default; // Use deleteValue() to delete a generic Instruction. 141 142 public: 143 User(const User &) = delete; 144 145 /// Free memory allocated for User and Use objects. 146 void operator delete(void *Usr); 147 /// Placement delete - required by std, called if the ctor throws. 148 void operator delete(void *Usr, HungOffOperandsAllocMarker) { 149 // Note: If a subclass manipulates the information which is required to 150 // calculate the Usr memory pointer, e.g. NumUserOperands, the operator 151 // delete of that subclass has to restore the changed information to the 152 // original value, since the dtor of that class is not called if the ctor 153 // fails. 154 User::operator delete(Usr); 155 156 #ifndef LLVM_ENABLE_EXCEPTIONS 157 llvm_unreachable("Constructor throws?"); 158 #endif 159 } 160 /// Placement delete - required by std, called if the ctor throws. 161 void operator delete(void *Usr, IntrusiveOperandsAllocMarker) { 162 // Note: If a subclass manipulates the information which is required to calculate the 163 // Usr memory pointer, e.g. NumUserOperands, the operator delete of that subclass has 164 // to restore the changed information to the original value, since the dtor of that class 165 // is not called if the ctor fails. 166 User::operator delete(Usr); 167 168 #ifndef LLVM_ENABLE_EXCEPTIONS 169 llvm_unreachable("Constructor throws?"); 170 #endif 171 } 172 /// Placement delete - required by std, called if the ctor throws. 173 void operator delete(void *Usr, IntrusiveOperandsAndDescriptorAllocMarker) { 174 // Note: If a subclass manipulates the information which is required to calculate the 175 // Usr memory pointer, e.g. NumUserOperands, the operator delete of that subclass has 176 // to restore the changed information to the original value, since the dtor of that class 177 // is not called if the ctor fails. 178 User::operator delete(Usr); 179 180 #ifndef LLVM_ENABLE_EXCEPTIONS 181 llvm_unreachable("Constructor throws?"); 182 #endif 183 } 184 185 protected: 186 template <int Idx, typename U> static Use &OpFrom(const U *that) { 187 return Idx < 0 188 ? OperandTraits<U>::op_end(const_cast<U*>(that))[Idx] 189 : OperandTraits<U>::op_begin(const_cast<U*>(that))[Idx]; 190 } 191 192 template <int Idx> Use &Op() { 193 return OpFrom<Idx>(this); 194 } 195 template <int Idx> const Use &Op() const { 196 return OpFrom<Idx>(this); 197 } 198 199 private: 200 const Use *getHungOffOperands() const { 201 return *(reinterpret_cast<const Use *const *>(this) - 1); 202 } 203 204 Use *&getHungOffOperands() { return *(reinterpret_cast<Use **>(this) - 1); } 205 206 const Use *getIntrusiveOperands() const { 207 return reinterpret_cast<const Use *>(this) - NumUserOperands; 208 } 209 210 Use *getIntrusiveOperands() { 211 return reinterpret_cast<Use *>(this) - NumUserOperands; 212 } 213 214 void setOperandList(Use *NewList) { 215 assert(HasHungOffUses && 216 "Setting operand list only required for hung off uses"); 217 getHungOffOperands() = NewList; 218 } 219 220 public: 221 const Use *getOperandList() const { 222 return HasHungOffUses ? getHungOffOperands() : getIntrusiveOperands(); 223 } 224 Use *getOperandList() { 225 return const_cast<Use *>(static_cast<const User *>(this)->getOperandList()); 226 } 227 228 Value *getOperand(unsigned i) const { 229 assert(i < NumUserOperands && "getOperand() out of range!"); 230 return getOperandList()[i]; 231 } 232 233 void setOperand(unsigned i, Value *Val) { 234 assert(i < NumUserOperands && "setOperand() out of range!"); 235 assert((!isa<Constant>((const Value*)this) || 236 isa<GlobalValue>((const Value*)this)) && 237 "Cannot mutate a constant with setOperand!"); 238 getOperandList()[i] = Val; 239 } 240 241 const Use &getOperandUse(unsigned i) const { 242 assert(i < NumUserOperands && "getOperandUse() out of range!"); 243 return getOperandList()[i]; 244 } 245 Use &getOperandUse(unsigned i) { 246 assert(i < NumUserOperands && "getOperandUse() out of range!"); 247 return getOperandList()[i]; 248 } 249 250 unsigned getNumOperands() const { return NumUserOperands; } 251 252 /// Returns the descriptor co-allocated with this User instance. 253 ArrayRef<const uint8_t> getDescriptor() const; 254 255 /// Returns the descriptor co-allocated with this User instance. 256 MutableArrayRef<uint8_t> getDescriptor(); 257 258 /// Subclasses with hung off uses need to manage the operand count 259 /// themselves. In these instances, the operand count isn't used to find the 260 /// OperandList, so there's no issue in having the operand count change. 261 void setNumHungOffUseOperands(unsigned NumOps) { 262 assert(HasHungOffUses && "Must have hung off uses to use this method"); 263 assert(NumOps < (1u << NumUserOperandsBits) && "Too many operands"); 264 NumUserOperands = NumOps; 265 } 266 267 /// A droppable user is a user for which uses can be dropped without affecting 268 /// correctness and should be dropped rather than preventing a transformation 269 /// from happening. 270 bool isDroppable() const; 271 272 // --------------------------------------------------------------------------- 273 // Operand Iterator interface... 274 // 275 using op_iterator = Use*; 276 using const_op_iterator = const Use*; 277 using op_range = iterator_range<op_iterator>; 278 using const_op_range = iterator_range<const_op_iterator>; 279 280 op_iterator op_begin() { return getOperandList(); } 281 const_op_iterator op_begin() const { return getOperandList(); } 282 op_iterator op_end() { 283 return getOperandList() + NumUserOperands; 284 } 285 const_op_iterator op_end() const { 286 return getOperandList() + NumUserOperands; 287 } 288 op_range operands() { 289 return op_range(op_begin(), op_end()); 290 } 291 const_op_range operands() const { 292 return const_op_range(op_begin(), op_end()); 293 } 294 295 /// Iterator for directly iterating over the operand Values. 296 struct value_op_iterator 297 : iterator_adaptor_base<value_op_iterator, op_iterator, 298 std::random_access_iterator_tag, Value *, 299 ptrdiff_t, Value *, Value *> { 300 explicit value_op_iterator(Use *U = nullptr) : iterator_adaptor_base(U) {} 301 302 Value *operator*() const { return *I; } 303 Value *operator->() const { return operator*(); } 304 }; 305 306 value_op_iterator value_op_begin() { 307 return value_op_iterator(op_begin()); 308 } 309 value_op_iterator value_op_end() { 310 return value_op_iterator(op_end()); 311 } 312 iterator_range<value_op_iterator> operand_values() { 313 return make_range(value_op_begin(), value_op_end()); 314 } 315 316 struct const_value_op_iterator 317 : iterator_adaptor_base<const_value_op_iterator, const_op_iterator, 318 std::random_access_iterator_tag, const Value *, 319 ptrdiff_t, const Value *, const Value *> { 320 explicit const_value_op_iterator(const Use *U = nullptr) : 321 iterator_adaptor_base(U) {} 322 323 const Value *operator*() const { return *I; } 324 const Value *operator->() const { return operator*(); } 325 }; 326 327 const_value_op_iterator value_op_begin() const { 328 return const_value_op_iterator(op_begin()); 329 } 330 const_value_op_iterator value_op_end() const { 331 return const_value_op_iterator(op_end()); 332 } 333 iterator_range<const_value_op_iterator> operand_values() const { 334 return make_range(value_op_begin(), value_op_end()); 335 } 336 337 /// Drop all references to operands. 338 /// 339 /// This function is in charge of "letting go" of all objects that this User 340 /// refers to. This allows one to 'delete' a whole class at a time, even 341 /// though there may be circular references... First all references are 342 /// dropped, and all use counts go to zero. Then everything is deleted for 343 /// real. Note that no operations are valid on an object that has "dropped 344 /// all references", except operator delete. 345 void dropAllReferences() { 346 for (Use &U : operands()) 347 U.set(nullptr); 348 } 349 350 /// Replace uses of one Value with another. 351 /// 352 /// Replaces all references to the "From" definition with references to the 353 /// "To" definition. Returns whether any uses were replaced. 354 bool replaceUsesOfWith(Value *From, Value *To); 355 356 // Methods for support type inquiry through isa, cast, and dyn_cast: 357 static bool classof(const Value *V) { 358 return isa<Instruction>(V) || isa<Constant>(V); 359 } 360 }; 361 362 // Either Use objects, or a Use pointer can be prepended to User. 363 static_assert(alignof(Use) >= alignof(User), 364 "Alignment is insufficient after objects prepended to User"); 365 static_assert(alignof(Use *) >= alignof(User), 366 "Alignment is insufficient after objects prepended to User"); 367 368 template<> struct simplify_type<User::op_iterator> { 369 using SimpleType = Value*; 370 371 static SimpleType getSimplifiedValue(User::op_iterator &Val) { 372 return Val->get(); 373 } 374 }; 375 template<> struct simplify_type<User::const_op_iterator> { 376 using SimpleType = /*const*/ Value*; 377 378 static SimpleType getSimplifiedValue(User::const_op_iterator &Val) { 379 return Val->get(); 380 } 381 }; 382 383 } // end namespace llvm 384 385 #endif // LLVM_IR_USER_H 386