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