Hashing: use 64-bit seed for hashing on all platforms.

get_execution_seed returns a size_t which varies across platforms, but its
users actually always feed it into a uint64_t role so it makes sense to be
consistent.

Mostly this is just a tidy-up, but it also apparently allows PCH files to be
shared between Clang compilers built for 32-bit and 64-bit hosts.

llvm-svn: 341113
This commit is contained in:
Tim Northover 2018-08-30 20:28:32 +00:00
parent f6cac798f3
commit 304cb3c4c6
2 changed files with 9 additions and 10 deletions

View File

@ -133,7 +133,7 @@ hash_code hash_value(const std::basic_string<T> &arg);
/// undone. This makes it thread-hostile and very hard to use outside of /// undone. This makes it thread-hostile and very hard to use outside of
/// immediately on start of a simple program designed for reproducible /// immediately on start of a simple program designed for reproducible
/// behavior. /// behavior.
void set_fixed_execution_hash_seed(size_t fixed_value); void set_fixed_execution_hash_seed(uint64_t fixed_value);
// All of the implementation details of actually computing the various hash // All of the implementation details of actually computing the various hash
@ -316,9 +316,9 @@ struct hash_state {
/// This variable can be set using the \see llvm::set_fixed_execution_seed /// This variable can be set using the \see llvm::set_fixed_execution_seed
/// function. See that function for details. Do not, under any circumstances, /// function. See that function for details. Do not, under any circumstances,
/// set or read this variable. /// set or read this variable.
extern size_t fixed_seed_override; extern uint64_t fixed_seed_override;
inline size_t get_execution_seed() { inline uint64_t get_execution_seed() {
// FIXME: This needs to be a per-execution seed. This is just a placeholder // FIXME: This needs to be a per-execution seed. This is just a placeholder
// implementation. Switching to a per-execution seed is likely to flush out // implementation. Switching to a per-execution seed is likely to flush out
// instability bugs and so will happen as its own commit. // instability bugs and so will happen as its own commit.
@ -326,8 +326,7 @@ inline size_t get_execution_seed() {
// However, if there is a fixed seed override set the first time this is // However, if there is a fixed seed override set the first time this is
// called, return that instead of the per-execution seed. // called, return that instead of the per-execution seed.
const uint64_t seed_prime = 0xff51afd7ed558ccdULL; const uint64_t seed_prime = 0xff51afd7ed558ccdULL;
static size_t seed = fixed_seed_override ? fixed_seed_override static uint64_t seed = fixed_seed_override ? fixed_seed_override : seed_prime;
: (size_t)seed_prime;
return seed; return seed;
} }
@ -402,7 +401,7 @@ bool store_and_advance(char *&buffer_ptr, char *buffer_end, const T& value,
/// combining them, this (as an optimization) directly combines the integers. /// combining them, this (as an optimization) directly combines the integers.
template <typename InputIteratorT> template <typename InputIteratorT>
hash_code hash_combine_range_impl(InputIteratorT first, InputIteratorT last) { hash_code hash_combine_range_impl(InputIteratorT first, InputIteratorT last) {
const size_t seed = get_execution_seed(); const uint64_t seed = get_execution_seed();
char buffer[64], *buffer_ptr = buffer; char buffer[64], *buffer_ptr = buffer;
char *const buffer_end = std::end(buffer); char *const buffer_end = std::end(buffer);
while (first != last && store_and_advance(buffer_ptr, buffer_end, while (first != last && store_and_advance(buffer_ptr, buffer_end,
@ -446,7 +445,7 @@ hash_code hash_combine_range_impl(InputIteratorT first, InputIteratorT last) {
template <typename ValueT> template <typename ValueT>
typename std::enable_if<is_hashable_data<ValueT>::value, hash_code>::type typename std::enable_if<is_hashable_data<ValueT>::value, hash_code>::type
hash_combine_range_impl(ValueT *first, ValueT *last) { hash_combine_range_impl(ValueT *first, ValueT *last) {
const size_t seed = get_execution_seed(); const uint64_t seed = get_execution_seed();
const char *s_begin = reinterpret_cast<const char *>(first); const char *s_begin = reinterpret_cast<const char *>(first);
const char *s_end = reinterpret_cast<const char *>(last); const char *s_end = reinterpret_cast<const char *>(last);
const size_t length = std::distance(s_begin, s_end); const size_t length = std::distance(s_begin, s_end);
@ -496,7 +495,7 @@ namespace detail {
struct hash_combine_recursive_helper { struct hash_combine_recursive_helper {
char buffer[64]; char buffer[64];
hash_state state; hash_state state;
const size_t seed; const uint64_t seed;
public: public:
/// Construct a recursive hash combining helper. /// Construct a recursive hash combining helper.

View File

@ -20,10 +20,10 @@ using namespace llvm;
// Provide a definition and static initializer for the fixed seed. This // Provide a definition and static initializer for the fixed seed. This
// initializer should always be zero to ensure its value can never appear to be // initializer should always be zero to ensure its value can never appear to be
// non-zero, even during dynamic initialization. // non-zero, even during dynamic initialization.
size_t llvm::hashing::detail::fixed_seed_override = 0; uint64_t llvm::hashing::detail::fixed_seed_override = 0;
// Implement the function for forced setting of the fixed seed. // Implement the function for forced setting of the fixed seed.
// FIXME: Use atomic operations here so that there is no data race. // FIXME: Use atomic operations here so that there is no data race.
void llvm::set_fixed_execution_hash_seed(size_t fixed_value) { void llvm::set_fixed_execution_hash_seed(uint64_t fixed_value) {
hashing::detail::fixed_seed_override = fixed_value; hashing::detail::fixed_seed_override = fixed_value;
} }