--Stop;
Stop->Val = 0;
if (!Count) {
- Stop->Prev.setFromOpaqueValue(reinterpret_cast<Use**>(Done == 0 ? fullStopTag : stopTag));
+ Stop->Prev.setFromOpaqueValue(reinterpret_cast<Use**>(Done == 0
+ ? fullStopTag
+ : stopTag));
++Done;
Count = Done;
} else {
// AugmentedUse layout struct
//===----------------------------------------------------------------------===//
-struct AugmentedUse : Use {
+struct AugmentedUse : public Use {
PointerIntPair<User*, 1, Tag> ref;
AugmentedUse(); // not implemented
};
User *Use::getUser() const {
const Use *End = getImpliedUser();
- PointerIntPair<User*, 1, Tag>& ref(static_cast<const AugmentedUse*>(End - 1)->ref);
+ const PointerIntPair<User*, 1, Tag>& ref(
+ static_cast<const AugmentedUse*>(End - 1)->ref);
User *She = ref.getPointer();
return ref.getInt()
? She
return Use::initTags(Begin, End);
}
+//===----------------------------------------------------------------------===//
+// User operator new Implementations
+//===----------------------------------------------------------------------===//
+
+void *User::operator new(size_t s, unsigned Us) {
+ void *Storage = ::operator new(s + sizeof(Use) * Us);
+ Use *Start = static_cast<Use*>(Storage);
+ Use *End = Start + Us;
+ User *Obj = reinterpret_cast<User*>(End);
+ Obj->OperandList = Start;
+ Obj->NumOperands = Us;
+ Use::initTags(Start, End);
+ return Obj;
+}
+
+/// Prefixed allocation - just before the first Use, allocate a NULL pointer.
+/// The destructor can detect its presence and readjust the OperandList
+/// for deletition.
+///
+void *User::operator new(size_t s, unsigned Us, bool Prefix) {
+ // currently prefixed allocation only admissible for
+ // unconditional branch instructions
+ if (!Prefix)
+ return operator new(s, Us);
+
+ assert(Us == 1 && "Other than one Use allocated?");
+ typedef PointerIntPair<void*, 2, Use::PrevPtrTag> TaggedPrefix;
+ void *Raw = ::operator new(s + sizeof(TaggedPrefix) + sizeof(Use) * Us);
+ TaggedPrefix *Pre = static_cast<TaggedPrefix*>(Raw);
+ Pre->setFromOpaqueValue(0);
+ void *Storage = Pre + 1; // skip over prefix
+ Use *Start = static_cast<Use*>(Storage);
+ Use *End = Start + Us;
+ User *Obj = reinterpret_cast<User*>(End);
+ Obj->OperandList = Start;
+ Obj->NumOperands = Us;
+ Use::initTags(Start, End);
+ return Obj;
+}
+
+//===----------------------------------------------------------------------===//
+// User operator delete Implementation
+//===----------------------------------------------------------------------===//
+
+void User::operator delete(void *Usr) {
+ User *Start = static_cast<User*>(Usr);
+ Use *Storage = static_cast<Use*>(Usr) - Start->NumOperands;
+ //
+ // look for a variadic User
+ if (Storage == Start->OperandList) {
+ ::operator delete(Storage);
+ return;
+ }
+ //
+ // check for the flag whether the destructor has detected a prefixed
+ // allocation, in which case we remove the flag and delete starting
+ // at OperandList
+ if (reinterpret_cast<intptr_t>(Start->OperandList) & 1) {
+ ::operator delete(reinterpret_cast<char*>(Start->OperandList) - 1);
+ return;
+ }
+ //
+ // in all other cases just delete the nullary User (covers hung-off
+ // uses also
+ ::operator delete(Usr);
+}
+
} // End llvm namespace