Skip to content

Commit fb17bbc

Browse files
authored
[DenseMap] Update combineHashValue
`combineHashValue` is a custom bit mixer from 2008 (5fc8ab6) used for std::pair and std::tuple. It has a long dependency chain and slow. Replace it with a simply multiply-xorshift style hash using a constant from splitmix64[1]. abseil-cpp and carbon also use this style, but with uint128 to probably get a lower avalanche bias. We don't use uint128 for MSVC portability. Measured time to compute [0,1000000000) values on an i7-11850H: * old: 1.163s * new: 0.427s [1]: https://jonkagstrom.com/tuning-bit-mixers/index.html Pull Request: #95970
1 parent 58d7a6e commit fb17bbc

File tree

1 file changed

+13
-11
lines changed

1 file changed

+13
-11
lines changed

llvm/include/llvm/ADT/DenseMapInfo.h

+13-11
Original file line numberDiff line numberDiff line change
@@ -23,20 +23,22 @@
2323

2424
namespace llvm {
2525

26+
namespace densemap::detail {
27+
// A bit mixer with very low latency using one multiplications and one
28+
// xor-shift. The constant is from splitmix64.
29+
inline uint64_t mix(uint64_t x) {
30+
x *= 0xbf58476d1ce4e5b9u;
31+
x ^= x >> 31;
32+
return x;
33+
}
34+
} // namespace densemap::detail
35+
2636
namespace detail {
2737

2838
/// 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;
39+
inline unsigned combineHashValue(unsigned a, unsigned b) {
40+
uint64_t x = (uint64_t)a << 32 | (uint64_t)b;
41+
return (unsigned)densemap::detail::mix(x);
4042
}
4143

4244
} // end namespace detail

0 commit comments

Comments
 (0)