diff --git a/docs/ProgrammersManual.html b/docs/ProgrammersManual.html index 8f352eabfd1..708211fa7d2 100644 --- a/docs/ProgrammersManual.html +++ b/docs/ProgrammersManual.html @@ -2234,7 +2234,7 @@ insert entries into the symbol table.

The -User class provides a base for expressing the ownership of User +User class provides a basis for expressing the ownership of User towards other Values. The Use helper class is employed to do the bookkeeping and to facilitate O(1) @@ -2242,7 +2242,7 @@ addition and removal.

- Interaction and relationship between User and Use objects + Interaction and relationship between User and Use objects
@@ -2303,7 +2303,7 @@ enforce the following memory layouts:

@@ -2344,7 +2344,7 @@ stops, so that the worst case is 20 memory accesses when there are
@@ -2434,7 +2434,7 @@ OK, passed 500 tests.

@@ -2446,7 +2446,8 @@ tag bits.

For layout b) instead of the User we find a pointer (User* with LSBit set). Following this pointer brings us to the User. A portable trick ensures that the first bytes of User (if interpreted as a pointer) never has -the LSBit set.

+the LSBit set. (Portability is relying on the fact that all known compilers place the +vptr in the first word of the instances.)

@@ -2491,7 +2492,7 @@ the lib/VMCore directory.

@@ -2513,7 +2514,7 @@ the lib/VMCore directory.

diff --git a/include/llvm/Use.h b/include/llvm/Use.h index b4d2c488243..7d6bf5027bc 100644 --- a/include/llvm/Use.h +++ b/include/llvm/Use.h @@ -18,6 +18,7 @@ #include "llvm/Support/Casting.h" #include "llvm/ADT/iterator.h" +#include "llvm/ADT/PointerIntPair.h" namespace llvm { @@ -25,46 +26,9 @@ class Value; class User; -//===----------------------------------------------------------------------===// -// Generic Tagging Functions -//===----------------------------------------------------------------------===// - -// We adhere to the following convention: The type of a tagged pointer -// to T is T volatile*. This means that functions that superpose a tag -// on a pointer will be supplied a T* (or T const*) and will return a -// tagged one: T volatile*. Untagging functions do it the other way -// 'round. While this scheme does not prevent dereferencing of tagged -// pointers, proper type annotations do catch most inappropriate uses. - /// Tag - generic tag type for (at least 32 bit) pointers enum Tag { noTag, tagOne, tagTwo, tagThree }; -/// addTag - insert tag bits into an (untagged) pointer -template -inline volatile T *addTag(const T *P, TAG Tag) { - return reinterpret_cast(ptrdiff_t(P) | Tag); -} - -/// stripTag - remove tag bits from a pointer, -/// making it dereferencable -template -inline T *stripTag(const volatile T *P) { - return reinterpret_cast(ptrdiff_t(P) & ~MASK); -} - -/// extractTag - extract tag bits from a pointer -template -inline TAG extractTag(const volatile T *P) { - return TAG(ptrdiff_t(P) & MASK); -} - -/// transferTag - transfer tag bits from a pointer, -/// to an untagged pointer -template -inline volatile T *transferTag(const volatile T *From, const T *To) { - return reinterpret_cast((ptrdiff_t(From) & MASK) | ptrdiff_t(To)); -} - //===----------------------------------------------------------------------===// // Use Class @@ -133,10 +97,11 @@ private: static Use *initTags(Use *Start, Use *Stop, ptrdiff_t Done = 0); Value *Val; - Use *Next, *volatile*Prev; + Use *Next; + PointerIntPair Prev; void setPrev(Use **NewPrev) { - Prev = transferTag(Prev, NewPrev); + Prev.setPointer(NewPrev); } void addToList(Use **List) { Next = *List; @@ -145,7 +110,7 @@ private: *List = this; } void removeFromList() { - Use **StrippedPrev = stripTag(Prev); + Use **StrippedPrev = Prev.getPointer(); *StrippedPrev = Next; if (Next) Next->setPrev(StrippedPrev); } diff --git a/lib/VMCore/Use.cpp b/lib/VMCore/Use.cpp index 5eadaadbb33..da21eba132a 100644 --- a/lib/VMCore/Use.cpp +++ b/lib/VMCore/Use.cpp @@ -52,7 +52,7 @@ const Use *Use::getImpliedUser() const { const Use *Current = this; while (true) { - unsigned Tag = extractTag((Current++)->Prev); + unsigned Tag = (Current++)->Prev.getInt(); switch (Tag) { case zeroDigitTag: case oneDigitTag: @@ -62,7 +62,7 @@ const Use *Use::getImpliedUser() const { ++Current; ptrdiff_t Offset = 1; while (true) { - unsigned Tag = extractTag(Current->Prev); + unsigned Tag = Current->Prev.getInt(); switch (Tag) { case zeroDigitTag: case oneDigitTag: @@ -91,11 +91,11 @@ Use *Use::initTags(Use * const Start, Use *Stop, ptrdiff_t Done) { --Stop; Stop->Val = 0; if (!Count) { - Stop->Prev = reinterpret_cast(Done == 0 ? fullStopTag : stopTag); + Stop->Prev.setFromOpaqueValue(reinterpret_cast(Done == 0 ? fullStopTag : stopTag)); ++Done; Count = Done; } else { - Stop->Prev = reinterpret_cast(Count & 1); + Stop->Prev.setFromOpaqueValue(reinterpret_cast(Count & 1)); Count >>= 1; ++Done; } @@ -127,7 +127,7 @@ void Use::zap(Use *Start, const Use *Stop, bool del) { //===----------------------------------------------------------------------===// struct AugmentedUse : Use { - volatile User *ref; + PointerIntPair ref; AugmentedUse(); // not implemented }; @@ -138,10 +138,11 @@ struct AugmentedUse : Use { User *Use::getUser() const { const Use *End = getImpliedUser(); - volatile User *She = static_cast(End - 1)->ref; - return extractTag(She) - ? llvm::stripTag(She) - : reinterpret_cast(const_cast(End)); + PointerIntPair& ref(static_cast(End - 1)->ref); + User *She = ref.getPointer(); + return ref.getInt() + ? She + : (User*)End; } //===----------------------------------------------------------------------===// @@ -153,7 +154,9 @@ Use *User::allocHungoffUses(unsigned N) const { + sizeof(AugmentedUse) - sizeof(Use))); Use *End = Begin + N; - static_cast(End[-1]).ref = addTag(this, tagOne); + PointerIntPair& ref(static_cast(End[-1]).ref); + ref.setPointer(const_cast(this)); + ref.setInt(tagOne); return Use::initTags(Begin, End); }