[llvm-commits] [PATCH] [Support][Endian] Add support for specifying the alignment and native unaligned types.

Michael Spencer bigcheesegs at gmail.com
Tue Dec 11 14:39:53 PST 2012



================
Comment at: include/llvm/Support/Endian.h:25
@@ -26,1 +24,3 @@
+enum endianness {big, little, native};
+enum {aligned = -1, unaligned = 1};
 
----------------
Richard Smith wrote:
> In C++11 [dcl.align]p2, the value 0 to alignas means "use the native alignment". It would seem reasonable to replicate that here. It would also be nice to document that these values are actually used as alignments, not just as opaque enumerators.
Ah interesting. Didn't know about that. Will do.

================
Comment at: include/llvm/Support/Endian.h:34-68
@@ -37,12 +33,37 @@
 
-// Provides unaligned loads and stores.
-#pragma pack(push)
-#pragma pack(1)
-template<typename value_type>
-struct alignment_access_helper<value_type, unaligned>
-{
-  value_type val;
+// We can't use AlignedCharArrayImpl here because it is larger than
+// the size of the alignment. It also doesn't provide an aligned Storage member.
+#if defined(_MSC_VER)
+# define LLVM_ALIGNED_DEF(a) template<> struct __declspec(align(a)) aligned<a>{}
+  template<int alignment> struct aligned;
+  LLVM_ALIGNED_DEF(1);
+  LLVM_ALIGNED_DEF(2);
+  LLVM_ALIGNED_DEF(4);
+  LLVM_ALIGNED_DEF(8);
+  LLVM_ALIGNED_DEF(16);
+  LLVM_ALIGNED_DEF(32);
+  LLVM_ALIGNED_DEF(64);
+# undef LLVM_ALIGNED_DEF
+
+template<typename value_type, int alignment>
+struct AlignmentHelper
+  : detail::aligned<detail::align<value_type, alignment>::value> {
+  uint8_t Storage[sizeof(value_type)];
 };
-#pragma pack(pop)
 
+#elif __has_feature(cxx_alignas)
+template<typename value_type, int alignment>
+struct AlignmentHelper {
+  uint8_t alignas(detail::align<value_type, alignment>::value)
+    Storage[sizeof(value_type)];
+};
+#elif defined(__GNUC__) || defined(__IBM_ATTRIBUTES)
+template<typename value_type, int alignment>
+struct AlignmentHelper {
+  uint8_t __attribute__((aligned(detail::align<value_type, alignment>::value)))
+    Storage[sizeof(value_type)];
+};
+#else
+# error "No supported alignment directive."
+#endif
 } // end namespace detail
----------------
Richard Smith wrote:
> I don't like duplicating this. Is there some way we can extend or reimplement AlignedCharArrayImpl so that we can use the same code for both cases? Since you're using a memcpy anyway, is this actually necessasry?
We may be able to. The problem with AlignedCharArrayImpl is that since the storage member has alignment 1, the compiler will generate unaligned loads and stores for read and write. The other problem is that AlignedCharArrayImpl is used in cases where it needs to be passed as an argument, and MSVC __declspec(align(N)) can't do that, so it has hacks for handling the MSVC case that require making the type larger. There may be a way around this though.


http://llvm-reviews.chandlerc.com/D200



More information about the llvm-commits mailing list