1 //===- llvm/ADT/DenseMapInfo.h - Type traits for DenseMap -------*- 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 DenseMapInfo traits for DenseMap. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_ADT_DENSEMAPINFO_H 15 #define LLVM_ADT_DENSEMAPINFO_H 16 17 #include "llvm/ADT/ArrayRef.h" 18 #include "llvm/ADT/Hashing.h" 19 #include "llvm/ADT/StringRef.h" 20 #include "llvm/Support/PointerLikeTypeTraits.h" 21 #include "llvm/Support/type_traits.h" 22 23 namespace llvm { 24 25 template<typename T> 26 struct DenseMapInfo { 27 //static inline T getEmptyKey(); 28 //static inline T getTombstoneKey(); 29 //static unsigned getHashValue(const T &Val); 30 //static bool isEqual(const T &LHS, const T &RHS); 31 }; 32 33 // Provide DenseMapInfo for all pointers. 34 template<typename T> 35 struct DenseMapInfo<T*> { 36 static inline T* getEmptyKey() { 37 uintptr_t Val = static_cast<uintptr_t>(-1); 38 Val <<= PointerLikeTypeTraits<T*>::NumLowBitsAvailable; 39 return reinterpret_cast<T*>(Val); 40 } 41 static inline T* getTombstoneKey() { 42 uintptr_t Val = static_cast<uintptr_t>(-2); 43 Val <<= PointerLikeTypeTraits<T*>::NumLowBitsAvailable; 44 return reinterpret_cast<T*>(Val); 45 } 46 static unsigned getHashValue(const T *PtrVal) { 47 return (unsigned((uintptr_t)PtrVal) >> 4) ^ 48 (unsigned((uintptr_t)PtrVal) >> 9); 49 } 50 static bool isEqual(const T *LHS, const T *RHS) { return LHS == RHS; } 51 }; 52 53 // Provide DenseMapInfo for chars. 54 template<> struct DenseMapInfo<char> { 55 static inline char getEmptyKey() { return ~0; } 56 static inline char getTombstoneKey() { return ~0 - 1; } 57 static unsigned getHashValue(const char& Val) { return Val * 37U; } 58 static bool isEqual(const char &LHS, const char &RHS) { 59 return LHS == RHS; 60 } 61 }; 62 63 // Provide DenseMapInfo for unsigned ints. 64 template<> struct DenseMapInfo<unsigned> { 65 static inline unsigned getEmptyKey() { return ~0U; } 66 static inline unsigned getTombstoneKey() { return ~0U - 1; } 67 static unsigned getHashValue(const unsigned& Val) { return Val * 37U; } 68 static bool isEqual(const unsigned& LHS, const unsigned& RHS) { 69 return LHS == RHS; 70 } 71 }; 72 73 // Provide DenseMapInfo for unsigned longs. 74 template<> struct DenseMapInfo<unsigned long> { 75 static inline unsigned long getEmptyKey() { return ~0UL; } 76 static inline unsigned long getTombstoneKey() { return ~0UL - 1L; } 77 static unsigned getHashValue(const unsigned long& Val) { 78 return (unsigned)(Val * 37UL); 79 } 80 static bool isEqual(const unsigned long& LHS, const unsigned long& RHS) { 81 return LHS == RHS; 82 } 83 }; 84 85 // Provide DenseMapInfo for unsigned long longs. 86 template<> struct DenseMapInfo<unsigned long long> { 87 static inline unsigned long long getEmptyKey() { return ~0ULL; } 88 static inline unsigned long long getTombstoneKey() { return ~0ULL - 1ULL; } 89 static unsigned getHashValue(const unsigned long long& Val) { 90 return (unsigned)(Val * 37ULL); 91 } 92 static bool isEqual(const unsigned long long& LHS, 93 const unsigned long long& RHS) { 94 return LHS == RHS; 95 } 96 }; 97 98 // Provide DenseMapInfo for ints. 99 template<> struct DenseMapInfo<int> { 100 static inline int getEmptyKey() { return 0x7fffffff; } 101 static inline int getTombstoneKey() { return -0x7fffffff - 1; } 102 static unsigned getHashValue(const int& Val) { return (unsigned)(Val * 37U); } 103 static bool isEqual(const int& LHS, const int& RHS) { 104 return LHS == RHS; 105 } 106 }; 107 108 // Provide DenseMapInfo for longs. 109 template<> struct DenseMapInfo<long> { 110 static inline long getEmptyKey() { 111 return (1UL << (sizeof(long) * 8 - 1)) - 1UL; 112 } 113 static inline long getTombstoneKey() { return getEmptyKey() - 1L; } 114 static unsigned getHashValue(const long& Val) { 115 return (unsigned)(Val * 37UL); 116 } 117 static bool isEqual(const long& LHS, const long& RHS) { 118 return LHS == RHS; 119 } 120 }; 121 122 // Provide DenseMapInfo for long longs. 123 template<> struct DenseMapInfo<long long> { 124 static inline long long getEmptyKey() { return 0x7fffffffffffffffLL; } 125 static inline long long getTombstoneKey() { return -0x7fffffffffffffffLL-1; } 126 static unsigned getHashValue(const long long& Val) { 127 return (unsigned)(Val * 37ULL); 128 } 129 static bool isEqual(const long long& LHS, 130 const long long& RHS) { 131 return LHS == RHS; 132 } 133 }; 134 135 // Provide DenseMapInfo for all pairs whose members have info. 136 template<typename T, typename U> 137 struct DenseMapInfo<std::pair<T, U> > { 138 typedef std::pair<T, U> Pair; 139 typedef DenseMapInfo<T> FirstInfo; 140 typedef DenseMapInfo<U> SecondInfo; 141 142 static inline Pair getEmptyKey() { 143 return std::make_pair(FirstInfo::getEmptyKey(), 144 SecondInfo::getEmptyKey()); 145 } 146 static inline Pair getTombstoneKey() { 147 return std::make_pair(FirstInfo::getTombstoneKey(), 148 SecondInfo::getTombstoneKey()); 149 } 150 static unsigned getHashValue(const Pair& PairVal) { 151 uint64_t key = (uint64_t)FirstInfo::getHashValue(PairVal.first) << 32 152 | (uint64_t)SecondInfo::getHashValue(PairVal.second); 153 key += ~(key << 32); 154 key ^= (key >> 22); 155 key += ~(key << 13); 156 key ^= (key >> 8); 157 key += (key << 3); 158 key ^= (key >> 15); 159 key += ~(key << 27); 160 key ^= (key >> 31); 161 return (unsigned)key; 162 } 163 static bool isEqual(const Pair &LHS, const Pair &RHS) { 164 return FirstInfo::isEqual(LHS.first, RHS.first) && 165 SecondInfo::isEqual(LHS.second, RHS.second); 166 } 167 }; 168 169 // Provide DenseMapInfo for StringRefs. 170 template <> struct DenseMapInfo<StringRef> { 171 static inline StringRef getEmptyKey() { 172 return StringRef(reinterpret_cast<const char *>(~static_cast<uintptr_t>(0)), 173 0); 174 } 175 static inline StringRef getTombstoneKey() { 176 return StringRef(reinterpret_cast<const char *>(~static_cast<uintptr_t>(1)), 177 0); 178 } 179 static unsigned getHashValue(StringRef Val) { 180 assert(Val.data() != getEmptyKey().data() && "Cannot hash the empty key!"); 181 assert(Val.data() != getTombstoneKey().data() && 182 "Cannot hash the tombstone key!"); 183 return (unsigned)(hash_value(Val)); 184 } 185 static bool isEqual(StringRef LHS, StringRef RHS) { 186 if (RHS.data() == getEmptyKey().data()) 187 return LHS.data() == getEmptyKey().data(); 188 if (RHS.data() == getTombstoneKey().data()) 189 return LHS.data() == getTombstoneKey().data(); 190 return LHS == RHS; 191 } 192 }; 193 194 // Provide DenseMapInfo for ArrayRefs. 195 template <typename T> struct DenseMapInfo<ArrayRef<T>> { 196 static inline ArrayRef<T> getEmptyKey() { 197 return ArrayRef<T>(reinterpret_cast<const T *>(~static_cast<uintptr_t>(0)), 198 size_t(0)); 199 } 200 static inline ArrayRef<T> getTombstoneKey() { 201 return ArrayRef<T>(reinterpret_cast<const T *>(~static_cast<uintptr_t>(1)), 202 size_t(0)); 203 } 204 static unsigned getHashValue(ArrayRef<T> Val) { 205 assert(Val.data() != getEmptyKey().data() && "Cannot hash the empty key!"); 206 assert(Val.data() != getTombstoneKey().data() && 207 "Cannot hash the tombstone key!"); 208 return (unsigned)(hash_value(Val)); 209 } 210 static bool isEqual(ArrayRef<T> LHS, ArrayRef<T> RHS) { 211 if (RHS.data() == getEmptyKey().data()) 212 return LHS.data() == getEmptyKey().data(); 213 if (RHS.data() == getTombstoneKey().data()) 214 return LHS.data() == getTombstoneKey().data(); 215 return LHS == RHS; 216 } 217 }; 218 219 } // end namespace llvm 220 221 #endif 222