From 9eb8958fc2177f4cdbb16827c705f3f359f594ed Mon Sep 17 00:00:00 2001 From: Kazu Hirata Date: Sun, 14 Sep 2025 22:22:45 -0700 Subject: [PATCH 1/2] [ADT] Use a C++17 fold expression in hash_combine (NFC) combine() combines hash values with recursion on variadic parameters. This patch replaces the recursion with a C++17 fold expression: (combine_data(length, buffer_ptr, buffer_end, get_hashable_data(args)), ...); which expands to: combine_data(length, buffer_ptr, buffer_end, get_hashable_data(a)); combine_data(length, buffer_ptr, buffer_end, get_hashable_data(b)); combine_data(length, buffer_ptr, buffer_end, get_hashable_data(c)); : A key benefit of this change is the unification of the recursive step and the base case. The argument processing and finalization logic now exist as straight-line code within a single function. combine_data now takes buffer_ptr by reference. This is necessary because the previous assignment pattern: buffer_ptr = combine_data(...) is syntactically incompatible with a fold expression. The new pattern: (combine_data(...), ...) discards return values, so combine_data must update buffer_ptr directly. For readability, this patch does the bare minimum to use a fold expression, leaving further cleanups to subsequent patches. For example, buffer_ptr and buffer_end could become member variables, and several comments that mention recursion still need updating. --- llvm/include/llvm/ADT/Hashing.h | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/llvm/include/llvm/ADT/Hashing.h b/llvm/include/llvm/ADT/Hashing.h index 41a730e24a6b1..ffe231249a5c2 100644 --- a/llvm/include/llvm/ADT/Hashing.h +++ b/llvm/include/llvm/ADT/Hashing.h @@ -503,7 +503,8 @@ struct hash_combine_recursive_helper { /// 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 - char *combine_data(size_t &length, char *buffer_ptr, char *buffer_end, T data) { + 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 @@ -541,21 +542,14 @@ struct hash_combine_recursive_helper { /// /// This function recurses through each argument, combining that argument /// into a single hash. - template + template 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)); + const Ts &...args) { + (combine_data(length, buffer_ptr, buffer_end, get_hashable_data(args)), + ...); - // 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) { + // Finalize the hash by flushing any remaining data in the buffer. + // // 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) From 527ced122470e689035fcaa53deebd1aae589785 Mon Sep 17 00:00:00 2001 From: Kazu Hirata Date: Sat, 20 Sep 2025 08:13:33 -0700 Subject: [PATCH 2/2] Address a comment. --- llvm/include/llvm/ADT/Hashing.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/llvm/include/llvm/ADT/Hashing.h b/llvm/include/llvm/ADT/Hashing.h index ffe231249a5c2..dffe3791e51c7 100644 --- a/llvm/include/llvm/ADT/Hashing.h +++ b/llvm/include/llvm/ADT/Hashing.h @@ -545,7 +545,8 @@ struct hash_combine_recursive_helper { template hash_code combine(size_t length, char *buffer_ptr, char *buffer_end, const Ts &...args) { - (combine_data(length, buffer_ptr, buffer_end, get_hashable_data(args)), + ((void)combine_data(length, buffer_ptr, buffer_end, + get_hashable_data(args)), ...); // Finalize the hash by flushing any remaining data in the buffer.