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

Chandler Carruth chandlerc at gmail.com
Fri Mar 2 02:56:41 PST 2012


Author: chandlerc
Date: Fri Mar  2 04:56:40 2012
New Revision: 151891

URL: http://llvm.org/viewvc/llvm-project?rev=151891&view=rev
Log:
Simplify the pair optimization. Rather than using complex type traits,
just ensure that the number of bytes in the pair is the sum of the bytes
in each side of the pair. As long as thats true, there are no extra
bytes that might be padding.

Also add a few tests that previously would have slipped through the
checking. The more accurate checking mechanism catches these and ensures
they are handled conservatively correctly.

Thanks to Duncan for prodding me to do this right and more simply.

Modified:
    llvm/trunk/include/llvm/ADT/Hashing.h
    llvm/trunk/include/llvm/Support/type_traits.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=151891&r1=151890&r2=151891&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ADT/Hashing.h (original)
+++ llvm/trunk/include/llvm/ADT/Hashing.h Fri Mar  2 04:56:40 2012
@@ -357,8 +357,8 @@
 template <typename T, typename U> struct is_hashable_data<std::pair<T, U> >
   : integral_constant<bool, (is_hashable_data<T>::value &&
                              is_hashable_data<U>::value &&
-                             !is_alignment_padded<std::pair<T, U> >::value &&
-                             !is_pod_pair_padded<T, U>::value)> {};
+                             (sizeof(T) + sizeof(U)) ==
+                              sizeof(std::pair<T, U>))> {};
 
 /// \brief Helper to get the hashable data representation for a type.
 /// This variant is enabled when the type itself can be used.

Modified: llvm/trunk/include/llvm/Support/type_traits.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/type_traits.h?rev=151891&r1=151890&r2=151891&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/type_traits.h (original)
+++ llvm/trunk/include/llvm/Support/type_traits.h Fri Mar  2 04:56:40 2012
@@ -126,24 +126,6 @@
 template <typename T> struct is_pointer : false_type {};
 template <typename T> struct is_pointer<T*> : true_type {};
 
-/// \brief Metafunction to compute whether a type requires alignment padding.
-/// When true, an object of this type will have padding bytes inside its
-/// 'sizeof' bytes.
-template <typename T> class is_alignment_padded {
-  struct pod_size_tester { T t; char c; };
-public:
-  enum { value = offsetof(pod_size_tester, c) != sizeof(T) };
-};
-
-/// \brief Metafunction to determine whether an adjacent pair of two types will
-/// require padding between them due to alignment.
-template <typename T, typename U> class is_pod_pair_padded {
-  struct pod_pair { T t; U u; };
-  struct pod_char_pair { T t; char c; };
-public:
-  enum { value = offsetof(pod_pair, u) != offsetof(pod_char_pair, c) };
-};
-
   
 // enable_if_c - Enable/disable a template based on a metafunction
 template<bool Cond, typename T = void>

Modified: llvm/trunk/unittests/ADT/HashingTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/HashingTest.cpp?rev=151891&r1=151890&r2=151891&view=diff
==============================================================================
--- llvm/trunk/unittests/ADT/HashingTest.cpp (original)
+++ llvm/trunk/unittests/ADT/HashingTest.cpp Fri Mar  2 04:56:40 2012
@@ -42,6 +42,16 @@
 
 namespace {
 
+struct NonPOD {
+  uint64_t x, y;
+  NonPOD(uint64_t x, uint64_t y) : x(x), y(y) {}
+  ~NonPOD() {}
+  friend hash_code hash_value(const NonPOD &obj) {
+    return hash_combine(obj.x, obj.y);
+  }
+};
+
+
 TEST(HashingTest, HashValueBasicTest) {
   int x = 42, y = 43, c = 'x';
   void *p = 0;
@@ -73,6 +83,16 @@
             hash_value(std::make_pair(42, std::make_pair(43, 44))));
   EXPECT_EQ(hash_value(std::make_pair(42, std::make_pair(43, 44))),
             hash_value(std::make_pair(std::make_pair(42, 43), 44)));
+
+  // Ensure that pairs which have padding bytes *inside* them don't get treated
+  // this way.
+  EXPECT_EQ(hash_combine('0', hash_combine(1ull, '2')),
+            hash_value(std::make_pair('0', std::make_pair(1ull, '2'))));
+
+  // Ensure that non-POD pairs don't explode the traits used.
+  NonPOD obj1(1, 2), obj2(3, 4), obj3(5, 6);
+  EXPECT_EQ(hash_combine(obj1, hash_combine(obj2, obj3)),
+            hash_value(std::make_pair(obj1, std::make_pair(obj2, obj3))));
 }
 
 template <typename T, size_t N> T *begin(T (&arr)[N]) { return arr; }





More information about the llvm-commits mailing list