Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

199 lines
7.6 KiB

  1. //===- llvm/ADT/PointerIntPair.h - Pair for pointer and int -----*- C++ -*-===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This file defines the PointerIntPair class.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #ifndef LLVM_ADT_POINTERINTPAIR_H
  14. #define LLVM_ADT_POINTERINTPAIR_H
  15. #include "llvm/Support/PointerLikeTypeTraits.h"
  16. #include <cassert>
  17. namespace llvm {
  18. template<typename T>
  19. struct DenseMapInfo;
  20. /// PointerIntPair - This class implements a pair of a pointer and small
  21. /// integer. It is designed to represent this in the space required by one
  22. /// pointer by bitmangling the integer into the low part of the pointer. This
  23. /// can only be done for small integers: typically up to 3 bits, but it depends
  24. /// on the number of bits available according to PointerLikeTypeTraits for the
  25. /// type.
  26. ///
  27. /// Note that PointerIntPair always puts the IntVal part in the highest bits
  28. /// possible. For example, PointerIntPair<void*, 1, bool> will put the bit for
  29. /// the bool into bit #2, not bit #0, which allows the low two bits to be used
  30. /// for something else. For example, this allows:
  31. /// PointerIntPair<PointerIntPair<void*, 1, bool>, 1, bool>
  32. /// ... and the two bools will land in different bits.
  33. ///
  34. template <typename PointerTy, unsigned IntBits, typename IntType=unsigned,
  35. typename PtrTraits = PointerLikeTypeTraits<PointerTy> >
  36. class PointerIntPair {
  37. intptr_t Value;
  38. enum {
  39. /// PointerBitMask - The bits that come from the pointer.
  40. PointerBitMask =
  41. ~(uintptr_t)(((intptr_t)1 << PtrTraits::NumLowBitsAvailable)-1),
  42. /// IntShift - The number of low bits that we reserve for other uses, and
  43. /// keep zero.
  44. IntShift = (uintptr_t)PtrTraits::NumLowBitsAvailable-IntBits,
  45. /// IntMask - This is the unshifted mask for valid bits of the int type.
  46. IntMask = (uintptr_t)(((intptr_t)1 << IntBits)-1),
  47. // ShiftedIntMask - This is the bits for the integer shifted in place.
  48. ShiftedIntMask = (uintptr_t)(IntMask << IntShift)
  49. };
  50. public:
  51. PointerIntPair() : Value(0) {}
  52. PointerIntPair(PointerTy PtrVal, IntType IntVal) {
  53. assert(IntBits <= PtrTraits::NumLowBitsAvailable &&
  54. "PointerIntPair formed with integer size too large for pointer");
  55. setPointerAndInt(PtrVal, IntVal);
  56. }
  57. explicit PointerIntPair(PointerTy PtrVal) {
  58. initWithPointer(PtrVal);
  59. }
  60. PointerTy getPointer() const {
  61. return PtrTraits::getFromVoidPointer(
  62. reinterpret_cast<void*>(Value & PointerBitMask));
  63. }
  64. IntType getInt() const {
  65. return (IntType)((Value >> IntShift) & IntMask);
  66. }
  67. void setPointer(PointerTy PtrVal) {
  68. intptr_t PtrWord
  69. = reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(PtrVal));
  70. assert((PtrWord & ((1 << PtrTraits::NumLowBitsAvailable)-1)) == 0 &&
  71. "Pointer is not sufficiently aligned");
  72. // Preserve all low bits, just update the pointer.
  73. Value = PtrWord | (Value & ~PointerBitMask);
  74. }
  75. void setInt(IntType IntVal) {
  76. intptr_t IntWord = static_cast<intptr_t>(IntVal);
  77. assert(IntWord < (1 << IntBits) && "Integer too large for field");
  78. // Preserve all bits other than the ones we are updating.
  79. Value &= ~ShiftedIntMask; // Remove integer field.
  80. Value |= IntWord << IntShift; // Set new integer.
  81. }
  82. void initWithPointer(PointerTy PtrVal) {
  83. intptr_t PtrWord
  84. = reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(PtrVal));
  85. assert((PtrWord & ((1 << PtrTraits::NumLowBitsAvailable)-1)) == 0 &&
  86. "Pointer is not sufficiently aligned");
  87. Value = PtrWord;
  88. }
  89. void setPointerAndInt(PointerTy PtrVal, IntType IntVal) {
  90. intptr_t PtrWord
  91. = reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(PtrVal));
  92. assert((PtrWord & ((1 << PtrTraits::NumLowBitsAvailable)-1)) == 0 &&
  93. "Pointer is not sufficiently aligned");
  94. intptr_t IntWord = static_cast<intptr_t>(IntVal);
  95. assert(IntWord < (1 << IntBits) && "Integer too large for field");
  96. Value = PtrWord | (IntWord << IntShift);
  97. }
  98. PointerTy const *getAddrOfPointer() const {
  99. return const_cast<PointerIntPair *>(this)->getAddrOfPointer();
  100. }
  101. PointerTy *getAddrOfPointer() {
  102. assert(Value == reinterpret_cast<intptr_t>(getPointer()) &&
  103. "Can only return the address if IntBits is cleared and "
  104. "PtrTraits doesn't change the pointer");
  105. return reinterpret_cast<PointerTy *>(&Value);
  106. }
  107. void *getOpaqueValue() const { return reinterpret_cast<void*>(Value); }
  108. void setFromOpaqueValue(void *Val) { Value = reinterpret_cast<intptr_t>(Val);}
  109. static PointerIntPair getFromOpaqueValue(void *V) {
  110. PointerIntPair P; P.setFromOpaqueValue(V); return P;
  111. }
  112. // Allow PointerIntPairs to be created from const void * if and only if the
  113. // pointer type could be created from a const void *.
  114. static PointerIntPair getFromOpaqueValue(const void *V) {
  115. (void)PtrTraits::getFromVoidPointer(V);
  116. return getFromOpaqueValue(const_cast<void *>(V));
  117. }
  118. bool operator==(const PointerIntPair &RHS) const {return Value == RHS.Value;}
  119. bool operator!=(const PointerIntPair &RHS) const {return Value != RHS.Value;}
  120. bool operator<(const PointerIntPair &RHS) const {return Value < RHS.Value;}
  121. bool operator>(const PointerIntPair &RHS) const {return Value > RHS.Value;}
  122. bool operator<=(const PointerIntPair &RHS) const {return Value <= RHS.Value;}
  123. bool operator>=(const PointerIntPair &RHS) const {return Value >= RHS.Value;}
  124. };
  125. template <typename T> struct isPodLike;
  126. template<typename PointerTy, unsigned IntBits, typename IntType>
  127. struct isPodLike<PointerIntPair<PointerTy, IntBits, IntType> > {
  128. static const bool value = true;
  129. };
  130. // Provide specialization of DenseMapInfo for PointerIntPair.
  131. template<typename PointerTy, unsigned IntBits, typename IntType>
  132. struct DenseMapInfo<PointerIntPair<PointerTy, IntBits, IntType> > {
  133. typedef PointerIntPair<PointerTy, IntBits, IntType> Ty;
  134. static Ty getEmptyKey() {
  135. uintptr_t Val = static_cast<uintptr_t>(-1);
  136. Val <<= PointerLikeTypeTraits<PointerTy>::NumLowBitsAvailable;
  137. return Ty(reinterpret_cast<PointerTy>(Val), IntType((1 << IntBits)-1));
  138. }
  139. static Ty getTombstoneKey() {
  140. uintptr_t Val = static_cast<uintptr_t>(-2);
  141. Val <<= PointerLikeTypeTraits<PointerTy>::NumLowBitsAvailable;
  142. return Ty(reinterpret_cast<PointerTy>(Val), IntType(0));
  143. }
  144. static unsigned getHashValue(Ty V) {
  145. uintptr_t IV = reinterpret_cast<uintptr_t>(V.getOpaqueValue());
  146. return unsigned(IV) ^ unsigned(IV >> 9);
  147. }
  148. static bool isEqual(const Ty &LHS, const Ty &RHS) { return LHS == RHS; }
  149. };
  150. // Teach SmallPtrSet that PointerIntPair is "basically a pointer".
  151. template<typename PointerTy, unsigned IntBits, typename IntType,
  152. typename PtrTraits>
  153. class PointerLikeTypeTraits<PointerIntPair<PointerTy, IntBits, IntType,
  154. PtrTraits> > {
  155. public:
  156. static inline void *
  157. getAsVoidPointer(const PointerIntPair<PointerTy, IntBits, IntType> &P) {
  158. return P.getOpaqueValue();
  159. }
  160. static inline PointerIntPair<PointerTy, IntBits, IntType>
  161. getFromVoidPointer(void *P) {
  162. return PointerIntPair<PointerTy, IntBits, IntType>::getFromOpaqueValue(P);
  163. }
  164. static inline PointerIntPair<PointerTy, IntBits, IntType>
  165. getFromVoidPointer(const void *P) {
  166. return PointerIntPair<PointerTy, IntBits, IntType>::getFromOpaqueValue(P);
  167. }
  168. enum {
  169. NumLowBitsAvailable = PtrTraits::NumLowBitsAvailable - IntBits
  170. };
  171. };
  172. } // end namespace llvm
  173. #endif