23
23
24
24
namespace llvm {
25
25
26
+ namespace detail {
27
+
28
+ // / Simplistic combination of 32-bit hash values into 32-bit hash values.
29
+ static inline unsigned combineHashValue (unsigned a, unsigned b) {
30
+ uint64_t key = (uint64_t )a << 32 | (uint64_t )b;
31
+ key += ~(key << 32 );
32
+ key ^= (key >> 22 );
33
+ key += ~(key << 13 );
34
+ key ^= (key >> 8 );
35
+ key += (key << 3 );
36
+ key ^= (key >> 15 );
37
+ key += ~(key << 27 );
38
+ key ^= (key >> 31 );
39
+ return (unsigned )key;
40
+ }
41
+
42
+ } // end namespace detail
43
+
26
44
template <typename T>
27
45
struct DenseMapInfo {
28
46
// static inline T getEmptyKey();
@@ -206,17 +224,8 @@ struct DenseMapInfo<std::pair<T, U>> {
206
224
}
207
225
208
226
static unsigned getHashValue (const Pair& PairVal) {
209
- uint64_t key = (uint64_t )FirstInfo::getHashValue (PairVal.first ) << 32
210
- | (uint64_t )SecondInfo::getHashValue (PairVal.second );
211
- key += ~(key << 32 );
212
- key ^= (key >> 22 );
213
- key += ~(key << 13 );
214
- key ^= (key >> 8 );
215
- key += (key << 3 );
216
- key ^= (key >> 15 );
217
- key += ~(key << 27 );
218
- key ^= (key >> 31 );
219
- return (unsigned )key;
227
+ return detail::combineHashValue (FirstInfo::getHashValue (PairVal.first ),
228
+ SecondInfo::getHashValue (PairVal.second ));
220
229
}
221
230
222
231
static bool isEqual (const Pair &LHS, const Pair &RHS) {
@@ -225,6 +234,56 @@ struct DenseMapInfo<std::pair<T, U>> {
225
234
}
226
235
};
227
236
237
+ // Provide DenseMapInfo for all tuples whose members have info.
238
+ template <typename ... Ts> struct DenseMapInfo <std::tuple<Ts...>> {
239
+ using Tuple = std::tuple<Ts...>;
240
+
241
+ static inline Tuple getEmptyKey () {
242
+ return Tuple (DenseMapInfo<Ts>::getEmptyKey ()...);
243
+ }
244
+
245
+ static inline Tuple getTombstoneKey () {
246
+ return Tuple (DenseMapInfo<Ts>::getTombstoneKey ()...);
247
+ }
248
+
249
+ template <unsigned I>
250
+ static unsigned getHashValueImpl (const Tuple &values, std::false_type) {
251
+ using EltType = typename std::tuple_element<I, Tuple>::type;
252
+ std::integral_constant<bool , I + 1 == sizeof ...(Ts)> atEnd;
253
+ return detail::combineHashValue (
254
+ DenseMapInfo<EltType>::getHashValue (std::get<I>(values)),
255
+ getHashValueImpl<I + 1 >(values, atEnd));
256
+ }
257
+
258
+ template <unsigned I>
259
+ static unsigned getHashValueImpl (const Tuple &values, std::true_type) {
260
+ return 0 ;
261
+ }
262
+
263
+ static unsigned getHashValue (const std::tuple<Ts...> &values) {
264
+ std::integral_constant<bool , 0 == sizeof ...(Ts)> atEnd;
265
+ return getHashValueImpl<0 >(values, atEnd);
266
+ }
267
+
268
+ template <unsigned I>
269
+ static bool isEqualImpl (const Tuple &lhs, const Tuple &rhs, std::false_type) {
270
+ using EltType = typename std::tuple_element<I, Tuple>::type;
271
+ std::integral_constant<bool , I + 1 == sizeof ...(Ts)> atEnd;
272
+ return DenseMapInfo<EltType>::isEqual (std::get<I>(lhs), std::get<I>(rhs)) &&
273
+ isEqualImpl<I + 1 >(lhs, rhs, atEnd);
274
+ }
275
+
276
+ template <unsigned I>
277
+ static bool isEqualImpl (const Tuple &lhs, const Tuple &rhs, std::true_type) {
278
+ return true ;
279
+ }
280
+
281
+ static bool isEqual (const Tuple &lhs, const Tuple &rhs) {
282
+ std::integral_constant<bool , 0 == sizeof ...(Ts)> atEnd;
283
+ return isEqualImpl<0 >(lhs, rhs, atEnd);
284
+ }
285
+ };
286
+
228
287
// Provide DenseMapInfo for StringRefs.
229
288
template <> struct DenseMapInfo <StringRef> {
230
289
static inline StringRef getEmptyKey () {
0 commit comments