1 //===-- Address.h - An aligned address -------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This class provides a simple wrapper for a pair of a pointer and an 10 // alignment. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_CLANG_LIB_CODEGEN_ADDRESS_H 15 #define LLVM_CLANG_LIB_CODEGEN_ADDRESS_H 16 17 #include "clang/AST/CharUnits.h" 18 #include "llvm/ADT/PointerIntPair.h" 19 #include "llvm/IR/Constants.h" 20 #include "llvm/Support/MathExtras.h" 21 22 namespace clang { 23 namespace CodeGen { 24 25 // Indicates whether a pointer is known not to be null. 26 enum KnownNonNull_t { NotKnownNonNull, KnownNonNull }; 27 28 /// An aligned address. 29 class Address { 30 llvm::PointerIntPair<llvm::Value *, 1, bool> PointerAndKnownNonNull; 31 llvm::Type *ElementType; 32 CharUnits Alignment; 33 34 protected: 35 Address(std::nullptr_t) : ElementType(nullptr) {} 36 37 public: 38 Address(llvm::Value *Pointer, llvm::Type *ElementType, CharUnits Alignment, 39 KnownNonNull_t IsKnownNonNull = NotKnownNonNull) 40 : PointerAndKnownNonNull(Pointer, IsKnownNonNull), 41 ElementType(ElementType), Alignment(Alignment) { 42 assert(Pointer != nullptr && "Pointer cannot be null"); 43 assert(ElementType != nullptr && "Element type cannot be null"); 44 } 45 46 static Address invalid() { return Address(nullptr); } 47 bool isValid() const { 48 return PointerAndKnownNonNull.getPointer() != nullptr; 49 } 50 51 llvm::Value *getPointer() const { 52 assert(isValid()); 53 return PointerAndKnownNonNull.getPointer(); 54 } 55 56 /// Return the type of the pointer value. 57 llvm::PointerType *getType() const { 58 return llvm::cast<llvm::PointerType>(getPointer()->getType()); 59 } 60 61 /// Return the type of the values stored in this address. 62 llvm::Type *getElementType() const { 63 assert(isValid()); 64 return ElementType; 65 } 66 67 /// Return the address space that this address resides in. 68 unsigned getAddressSpace() const { 69 return getType()->getAddressSpace(); 70 } 71 72 /// Return the IR name of the pointer value. 73 llvm::StringRef getName() const { 74 return getPointer()->getName(); 75 } 76 77 /// Return the alignment of this pointer. 78 CharUnits getAlignment() const { 79 assert(isValid()); 80 return Alignment; 81 } 82 83 /// Return address with different pointer, but same element type and 84 /// alignment. 85 Address withPointer(llvm::Value *NewPointer, 86 KnownNonNull_t IsKnownNonNull) const { 87 return Address(NewPointer, getElementType(), getAlignment(), 88 IsKnownNonNull); 89 } 90 91 /// Return address with different alignment, but same pointer and element 92 /// type. 93 Address withAlignment(CharUnits NewAlignment) const { 94 return Address(getPointer(), getElementType(), NewAlignment, 95 isKnownNonNull()); 96 } 97 98 /// Return address with different element type, but same pointer and 99 /// alignment. 100 Address withElementType(llvm::Type *ElemTy) const { 101 return Address(getPointer(), ElemTy, getAlignment(), isKnownNonNull()); 102 } 103 104 /// Whether the pointer is known not to be null. 105 KnownNonNull_t isKnownNonNull() const { 106 assert(isValid()); 107 return (KnownNonNull_t)PointerAndKnownNonNull.getInt(); 108 } 109 110 /// Set the non-null bit. 111 Address setKnownNonNull() { 112 assert(isValid()); 113 PointerAndKnownNonNull.setInt(true); 114 return *this; 115 } 116 }; 117 118 /// A specialization of Address that requires the address to be an 119 /// LLVM Constant. 120 class ConstantAddress : public Address { 121 ConstantAddress(std::nullptr_t) : Address(nullptr) {} 122 123 public: 124 ConstantAddress(llvm::Constant *pointer, llvm::Type *elementType, 125 CharUnits alignment) 126 : Address(pointer, elementType, alignment) {} 127 128 static ConstantAddress invalid() { 129 return ConstantAddress(nullptr); 130 } 131 132 llvm::Constant *getPointer() const { 133 return llvm::cast<llvm::Constant>(Address::getPointer()); 134 } 135 136 ConstantAddress withElementType(llvm::Type *ElemTy) const { 137 return ConstantAddress(getPointer(), ElemTy, getAlignment()); 138 } 139 140 static bool isaImpl(Address addr) { 141 return llvm::isa<llvm::Constant>(addr.getPointer()); 142 } 143 static ConstantAddress castImpl(Address addr) { 144 return ConstantAddress(llvm::cast<llvm::Constant>(addr.getPointer()), 145 addr.getElementType(), addr.getAlignment()); 146 } 147 }; 148 149 } 150 151 // Present a minimal LLVM-like casting interface. 152 template <class U> inline U cast(CodeGen::Address addr) { 153 return U::castImpl(addr); 154 } 155 template <class U> inline bool isa(CodeGen::Address addr) { 156 return U::isaImpl(addr); 157 } 158 159 } 160 161 #endif 162