Changeset View
Changeset View
Standalone View
Standalone View
lib/IR/User.cpp
Show First 20 Lines • Show All 85 Lines • ▼ Show 20 Lines | void User::growHungoffUses(unsigned NewNumUses, bool IsPhi) { | ||||
} | } | ||||
Use::zap(OldOps, OldOps + OldNumUses, true); | Use::zap(OldOps, OldOps + OldNumUses, true); | ||||
} | } | ||||
// This is a private struct used by `User` to track the co-allocated descriptor | // This is a private struct used by `User` to track the co-allocated descriptor | ||||
// section. | // section. | ||||
struct DescriptorInfo { | struct DescriptorInfo { | ||||
uint32_t Size; | uint32_t SizeInBytes; | ||||
}; | }; | ||||
std::pair<const uint8_t *, const uint8_t *> User::getDescriptor() const { | std::pair<const uint8_t *, const uint8_t *> User::getDescriptor() const { | ||||
assert(HasDescriptor && "Don't call otherwise!"); | return const_cast<User *>(this)->getDescriptor(); | ||||
auto *DI = reinterpret_cast<const DescriptorInfo *>(&getOperandUse(0)) - 1; | |||||
return std::make_pair(reinterpret_cast<const uint8_t *>(DI) - DI->Size, | |||||
reinterpret_cast<const uint8_t *>(DI)); | |||||
} | } | ||||
std::pair<uint8_t *, uint8_t *> User::getDescriptor() { | std::pair<uint8_t *, uint8_t *> User::getDescriptor() { | ||||
assert(HasDescriptor && "Don't call otherwise!"); | assert(HasDescriptor && "Don't call otherwise!"); | ||||
auto *DI = reinterpret_cast<DescriptorInfo *>(&getOperandUse(0)) - 1; | assert(!HasHungOffUses && "Invariant!"); | ||||
return std::make_pair(reinterpret_cast<uint8_t *>(DI) - DI->Size, | |||||
auto *DI = reinterpret_cast<DescriptorInfo *>(getIntrusiveOperands()) - 1; | |||||
assert(DI->SizeInBytes != 0 && "Should not have had a descriptor otherwise!"); | |||||
return std::make_pair(reinterpret_cast<uint8_t *>(DI) - DI->SizeInBytes, | |||||
reinterpret_cast<uint8_t *>(DI)); | reinterpret_cast<uint8_t *>(DI)); | ||||
} | } | ||||
//===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||
// User operator new Implementations | // User operator new Implementations | ||||
//===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||
void *User::operator new(size_t Size, unsigned Us, unsigned DescBytes) { | void *User::operator new(size_t Size, unsigned Us, unsigned DescBytes) { | ||||
assert(Us < (1u << NumUserOperandsBits) && "Too many operands"); | assert(Us < (1u << NumUserOperandsBits) && "Too many operands"); | ||||
unsigned DescBytesToAllocate = | unsigned DescBytesToAllocate = | ||||
DescBytes == 0 ? 0 : (DescBytes + sizeof(DescriptorInfo)); | DescBytes == 0 ? 0 : (DescBytes + sizeof(DescriptorInfo)); | ||||
assert(DescBytesToAllocate % 4 == 0 && | |||||
"We need this to satisfy alignment constraints for Uses"); | |||||
JosephTremoulet: Ok, I should have read ahead :). But I still think it would be good to discuss alignment in… | |||||
sanjoyAuthorUnsubmitted Not Done ReplyInline ActionsI intended this to be part of the first change, I must have messed up rebasing somewhere. I'll move this bit to D12455 and add a comment, as you suggested. sanjoy: I intended this to be part of the first change, I must have messed up rebasing somewhere. I'll… | |||||
uint8_t *Storage = static_cast<uint8_t *>( | uint8_t *Storage = static_cast<uint8_t *>( | ||||
::operator new(Size + sizeof(Use) * Us + DescBytesToAllocate)); | ::operator new(Size + sizeof(Use) * Us + DescBytesToAllocate)); | ||||
Use *Start = reinterpret_cast<Use *>(Storage + DescBytesToAllocate); | Use *Start = reinterpret_cast<Use *>(Storage + DescBytesToAllocate); | ||||
Use *End = Start + Us; | Use *End = Start + Us; | ||||
User *Obj = reinterpret_cast<User*>(End); | User *Obj = reinterpret_cast<User*>(End); | ||||
Obj->NumUserOperands = Us; | Obj->NumUserOperands = Us; | ||||
Obj->HasHungOffUses = false; | Obj->HasHungOffUses = false; | ||||
Obj->HasDescriptor = DescBytes != 0; | Obj->HasDescriptor = DescBytes != 0; | ||||
Use::initTags(Start, End); | Use::initTags(Start, End); | ||||
if (DescBytes != 0) | if (DescBytes != 0) { | ||||
reinterpret_cast<DescriptorInfo *>(Storage + DescBytes)->Size = DescBytes; | auto *DescInfo = reinterpret_cast<DescriptorInfo *>(Storage + DescBytes); | ||||
DescInfo->SizeInBytes = DescBytes; | |||||
} | |||||
return Obj; | return Obj; | ||||
} | } | ||||
void *User::operator new(size_t Size) { | void *User::operator new(size_t Size) { | ||||
// Allocate space for a single Use* | // Allocate space for a single Use* | ||||
void *Storage = ::operator new(Size + sizeof(Use *)); | void *Storage = ::operator new(Size + sizeof(Use *)); | ||||
Use **HungOffOperandList = static_cast<Use **>(Storage); | Use **HungOffOperandList = static_cast<Use **>(Storage); | ||||
Show All 21 Lines | if (Obj->HasHungOffUses) { | ||||
Use::zap(*HungOffOperandList, *HungOffOperandList + Obj->NumUserOperands, | Use::zap(*HungOffOperandList, *HungOffOperandList + Obj->NumUserOperands, | ||||
/* Delete */ true); | /* Delete */ true); | ||||
::operator delete(HungOffOperandList); | ::operator delete(HungOffOperandList); | ||||
} else if (Obj->HasDescriptor) { | } else if (Obj->HasDescriptor) { | ||||
Use *UseBegin = static_cast<Use *>(Usr) - Obj->NumUserOperands; | Use *UseBegin = static_cast<Use *>(Usr) - Obj->NumUserOperands; | ||||
Use::zap(UseBegin, UseBegin + Obj->NumUserOperands, /* Delete */ false); | Use::zap(UseBegin, UseBegin + Obj->NumUserOperands, /* Delete */ false); | ||||
auto *DI = reinterpret_cast<DescriptorInfo *>(UseBegin) - 1; | auto *DI = reinterpret_cast<DescriptorInfo *>(UseBegin) - 1; | ||||
uint8_t *Storage = reinterpret_cast<uint8_t *>(DI) - DI->Size; | uint8_t *Storage = reinterpret_cast<uint8_t *>(DI) - DI->SizeInBytes; | ||||
::operator delete(Storage); | ::operator delete(Storage); | ||||
} else { | } else { | ||||
Use *Storage = static_cast<Use *>(Usr) - Obj->NumUserOperands; | Use *Storage = static_cast<Use *>(Usr) - Obj->NumUserOperands; | ||||
Use::zap(Storage, Storage + Obj->NumUserOperands, | Use::zap(Storage, Storage + Obj->NumUserOperands, | ||||
/* Delete */ false); | /* Delete */ false); | ||||
::operator delete(Storage); | ::operator delete(Storage); | ||||
} | } | ||||
} | } | ||||
Show All 10 Lines |
Ok, I should have read ahead :). But I still think it would be good to discuss alignment in the method header comment, and to 8-byte align the CallInst/InvokeInst bundles on 64-bit platforms for the pointer to the string map entry.