LLVM  14.0.0git
User.h
Go to the documentation of this file.
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"
23 #include "llvm/IR/Use.h"
24 #include "llvm/IR/Value.h"
25 #include "llvm/Support/Casting.h"
26 #include "llvm/Support/Compiler.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>
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.
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) {
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  }
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.
195 
196  /// Returns the descriptor co-allocated with this User instance.
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*;
233 
237  return getOperandList() + NumUserOperands;
238  }
240  return getOperandList() + NumUserOperands;
241  }
243  return op_range(op_begin(), op_end());
244  }
246  return const_op_range(op_begin(), op_end());
247  }
248 
249  /// Iterator for directly iterating over the operand Values.
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 
261  return value_op_iterator(op_begin());
262  }
264  return value_op_iterator(op_end());
265  }
268  }
269 
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) :
276 
277  const Value *operator*() const { return *I; }
278  const Value *operator->() const { return operator*(); }
279  };
280 
283  }
286  }
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.
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.
308  void 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 
326  return Val->get();
327  }
328 };
329 template<> struct simplify_type<User::const_op_iterator> {
330  using SimpleType = /*const*/ Value*;
331 
333  return Val->get();
334  }
335 };
336 
337 } // end namespace llvm
338 
339 #endif // LLVM_IR_USER_H
llvm::Check::Size
@ Size
Definition: FileCheck.h:73
i
i
Definition: README.txt:29
llvm
This file implements support for optimizing divisions by a constant.
Definition: AllocatorList.h:23
llvm::make_range
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
Definition: iterator_range.h:53
llvm::User::operands
const_op_range operands() const
Definition: User.h:245
llvm::User::operands
op_range operands()
Definition: User.h:242
llvm::User::dropAllReferences
void dropAllReferences()
Drop all references to operands.
Definition: User.h:299
llvm::iterator_adaptor_base< value_op_iterator, op_iterator, std::random_access_iterator_tag, Value *, ptrdiff_t, Value *, Value * >::I
op_iterator I
Definition: iterator.h:235
ErrorHandling.h
llvm::User::getOperandUse
Use & getOperandUse(unsigned i)
Definition: User.h:186
llvm::simplify_type< User::op_iterator >::getSimplifiedValue
static SimpleType getSimplifiedValue(User::op_iterator &Val)
Definition: User.h:325
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
llvm::User::value_op_begin
value_op_iterator value_op_begin()
Definition: User.h:260
llvm::iterator_adaptor_base
CRTP base class for adapting an iterator to a different type.
Definition: iterator.h:229
llvm::Value::HasHungOffUses
unsigned HasHungOffUses
Definition: Value.h:121
LLVM_ATTRIBUTE_ALWAYS_INLINE
#define LLVM_ATTRIBUTE_ALWAYS_INLINE
LLVM_ATTRIBUTE_ALWAYS_INLINE - On compilers where we have a directive to do so, mark a method "always...
Definition: Compiler.h:246
llvm::User::op_range
iterator_range< op_iterator > op_range
Definition: User.h:231
llvm::Value::NumUserOperands
unsigned NumUserOperands
Definition: Value.h:115
that
we should consider alternate ways to model stack dependencies Lots of things could be done in WebAssemblyTargetTransformInfo cpp there are numerous optimization related hooks that can be overridden in WebAssemblyTargetLowering Instead of the OptimizeReturned which should consider preserving the returned attribute through to MachineInstrs and extending the MemIntrinsicResults pass to do this optimization on calls too That would also let the WebAssemblyPeephole pass clean up dead defs for such as it does for stores Consider implementing and or getMachineCombinerPatterns Find a clean way to fix the problem which leads to the Shrink Wrapping pass being run after the WebAssembly PEI pass When setting multiple variables to the same we currently get code like const It could be done with a smaller encoding like local tee $pop5 local $pop6 WebAssembly registers are implicitly initialized to zero Explicit zeroing is therefore often redundant and could be optimized away Small indices may use smaller encodings than large indices WebAssemblyRegColoring and or WebAssemblyRegRenumbering should sort registers according to their usage frequency to maximize the usage of smaller encodings Many cases of irreducible control flow could be transformed more optimally than via the transform in WebAssemblyFixIrreducibleControlFlow cpp It may also be worthwhile to do transforms before register particularly when duplicating to allow register coloring to be aware of the duplication WebAssemblyRegStackify could use AliasAnalysis to reorder loads and stores more aggressively WebAssemblyRegStackify is currently a greedy algorithm This means that
Definition: README.txt:130
Use.h
llvm::User::growHungoffUses
void growHungoffUses(unsigned N, bool IsPhi=false)
Grow the number of hung off uses.
Definition: User.cpp:61
llvm::User::setGlobalVariableNumOperands
void setGlobalVariableNumOperands(unsigned NumOps)
Set the number of operands on a GlobalVariable.
Definition: User.h:207
llvm::User::getOperandUse
const Use & getOperandUse(unsigned i) const
Definition: User.h:182
llvm::User::value_op_iterator
Iterator for directly iterating over the operand Values.
Definition: User.h:250
llvm::OperandTraits
Compile-time customization of User operands.
Definition: User.h:42
llvm::MutableArrayRef< uint8_t >
llvm::User
Definition: User.h:44
llvm::User::op_begin
const_op_iterator op_begin() const
Definition: User.h:235
llvm::simplify_type< User::const_op_iterator >::getSimplifiedValue
static SimpleType getSimplifiedValue(User::const_op_iterator &Val)
Definition: User.h:332
llvm::User::value_op_iterator::operator*
Value * operator*() const
Definition: User.h:256
llvm::simplify_type
Definition: ilist_iterator.h:178
llvm::User::getDescriptor
ArrayRef< const uint8_t > getDescriptor() const
Returns the descriptor co-allocated with this User instance.
Definition: User.cpp:93
llvm::User::~User
~User()=default
llvm::Value::NumUserOperandsBits
@ NumUserOperandsBits
Definition: Value.h:114
llvm::User::operand_values
iterator_range< const_value_op_iterator > operand_values() const
Definition: User.h:287
llvm::User::allocHungoffUses
void allocHungoffUses(unsigned N, bool IsPhi=false)
Allocate the array of Uses, followed by a pointer (with bottom bit set) to the User.
Definition: User.cpp:44
iterator.h
llvm::User::const_value_op_iterator::const_value_op_iterator
const_value_op_iterator(const Use *U=nullptr)
Definition: User.h:274
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::User::replaceUsesOfWith
void replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
Definition: User.cpp:21
llvm::User::value_op_iterator::value_op_iterator
value_op_iterator(Use *U=nullptr)
Definition: User.h:254
iterator_range.h
llvm::User::isDroppable
bool isDroppable() const
A droppable user is a user for which uses can be dropped without affecting correctness and should be ...
Definition: User.cpp:109
llvm::User::const_value_op_iterator::operator*
const Value * operator*() const
Definition: User.h:277
llvm::User::setOperand
void setOperand(unsigned i, Value *Val)
Definition: User.h:174
llvm::User::const_value_op_iterator::operator->
const Value * operator->() const
Definition: User.h:278
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: APInt.h:32
llvm::User::User
User(Type *ty, unsigned vty, Use *, unsigned NumOps)
Definition: User.h:73
llvm::User::getOperandList
const Use * getOperandList() const
Definition: User.h:162
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:134
llvm::User::Op
const Use & Op() const
Definition: User.h:136
Compiler.h
llvm::User::value_op_end
value_op_iterator value_op_end()
Definition: User.h:263
llvm::User::getOperandList
Use * getOperandList()
Definition: User.h:165
llvm::User::op_end
const_op_iterator op_end() const
Definition: User.h:239
Casting.h
llvm::User::operand_values
iterator_range< value_op_iterator > operand_values()
Definition: User.h:266
llvm::User::const_op_range
iterator_range< const_op_iterator > const_op_range
Definition: User.h:232
llvm::User::getNumOperands
unsigned getNumOperands() const
Definition: User.h:191
llvm::User::op_begin
op_iterator op_begin()
Definition: User.h:234
N
#define N
llvm::User::const_value_op_iterator
Definition: User.h:270
llvm::iterator_range
A range adaptor for a pair of iterators.
Definition: iterator_range.h:30
llvm::User::Op
Use & Op()
Definition: User.h:133
From
BlockVerifier::State From
Definition: BlockVerifier.cpp:55
llvm::User::getOperand
Value * getOperand(unsigned i) const
Definition: User.h:169
llvm::HungoffOperandTraits
HungoffOperandTraits - determine the allocation regime of the Use array when it is not a prefix to th...
Definition: OperandTraits.h:95
Value.h
llvm::User::value_op_begin
const_value_op_iterator value_op_begin() const
Definition: User.h:281
llvm::User::value_op_iterator::operator->
Value * operator->() const
Definition: User.h:257
llvm::Value
LLVM Value Representation.
Definition: Value.h:75
llvm::User::setNumHungOffUseOperands
void setNumHungOffUseOperands(unsigned NumOps)
Subclasses with hung off uses need to manage the operand count themselves.
Definition: User.h:215
llvm::User::classof
static bool classof(const Value *V)
Definition: User.h:311
llvm::User::OpFrom
static Use & OpFrom(const U *that)
Definition: User.h:127
llvm::Use
A Use represents the edge between a Value definition and its users.
Definition: Use.h:44
llvm::User::value_op_end
const_value_op_iterator value_op_end() const
Definition: User.h:284
llvm::User::op_end
op_iterator op_end()
Definition: User.h:236