[llvm-commits] [llvm] r151865 - in /llvm/trunk: include/llvm/ADT/Hashing.h unittests/ADT/HashingTest.cpp

Chandler Carruth chandlerc at gmail.com
Thu Mar 1 16:48:38 PST 2012


Author: chandlerc
Date: Thu Mar  1 18:48:38 2012
New Revision: 151865

URL: http://llvm.org/viewvc/llvm-project?rev=151865&view=rev
Log:
Remove the misguided extension here that reserved two special values in
the hash_code. I'm not sure what I was thinking here, the use cases for
special values are in the *keys*, not in the hashes of those keys.

We can always resurrect this if needed, or clients can accomplish the
same goal themselves. This makes the general case somewhat faster (~5
cycles faster on my machine) and smaller with less branching.

Modified:
    llvm/trunk/include/llvm/ADT/Hashing.h
    llvm/trunk/unittests/ADT/HashingTest.cpp

Modified: llvm/trunk/include/llvm/ADT/Hashing.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/Hashing.h?rev=151865&r1=151864&r2=151865&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ADT/Hashing.h (original)
+++ llvm/trunk/include/llvm/ADT/Hashing.h Thu Mar  1 18:48:38 2012
@@ -82,35 +82,16 @@
   size_t value;
 
 public:
-  /// \brief Default construct a hash_code. Constructs a null code.
-  hash_code() : value() {}
+  /// \brief Default construct a hash_code.
+  /// Note that this leaves the value uninitialized.
+  hash_code() {}
 
   /// \brief Form a hash code directly from a numerical value.
-  hash_code(size_t value) : value(value) {
-    // Ensure we don't form a hash_code with one of the prohibited values.
-    assert(value != get_null_code().value);
-    assert(value != get_invalid_code().value);
-  }
+  hash_code(size_t value) : value(value) {}
 
   /// \brief Convert the hash code to its numerical value for use.
   /*explicit*/ operator size_t() const { return value; }
 
-  /// \brief Get a hash_code object which corresponds to a null code.
-  ///
-  /// The null code must never be the result of any 'hash_value' calls and can
-  /// be used to detect an unset hash_code.
-  static hash_code get_null_code() { return hash_code(); }
-
-  /// \brief Get a hash_code object which corresponds to an invalid code.
-  ///
-  /// The invalid code must never be the result of any 'hash_value' calls. This
-  /// can be used to flag invalid hash_codes or mark entries in a hash table.
-  static hash_code get_invalid_code() {
-    hash_code invalid_code;
-    invalid_code.value = static_cast<size_t>(-1);
-    return invalid_code;
-  }
-
   friend bool operator==(const hash_code &lhs, const hash_code &rhs) {
     return lhs.value == rhs.value;
   }
@@ -223,27 +204,18 @@
 }
 
 inline uint64_t hash_short(const char *s, size_t length, uint64_t seed) {
-  uint64_t hash;
   if (length >= 4 && length <= 8)
-    hash = hash_4to8_bytes(s, length, seed);
-  else if (length > 8 && length <= 16)
-    hash = hash_9to16_bytes(s, length, seed);
-  else if (length > 16 && length <= 32)
-    hash = hash_17to32_bytes(s, length, seed);
-  else if (length > 32)
-    hash = hash_33to64_bytes(s, length, seed);
-  else if (length != 0)
-    hash = hash_1to3_bytes(s, length, seed);
-  else
-    return k2 ^ seed;
-
-  // FIXME: The invalid hash_code check is really expensive; there should be
-  // a better way of ensuring these invariants hold.
-  if (hash == static_cast<uint64_t>(hash_code::get_null_code()))
-    hash = k1 ^ seed;
-  else if (hash == static_cast<uint64_t>(hash_code::get_invalid_code()))
-    hash = k3 ^ seed;
-  return hash;
+    return hash_4to8_bytes(s, length, seed);
+  if (length > 8 && length <= 16)
+    return hash_9to16_bytes(s, length, seed);
+  if (length > 16 && length <= 32)
+    return hash_17to32_bytes(s, length, seed);
+  if (length > 32)
+    return hash_33to64_bytes(s, length, seed);
+  if (length != 0)
+    return hash_1to3_bytes(s, length, seed);
+
+  return k2 ^ seed;
 }
 
 /// \brief The intermediate state used during hashing.
