Go to the documentation of this file.
22 if (
From == To)
return;
24 assert((!isa<Constant>(
this) || isa<GlobalValue>(
this)) &&
25 "Cannot call User::replaceUsesOfWith on a constant!");
34 if (
auto DVI = dyn_cast_or_null<DbgVariableIntrinsic>(
this)) {
36 DVI->replaceVariableLocationOp(
From, To);
48 "Alignment is insufficient for 'hung-off-uses' pieces");
54 Use *Begin =
static_cast<Use*
>(::operator
new(
size));
56 setOperandList(Begin);
57 for (; Begin != End; Begin++)
58 new (Begin)
Use(
this);
68 assert(NewNumUses > OldNumUses &&
"realloc must grow num uses");
75 std::copy(OldOps, OldOps + OldNumUses, NewOps);
79 auto *OldPtr =
reinterpret_cast<char *
>(OldOps + OldNumUses);
80 auto *NewPtr =
reinterpret_cast<char *
>(NewOps + NewNumUses);
83 Use::zap(OldOps, OldOps + OldNumUses,
true);
95 return {MutableARef.begin(), MutableARef.end()};
102 auto *DI =
reinterpret_cast<DescriptorInfo *
>(getIntrusiveOperands()) - 1;
103 assert(DI->SizeInBytes != 0 &&
"Should not have had a descriptor otherwise!");
106 reinterpret_cast<uint8_t *
>(DI) - DI->SizeInBytes, DI->SizeInBytes);
110 return isa<AssumeInst>(
this);
117 void *User::allocateFixedOperandUser(
size_t Size,
unsigned Us,
118 unsigned DescBytes) {
121 static_assert(
sizeof(
DescriptorInfo) %
sizeof(
void *) == 0,
"Required below");
123 unsigned DescBytesToAllocate =
125 assert(DescBytesToAllocate %
sizeof(
void *) == 0 &&
126 "We need this to satisfy alignment constraints for Uses");
128 uint8_t *Storage =
static_cast<uint8_t *
>(
129 ::operator
new(
Size +
sizeof(
Use) * Us + DescBytesToAllocate));
130 Use *Start =
reinterpret_cast<Use *
>(Storage + DescBytesToAllocate);
131 Use *End = Start + Us;
132 User *Obj =
reinterpret_cast<User*
>(End);
136 for (; Start != End; Start++)
137 new (Start)
Use(Obj);
139 if (DescBytes != 0) {
140 auto *DescInfo =
reinterpret_cast<DescriptorInfo *
>(Storage + DescBytes);
147 void *User::operator
new(
size_t Size,
unsigned Us) {
148 return allocateFixedOperandUser(
Size, Us, 0);
151 void *User::operator
new(
size_t Size,
unsigned Us,
unsigned DescBytes) {
152 return allocateFixedOperandUser(
Size, Us, DescBytes);
155 void *User::operator
new(
size_t Size) {
157 void *Storage = ::operator
new(
Size +
sizeof(
Use *));
158 Use **HungOffOperandList =
static_cast<Use **
>(Storage);
159 User *Obj =
reinterpret_cast<User *
>(HungOffOperandList + 1);
163 *HungOffOperandList =
nullptr;
176 User *Obj =
static_cast<User *
>(Usr);
180 Use **HungOffOperandList =
static_cast<Use **
>(Usr) - 1;
184 ::operator
delete(HungOffOperandList);
190 uint8_t *Storage =
reinterpret_cast<uint8_t *
>(DI) - DI->
SizeInBytes;
191 ::
operator delete(Storage);
196 ::operator
delete(Storage);
static void zap(Use *Start, const Use *Stop, bool del=false)
Destroys Use operands when the number of operands of a User changes.
void growHungoffUses(unsigned N, bool IsPhi=false)
Grow the number of hung off uses.
LLVM Basic Block Representation.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
ArrayRef< const uint8_t > getDescriptor() const
Returns the descriptor co-allocated with this User instance.
void allocHungoffUses(unsigned N, bool IsPhi=false)
Allocate the array of Uses, followed by a pointer (with bottom bit set) to the User.
bool is_contained(R &&Range, const E &Element)
Wrapper function around std::find to detect if an element exists in a container.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
@ BasicBlock
Various leaf nodes.
bool isDroppable() const
A droppable user is a user for which uses can be dropped without affecting correctness and should be ...
void setOperand(unsigned i, Value *Val)
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
const Use * getOperandList() const
#define LLVM_NO_SANITIZE_MEMORY_ATTRIBUTE
unsigned getNumOperands() const
BlockVerifier::State From
Value * getOperand(unsigned i) const
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 copy
LLVM Value Representation.
A Use represents the edge between a Value definition and its users.