clang  16.0.0git
Address.h
Go to the documentation of this file.
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 // We try to save some space by using 6 bits over two PointerIntPairs to store
26 // the alignment. However, some arches don't support 3 bits in a PointerIntPair
27 // so we fallback to storing the alignment separately.
28 template <typename T, bool = alignof(llvm::Value *) >= 8> class AddressImpl {};
29 
30 template <typename T> class AddressImpl<T, false> {
31  llvm::Value *Pointer;
32  llvm::Type *ElementType;
33  CharUnits Alignment;
34 
35 public:
36  AddressImpl(llvm::Value *Pointer, llvm::Type *ElementType,
37  CharUnits Alignment)
38  : Pointer(Pointer), ElementType(ElementType), Alignment(Alignment) {}
39  llvm::Value *getPointer() const { return Pointer; }
40  llvm::Type *getElementType() const { return ElementType; }
41  CharUnits getAlignment() const { return Alignment; }
42 };
43 
44 template <typename T> class AddressImpl<T, true> {
45  // Int portion stores upper 3 bits of the log of the alignment.
46  llvm::PointerIntPair<llvm::Value *, 3, unsigned> Pointer;
47  // Int portion stores lower 3 bits of the log of the alignment.
48  llvm::PointerIntPair<llvm::Type *, 3, unsigned> ElementType;
49 
50 public:
51  AddressImpl(llvm::Value *Pointer, llvm::Type *ElementType,
52  CharUnits Alignment)
53  : Pointer(Pointer), ElementType(ElementType) {
54  if (Alignment.isZero())
55  return;
56  // Currently the max supported alignment is much less than 1 << 63 and is
57  // guaranteed to be a power of 2, so we can store the log of the alignment
58  // into 6 bits.
59  assert(Alignment.isPowerOfTwo() && "Alignment cannot be zero");
60  auto AlignLog = llvm::Log2_64(Alignment.getQuantity());
61  assert(AlignLog < (1 << 6) && "cannot fit alignment into 6 bits");
62  this->Pointer.setInt(AlignLog >> 3);
63  this->ElementType.setInt(AlignLog & 7);
64  }
65  llvm::Value *getPointer() const { return Pointer.getPointer(); }
66  llvm::Type *getElementType() const { return ElementType.getPointer(); }
68  unsigned AlignLog = (Pointer.getInt() << 3) | ElementType.getInt();
69  return CharUnits::fromQuantity(CharUnits::QuantityType(1) << AlignLog);
70  }
71 };
72 
73 /// An aligned address.
74 class Address {
75  AddressImpl<void> A;
76 
77 protected:
78  Address(std::nullptr_t) : A(nullptr, nullptr, CharUnits::Zero()) {}
79 
80 public:
81  Address(llvm::Value *Pointer, llvm::Type *ElementType, CharUnits Alignment)
82  : A(Pointer, ElementType, Alignment) {
83  assert(Pointer != nullptr && "Pointer cannot be null");
84  assert(ElementType != nullptr && "Element type cannot be null");
85  assert(llvm::cast<llvm::PointerType>(Pointer->getType())
86  ->isOpaqueOrPointeeTypeMatches(ElementType) &&
87  "Incorrect pointer element type");
88  }
89 
90  static Address invalid() { return Address(nullptr); }
91  bool isValid() const { return A.getPointer() != nullptr; }
92 
93  llvm::Value *getPointer() const {
94  assert(isValid());
95  return A.getPointer();
96  }
97 
98  /// Return the type of the pointer value.
99  llvm::PointerType *getType() const {
100  return llvm::cast<llvm::PointerType>(getPointer()->getType());
101  }
102 
103  /// Return the type of the values stored in this address.
104  llvm::Type *getElementType() const {
105  assert(isValid());
106  return A.getElementType();
107  }
108 
109  /// Return the address space that this address resides in.
110  unsigned getAddressSpace() const {
111  return getType()->getAddressSpace();
112  }
113 
114  /// Return the IR name of the pointer value.
115  llvm::StringRef getName() const {
116  return getPointer()->getName();
117  }
118 
119  /// Return the alignment of this pointer.
121  assert(isValid());
122  return A.getAlignment();
123  }
124 
125  /// Return address with different pointer, but same element type and
126  /// alignment.
127  Address withPointer(llvm::Value *NewPointer) const {
128  return Address(NewPointer, getElementType(), getAlignment());
129  }
130 
131  /// Return address with different alignment, but same pointer and element
132  /// type.
133  Address withAlignment(CharUnits NewAlignment) const {
134  return Address(getPointer(), getElementType(), NewAlignment);
135  }
136 };
137 
138 /// A specialization of Address that requires the address to be an
139 /// LLVM Constant.
140 class ConstantAddress : public Address {
141  ConstantAddress(std::nullptr_t) : Address(nullptr) {}
142 
143 public:
144  ConstantAddress(llvm::Constant *pointer, llvm::Type *elementType,
145  CharUnits alignment)
146  : Address(pointer, elementType, alignment) {}
147 
149  return ConstantAddress(nullptr);
150  }
151 
152  llvm::Constant *getPointer() const {
153  return llvm::cast<llvm::Constant>(Address::getPointer());
154  }
155 
156  ConstantAddress getElementBitCast(llvm::Type *ElemTy) const {
157  llvm::Constant *BitCast = llvm::ConstantExpr::getBitCast(
158  getPointer(), ElemTy->getPointerTo(getAddressSpace()));
159  return ConstantAddress(BitCast, ElemTy, getAlignment());
160  }
161 
162  static bool isaImpl(Address addr) {
163  return llvm::isa<llvm::Constant>(addr.getPointer());
164  }
166  return ConstantAddress(llvm::cast<llvm::Constant>(addr.getPointer()),
167  addr.getElementType(), addr.getAlignment());
168  }
169 };
170 
171 }
172 
173 // Present a minimal LLVM-like casting interface.
174 template <class U> inline U cast(CodeGen::Address addr) {
175  return U::castImpl(addr);
176 }
177 template <class U> inline bool isa(CodeGen::Address addr) {
178  return U::isaImpl(addr);
179 }
180 
181 }
182 
183 #endif
clang::CodeGen::AddressImpl< T, false >::getAlignment
CharUnits getAlignment() const
Definition: Address.h:41
clang::CodeGen::ConstantAddress::getElementBitCast
ConstantAddress getElementBitCast(llvm::Type *ElemTy) const
Definition: Address.h:156
clang::CodeGen::ConstantAddress
A specialization of Address that requires the address to be an LLVM Constant.
Definition: Address.h:140
clang::CodeGen::Address::getAlignment
CharUnits getAlignment() const
Return the alignment of this pointer.
Definition: Address.h:120
clang::CharUnits::QuantityType
int64_t QuantityType
Definition: CharUnits.h:40
clang::CodeGen::AddressImpl< T, false >::getElementType
llvm::Type * getElementType() const
Definition: Address.h:40
clang::cast
U cast(CodeGen::Address addr)
Definition: Address.h:174
clang::CodeGen::Address::isValid
bool isValid() const
Definition: Address.h:91
clang::CodeGen::AddressImpl< T, true >::AddressImpl
AddressImpl(llvm::Value *Pointer, llvm::Type *ElementType, CharUnits Alignment)
Definition: Address.h:51
clang::CodeGen::ConstantAddress::isaImpl
static bool isaImpl(Address addr)
Definition: Address.h:162
clang::CodeGen::ConstantAddress::ConstantAddress
ConstantAddress(llvm::Constant *pointer, llvm::Type *elementType, CharUnits alignment)
Definition: Address.h:144
U
clang::CodeGen::Address::getName
llvm::StringRef getName() const
Return the IR name of the pointer value.
Definition: Address.h:115
clang::CharUnits::fromQuantity
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
Definition: CharUnits.h:63
clang::CodeGen::AddressImpl< T, false >::AddressImpl
AddressImpl(llvm::Value *Pointer, llvm::Type *ElementType, CharUnits Alignment)
Definition: Address.h:36
clang::CodeGen::Address::getType
llvm::PointerType * getType() const
Return the type of the pointer value.
Definition: Address.h:99
clang::CharUnits::isPowerOfTwo
bool isPowerOfTwo() const
isPowerOfTwo - Test whether the quantity is a power of two.
Definition: CharUnits.h:129
clang::isa
bool isa(CodeGen::Address addr)
Definition: Address.h:177
clang::interp::Zero
bool Zero(InterpState &S, CodePtr OpPC)
Definition: Interp.h:853
clang::CodeGen::Address::Address
Address(llvm::Value *Pointer, llvm::Type *ElementType, CharUnits Alignment)
Definition: Address.h:81
clang::CodeGen::Address
An aligned address.
Definition: Address.h:74
clang::CodeGen::Address::getAddressSpace
unsigned getAddressSpace() const
Return the address space that this address resides in.
Definition: Address.h:110
clang::CodeGen::AddressImpl< T, true >::getAlignment
CharUnits getAlignment() const
Definition: Address.h:67
CharUnits.h
clang::CodeGen::Address::withAlignment
Address withAlignment(CharUnits NewAlignment) const
Return address with different alignment, but same pointer and element type.
Definition: Address.h:133
clang::CodeGen::ConstantAddress::castImpl
static ConstantAddress castImpl(Address addr)
Definition: Address.h:165
clang::CodeGen::AddressImpl< T, false >::getPointer
llvm::Value * getPointer() const
Definition: Address.h:39
false
#define false
Definition: stdbool.h:22
clang::CodeGen::Address::getPointer
llvm::Value * getPointer() const
Definition: Address.h:93
clang::CharUnits::isZero
bool isZero() const
isZero - Test whether the quantity equals zero.
Definition: CharUnits.h:116
clang::CodeGen::Address::withPointer
Address withPointer(llvm::Value *NewPointer) const
Return address with different pointer, but same element type and alignment.
Definition: Address.h:127
clang::CodeGen::Address::Address
Address(std::nullptr_t)
Definition: Address.h:78
clang::CodeGen::Address::invalid
static Address invalid()
Definition: Address.h:90
clang::CodeGen::Address::getElementType
llvm::Type * getElementType() const
Return the type of the values stored in this address.
Definition: Address.h:104
clang::CodeGen::ConstantAddress::getPointer
llvm::Constant * getPointer() const
Definition: Address.h:152
clang::CodeGen::ConstantAddress::invalid
static ConstantAddress invalid()
Definition: Address.h:148
clang::CodeGen::AddressImpl< T, true >::getPointer
llvm::Value * getPointer() const
Definition: Address.h:65
clang
Definition: CalledOnceCheck.h:17
clang::CharUnits
CharUnits - This is an opaque type for sizes expressed in character units.
Definition: CharUnits.h:38
true
#define true
Definition: stdbool.h:21
clang::CharUnits::getQuantity
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
Definition: CharUnits.h:179
clang::CodeGen::AddressImpl< T, true >::getElementType
llvm::Type * getElementType() const
Definition: Address.h:66