a9458bb5a5a16dc12dfc005a23355060c9beea75
[oota-llvm.git] / unittests / ADT / HashingTest.cpp
1 //===- llvm/unittest/ADT/HashingTest.cpp ----------------------------------===//
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 // Hashing.h unit tests.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "gtest/gtest.h"
15 #include "llvm/ADT/Hashing.h"
16 #include "llvm/Support/DataTypes.h"
17 #include <deque>
18 #include <list>
19 #include <map>
20 #include <vector>
21
22 namespace llvm {
23
24 // Helper for test code to print hash codes.
25 void PrintTo(const hash_code &code, std::ostream *os) {
26   *os << static_cast<size_t>(code);
27 }
28
29 // Fake an object that is recognized as hashable data to test super large
30 // objects.
31 struct LargeTestInteger { uint64_t arr[8]; };
32
33 namespace hashing {
34 namespace detail {
35 template <> struct is_hashable_data<LargeTestInteger> : true_type {};
36 } // namespace detail
37 } // namespace hashing
38
39 } // namespace llvm
40
41 using namespace llvm;
42
43 namespace {
44
45 TEST(HashingTest, HashValueBasicTest) {
46   int x = 42, y = 43, c = 'x';
47   void *p = 0;
48   uint64_t i = 71;
49   const unsigned ci = 71;
50   volatile int vi = 71;
51   const volatile int cvi = 71;
52   uintptr_t addr = reinterpret_cast<uintptr_t>(&y);
53   EXPECT_EQ(hash_value(42), hash_value(x));
54   EXPECT_NE(hash_value(42), hash_value(y));
55   EXPECT_NE(hash_value(42), hash_value(p));
56   EXPECT_EQ(hash_value(71), hash_value(i));
57   EXPECT_EQ(hash_value(71), hash_value(ci));
58   EXPECT_EQ(hash_value(71), hash_value(vi));
59   EXPECT_EQ(hash_value(71), hash_value(cvi));
60   EXPECT_EQ(hash_value(c), hash_value('x'));
61   EXPECT_EQ(hash_value('4'), hash_value('0' + 4));
62   EXPECT_EQ(hash_value(addr), hash_value(&y));
63
64   EXPECT_EQ(hash_combine(42, 43), hash_value(std::make_pair(42, 43)));
65   EXPECT_NE(hash_combine(43, 42), hash_value(std::make_pair(42, 43)));
66   EXPECT_NE(hash_combine(42, 43), hash_value(std::make_pair(42ull, 43ull)));
67   EXPECT_NE(hash_combine(42, 43), hash_value(std::make_pair(42, 43ull)));
68   EXPECT_NE(hash_combine(42, 43), hash_value(std::make_pair(42ull, 43)));
69   EXPECT_EQ(hash_combine(42, hash_combine(43, hash_combine(44, 45))),
70             hash_value(
71               std::make_pair(42, std::make_pair(43, std::make_pair(44, 45)))));
72   EXPECT_EQ(hash_combine(42, 43), hash_value(std::make_pair(42, 43)));
73   EXPECT_EQ(hash_combine(42, 43), hash_value(std::make_pair(42, 43)));
74 }
75
76 template <typename T, size_t N> T *begin(T (&arr)[N]) { return arr; }
77 template <typename T, size_t N> T *end(T (&arr)[N]) { return arr + N; }
78
79 // Provide a dummy, hashable type designed for easy verification: its hash is
80 // the same as its value.
81 struct HashableDummy { size_t value; };
82 hash_code hash_value(HashableDummy dummy) { return dummy.value; }
83
84 TEST(HashingTest, HashCombineRangeBasicTest) {
85   // Leave this uninitialized in the hope that valgrind will catch bad reads.
86   int dummy;
87   hash_code dummy_hash = hash_combine_range(&dummy, &dummy);
88   EXPECT_NE(hash_code(0), dummy_hash);
89
90   const int arr1[] = { 1, 2, 3 };
91   hash_code arr1_hash = hash_combine_range(begin(arr1), end(arr1));
92   EXPECT_NE(dummy_hash, arr1_hash);
93   EXPECT_EQ(arr1_hash, hash_combine_range(begin(arr1), end(arr1)));
94
95   const std::vector<int> vec(begin(arr1), end(arr1));
96   EXPECT_EQ(arr1_hash, hash_combine_range(vec.begin(), vec.end()));
97
98   const std::list<int> list(begin(arr1), end(arr1));
99   EXPECT_EQ(arr1_hash, hash_combine_range(list.begin(), list.end()));
100
101   const std::deque<int> deque(begin(arr1), end(arr1));
102   EXPECT_EQ(arr1_hash, hash_combine_range(deque.begin(), deque.end()));
103
104   const int arr2[] = { 3, 2, 1 };
105   hash_code arr2_hash = hash_combine_range(begin(arr2), end(arr2));
106   EXPECT_NE(dummy_hash, arr2_hash);
107   EXPECT_NE(arr1_hash, arr2_hash);
108
109   const int arr3[] = { 1, 1, 2, 3 };
110   hash_code arr3_hash = hash_combine_range(begin(arr3), end(arr3));
111   EXPECT_NE(dummy_hash, arr3_hash);
112   EXPECT_NE(arr1_hash, arr3_hash);
113
114   const int arr4[] = { 1, 2, 3, 3 };
115   hash_code arr4_hash = hash_combine_range(begin(arr4), end(arr4));
116   EXPECT_NE(dummy_hash, arr4_hash);
117   EXPECT_NE(arr1_hash, arr4_hash);
118
119   const size_t arr5[] = { 1, 2, 3 };
120   const HashableDummy d_arr5[] = { {1}, {2}, {3} };
121   hash_code arr5_hash = hash_combine_range(begin(arr5), end(arr5));
122   hash_code d_arr5_hash = hash_combine_range(begin(d_arr5), end(d_arr5));
123   EXPECT_EQ(arr5_hash, d_arr5_hash);
124 }
125
126 TEST(HashingTest, HashCombineRangeLengthDiff) {
127   // Test that as only the length varies, we compute different hash codes for
128   // sequences.
129   std::map<size_t, size_t> code_to_size;
130   std::vector<char> all_one_c(256, '\xff');
131   for (unsigned Idx = 1, Size = all_one_c.size(); Idx < Size; ++Idx) {
132     hash_code code = hash_combine_range(&all_one_c[0], &all_one_c[0] + Idx);
133     std::map<size_t, size_t>::iterator
134       I = code_to_size.insert(std::make_pair(code, Idx)).first;
135     EXPECT_EQ(Idx, I->second);
136   }
137   code_to_size.clear();
138   std::vector<char> all_zero_c(256, '\0');
139   for (unsigned Idx = 1, Size = all_zero_c.size(); Idx < Size; ++Idx) {
140     hash_code code = hash_combine_range(&all_zero_c[0], &all_zero_c[0] + Idx);
141     std::map<size_t, size_t>::iterator
142       I = code_to_size.insert(std::make_pair(code, Idx)).first;
143     EXPECT_EQ(Idx, I->second);
144   }
145   code_to_size.clear();
146   std::vector<unsigned> all_one_int(512, -1);
147   for (unsigned Idx = 1, Size = all_one_int.size(); Idx < Size; ++Idx) {
148     hash_code code = hash_combine_range(&all_one_int[0], &all_one_int[0] + Idx);
149     std::map<size_t, size_t>::iterator
150       I = code_to_size.insert(std::make_pair(code, Idx)).first;
151     EXPECT_EQ(Idx, I->second);
152   }
153   code_to_size.clear();
154   std::vector<unsigned> all_zero_int(512, 0);
155   for (unsigned Idx = 1, Size = all_zero_int.size(); Idx < Size; ++Idx) {
156     hash_code code = hash_combine_range(&all_zero_int[0], &all_zero_int[0] + Idx);
157     std::map<size_t, size_t>::iterator
158       I = code_to_size.insert(std::make_pair(code, Idx)).first;
159     EXPECT_EQ(Idx, I->second);
160   }
161 }
162
163 TEST(HashingTest, HashCombineRangeGoldenTest) {
164   struct { const char *s; uint64_t hash; } golden_data[] = {
165 #if SIZE_MAX == UINT64_MAX
166     { "a",                                0xaeb6f9d5517c61f8ULL },
167     { "ab",                               0x7ab1edb96be496b4ULL },
168     { "abc",                              0xe38e60bf19c71a3fULL },
169     { "abcde",                            0xd24461a66de97f6eULL },
170     { "abcdefgh",                         0x4ef872ec411dec9dULL },
171     { "abcdefghijklm",                    0xe8a865539f4eadfeULL },
172     { "abcdefghijklmnopqrstu",            0x261cdf85faaf4e79ULL },
173     { "abcdefghijklmnopqrstuvwxyzabcdef", 0x43ba70e4198e3b2aULL },
174     { "abcdefghijklmnopqrstuvwxyzabcdef"
175       "abcdefghijklmnopqrstuvwxyzghijkl"
176       "abcdefghijklmnopqrstuvwxyzmnopqr"
177       "abcdefghijklmnopqrstuvwxyzstuvwx"
178       "abcdefghijklmnopqrstuvwxyzyzabcd", 0xdcd57fb2afdf72beULL },
179     { "a",                                0xaeb6f9d5517c61f8ULL },
180     { "aa",                               0xf2b3b69a9736a1ebULL },
181     { "aaa",                              0xf752eb6f07b1cafeULL },
182     { "aaaaa",                            0x812bd21e1236954cULL },
183     { "aaaaaaaa",                         0xff07a2cff08ac587ULL },
184     { "aaaaaaaaaaaaa",                    0x84ac949d54d704ecULL },
185     { "aaaaaaaaaaaaaaaaaaaaa",            0xcb2c8fb6be8f5648ULL },
186     { "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 0xcc40ab7f164091b6ULL },
187     { "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
188       "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
189       "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
190       "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
191       "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 0xc58e174c1e78ffe9ULL },
192     { "z",                                0x1ba160d7e8f8785cULL },
193     { "zz",                               0x2c5c03172f1285d7ULL },
194     { "zzz",                              0x9d2c4f4b507a2ac3ULL },
195     { "zzzzz",                            0x0f03b9031735693aULL },
196     { "zzzzzzzz",                         0xe674147c8582c08eULL },
197     { "zzzzzzzzzzzzz",                    0x3162d9fa6938db83ULL },
198     { "zzzzzzzzzzzzzzzzzzzzz",            0x37b9a549e013620cULL },
199     { "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz", 0x8921470aff885016ULL },
200     { "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
201       "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
202       "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
203       "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
204       "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz", 0xf60fdcd9beb08441ULL },
205     { "a",                                0xaeb6f9d5517c61f8ULL },
206     { "ab",                               0x7ab1edb96be496b4ULL },
207     { "aba",                              0x3edb049950884d0aULL },
208     { "ababa",                            0x8f2de9e73a97714bULL },
209     { "abababab",                         0xee14a29ddf0ce54cULL },
210     { "ababababababa",                    0x38b3ddaada2d52b4ULL },
211     { "ababababababababababa",            0xd3665364219f2b85ULL },
212     { "abababababababababababababababab"
213       "abababababababababababababababab"
214       "abababababababababababababababab"
215       "abababababababababababababababab"
216       "abababababababababababababababab", 0x840192d129f7a22bULL }
217 #elif SIZE_MAX == UINT32_MAX
218  { "a",                                0x000000004605f745ULL },
219  { "ab",                               0x00000000d5f06301ULL },
220  { "abc",                              0x00000000559fe1eeULL },
221  { "abcde",                            0x00000000424028d7ULL },
222  { "abcdefgh",                         0x000000007bb119f8ULL },
223  { "abcdefghijklm",                    0x00000000edbca513ULL },
224  { "abcdefghijklmnopqrstu",            0x000000007c15712eULL },
225  { "abcdefghijklmnopqrstuvwxyzabcdef", 0x000000000b3aad66ULL },
226  { "abcdefghijklmnopqrstuvwxyzabcdef"
227    "abcdefghijklmnopqrstuvwxyzghijkl"
228    "abcdefghijklmnopqrstuvwxyzmnopqr"
229    "abcdefghijklmnopqrstuvwxyzstuvwx"
230    "abcdefghijklmnopqrstuvwxyzyzabcd", 0x000000008c758c8bULL },
231  { "a",                                0x000000004605f745ULL },
232  { "aa",                               0x00000000dc0a52daULL },
233  { "aaa",                              0x00000000b309274fULL },
234  { "aaaaa",                            0x00000000203b5ef6ULL },
235  { "aaaaaaaa",                         0x00000000a429e18fULL },
236  { "aaaaaaaaaaaaa",                    0x000000008662070bULL },
237  { "aaaaaaaaaaaaaaaaaaaaa",            0x000000003f11151cULL },
238  { "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 0x000000008600fe20ULL },
239  { "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
240    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
241    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
242    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
243    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 0x000000004e0e0804ULL },
244  { "z",                                0x00000000c5e405e9ULL },
245  { "zz",                               0x00000000a8d8a2c6ULL },
246  { "zzz",                              0x00000000fc2af672ULL },
247  { "zzzzz",                            0x0000000047d9efe6ULL },
248  { "zzzzzzzz",                         0x0000000080d77794ULL },
249  { "zzzzzzzzzzzzz",                    0x00000000405f93adULL },
250  { "zzzzzzzzzzzzzzzzzzzzz",            0x00000000fc72838dULL },
251  { "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz", 0x000000007ce160f1ULL },
252  { "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
253    "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
254    "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
255    "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
256    "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz", 0x00000000aed9ed1bULL },
257  { "a",                                0x000000004605f745ULL },
258  { "ab",                               0x00000000d5f06301ULL },
259  { "aba",                              0x00000000a85cd91bULL },
260  { "ababa",                            0x000000009e3bb52eULL },
261  { "abababab",                         0x000000002709b3b9ULL },
262  { "ababababababa",                    0x000000003a234174ULL },
263  { "ababababababababababa",            0x000000005c63e5ceULL },
264  { "abababababababababababababababab", 0x0000000013f74334ULL },
265  { "abababababababababababababababab"
266    "abababababababababababababababab"
267    "abababababababababababababababab"
268    "abababababababababababababababab"
269    "abababababababababababababababab", 0x00000000c1a6f135ULL },
270 #else
271 #error This test only supports 64-bit and 32-bit systems.
272 #endif
273   };
274   for (unsigned i = 0; i < sizeof(golden_data)/sizeof(*golden_data); ++i) {
275     StringRef str = golden_data[i].s;
276     hash_code hash = hash_combine_range(str.begin(), str.end());
277 #if 0 // Enable this to generate paste-able text for the above structure.
278     std::string member_str = "\"" + str.str() + "\",";
279     fprintf(stderr, " { %-35s 0x%016llxULL },\n",
280             member_str.c_str(), static_cast<uint64_t>(hash));
281 #endif
282     EXPECT_EQ(static_cast<size_t>(golden_data[i].hash),
283               static_cast<size_t>(hash));
284   }
285 }
286
287 TEST(HashingTest, HashCombineBasicTest) {
288   // Hashing a sequence of homogenous types matches range hashing.
289   const int i1 = 42, i2 = 43, i3 = 123, i4 = 999, i5 = 0, i6 = 79;
290   const int arr1[] = { i1, i2, i3, i4, i5, i6 };
291   EXPECT_EQ(hash_combine_range(arr1, arr1 + 1), hash_combine(i1));
292   EXPECT_EQ(hash_combine_range(arr1, arr1 + 2), hash_combine(i1, i2));
293   EXPECT_EQ(hash_combine_range(arr1, arr1 + 3), hash_combine(i1, i2, i3));
294   EXPECT_EQ(hash_combine_range(arr1, arr1 + 4), hash_combine(i1, i2, i3, i4));
295   EXPECT_EQ(hash_combine_range(arr1, arr1 + 5),
296             hash_combine(i1, i2, i3, i4, i5));
297   EXPECT_EQ(hash_combine_range(arr1, arr1 + 6),
298             hash_combine(i1, i2, i3, i4, i5, i6));
299
300   // Hashing a sequence of heterogenous types which *happen* to all produce the
301   // same data for hashing produces the same as a range-based hash of the
302   // fundamental values.
303   const size_t s1 = 1024, s2 = 8888, s3 = 9000000;
304   const HashableDummy d1 = { 1024 }, d2 = { 8888 }, d3 = { 9000000 };
305   const size_t arr2[] = { s1, s2, s3 };
306   EXPECT_EQ(hash_combine_range(begin(arr2), end(arr2)),
307             hash_combine(s1, s2, s3));
308   EXPECT_EQ(hash_combine(s1, s2, s3), hash_combine(s1, s2, d3));
309   EXPECT_EQ(hash_combine(s1, s2, s3), hash_combine(s1, d2, s3));
310   EXPECT_EQ(hash_combine(s1, s2, s3), hash_combine(d1, s2, s3));
311   EXPECT_EQ(hash_combine(s1, s2, s3), hash_combine(d1, d2, s3));
312   EXPECT_EQ(hash_combine(s1, s2, s3), hash_combine(d1, d2, d3));
313
314   // Permuting values causes hashes to change.
315   EXPECT_NE(hash_combine(i1, i1, i1), hash_combine(i1, i1, i2));
316   EXPECT_NE(hash_combine(i1, i1, i1), hash_combine(i1, i2, i1));
317   EXPECT_NE(hash_combine(i1, i1, i1), hash_combine(i2, i1, i1));
318   EXPECT_NE(hash_combine(i1, i1, i1), hash_combine(i2, i2, i1));
319   EXPECT_NE(hash_combine(i1, i1, i1), hash_combine(i2, i2, i2));
320   EXPECT_NE(hash_combine(i2, i1, i1), hash_combine(i1, i1, i2));
321   EXPECT_NE(hash_combine(i1, i1, i2), hash_combine(i1, i2, i1));
322   EXPECT_NE(hash_combine(i1, i2, i1), hash_combine(i2, i1, i1));
323
324   // Changing type w/o changing value causes hashes to change.
325   EXPECT_NE(hash_combine(i1, i2, i3), hash_combine((char)i1, i2, i3));
326   EXPECT_NE(hash_combine(i1, i2, i3), hash_combine(i1, (char)i2, i3));
327   EXPECT_NE(hash_combine(i1, i2, i3), hash_combine(i1, i2, (char)i3));
328
329   // This is array of uint64, but it should have the exact same byte pattern as
330   // an array of LargeTestIntegers.
331   const uint64_t bigarr[] = {
332     0xaaaaaaaaababababULL, 0xacacacacbcbcbcbcULL, 0xccddeeffeeddccbbULL,
333     0xdeadbeafdeadbeefULL, 0xfefefefededededeULL, 0xafafafafededededULL,
334     0xffffeeeeddddccccULL, 0xaaaacbcbffffababULL,
335     0xaaaaaaaaababababULL, 0xacacacacbcbcbcbcULL, 0xccddeeffeeddccbbULL,
336     0xdeadbeafdeadbeefULL, 0xfefefefededededeULL, 0xafafafafededededULL,
337     0xffffeeeeddddccccULL, 0xaaaacbcbffffababULL,
338     0xaaaaaaaaababababULL, 0xacacacacbcbcbcbcULL, 0xccddeeffeeddccbbULL,
339     0xdeadbeafdeadbeefULL, 0xfefefefededededeULL, 0xafafafafededededULL,
340     0xffffeeeeddddccccULL, 0xaaaacbcbffffababULL
341   };
342   // Hash a preposterously large integer, both aligned with the buffer and
343   // misaligned.
344   const LargeTestInteger li = { {
345     0xaaaaaaaaababababULL, 0xacacacacbcbcbcbcULL, 0xccddeeffeeddccbbULL,
346     0xdeadbeafdeadbeefULL, 0xfefefefededededeULL, 0xafafafafededededULL,
347     0xffffeeeeddddccccULL, 0xaaaacbcbffffababULL
348   } };
349   // Rotate the storage from 'li'.
350   const LargeTestInteger l2 = { {
351     0xacacacacbcbcbcbcULL, 0xccddeeffeeddccbbULL, 0xdeadbeafdeadbeefULL,
352     0xfefefefededededeULL, 0xafafafafededededULL, 0xffffeeeeddddccccULL,
353     0xaaaacbcbffffababULL, 0xaaaaaaaaababababULL
354   } };
355   const LargeTestInteger l3 = { {
356     0xccddeeffeeddccbbULL, 0xdeadbeafdeadbeefULL, 0xfefefefededededeULL,
357     0xafafafafededededULL, 0xffffeeeeddddccccULL, 0xaaaacbcbffffababULL,
358     0xaaaaaaaaababababULL, 0xacacacacbcbcbcbcULL
359   } };
360   EXPECT_EQ(hash_combine_range(begin(bigarr), end(bigarr)),
361             hash_combine(li, li, li));
362   EXPECT_EQ(hash_combine_range(bigarr, bigarr + 9),
363             hash_combine(bigarr[0], l2));
364   EXPECT_EQ(hash_combine_range(bigarr, bigarr + 10),
365             hash_combine(bigarr[0], bigarr[1], l3));
366   EXPECT_EQ(hash_combine_range(bigarr, bigarr + 17),
367             hash_combine(li, bigarr[0], l2));
368   EXPECT_EQ(hash_combine_range(bigarr, bigarr + 18),
369             hash_combine(li, bigarr[0], bigarr[1], l3));
370   EXPECT_EQ(hash_combine_range(bigarr, bigarr + 18),
371             hash_combine(bigarr[0], l2, bigarr[9], l3));
372   EXPECT_EQ(hash_combine_range(bigarr, bigarr + 20),
373             hash_combine(bigarr[0], l2, bigarr[9], l3, bigarr[18], bigarr[19]));
374 }
375
376 }