LLVM  16.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 template <typename PointerT, unsigned IntBits, typename PtrTraits>
132 struct PointerIntPairInfo {
133  static_assert(PtrTraits::NumLowBitsAvailable <
134  std::numeric_limits<uintptr_t>::digits,
135  "cannot use a pointer type that has all bits free");
136  static_assert(IntBits <= PtrTraits::NumLowBitsAvailable,
137  "PointerIntPair with integer size too large for pointer");
138  enum MaskAndShiftConstants : uintptr_t {
139  /// PointerBitMask - The bits that come from the pointer.
141  ~(uintptr_t)(((intptr_t)1 << PtrTraits::NumLowBitsAvailable) - 1),
142 
143  /// IntShift - The number of low bits that we reserve for other uses, and
144  /// keep zero.
145  IntShift = (uintptr_t)PtrTraits::NumLowBitsAvailable - IntBits,
146 
147  /// IntMask - This is the unshifted mask for valid bits of the int type.
148  IntMask = (uintptr_t)(((intptr_t)1 << IntBits) - 1),
149 
150  // ShiftedIntMask - This is the bits for the integer shifted in place.
151  ShiftedIntMask = (uintptr_t)(IntMask << IntShift)
152  };
153 
154  static PointerT getPointer(intptr_t Value) {
155  return PtrTraits::getFromVoidPointer(
156  reinterpret_cast<void *>(Value & PointerBitMask));
157  }
158 
160  return (Value >> IntShift) & IntMask;
161  }
162 
163  static intptr_t updatePointer(intptr_t OrigValue, PointerT Ptr) {
164  intptr_t PtrWord =
165  reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(Ptr));
166  assert((PtrWord & ~PointerBitMask) == 0 &&
167  "Pointer is not sufficiently aligned");
168  // Preserve all low bits, just update the pointer.
169  return PtrWord | (OrigValue & ~PointerBitMask);
170  }
171 
172  static intptr_t updateInt(intptr_t OrigValue, intptr_t Int) {
173  intptr_t IntWord = static_cast<intptr_t>(Int);
174  assert((IntWord & ~IntMask) == 0 && "Integer too large for field");
175 
176  // Preserve all bits other than the ones we are updating.
177  return (OrigValue & ~ShiftedIntMask) | IntWord << IntShift;
178  }
179 };
180 
181 // Provide specialization of DenseMapInfo for PointerIntPair.
182 template <typename PointerTy, unsigned IntBits, typename IntType>
183 struct DenseMapInfo<PointerIntPair<PointerTy, IntBits, IntType>, void> {
185 
186  static Ty getEmptyKey() {
187  uintptr_t Val = static_cast<uintptr_t>(-1);
188  Val <<= PointerLikeTypeTraits<Ty>::NumLowBitsAvailable;
189  return Ty::getFromOpaqueValue(reinterpret_cast<void *>(Val));
190  }
191 
192  static Ty getTombstoneKey() {
193  uintptr_t Val = static_cast<uintptr_t>(-2);
194  Val <<= PointerLikeTypeTraits<PointerTy>::NumLowBitsAvailable;
195  return Ty::getFromOpaqueValue(reinterpret_cast<void *>(Val));
196  }
197 
198  static unsigned getHashValue(Ty V) {
199  uintptr_t IV = reinterpret_cast<uintptr_t>(V.getOpaqueValue());
200  return unsigned(IV) ^ unsigned(IV >> 9);
201  }
202 
203  static bool isEqual(const Ty &LHS, const Ty &RHS) { return LHS == RHS; }
204 };
205 
206 // Teach SmallPtrSet that PointerIntPair is "basically a pointer".
207 template <typename PointerTy, unsigned IntBits, typename IntType,
208  typename PtrTraits>
210  PointerIntPair<PointerTy, IntBits, IntType, PtrTraits>> {
211  static inline void *
213  return P.getOpaqueValue();
214  }
215 
219  }
220 
222  getFromVoidPointer(const void *P) {
224  }
225 
226  static constexpr int NumLowBitsAvailable =
227  PtrTraits::NumLowBitsAvailable - IntBits;
228 };
229 
230 } // end namespace llvm
231 
232 #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:18
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:222
llvm::PointerIntPairInfo::IntMask
@ IntMask
IntMask - This is the unshifted mask for valid bits of the int type.
Definition: PointerIntPair.h:148
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:159
llvm::DenseMapInfo< PointerIntPair< PointerTy, IntBits, IntType >, void >::getTombstoneKey
static Ty getTombstoneKey()
Definition: PointerIntPair.h:192
llvm::PointerIntPairInfo::getPointer
static PointerT getPointer(intptr_t Value)
Definition: PointerIntPair.h:154
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:172
llvm::DenseMapInfo< PointerIntPair< PointerTy, IntBits, IntType >, void >::getHashValue
static unsigned getHashValue(Ty V)
Definition: PointerIntPair.h:198
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:217
llvm::PointerIntPairInfo::PointerBitMask
@ PointerBitMask
PointerBitMask - The bits that come from the pointer.
Definition: PointerIntPair.h:140
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
Int
@ Int
Definition: TargetLibraryInfo.cpp:48
llvm::PointerIntPair::setPointerAndInt
void setPointerAndInt(PointerTy PtrVal, IntType IntVal) &
Definition: PointerIntPair.h:76
llvm::PointerIntPair::getPointer
PointerTy getPointer() const
Definition: PointerIntPair.h:60
llvm::PointerIntPairInfo::MaskAndShiftConstants
MaskAndShiftConstants
Definition: PointerIntPair.h:138
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
Ptr
@ Ptr
Definition: TargetLibraryInfo.cpp:60
llvm::PointerLikeTypeTraits< PointerIntPair< PointerTy, IntBits, IntType, PtrTraits > >::getAsVoidPointer
static void * getAsVoidPointer(const PointerIntPair< PointerTy, IntBits, IntType > &P)
Definition: PointerIntPair.h:212
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:145
llvm::DenseMapInfo< PointerIntPair< PointerTy, IntBits, IntType >, void >::isEqual
static bool isEqual(const Ty &LHS, const Ty &RHS)
Definition: PointerIntPair.h:203
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:65
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:186
llvm::PointerIntPairInfo::updatePointer
static intptr_t updatePointer(intptr_t OrigValue, PointerT Ptr)
Definition: PointerIntPair.h:163
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:151