[llvm] r300471 - [IR] Put the Use list waymarking bits in the bit positions documentation says they are using

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 17 11:12:30 PDT 2017


Author: ctopper
Date: Mon Apr 17 13:12:30 2017
New Revision: 300471

URL: http://llvm.org/viewvc/llvm-project?rev=300471&view=rev
Log:
[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



Modified:
    llvm/trunk/include/llvm/IR/Use.h

Modified: llvm/trunk/include/llvm/IR/Use.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Use.h?rev=300471&r1=300470&r2=300471&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Use.h (original)
+++ llvm/trunk/include/llvm/IR/Use.h Mon Apr 17 13:12:30 2017
@@ -61,9 +61,29 @@ public:
   /// that also works with less standard-compliant compilers
   void swap(Use &RHS);
 
+  /// Pointer traits for the UserRef PointerIntPair. This ensures we always
+  /// use the LSB regardless of pointer alignment on different targets.
+  struct UserRefPointerTraits {
+    static inline void *getAsVoidPointer(User *P) { return P; }
+    static inline User *getFromVoidPointer(void *P) {
+      return (User *)P;
+    }
+    enum { NumLowBitsAvailable = 1 };
+  };
+
   // A type for the word following an array of hung-off Uses in memory, which is
   // a pointer back to their User with the bottom bit set.
-  typedef PointerIntPair<User *, 1, unsigned> UserRef;
+  typedef PointerIntPair<User *, 1, unsigned, UserRefPointerTraits> UserRef;
+
+  /// Pointer traits for the Prev PointerIntPair. This ensures we always use
+  /// the two LSBs regardless of pointer alignment on different targets.
+  struct PrevPointerTraits {
+    static inline void *getAsVoidPointer(Use **P) { return P; }
+    static inline Use **getFromVoidPointer(void *P) {
+      return (Use **)P;
+    }
+    enum { NumLowBitsAvailable = 2 };
+  };
 
 private:
   /// Destructor - Only for zap()
@@ -115,7 +135,7 @@ private:
 
   Value *Val;
   Use *Next;
-  PointerIntPair<Use **, 2, PrevPtrTag> Prev;
+  PointerIntPair<Use **, 2, PrevPtrTag, PrevPointerTraits> Prev;
 
   void setPrev(Use **NewPrev) { Prev.setPointer(NewPrev); }
 




More information about the llvm-commits mailing list