[llvm] [ADT] Simplify hash_combine (NFC) (PR #159938)
Kazu Hirata via llvm-commits
llvm-commits at lists.llvm.org
Sat Sep 20 11:18:41 PDT 2025
https://github.com/kazutakahirata created https://github.com/llvm/llvm-project/pull/159938
We just started using a C++17 fold expression inside combine
(#159901). We still carry the style that was suitable for recursive
calls of combine_data. Specifically, we keep passing several state
variables as parameters of combine_data.
Now that we no longer use recursion, this patch simplifies
hash_combine_recursive_helper by making buffer_ptr, buffer_end, and
length member variables while dropping the return value from
hash_combine. This patch also names hash_combine_recursive_helper to
hash_combine_helper.
I will follow up to update comments that still mention "recursion".
>From 3f00e4388dd7625ecc83e5133ebc70029675157c Mon Sep 17 00:00:00 2001
From: Kazu Hirata <kazu at google.com>
Date: Sat, 20 Sep 2025 08:37:52 -0700
Subject: [PATCH] [ADT] Simplify hash_combine (NFC)
We just started using a C++17 fold expression inside combine
(#159901). We still carry the style that was suitable for recursive
calls of combine_data. Specifically, we keep passing several state
variables as parameters of combine_data.
Now that we no longer use recursion, this patch simplifies
hash_combine_recursive_helper by making buffer_ptr, buffer_end, and
length member variables while dropping the return value from
hash_combine. This patch also names hash_combine_recursive_helper to
hash_combine_helper.
I will follow up to update comments that still mention "recursion".
---
llvm/include/llvm/ADT/Hashing.h | 29 +++++++++++++----------------
1 file changed, 13 insertions(+), 16 deletions(-)
diff --git a/llvm/include/llvm/ADT/Hashing.h b/llvm/include/llvm/ADT/Hashing.h
index dffe3791e51c7..31d7be2714a20 100644
--- a/llvm/include/llvm/ADT/Hashing.h
+++ b/llvm/include/llvm/ADT/Hashing.h
@@ -483,8 +483,11 @@ namespace detail {
/// recursive combining of arguments used in hash_combine. It is particularly
/// useful at minimizing the code in the recursive calls to ease the pain
/// caused by a lack of variadic functions.
-struct hash_combine_recursive_helper {
+struct hash_combine_helper {
char buffer[64] = {};
+ char *buffer_ptr;
+ char *const buffer_end;
+ size_t length = 0;
hash_state state;
const uint64_t seed;
@@ -493,8 +496,9 @@ struct hash_combine_recursive_helper {
///
/// This sets up the state for a recursive hash combine, including getting
/// the seed and buffer setup.
- hash_combine_recursive_helper()
- : seed(get_execution_seed()) {}
+ hash_combine_helper()
+ : buffer_ptr(buffer), buffer_end(buffer + 64),
+ seed(get_execution_seed()) {}
/// Combine one chunk of data into the current in-flight hash.
///
@@ -502,9 +506,7 @@ struct hash_combine_recursive_helper {
/// the data. If the buffer is full, it hashes the buffer into its
/// hash_state, empties it, and then merges the new chunk in. This also
/// handles cases where the data straddles the end of the buffer.
- template <typename T>
- char *combine_data(size_t &length, char *&buffer_ptr, char *buffer_end,
- T data) {
+ template <typename T> void combine_data(T data) {
if (!store_and_advance(buffer_ptr, buffer_end, data)) {
// Check for skew which prevents the buffer from being packed, and do
// a partial store into the buffer to fill it. This is only a concern
@@ -535,19 +537,14 @@ struct hash_combine_recursive_helper {
partial_store_size))
llvm_unreachable("buffer smaller than stored type");
}
- return buffer_ptr;
}
/// Recursive, variadic combining method.
///
/// This function recurses through each argument, combining that argument
/// into a single hash.
- template <typename... Ts>
- hash_code combine(size_t length, char *buffer_ptr, char *buffer_end,
- const Ts &...args) {
- ((void)combine_data(length, buffer_ptr, buffer_end,
- get_hashable_data(args)),
- ...);
+ template <typename... Ts> hash_code combine(const Ts &...args) {
+ (combine_data(get_hashable_data(args)), ...);
// Finalize the hash by flushing any remaining data in the buffer.
//
@@ -584,10 +581,10 @@ struct hash_combine_recursive_helper {
/// The result is suitable for returning from a user's hash_value
/// *implementation* for their user-defined type. Consumers of a type should
/// *not* call this routine, they should instead call 'hash_value'.
-template <typename ...Ts> hash_code hash_combine(const Ts &...args) {
+template <typename... Ts> hash_code hash_combine(const Ts &...args) {
// Recursively hash each argument using a helper class.
- ::llvm::hashing::detail::hash_combine_recursive_helper helper;
- return helper.combine(0, helper.buffer, helper.buffer + 64, args...);
+ ::llvm::hashing::detail::hash_combine_helper helper;
+ return helper.combine(args...);
}
// Implementation details for implementations of hash_value overloads provided
More information about the llvm-commits
mailing list