30 "Cannot call User::replaceUsesOfWith on a constant!");
32 for (
unsigned i = 0,
E = getNumOperands(); i !=
E; ++i)
33 if (getOperand(i) == From) {
49 assert(HasHungOffUses &&
"alloc must have hung off uses");
51 static_assert(
alignof(
Use) >=
alignof(Value *),
52 "Alignment is insufficient for 'hung-off-uses' pieces");
57 size +=
N *
sizeof(Value *);
58 Use *Begin =
static_cast<Use*
>(::operator
new(
size));
60 setOperandList(Begin);
61 for (; Begin !=
End; Begin++)
62 new (Begin)
Use(
this);
66 assert(HasHungOffUses &&
"realloc must have hung off uses");
68 unsigned OldNumUses = getNumOperands();
72 assert(NewNumUses > OldNumUses &&
"realloc must grow num uses");
74 Use *OldOps = getOperandList();
75 allocHungoffUses(NewNumUses, WithExtraValues);
76 Use *NewOps = getOperandList();
79 std::copy(OldOps, OldOps + OldNumUses, NewOps);
83 if (WithExtraValues) {
84 auto *OldPtr =
reinterpret_cast<char *
>(OldOps + OldNumUses);
85 auto *NewPtr =
reinterpret_cast<char *
>(NewOps + NewNumUses);
86 std::copy(OldPtr, OldPtr + (OldNumUses *
sizeof(Value *)), NewPtr);
88 Use::zap(OldOps, OldOps + OldNumUses,
true);
99 return {MutableARef.begin(), MutableARef.end()};
103 assert(HasDescriptor &&
"Don't call otherwise!");
104 assert(!HasHungOffUses &&
"Invariant!");
106 auto *DI =
reinterpret_cast<DescriptorInfo *
>(getIntrusiveOperands()) - 1;
107 assert(DI->SizeInBytes != 0 &&
"Should not have had a descriptor otherwise!");
110 reinterpret_cast<uint8_t *
>(DI) - DI->SizeInBytes, DI->SizeInBytes);
115 switch (
II->getIntrinsicID()) {
118 case Intrinsic::assume:
119 case Intrinsic::pseudoprobe:
120 case Intrinsic::experimental_noalias_scope_decl:
131void *User::allocateFixedOperandUser(
size_t Size,
unsigned Us,
132 unsigned DescBytes) {
133 assert(Us < (1u << NumUserOperandsBits) &&
"Too many operands");
135 static_assert(
sizeof(
DescriptorInfo) %
sizeof(
void *) == 0,
"Required below");
137 unsigned DescBytesToAllocate =
139 assert(DescBytesToAllocate %
sizeof(
void *) == 0 &&
140 "We need this to satisfy alignment constraints for Uses");
142 size_t LeadingSize = DescBytesToAllocate +
sizeof(
Use) * Us;
147 LeadingSize = std::max(LeadingSize,
sizeof(
void *));
150 User *
Obj =
reinterpret_cast<User *
>(Storage + LeadingSize);
152 Obj->NumUserOperands = Us;
153 Obj->HasHungOffUses =
false;
154 Obj->HasDescriptor = DescBytes != 0;
156 if (DescBytes != 0) {
164void *User::operator
new(
size_t Size, IntrusiveOperandsAllocMarker allocTrait) {
165 return allocateFixedOperandUser(
Size, allocTrait.NumOps, 0);
168void *User::operator
new(
size_t Size,
169 IntrusiveOperandsAndDescriptorAllocMarker allocTrait) {
170 return allocateFixedOperandUser(
Size, allocTrait.NumOps,
171 allocTrait.DescBytes);
174void *User::operator
new(
size_t Size, HungOffOperandsAllocMarker) {
176 void *Storage = ::operator
new(
Size +
sizeof(
Use *));
177 Use **HungOffOperandList =
static_cast<Use **
>(Storage);
178 User *
Obj =
reinterpret_cast<User *
>(HungOffOperandList + 1);
179 Obj->NumUserOperands = 0;
180 Obj->HasHungOffUses =
true;
181 Obj->HasDescriptor =
false;
182 *HungOffOperandList =
nullptr;
193 void *AllocStart =
nullptr;
194 if (HasHungOffUses) {
195 assert(!HasDescriptor &&
"not supported!");
197 Use **HungOffOperandList =
reinterpret_cast<Use **
>(
this) - 1;
199 Use::zap(*HungOffOperandList, *HungOffOperandList + NumUserOperands,
201 AllocStart = HungOffOperandList;
202 }
else if (HasDescriptor) {
203 Use *UseBegin =
reinterpret_cast<Use *
>(
this) - NumUserOperands;
204 Use::zap(UseBegin, UseBegin + NumUserOperands,
false);
207 AllocStart =
reinterpret_cast<uint8_t *
>(DI) - DI->SizeInBytes;
208 }
else if (NumUserOperands > 0) {
209 Use *Storage =
reinterpret_cast<Use *
>(
this) - NumUserOperands;
210 Use::zap(Storage, Storage + NumUserOperands,
212 AllocStart = Storage;
215 AllocStart = (
void **)(
this) - 1;
225 ((
void **)
this)[-1] = AllocStart;
228void User::operator
delete(
void *Usr) { ::operator
delete(((
void **)Usr)[-1]); }
230void User::operator
delete(
void *Usr, HungOffOperandsAllocMarker) {
231 Use **HungOffOperandList =
static_cast<Use **
>(Usr) - 1;
232 ::operator
delete(HungOffOperandList);
235void User::operator
delete(
void *Usr,
236 IntrusiveOperandsAndDescriptorAllocMarker Marker) {
237 unsigned NumOps = Marker.NumOps;
240 uint8_t *Storage =
reinterpret_cast<uint8_t *
>(DI) - DI->SizeInBytes;
241 ::operator
delete(Storage);
244void User::operator
delete(
void *Usr, IntrusiveOperandsAllocMarker Marker) {
245 unsigned NumOps = Marker.NumOps;
246 size_t LeadingSize =
sizeof(
Use) *
NumOps;
248 LeadingSize = std::max(LeadingSize,
sizeof(
void *));
250 ::operator
delete(Storage);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
uint64_t IntrinsicInst * II
Represent a constant reference to an array (0 or more elements consecutively in memory),...
LLVM Basic Block Representation.
Represent a mutable reference to an array (0 or more elements consecutively in memory),...
A Use represents the edge between a Value definition and its users.
static LLVM_ABI void zap(Use *Start, const Use *Stop, bool del=false)
Destroys Use operands when the number of operands of a User changes.
LLVM_ABI void allocHungoffUses(unsigned N, bool WithExtraValues=false)
Allocate the array of Uses, followed by a pointer (with bottom bit set) to the User.
LLVM_ABI ArrayRef< const uint8_t > getDescriptor() const
Returns the descriptor co-allocated with this User instance.
LLVM_ABI bool isDroppable() const
A droppable user is a user for which uses can be dropped without affecting correctness and should be ...
LLVM_ABI bool replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
LLVM_ABI void growHungoffUses(unsigned N, bool WithExtraValues=false)
Grow the number of hung off uses.
LLVM_ABI const descriptor::Clause & getDescriptor(Clause C)
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 isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
@ End
Run the machine verifier once, at the end of the pipeline.