[clang] b1613f0 - [NFC] Store Address's alignment into PointerIntPairs

Arthur Eubanks via cfe-commits cfe-commits at lists.llvm.org
Wed Jan 26 10:39:39 PST 2022


Author: Arthur Eubanks
Date: 2022-01-26T10:35:28-08:00
New Revision: b1613f05ae0ce4efc6b6475ea4459957ebcb0150

URL: https://github.com/llvm/llvm-project/commit/b1613f05ae0ce4efc6b6475ea4459957ebcb0150
DIFF: https://github.com/llvm/llvm-project/commit/b1613f05ae0ce4efc6b6475ea4459957ebcb0150.diff

LOG: [NFC] Store Address's alignment into PointerIntPairs

This mitigates the extra memory caused by D115725.

On 32-bit arches where we only have 2 bits per PointerIntPair we fall
back to simply storing alignment separately.

Reviewed By: rnk, nikic

Differential Revision: https://reviews.llvm.org/D117262

Added: 
    

Modified: 
    clang/lib/CodeGen/Address.h

Removed: 
    


################################################################################
diff  --git a/clang/lib/CodeGen/Address.h b/clang/lib/CodeGen/Address.h
index 37c20291c0e80..06b82e404cce4 100644
--- a/clang/lib/CodeGen/Address.h
+++ b/clang/lib/CodeGen/Address.h
@@ -14,30 +14,79 @@
 #ifndef LLVM_CLANG_LIB_CODEGEN_ADDRESS_H
 #define LLVM_CLANG_LIB_CODEGEN_ADDRESS_H
 
-#include "llvm/IR/Constants.h"
 #include "clang/AST/CharUnits.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/Support/MathExtras.h"
 
 namespace clang {
 namespace CodeGen {
 
-/// An aligned address.
-class Address {
+namespace {
+// We try to save some space by using 6 bits over two PointerIntPairs to store
+// the alignment. However, some arches don't support 3 bits in a PointerIntPair
+// so we fallback to storing the alignment separately.
+template <typename T, bool = alignof(llvm::Value *) >= 8> class AddressImpl {};
+
+template <typename T> class AddressImpl<T, false> {
   llvm::Value *Pointer;
   llvm::Type *ElementType;
   CharUnits Alignment;
 
+public:
+  AddressImpl(llvm::Value *Pointer, llvm::Type *ElementType,
+              CharUnits Alignment)
+      : Pointer(Pointer), ElementType(ElementType), Alignment(Alignment) {}
+  llvm::Value *getPointer() const { return Pointer; }
+  llvm::Type *getElementType() const { return ElementType; }
+  CharUnits getAlignment() const { return Alignment; }
+};
+
+template <typename T> class AddressImpl<T, true> {
+  // Int portion stores upper 3 bits of the log of the alignment.
+  llvm::PointerIntPair<llvm::Value *, 3, unsigned> Pointer;
+  // Int portion stores lower 3 bits of the log of the alignment.
+  llvm::PointerIntPair<llvm::Type *, 3, unsigned> ElementType;
+
+public:
+  AddressImpl(llvm::Value *Pointer, llvm::Type *ElementType,
+              CharUnits Alignment)
+      : Pointer(Pointer), ElementType(ElementType) {
+    if (Alignment.isZero())
+      return;
+    // Currently the max supported alignment is much less than 1 << 63 and is
+    // guaranteed to be a power of 2, so we can store the log of the alignment
+    // into 6 bits.
+    assert(Alignment.isPowerOfTwo() && "Alignment cannot be zero");
+    auto AlignLog = llvm::Log2_64(Alignment.getQuantity());
+    assert(AlignLog < (1 << 6) && "cannot fit alignment into 6 bits");
+    this->Pointer.setInt(AlignLog >> 3);
+    this->ElementType.setInt(AlignLog & 7);
+  }
+  llvm::Value *getPointer() const { return Pointer.getPointer(); }
+  llvm::Type *getElementType() const { return ElementType.getPointer(); }
+  CharUnits getAlignment() const {
+    unsigned AlignLog = (Pointer.getInt() << 3) | ElementType.getInt();
+    return CharUnits::fromQuantity(1UL << AlignLog);
+  }
+};
+} // namespace
+
+/// An aligned address.
+class Address {
+  AddressImpl<void> A;
+
 protected:
-  Address(std::nullptr_t) : Pointer(nullptr), ElementType(nullptr) {}
+  Address(std::nullptr_t) : A(nullptr, nullptr, CharUnits::Zero()) {}
 
 public:
-  Address(llvm::Value *pointer, llvm::Type *elementType, CharUnits alignment)
-      : Pointer(pointer), ElementType(elementType), Alignment(alignment) {
-    assert(pointer != nullptr && "Pointer cannot be null");
-    assert(elementType != nullptr && "Element type cannot be null");
-    assert(llvm::cast<llvm::PointerType>(pointer->getType())
-               ->isOpaqueOrPointeeTypeMatches(elementType) &&
+  Address(llvm::Value *Pointer, llvm::Type *ElementType, CharUnits Alignment)
+      : A(Pointer, ElementType, Alignment) {
+    assert(Pointer != nullptr && "Pointer cannot be null");
+    assert(ElementType != nullptr && "Element type cannot be null");
+    assert(llvm::cast<llvm::PointerType>(Pointer->getType())
+               ->isOpaqueOrPointeeTypeMatches(ElementType) &&
            "Incorrect pointer element type");
-    assert(!alignment.isZero() && "Alignment cannot be zero");
   }
 
   // Deprecated: Use constructor with explicit element type instead.
@@ -46,11 +95,11 @@ class Address {
                 Alignment) {}
 
   static Address invalid() { return Address(nullptr); }
-  bool isValid() const { return Pointer != nullptr; }
+  bool isValid() const { return A.getPointer() != nullptr; }
 
   llvm::Value *getPointer() const {
     assert(isValid());
-    return Pointer;
+    return A.getPointer();
   }
 
   /// Return the type of the pointer value.
@@ -61,7 +110,7 @@ class Address {
   /// Return the type of the values stored in this address.
   llvm::Type *getElementType() const {
     assert(isValid());
-    return ElementType;
+    return A.getElementType();
   }
 
   /// Return the address space that this address resides in.
@@ -77,19 +126,19 @@ class Address {
   /// Return the alignment of this pointer.
   CharUnits getAlignment() const {
     assert(isValid());
-    return Alignment;
+    return A.getAlignment();
   }
 
   /// Return address with 
diff erent pointer, but same element type and
   /// alignment.
   Address withPointer(llvm::Value *NewPointer) const {
-    return Address(NewPointer, ElementType, Alignment);
+    return Address(NewPointer, getElementType(), getAlignment());
   }
 
   /// Return address with 
diff erent alignment, but same pointer and element
   /// type.
   Address withAlignment(CharUnits NewAlignment) const {
-    return Address(Pointer, ElementType, NewAlignment);
+    return Address(getPointer(), getElementType(), NewAlignment);
   }
 };
 


        


More information about the cfe-commits mailing list