23 if (
From == To)
return Changed;
25 assert((!isa<Constant>(
this) || isa<GlobalValue>(
this)) &&
26 "Cannot call User::replaceUsesOfWith on a constant!");
36 if (
auto DVI = dyn_cast_or_null<DbgVariableIntrinsic>(
this)) {
38 DVI->replaceVariableLocationOp(
From, To);
54 "Alignment is insufficient for 'hung-off-uses' pieces");
60 Use *Begin =
static_cast<Use*
>(::operator
new(
size));
62 setOperandList(Begin);
63 for (; Begin !=
End; Begin++)
64 new (Begin)
Use(
this);
74 assert(NewNumUses > OldNumUses &&
"realloc must grow num uses");
81 std::copy(OldOps, OldOps + OldNumUses, NewOps);
85 auto *OldPtr =
reinterpret_cast<char *
>(OldOps + OldNumUses);
86 auto *NewPtr =
reinterpret_cast<char *
>(NewOps + NewNumUses);
87 std::copy(OldPtr, OldPtr + (OldNumUses *
sizeof(
BasicBlock *)), NewPtr);
89 Use::zap(OldOps, OldOps + OldNumUses,
true);
101 return {MutableARef.begin(), MutableARef.end()};
108 auto *DI =
reinterpret_cast<DescriptorInfo *
>(getIntrusiveOperands()) - 1;
109 assert(DI->SizeInBytes != 0 &&
"Should not have had a descriptor otherwise!");
112 reinterpret_cast<uint8_t *
>(DI) - DI->SizeInBytes, DI->SizeInBytes);
116 return isa<AssumeInst>(
this) || isa<PseudoProbeInst>(
this);
123void *User::allocateFixedOperandUser(
size_t Size,
unsigned Us,
124 unsigned DescBytes) {
127 static_assert(
sizeof(
DescriptorInfo) %
sizeof(
void *) == 0,
"Required below");
129 unsigned DescBytesToAllocate =
131 assert(DescBytesToAllocate %
sizeof(
void *) == 0 &&
132 "We need this to satisfy alignment constraints for Uses");
134 uint8_t *Storage =
static_cast<uint8_t *
>(
135 ::operator
new(
Size +
sizeof(
Use) * Us + DescBytesToAllocate));
136 Use *Start =
reinterpret_cast<Use *
>(Storage + DescBytesToAllocate);
142 for (; Start !=
End; Start++)
143 new (Start)
Use(Obj);
145 if (DescBytes != 0) {
146 auto *DescInfo =
reinterpret_cast<DescriptorInfo *
>(Storage + DescBytes);
153void *User::operator
new(
size_t Size,
unsigned Us) {
154 return allocateFixedOperandUser(
Size, Us, 0);
157void *User::operator
new(
size_t Size,
unsigned Us,
unsigned DescBytes) {
158 return allocateFixedOperandUser(
Size, Us, DescBytes);
161void *User::operator
new(
size_t Size) {
163 void *Storage = ::operator
new(
Size +
sizeof(
Use *));
164 Use **HungOffOperandList =
static_cast<Use **
>(Storage);
165 User *Obj =
reinterpret_cast<User *
>(HungOffOperandList + 1);
169 *HungOffOperandList =
nullptr;
182 User *Obj =
static_cast<User *
>(Usr);
186 Use **HungOffOperandList =
static_cast<Use **
>(Usr) - 1;
190 ::operator
delete(HungOffOperandList);
196 uint8_t *Storage =
reinterpret_cast<uint8_t *
>(DI) - DI->
SizeInBytes;
197 ::operator
delete(Storage);
202 ::operator
delete(Storage);
BlockVerifier::State From
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_NO_SANITIZE_MEMORY_ATTRIBUTE
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
LLVM Basic Block Representation.
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
A Use represents the edge between a Value definition and its users.
static void zap(Use *Start, const Use *Stop, bool del=false)
Destroys Use operands when the number of operands of a User changes.
const Use * getOperandList() const
ArrayRef< const uint8_t > getDescriptor() const
Returns the descriptor co-allocated with this User instance.
bool replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
void allocHungoffUses(unsigned N, bool IsPhi=false)
Allocate the array of Uses, followed by a pointer (with bottom bit set) to the User.
void setOperand(unsigned i, Value *Val)
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
bool isDroppable() const
A droppable user is a user for which uses can be dropped without affecting correctness and should be ...
void growHungoffUses(unsigned N, bool IsPhi=false)
Grow the number of hung off uses.
LLVM Value Representation.
@ BasicBlock
Various leaf nodes.
This is an optimization pass for GlobalISel generic memory operations.
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.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.