mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-27 02:31:09 +00:00
Get rid of the tagging functions and use PointerIntPair.
This means that we have to include an additional header. This patch should be functionally equivalent. I cannot outrule any performance degradation, though I do not expect any. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@61694 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
4050a2324c
commit
fd095b6389
@ -2234,7 +2234,7 @@ insert entries into the symbol table.</p>
|
|||||||
|
|
||||||
<div class="doc_text">
|
<div class="doc_text">
|
||||||
<p>The <tt><a href="http://llvm.org/doxygen/classllvm_1_1User.html">
|
<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">
|
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">
|
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>
|
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">
|
<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>
|
||||||
|
|
||||||
<div class="doc_text">
|
<div class="doc_text">
|
||||||
@ -2303,7 +2303,7 @@ enforce the following memory layouts:</p>
|
|||||||
|
|
||||||
<!-- ______________________________________________________________________ -->
|
<!-- ______________________________________________________________________ -->
|
||||||
<div class="doc_subsubsection">
|
<div class="doc_subsubsection">
|
||||||
<a name="PATypeHolder">The waymarking algorithm</a>
|
<a name="Waymarking">The waymarking algorithm</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="doc_text">
|
<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">
|
<div class="doc_subsubsection">
|
||||||
<a name="PATypeHolder">Reference implementation</a>
|
<a name="ReferenceImpl">Reference implementation</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="doc_text">
|
<div class="doc_text">
|
||||||
@ -2434,7 +2434,7 @@ OK, passed 500 tests.
|
|||||||
|
|
||||||
<!-- ______________________________________________________________________ -->
|
<!-- ______________________________________________________________________ -->
|
||||||
<div class="doc_subsubsection">
|
<div class="doc_subsubsection">
|
||||||
<a name="PATypeHolder">Tagging considerations</a>
|
<a name="Tagging">Tagging considerations</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p>
|
<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).
|
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
|
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
|
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>
|
</div>
|
||||||
|
|
||||||
@ -2491,7 +2492,7 @@ the <tt>lib/VMCore</tt> directory.</p>
|
|||||||
|
|
||||||
<!-- _______________________________________________________________________ -->
|
<!-- _______________________________________________________________________ -->
|
||||||
<div class="doc_subsubsection">
|
<div class="doc_subsubsection">
|
||||||
<a name="m_Value">Important Public Methods</a>
|
<a name="m_Type">Important Public Methods</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="doc_text">
|
<div class="doc_text">
|
||||||
@ -2513,7 +2514,7 @@ the <tt>lib/VMCore</tt> directory.</p>
|
|||||||
|
|
||||||
<!-- _______________________________________________________________________ -->
|
<!-- _______________________________________________________________________ -->
|
||||||
<div class="doc_subsubsection">
|
<div class="doc_subsubsection">
|
||||||
<a name="m_Value">Important Derived Types</a>
|
<a name="derivedtypes">Important Derived Types</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="doc_text">
|
<div class="doc_text">
|
||||||
<dl>
|
<dl>
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include "llvm/Support/Casting.h"
|
#include "llvm/Support/Casting.h"
|
||||||
#include "llvm/ADT/iterator.h"
|
#include "llvm/ADT/iterator.h"
|
||||||
|
#include "llvm/ADT/PointerIntPair.h"
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
@ -25,46 +26,9 @@ class Value;
|
|||||||
class User;
|
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
|
/// Tag - generic tag type for (at least 32 bit) pointers
|
||||||
enum Tag { noTag, tagOne, tagTwo, tagThree };
|
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
|
// Use Class
|
||||||
@ -133,10 +97,11 @@ private:
|
|||||||
static Use *initTags(Use *Start, Use *Stop, ptrdiff_t Done = 0);
|
static Use *initTags(Use *Start, Use *Stop, ptrdiff_t Done = 0);
|
||||||
|
|
||||||
Value *Val;
|
Value *Val;
|
||||||
Use *Next, *volatile*Prev;
|
Use *Next;
|
||||||
|
PointerIntPair<Use**, 2, PrevPtrTag> Prev;
|
||||||
|
|
||||||
void setPrev(Use **NewPrev) {
|
void setPrev(Use **NewPrev) {
|
||||||
Prev = transferTag<fullStopTag>(Prev, NewPrev);
|
Prev.setPointer(NewPrev);
|
||||||
}
|
}
|
||||||
void addToList(Use **List) {
|
void addToList(Use **List) {
|
||||||
Next = *List;
|
Next = *List;
|
||||||
@ -145,7 +110,7 @@ private:
|
|||||||
*List = this;
|
*List = this;
|
||||||
}
|
}
|
||||||
void removeFromList() {
|
void removeFromList() {
|
||||||
Use **StrippedPrev = stripTag<fullStopTag>(Prev);
|
Use **StrippedPrev = Prev.getPointer();
|
||||||
*StrippedPrev = Next;
|
*StrippedPrev = Next;
|
||||||
if (Next) Next->setPrev(StrippedPrev);
|
if (Next) Next->setPrev(StrippedPrev);
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ const Use *Use::getImpliedUser() const {
|
|||||||
const Use *Current = this;
|
const Use *Current = this;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
unsigned Tag = extractTag<PrevPtrTag, fullStopTag>((Current++)->Prev);
|
unsigned Tag = (Current++)->Prev.getInt();
|
||||||
switch (Tag) {
|
switch (Tag) {
|
||||||
case zeroDigitTag:
|
case zeroDigitTag:
|
||||||
case oneDigitTag:
|
case oneDigitTag:
|
||||||
@ -62,7 +62,7 @@ const Use *Use::getImpliedUser() const {
|
|||||||
++Current;
|
++Current;
|
||||||
ptrdiff_t Offset = 1;
|
ptrdiff_t Offset = 1;
|
||||||
while (true) {
|
while (true) {
|
||||||
unsigned Tag = extractTag<PrevPtrTag, fullStopTag>(Current->Prev);
|
unsigned Tag = Current->Prev.getInt();
|
||||||
switch (Tag) {
|
switch (Tag) {
|
||||||
case zeroDigitTag:
|
case zeroDigitTag:
|
||||||
case oneDigitTag:
|
case oneDigitTag:
|
||||||
@ -91,11 +91,11 @@ Use *Use::initTags(Use * const Start, Use *Stop, ptrdiff_t Done) {
|
|||||||
--Stop;
|
--Stop;
|
||||||
Stop->Val = 0;
|
Stop->Val = 0;
|
||||||
if (!Count) {
|
if (!Count) {
|
||||||
Stop->Prev = reinterpret_cast<Use**>(Done == 0 ? fullStopTag : stopTag);
|
Stop->Prev.setFromOpaqueValue(reinterpret_cast<Use**>(Done == 0 ? fullStopTag : stopTag));
|
||||||
++Done;
|
++Done;
|
||||||
Count = Done;
|
Count = Done;
|
||||||
} else {
|
} else {
|
||||||
Stop->Prev = reinterpret_cast<Use**>(Count & 1);
|
Stop->Prev.setFromOpaqueValue(reinterpret_cast<Use**>(Count & 1));
|
||||||
Count >>= 1;
|
Count >>= 1;
|
||||||
++Done;
|
++Done;
|
||||||
}
|
}
|
||||||
@ -127,7 +127,7 @@ void Use::zap(Use *Start, const Use *Stop, bool del) {
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
struct AugmentedUse : Use {
|
struct AugmentedUse : Use {
|
||||||
volatile User *ref;
|
PointerIntPair<User*, 1, Tag> ref;
|
||||||
AugmentedUse(); // not implemented
|
AugmentedUse(); // not implemented
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -138,10 +138,11 @@ struct AugmentedUse : Use {
|
|||||||
|
|
||||||
User *Use::getUser() const {
|
User *Use::getUser() const {
|
||||||
const Use *End = getImpliedUser();
|
const Use *End = getImpliedUser();
|
||||||
volatile User *She = static_cast<const AugmentedUse*>(End - 1)->ref;
|
PointerIntPair<User*, 1, Tag>& ref(static_cast<const AugmentedUse*>(End - 1)->ref);
|
||||||
return extractTag<Tag, tagOne>(She)
|
User *She = ref.getPointer();
|
||||||
? llvm::stripTag<tagOne>(She)
|
return ref.getInt()
|
||||||
: reinterpret_cast<User*>(const_cast<Use*>(End));
|
? She
|
||||||
|
: (User*)End;
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
@ -153,7 +154,9 @@ Use *User::allocHungoffUses(unsigned N) const {
|
|||||||
+ sizeof(AugmentedUse)
|
+ sizeof(AugmentedUse)
|
||||||
- sizeof(Use)));
|
- sizeof(Use)));
|
||||||
Use *End = Begin + N;
|
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);
|
return Use::initTags(Begin, End);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user