[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