[llvm] 5466211 - Revert "[ADT] Use a C++17 fold expression in hash_combine (NFC) (#159901)"

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Sun Sep 21 01:14:51 PDT 2025


Author: Nikita Popov
Date: 2025-09-21T10:01:17+02:00
New Revision: 54662112676976b57fdb67a806d4d471be0d4aa9

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

LOG: Revert "[ADT] Use a C++17 fold expression in hash_combine (NFC) (#159901)"

This has a negative impact on compile times.

This reverts commit a36a1ec0546c59917c7b40a8733b1d3f8b5df8f3.
This reverts commit b3c7d25422355949227a12ded7515f5114db5bda.

Added: 
    

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

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/ADT/Hashing.h b/llvm/include/llvm/ADT/Hashing.h
index 31d7be2714a20..41a730e24a6b1 100644
--- a/llvm/include/llvm/ADT/Hashing.h
+++ b/llvm/include/llvm/ADT/Hashing.h
@@ -483,11 +483,8 @@ 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_helper {
+struct hash_combine_recursive_helper {
   char buffer[64] = {};
-  char *buffer_ptr;
-  char *const buffer_end;
-  size_t length = 0;
   hash_state state;
   const uint64_t seed;
 
@@ -496,9 +493,8 @@ struct hash_combine_helper {
   ///
   /// This sets up the state for a recursive hash combine, including getting
   /// the seed and buffer setup.
-  hash_combine_helper()
-      : buffer_ptr(buffer), buffer_end(buffer + 64),
-        seed(get_execution_seed()) {}
+  hash_combine_recursive_helper()
+    : seed(get_execution_seed()) {}
 
   /// Combine one chunk of data into the current in-flight hash.
   ///
@@ -506,7 +502,8 @@ struct hash_combine_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> void combine_data(T data) {
+  template <typename T>
+  char *combine_data(size_t &length, char *buffer_ptr, char *buffer_end, 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
@@ -537,17 +534,28 @@ struct hash_combine_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(const Ts &...args) {
-    (combine_data(get_hashable_data(args)), ...);
+  template <typename T, typename ...Ts>
+  hash_code combine(size_t length, char *buffer_ptr, char *buffer_end,
+                    const T &arg, const Ts &...args) {
+    buffer_ptr = combine_data(length, buffer_ptr, buffer_end, get_hashable_data(arg));
 
-    // Finalize the hash by flushing any remaining data in the buffer.
-    //
+    // Recurse to the next argument.
+    return combine(length, buffer_ptr, buffer_end, args...);
+  }
+
+  /// Base case for recursive, variadic combining.
+  ///
+  /// The base case when combining arguments recursively is reached when all
+  /// arguments have been handled. It flushes the remaining buffer and
+  /// constructs a hash_code.
+  hash_code combine(size_t length, char *buffer_ptr, char *buffer_end) {
     // Check whether the entire set of values fit in the buffer. If so, we'll
     // use the optimized short hashing routine and skip state entirely.
     if (length == 0)
@@ -581,10 +589,10 @@ struct hash_combine_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_helper helper;
-  return helper.combine(args...);
+  ::llvm::hashing::detail::hash_combine_recursive_helper helper;
+  return helper.combine(0, helper.buffer, helper.buffer + 64, args...);
 }
 
 // Implementation details for implementations of hash_value overloads provided


        


More information about the llvm-commits mailing list