@@ -299,14 +271,8 @@
   /// \brief Compute the final 64-bit hash code value based on the current
   /// state and the length of bytes hashed.
   uint64_t finalize(size_t length) {
-    uint64_t final_value
-      = hash_16_bytes(hash_16_bytes(h3, h5) + shift_mix(h1) * k1 + h2,
-                      hash_16_bytes(h4, h6) + shift_mix(length) * k1 + h0);
-    if (final_value == static_cast<uint64_t>(hash_code::get_null_code()))
-      final_value = k1 ^ seed;
-    if (final_value == static_cast<uint64_t>(hash_code::get_invalid_code()))
-      final_value = k3 ^ seed;
-    return final_value;
+    return hash_16_bytes(hash_16_bytes(h3, h5) + shift_mix(h1) * k1 + h2,
+                         hash_16_bytes(h4, h6) + shift_mix(length) * k1 + h0);
   }
 };
 

Modified: llvm/trunk/unittests/ADT/HashingTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/HashingTest.cpp?rev=151865&r1=151864&r2=151865&view=diff
==============================================================================
--- llvm/trunk/unittests/ADT/HashingTest.cpp (original)
+++ llvm/trunk/unittests/ADT/HashingTest.cpp Thu Mar  1 18:48:38 2012
@@ -53,7 +53,6 @@
   EXPECT_EQ(hash_value(42), hash_value(x));
   EXPECT_NE(hash_value(42), hash_value(y));
   EXPECT_NE(hash_value(42), hash_value(p));
-  EXPECT_NE(hash_code::get_null_code(), hash_value(p));
   EXPECT_EQ(hash_value(71), hash_value(i));
   EXPECT_EQ(hash_value(71), hash_value(ci));
   EXPECT_EQ(hash_value(71), hash_value(vi));
@@ -75,13 +74,10 @@
   // Leave this uninitialized in the hope that valgrind will catch bad reads.
   int dummy;
   hash_code dummy_hash = hash_combine_range(&dummy, &dummy);
-  EXPECT_NE(hash_code::get_null_code(), dummy_hash);
-  EXPECT_NE(hash_code::get_invalid_code(), dummy_hash);
+  EXPECT_NE(hash_code(0), dummy_hash);
 
   const int arr1[] = { 1, 2, 3 };
   hash_code arr1_hash = hash_combine_range(begin(arr1), end(arr1));
-  EXPECT_NE(hash_code::get_null_code(), arr1_hash);
-  EXPECT_NE(hash_code::get_invalid_code(), arr1_hash);
   EXPECT_NE(dummy_hash, arr1_hash);
   EXPECT_EQ(arr1_hash, hash_combine_range(begin(arr1), end(arr1)));
 
@@ -96,22 +92,16 @@
 
   const int arr2[] = { 3, 2, 1 };
   hash_code arr2_hash = hash_combine_range(begin(arr2), end(arr2));
-  EXPECT_NE(hash_code::get_null_code(), arr2_hash);
-  EXPECT_NE(hash_code::get_invalid_code(), arr2_hash);
   EXPECT_NE(dummy_hash, arr2_hash);
   EXPECT_NE(arr1_hash, arr2_hash);
 
   const int arr3[] = { 1, 1, 2, 3 };
   hash_code arr3_hash = hash_combine_range(begin(arr3), end(arr3));
-  EXPECT_NE(hash_code::get_null_code(), arr3_hash);
-  EXPECT_NE(hash_code::get_invalid_code(), arr3_hash);
   EXPECT_NE(dummy_hash, arr3_hash);
   EXPECT_NE(arr1_hash, arr3_hash);
 
   const int arr4[] = { 1, 2, 3, 3 };
   hash_code arr4_hash = hash_combine_range(begin(arr4), end(arr4));
-  EXPECT_NE(hash_code::get_null_code(), arr4_hash);
-  EXPECT_NE(hash_code::get_invalid_code(), arr4_hash);
   EXPECT_NE(dummy_hash, arr4_hash);
   EXPECT_NE(arr1_hash, arr4_hash);
 





More information about the llvm-commits mailing list