Skip to content

Commit bf1ded2

Browse files
committed
[IR] Put the Use list waymarking bits in the bit positions documentation says they are using
The documentation for the waymarking algorithm says that we use the lower 2 bits of Use::Prev to store the way marking bits. But because we use a PointerIntPair with the default PointerLikeTypeTraits, we're using bits 2:1 on 64-bit targets. There's also a trick employed for distinguishing Users that have Uses stored with them and Users that have Uses stored in a separate array. The documentation says we use the LSB of the first byte of the real User object or the User* that occurs at the end of the Use array. But again due to the PointerLikeTypeTraits we're really using bit 2(64-bit) or bit 1(32-bit) and not the LSB. This is a little worrying because the first byte of the User object is the vtable ptr so we're assuming the vtable has 8 byte or 4 byte alignment where what is documented would only require 2 byte alignment. This patch provides a custom traits override for these two cases to put the bits where the documentation says they are. It also has the side effect of removing some shifts from the waymarking traversal implementation. Differential Revision: https://reviews.llvm.org/D31733 llvm-svn: 300471
1 parent 1209684 commit bf1ded2

File tree

1 file changed

+22
-2
lines changed
  • llvm/include/llvm/IR

1 file changed

+22
-2
lines changed

llvm/include/llvm/IR/Use.h

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,29 @@ class Use {
6161
/// that also works with less standard-compliant compilers
6262
void swap(Use &RHS);
6363

64+
/// Pointer traits for the UserRef PointerIntPair. This ensures we always
65+
/// use the LSB regardless of pointer alignment on different targets.
66+
struct UserRefPointerTraits {
67+
static inline void *getAsVoidPointer(User *P) { return P; }
68+
static inline User *getFromVoidPointer(void *P) {
69+
return (User *)P;
70+
}
71+
enum { NumLowBitsAvailable = 1 };
72+
};
73+
6474
// A type for the word following an array of hung-off Uses in memory, which is
6575
// a pointer back to their User with the bottom bit set.
66-
typedef PointerIntPair<User *, 1, unsigned> UserRef;
76+
typedef PointerIntPair<User *, 1, unsigned, UserRefPointerTraits> UserRef;
77+
78+
/// Pointer traits for the Prev PointerIntPair. This ensures we always use
79+
/// the two LSBs regardless of pointer alignment on different targets.
80+
struct PrevPointerTraits {
81+
static inline void *getAsVoidPointer(Use **P) { return P; }
82+
static inline Use **getFromVoidPointer(void *P) {
83+
return (Use **)P;
84+
}
85+
enum { NumLowBitsAvailable = 2 };
86+
};
6787

6888
private:
6989
/// Destructor - Only for zap()
@@ -115,7 +135,7 @@ class Use {
115135

116136
Value *Val;
117137
Use *Next;
118-
PointerIntPair<Use **, 2, PrevPtrTag> Prev;
138+
PointerIntPair<Use **, 2, PrevPtrTag, PrevPointerTraits> Prev;
119139

120140
void setPrev(Use **NewPrev) { Prev.setPointer(NewPrev); }
121141

0 commit comments

Comments
 (0)