[llvm] fb17bbc - [DenseMap] Update combineHashValue

via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 19 10:30:18 PDT 2024


Author: Fangrui Song
Date: 2024-06-19T10:30:13-07:00
New Revision: fb17bbce80cf76ce1a31eff463f451f626bc36b5

URL: https://github.com/llvm/llvm-project/commit/fb17bbce80cf76ce1a31eff463f451f626bc36b5
DIFF: https://github.com/llvm/llvm-project/commit/fb17bbce80cf76ce1a31eff463f451f626bc36b5.diff

LOG: [DenseMap] Update combineHashValue

`combineHashValue` is a custom bit mixer from 2008
(5fc8ab6d187aefbf1d2cbd36e191e675b14db8f6) 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: https://github.com/llvm/llvm-project/pull/95970

Added: 
    

Modified: 
    llvm/include/llvm/ADT/DenseMapInfo.h

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/ADT/DenseMapInfo.h b/llvm/include/llvm/ADT/DenseMapInfo.h
index c405f7446d5a9..7e1525ac41c3a 100644
--- a/llvm/include/llvm/ADT/DenseMapInfo.h
+++ b/llvm/include/llvm/ADT/DenseMapInfo.h
@@ -23,20 +23,22 @@
 
 namespace llvm {
 
+namespace densemap::detail {
+// A bit mixer with very low latency using one multiplications and one
+// xor-shift. The constant is from splitmix64.
+inline uint64_t mix(uint64_t x) {
+  x *= 0xbf58476d1ce4e5b9u;
+  x ^= x >> 31;
+  return x;
+}
+} // namespace densemap::detail
+
 namespace detail {
 
 /// Simplistic combination of 32-bit hash values into 32-bit hash values.
-static inline unsigned combineHashValue(unsigned a, unsigned b) {
-  uint64_t key = (uint64_t)a << 32 | (uint64_t)b;
-  key += ~(key << 32);
-  key ^= (key >> 22);
-  key += ~(key << 13);
-  key ^= (key >> 8);
-  key += (key << 3);
-  key ^= (key >> 15);
-  key += ~(key << 27);
-  key ^= (key >> 31);
-  return (unsigned)key;
+inline unsigned combineHashValue(unsigned a, unsigned b) {
+  uint64_t x = (uint64_t)a << 32 | (uint64_t)b;
+  return (unsigned)densemap::detail::mix(x);
 }
 
 } // end namespace detail


        


More information about the llvm-commits mailing list