diff --git a/clang/lib/CodeGen/Address.h b/clang/lib/CodeGen/Address.h --- a/clang/lib/CodeGen/Address.h +++ b/clang/lib/CodeGen/Address.h @@ -14,30 +14,36 @@ #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 { - llvm::Value *Pointer; - llvm::Type *ElementType; - CharUnits Alignment; + llvm::PointerIntPair Pointer; + llvm::PointerIntPair ElementType; + // CharUnits Alignment; protected: Address(std::nullptr_t) : Pointer(nullptr), ElementType(nullptr) {} public: Address(llvm::Value *pointer, llvm::Type *elementType, CharUnits alignment) - : Pointer(pointer), ElementType(elementType), Alignment(alignment) { + : Pointer(pointer), ElementType(elementType) { assert(pointer != nullptr && "Pointer cannot be null"); assert(elementType != nullptr && "Element type cannot be null"); assert(llvm::cast(pointer->getType()) ->isOpaqueOrPointeeTypeMatches(elementType) && "Incorrect pointer element type"); - assert(!alignment.isZero() && "Alignment cannot be zero"); + assert(alignment.isPowerOfTwo() && "Alignment cannot be zero"); + auto AlignLog = llvm::Log2_64(alignment.getQuantity()); + assert(AlignLog < (1 << 6) && "cannot fit alignment into 6 bits"); + Pointer.setInt(AlignLog >> 3); + ElementType.setInt(AlignLog & 7); } // Deprecated: Use constructor with explicit element type instead. @@ -46,11 +52,11 @@ Alignment) {} static Address invalid() { return Address(nullptr); } - bool isValid() const { return Pointer != nullptr; } + bool isValid() const { return Pointer.getPointer() != nullptr; } llvm::Value *getPointer() const { assert(isValid()); - return Pointer; + return Pointer.getPointer(); } /// Return the type of the pointer value. @@ -61,7 +67,7 @@ /// Return the type of the values stored in this address. llvm::Type *getElementType() const { assert(isValid()); - return ElementType; + return ElementType.getPointer(); } /// Return the address space that this address resides in. @@ -77,19 +83,21 @@ /// Return the alignment of this pointer. CharUnits getAlignment() const { assert(isValid()); - return Alignment; + unsigned AlignLog = (Pointer.getInt() << 3) | ElementType.getInt(); + return CharUnits::fromQuantity(1 << AlignLog); } /// Return address with different pointer, but same element type and /// alignment. Address withPointer(llvm::Value *NewPointer) const { - return Address(NewPointer, ElementType, Alignment); + return Address(NewPointer, ElementType.getPointer(), getAlignment()); } /// Return address with different alignment, but same pointer and element /// type. Address withAlignment(CharUnits NewAlignment) const { - return Address(Pointer, ElementType, NewAlignment); + return Address(Pointer.getPointer(), ElementType.getPointer(), + NewAlignment); } };