[llvm] ad79a14 - [ADT] Update hash function of uint64_t for DenseMap (#95734)

via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 19 18:58:15 PDT 2024


Author: Chuanqi Xu
Date: 2024-06-20T09:58:12+08:00
New Revision: ad79a14c9e5ec4a369eed4adf567c22cc029863f

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

LOG: [ADT] Update hash function of uint64_t for DenseMap (#95734)

(Background: See the comment:
https://github.com/llvm/llvm-project/pull/92083#issuecomment-2168121729)

It looks like the hash function for 64bits integers are not very good:

```
  static unsigned getHashValue(const unsigned long long& Val) {
    return (unsigned)(Val * 37ULL);
  }
```

Since the result is truncated to 32 bits. It looks like the higher 32
bits won't contribute to the result. So that `0x1'00000001` will have
the the same results to `0x2'00000001`, `0x3'00000001`, ...

Then we may meet a lot collisions in such cases. I feel it should
generally good to include higher 32 bits for hashing functions.

Not sure who's the appropriate reviewer, adding some people by
impressions.

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 7e1525ac41c3a..4f0aaa1ad48bb 100644
--- a/llvm/include/llvm/ADT/DenseMapInfo.h
+++ b/llvm/include/llvm/ADT/DenseMapInfo.h
@@ -139,7 +139,10 @@ template<> struct DenseMapInfo<unsigned long> {
   static inline unsigned long getTombstoneKey() { return ~0UL - 1L; }
 
   static unsigned getHashValue(const unsigned long& Val) {
-    return (unsigned)(Val * 37UL);
+    if constexpr (sizeof(Val) == 4)
+      return DenseMapInfo<unsigned>::getHashValue(Val);
+    else
+      return detail::combineHashValue(Val >> 32, Val);
   }
 
   static bool isEqual(const unsigned long& LHS, const unsigned long& RHS) {
@@ -153,7 +156,7 @@ template<> struct DenseMapInfo<unsigned long long> {
   static inline unsigned long long getTombstoneKey() { return ~0ULL - 1ULL; }
 
   static unsigned getHashValue(const unsigned long long& Val) {
-    return (unsigned)(Val * 37ULL);
+    return detail::combineHashValue(Val >> 32, Val);
   }
 
   static bool isEqual(const unsigned long long& LHS,


        


More information about the llvm-commits mailing list