Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 13 additions & 16 deletions llvm/include/llvm/ADT/Hashing.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -493,18 +496,17 @@ 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.
///
/// This merges one chunk of data into the hash. First it tries to buffer
/// 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
Expand Down Expand Up @@ -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.
//
Expand Down Expand Up @@ -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
Expand Down