diff options
-rw-r--r-- | docs/ProgrammersManual.html | 17 | ||||
-rw-r--r-- | include/llvm/Use.h | 45 | ||||
-rw-r--r-- | lib/VMCore/Use.cpp | 23 |
3 files changed, 27 insertions, 58 deletions
diff --git a/docs/ProgrammersManual.html b/docs/ProgrammersManual.html index 8f352ea..708211f 100644 --- a/docs/ProgrammersManual.html +++ b/docs/ProgrammersManual.html @@ -2234,7 +2234,7 @@ insert entries into the symbol table.</p> <div class="doc_text"> <p>The <tt><a href="http://llvm.org/doxygen/classllvm_1_1User.html"> -User</a></tt> class provides a base for expressing the ownership of <tt>User</tt> +User</a></tt> class provides a basis for expressing the ownership of <tt>User</tt> towards other <tt><a href="http://llvm.org/doxygen/classllvm_1_1Value.html"> Value</a></tt>s. The <tt><a href="http://llvm.org/doxygen/classllvm_1_1Use.html"> Use</a></tt> helper class is employed to do the bookkeeping and to facilitate <i>O(1)</i> @@ -2242,7 +2242,7 @@ addition and removal.</p> <!-- ______________________________________________________________________ --> <div class="doc_subsubsection"> - <a name="PATypeHolder">Interaction and relationship between <tt>User</tt> and <tt>Use</tt> objects</a> + <a name="Use2User">Interaction and relationship between <tt>User</tt> and <tt>Use</tt> objects</a> </div> <div class="doc_text"> @@ -2303,7 +2303,7 @@ enforce the following memory layouts:</p> <!-- ______________________________________________________________________ --> <div class="doc_subsubsection"> - <a name="PATypeHolder">The waymarking algorithm</a> + <a name="Waymarking">The waymarking algorithm</a> </div> <div class="doc_text"> @@ -2344,7 +2344,7 @@ stops, so that the <i>worst case is 20 memory accesses</i> when there are <!-- ______________________________________________________________________ --> <div class="doc_subsubsection"> - <a name="PATypeHolder">Reference implementation</a> + <a name="ReferenceImpl">Reference implementation</a> </div> <div class="doc_text"> @@ -2434,7 +2434,7 @@ OK, passed 500 tests. <!-- ______________________________________________________________________ --> <div class="doc_subsubsection"> - <a name="PATypeHolder">Tagging considerations</a> + <a name="Tagging">Tagging considerations</a> </div> <p> @@ -2446,7 +2446,8 @@ tag bits.</p> For layout b) instead of the <tt>User</tt> we find a pointer (<tt>User*</tt> with LSBit set). Following this pointer brings us to the <tt>User</tt>. A portable trick ensures that the first bytes of <tt>User</tt> (if interpreted as a pointer) never has -the LSBit set.</p> +the LSBit set. (Portability is relying on the fact that all known compilers place the +<tt>vptr</tt> in the first word of the instances.)</p> </div> @@ -2491,7 +2492,7 @@ the <tt>lib/VMCore</tt> directory.</p> <!-- _______________________________________________________________________ --> <div class="doc_subsubsection"> - <a name="m_Value">Important Public Methods</a> + <a name="m_Type">Important Public Methods</a> </div> <div class="doc_text"> @@ -2513,7 +2514,7 @@ the <tt>lib/VMCore</tt> directory.</p> <!-- _______________________________________________________________________ --> <div class="doc_subsubsection"> - <a name="m_Value">Important Derived Types</a> + <a name="derivedtypes">Important Derived Types</a> </div> <div class="doc_text"> <dl> diff --git a/include/llvm/Use.h b/include/llvm/Use.h index b4d2c48..7d6bf50 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 <typename T, typename TAG> -inline volatile T *addTag(const T *P, TAG Tag) { - return reinterpret_cast<T*>(ptrdiff_t(P) | Tag); -} - -/// stripTag - remove tag bits from a pointer, -/// making it dereferencable -template <ptrdiff_t MASK, typename T> -inline T *stripTag(const volatile T *P) { - return reinterpret_cast<T*>(ptrdiff_t(P) & ~MASK); -} - -/// extractTag - extract tag bits from a pointer -template <typename TAG, TAG MASK, typename T> -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 <ptrdiff_t MASK, typename T> -inline volatile T *transferTag(const volatile T *From, const T *To) { - return reinterpret_cast<T*>((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<Use**, 2, PrevPtrTag> Prev; void setPrev(Use **NewPrev) { - Prev = transferTag<fullStopTag>(Prev, NewPrev); + Prev.setPointer(NewPrev); } void addToList(Use **List) { Next = *List; @@ -145,7 +110,7 @@ private: *List = this; } void removeFromList() { - Use **StrippedPrev = stripTag<fullStopTag>(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 5eadaad..da21eba 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<PrevPtrTag, fullStopTag>((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<PrevPtrTag, fullStopTag>(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<Use**>(Done == 0 ? fullStopTag : stopTag); + Stop->Prev.setFromOpaqueValue(reinterpret_cast<Use**>(Done == 0 ? fullStopTag : stopTag)); ++Done; Count = Done; } else { - Stop->Prev = reinterpret_cast<Use**>(Count & 1); + Stop->Prev.setFromOpaqueValue(reinterpret_cast<Use**>(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<User*, 1, Tag> ref; AugmentedUse(); // not implemented }; @@ -138,10 +138,11 @@ struct AugmentedUse : Use { User *Use::getUser() const { const Use *End = getImpliedUser(); - volatile User *She = static_cast<const AugmentedUse*>(End - 1)->ref; - return extractTag<Tag, tagOne>(She) - ? llvm::stripTag<tagOne>(She) - : reinterpret_cast<User*>(const_cast<Use*>(End)); + PointerIntPair<User*, 1, Tag>& ref(static_cast<const AugmentedUse*>(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<AugmentedUse&>(End[-1]).ref = addTag(this, tagOne); + PointerIntPair<User*, 1, Tag>& ref(static_cast<AugmentedUse&>(End[-1]).ref); + ref.setPointer(const_cast<User*>(this)); + ref.setInt(tagOne); return Use::initTags(Begin, End); } |