aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChuanqi Xu <yedeng.yd@linux.alibaba.com>2024-06-20 09:58:12 +0800
committerGitHub <noreply@github.com>2024-06-20 09:58:12 +0800
commitad79a14c9e5ec4a369eed4adf567c22cc029863f (patch)
tree63152ca88e9faf8274c3661af0f66b323a334f06
parent57778ec36c9c7e96b76a167f19dccbe00d49c9d4 (diff)
downloadllvm-ad79a14c9e5ec4a369eed4adf567c22cc029863f.zip
llvm-ad79a14c9e5ec4a369eed4adf567c22cc029863f.tar.gz
llvm-ad79a14c9e5ec4a369eed4adf567c22cc029863f.tar.bz2
[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.
-rw-r--r--llvm/include/llvm/ADT/DenseMapInfo.h7
1 files changed, 5 insertions, 2 deletions
diff --git a/llvm/include/llvm/ADT/DenseMapInfo.h b/llvm/include/llvm/ADT/DenseMapInfo.h
index 7e1525a..4f0aaa1 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,