LLVM  14.0.0git
PointerIntPair.h
Go to the documentation of this file.
1 //===- llvm/ADT/PointerIntPair.h - Pair for pointer and int -----*- 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 file defines the PointerIntPair class.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LLVM_ADT_POINTERINTPAIR_H
14 #define LLVM_ADT_POINTERINTPAIR_H
15 
16 #include "llvm/Support/Compiler.h"
19 #include <cassert>
20 #include <cstdint>
21 #include <limits>
22 
23 namespace llvm {
24 
25 template <typename T> struct DenseMapInfo;
26 template <typename PointerT, unsigned IntBits, typename PtrTraits>
28 
29 /// PointerIntPair - This class implements a pair of a pointer and small
30 /// integer. It is designed to represent this in the space required by one
31 /// pointer by bitmangling the integer into the low part of the pointer. This
32 /// can only be done for small integers: typically up to 3 bits, but it depends
33 /// on the number of bits available according to PointerLikeTypeTraits for the
34 /// type.
35 ///
36 /// Note that PointerIntPair always puts the IntVal part in the highest bits
37 /// possible. For example, PointerIntPair<void*, 1, bool> will put the bit for
38 /// the bool into bit #2, not bit #0, which allows the low two bits to be used
39 /// for something else. For example, this allows:
40 /// PointerIntPair<PointerIntPair<void*, 1, bool>, 1, bool>
41 /// ... and the two bools will land in different bits.
42 template <typename PointerTy, unsigned IntBits, typename IntType = unsigned,
43  typename PtrTraits = PointerLikeTypeTraits<PointerTy>,
46  // Used by MSVC visualizer and generally helpful for debugging/visualizing.
47  using InfoTy = Info;
48  intptr_t Value = 0;
49 
50 public:
51  constexpr PointerIntPair() = default;
52 
53  PointerIntPair(PointerTy PtrVal, IntType IntVal) {
54  setPointerAndInt(PtrVal, IntVal);
55  }
56 
57  explicit PointerIntPair(PointerTy PtrVal) { initWithPointer(PtrVal); }
58 
59  PointerTy getPointer() const { return Info::getPointer(Value); }
60 
61  IntType getInt() const { return (IntType)Info::getInt(Value); }
62 
64  Value = Info::updatePointer(Value, PtrVal);
65  }
66 
68  Value = Info::updateInt(Value, static_cast<intptr_t>(IntVal));
69  }
70 
72  Value = Info::updatePointer(0, PtrVal);
73  }
74 
76  Value = Info::updateInt(Info::updatePointer(0, PtrVal),
77  static_cast<intptr_t>(IntVal));
78  }
79 
80  PointerTy const *getAddrOfPointer() const {
81  return const_cast<PointerIntPair *>(this)->getAddrOfPointer();
82  }
83 
85  assert(Value == reinterpret_cast<intptr_t>(getPointer()) &&
86  "Can only return the address if IntBits is cleared and "
87  "PtrTraits doesn't change the pointer");
88  return reinterpret_cast<PointerTy *>(&Value);
89  }
90 
91  void *getOpaqueValue() const { return reinterpret_cast<void *>(Value); }
92 
94  Value = reinterpret_cast<intptr_t>(Val);
95  }
96 
99  P.setFromOpaqueValue(V);
100  return P;
101  }
102 
103  // Allow PointerIntPairs to be created from const void * if and only if the
104  // pointer type could be created from a const void *.
105  static PointerIntPair getFromOpaqueValue(const void *V) {
106  (void)PtrTraits::getFromVoidPointer(V);
107  return getFromOpaqueValue(const_cast<void *>(V));
108  }
109 
110  bool operator==(const PointerIntPair &RHS) const {
111  return Value == RHS.Value;
112  }
113 
114  bool operator!=(const PointerIntPair &RHS) const {
115  return Value != RHS.Value;
116  }
117 
118  bool operator<(const PointerIntPair &RHS) const { return Value < RHS.Value; }
119  bool operator>(const PointerIntPair &RHS) const { return Value > RHS.Value; }
120 
121  bool operator<=(const PointerIntPair &RHS) const {
122  return Value <= RHS.Value;
123  }
124 
125  bool operator>=(const PointerIntPair &RHS) const {
126  return Value >= RHS.Value;
127  }
128 };
129 
130 // Specialize is_trivially_copyable to avoid limitation of llvm::is_trivially_copyable
131 // when compiled with gcc 4.9.
132 template <typename PointerTy, unsigned IntBits, typename IntType,
133  typename PtrTraits,
134  typename Info>
135 struct is_trivially_copyable<PointerIntPair<PointerTy, IntBits, IntType, PtrTraits, Info>> : std::true_type {
136 #ifdef HAVE_STD_IS_TRIVIALLY_COPYABLE
137  static_assert(std::is_trivially_copyable<PointerIntPair<PointerTy, IntBits, IntType, PtrTraits, Info>>::value,
138  "inconsistent behavior between llvm:: and std:: implementation of is_trivially_copyable");
139 #endif
140 };
141 
142 
143 template <typename PointerT, unsigned IntBits, typename PtrTraits>
144 struct PointerIntPairInfo {
145  static_assert(PtrTraits::NumLowBitsAvailable <
146  std::numeric_limits<uintptr_t>::digits,
147  "cannot use a pointer type that has all bits free");
148  static_assert(IntBits <= PtrTraits::NumLowBitsAvailable,
149  "PointerIntPair with integer size too large for pointer");
150  enum MaskAndShiftConstants : uintptr_t {
151  /// PointerBitMask - The bits that come from the pointer.
153  ~(uintptr_t)(((intptr_t)1 << PtrTraits::NumLowBitsAvailable) - 1),
154 
155  /// IntShift - The number of low bits that we reserve for other uses, and
156  /// keep zero.
157  IntShift = (uintptr_t)PtrTraits::NumLowBitsAvailable - IntBits,
158 
159  /// IntMask - This is the unshifted mask for valid bits of the int type.
160  IntMask = (uintptr_t)(((intptr_t)1 << IntBits) - 1),
161 
162  // ShiftedIntMask - This is the bits for the integer shifted in place.
163  ShiftedIntMask = (uintptr_t)(IntMask << IntShift)
164  };
165 
166  static PointerT getPointer(intptr_t Value) {
167  return PtrTraits::getFromVoidPointer(
168  reinterpret_cast<void *>(Value & PointerBitMask));
169  }
170 
172  return (Value >> IntShift) & IntMask;
173  }
174 
175  static intptr_t updatePointer(intptr_t OrigValue, PointerT Ptr) {
176  intptr_t PtrWord =
177  reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(Ptr));
178  assert((PtrWord & ~PointerBitMask) == 0 &&
179  "Pointer is not sufficiently aligned");
180  // Preserve all low bits, just update the pointer.
181  return PtrWord | (OrigValue & ~PointerBitMask);
182  }
183 
184  static intptr_t updateInt(intptr_t OrigValue, intptr_t Int) {
185  intptr_t IntWord = static_cast<intptr_t>(Int);
186  assert((IntWord & ~IntMask) == 0 && "Integer too large for field");
187 
188  // Preserve all bits other than the ones we are updating.
189  return (OrigValue & ~ShiftedIntMask) | IntWord << IntShift;
190  }
191 };
192 
193 // Provide specialization of DenseMapInfo for PointerIntPair.
194 template <typename PointerTy, unsigned IntBits, typename IntType>
195 struct DenseMapInfo<PointerIntPair<PointerTy, IntBits, IntType>> {
197 
198  static Ty getEmptyKey() {
199  uintptr_t Val = static_cast<uintptr_t>(-1);
200  Val <<= PointerLikeTypeTraits<Ty>::NumLowBitsAvailable;
201  return Ty::getFromOpaqueValue(reinterpret_cast<void *>(Val));
202  }
203 
204  static Ty getTombstoneKey() {
205  uintptr_t Val = static_cast<uintptr_t>(-2);
206  Val <<= PointerLikeTypeTraits<PointerTy>::NumLowBitsAvailable;
207  return Ty::getFromOpaqueValue(reinterpret_cast<void *>(Val));
208  }
209 
210  static unsigned getHashValue(Ty V) {
211  uintptr_t IV = reinterpret_cast<uintptr_t>(V.getOpaqueValue());
212  return unsigned(IV) ^ unsigned(IV >> 9);
213  }
214 
215  static bool isEqual(const Ty &LHS, const Ty &RHS) { return LHS == RHS; }
216 };
217 
218 // Teach SmallPtrSet that PointerIntPair is "basically a pointer".
219 template <typename PointerTy, unsigned IntBits, typename IntType,
220  typename PtrTraits>
222  PointerIntPair<PointerTy, IntBits, IntType, PtrTraits>> {
223  static inline void *
225  return P.getOpaqueValue();
226  }
227 
231  }
232 
234  getFromVoidPointer(const void *P) {
236  }
237 
238  static constexpr int NumLowBitsAvailable =
239  PtrTraits::NumLowBitsAvailable - IntBits;
240 };
241 
242 } // end namespace llvm
243 
244 #endif // LLVM_ADT_POINTERINTPAIR_H
llvm::DenseMapInfo< PointerIntPair< PointerTy, IntBits, IntType > >::getEmptyKey
static Ty getEmptyKey()
Definition: PointerIntPair.h:198
llvm::PointerIntPair::PointerIntPair
constexpr PointerIntPair()=default
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
intptr_t
llvm::PointerLikeTypeTraits< PointerIntPair< PointerTy, IntBits, IntType, PtrTraits > >::getFromVoidPointer
static PointerIntPair< PointerTy, IntBits, IntType > getFromVoidPointer(const void *P)
Definition: PointerIntPair.h:234
llvm::PointerIntPairInfo::IntMask
@ IntMask
IntMask - This is the unshifted mask for valid bits of the int type.
Definition: PointerIntPair.h:160
P
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
Definition: README-SSE.txt:411
llvm::DenseMapInfo< PointerIntPair< PointerTy, IntBits, IntType > >::getHashValue
static unsigned getHashValue(Ty V)
Definition: PointerIntPair.h:210
llvm::PointerIntPairInfo::getInt
static intptr_t getInt(intptr_t Value)
Definition: PointerIntPair.h:171
llvm::PointerIntPairInfo::getPointer
static PointerT getPointer(intptr_t Value)
Definition: PointerIntPair.h:166
LLVM_LVALUE_FUNCTION
#define LLVM_LVALUE_FUNCTION
Expands to '&' if ref-qualifiers for *this are supported.
Definition: Compiler.h:114
llvm::PointerIntPair::getAddrOfPointer
const PointerTy * getAddrOfPointer() const
Definition: PointerIntPair.h:80
getInt
static Error getInt(StringRef R, IntTy &Result)
Get an unsigned integer, including error checks.
Definition: DataLayout.cpp:229
llvm::PointerIntPair::operator>=
bool operator>=(const PointerIntPair &RHS) const
Definition: PointerIntPair.h:125
llvm::PointerIntPair::PointerIntPair
PointerIntPair(PointerTy PtrVal, IntType IntVal)
Definition: PointerIntPair.h:53
llvm::PointerIntPairInfo::updateInt
static intptr_t updateInt(intptr_t OrigValue, intptr_t Int)
Definition: PointerIntPair.h:184
llvm::is_trivially_copyable
Definition: type_traits.h:140
llvm::DenseMapInfo
Definition: APInt.h:34
llvm::PointerIntPair::operator<
bool operator<(const PointerIntPair &RHS) const
Definition: PointerIntPair.h:118
llvm::PointerLikeTypeTraits< PointerIntPair< PointerTy, IntBits, IntType, PtrTraits > >::getFromVoidPointer
static PointerIntPair< PointerTy, IntBits, IntType > getFromVoidPointer(void *P)
Definition: PointerIntPair.h:229
llvm::PointerIntPairInfo::PointerBitMask
@ PointerBitMask
PointerBitMask - The bits that come from the pointer.
Definition: PointerIntPair.h:152
llvm::PointerIntPair::operator!=
bool operator!=(const PointerIntPair &RHS) const
Definition: PointerIntPair.h:114
PointerLikeTypeTraits.h
Info
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
llvm::PointerIntPairInfo
Definition: PointerIntPair.h:27
llvm::PointerIntPair::PointerIntPair
PointerIntPair(PointerTy PtrVal)
Definition: PointerIntPair.h:57
llvm::is_trivially_copyable::value
static constexpr bool value
Definition: type_traits.h:172
llvm::PointerIntPair::getPointer
PointerTy getPointer() const
Definition: PointerIntPair.h:59
llvm::PointerIntPair::initWithPointer
void initWithPointer(PointerTy PtrVal) LLVM_LVALUE_FUNCTION
Definition: PointerIntPair.h:71
llvm::PointerIntPair::setFromOpaqueValue
void setFromOpaqueValue(void *Val) LLVM_LVALUE_FUNCTION
Definition: PointerIntPair.h:93
llvm::PointerIntPairInfo::MaskAndShiftConstants
MaskAndShiftConstants
Definition: PointerIntPair.h:150
llvm::PointerIntPair::getInt
IntType getInt() const
Definition: PointerIntPair.h:61
llvm::PointerIntPair::operator>
bool operator>(const PointerIntPair &RHS) const
Definition: PointerIntPair.h:119
llvm::PointerIntPair::operator==
bool operator==(const PointerIntPair &RHS) const
Definition: PointerIntPair.h:110
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::PointerIntPair::getFromOpaqueValue
static PointerIntPair getFromOpaqueValue(const void *V)
Definition: PointerIntPair.h:105
llvm::PointerIntPair::setPointerAndInt
void setPointerAndInt(PointerTy PtrVal, IntType IntVal) LLVM_LVALUE_FUNCTION
Definition: PointerIntPair.h:75
llvm::PointerLikeTypeTraits< PointerIntPair< PointerTy, IntBits, IntType, PtrTraits > >::getAsVoidPointer
static void * getAsVoidPointer(const PointerIntPair< PointerTy, IntBits, IntType > &P)
Definition: PointerIntPair.h:224
llvm::PointerIntPairInfo::IntShift
@ IntShift
IntShift - The number of low bits that we reserve for other uses, and keep zero.
Definition: PointerIntPair.h:157
llvm::PointerTy
void * PointerTy
Definition: GenericValue.h:21
Compiler.h
llvm::PointerIntPair::getAddrOfPointer
PointerTy * getAddrOfPointer()
Definition: PointerIntPair.h:84
llvm::DenseMapInfo< PointerIntPair< PointerTy, IntBits, IntType > >::getTombstoneKey
static Ty getTombstoneKey()
Definition: PointerIntPair.h:204
llvm::PointerIntPair::setPointer
void setPointer(PointerTy PtrVal) LLVM_LVALUE_FUNCTION
Definition: PointerIntPair.h:63
llvm::tgtok::IntVal
@ IntVal
Definition: TGLexer.h:64
type_traits.h
llvm::PointerIntPair::getOpaqueValue
void * getOpaqueValue() const
Definition: PointerIntPair.h:91
llvm::PointerIntPair::setInt
void setInt(IntType IntVal) LLVM_LVALUE_FUNCTION
Definition: PointerIntPair.h:67
llvm::DenseMapInfo< PointerIntPair< PointerTy, IntBits, IntType > >::isEqual
static bool isEqual(const Ty &LHS, const Ty &RHS)
Definition: PointerIntPair.h:215
llvm::PointerIntPairInfo::updatePointer
static intptr_t updatePointer(intptr_t OrigValue, PointerT Ptr)
Definition: PointerIntPair.h:175
llvm::PointerLikeTypeTraits
A traits type that is used to handle pointer types and things that are just wrappers for pointers as ...
Definition: PointerLikeTypeTraits.h:25
llvm::PointerIntPair
PointerIntPair - This class implements a pair of a pointer and small integer.
Definition: PointerIntPair.h:45
llvm::PointerIntPair::getFromOpaqueValue
static PointerIntPair getFromOpaqueValue(void *V)
Definition: PointerIntPair.h:97
llvm::PointerIntPair::operator<=
bool operator<=(const PointerIntPair &RHS) const
Definition: PointerIntPair.h:121
llvm::Value
LLVM Value Representation.
Definition: Value.h:75
llvm::PointerIntPairInfo::ShiftedIntMask
@ ShiftedIntMask
Definition: PointerIntPair.h:163