aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--Eigen/Core36
-rw-r--r--Eigen/src/Core/util/Macros.h45
-rw-r--r--Eigen/src/Core/util/Memory.h8
-rw-r--r--Eigen/src/Core/util/XprHelper.h27
-rw-r--r--doc/D11_UnalignedArrayAssert.dox7
-rw-r--r--test/dynalloc.cpp2
-rw-r--r--test/unalignedassert.cpp6
7 files changed, 78 insertions, 53 deletions
diff --git a/Eigen/Core b/Eigen/Core
index 075f95e5a..ce27d10b0 100644
--- a/Eigen/Core
+++ b/Eigen/Core
@@ -29,6 +29,26 @@
// first thing Eigen does: prevent MSVC from committing suicide
#include "src/Core/util/DisableMSVCWarnings.h"
+// then include this file where all our macros are defined. It's really important to do it first because
+// it's where we do all the alignment settings (platform detection and honoring the user's will if he
+// defined e.g. EIGEN_DONT_ALIGN) so it needs to be done before we do anything with vectorization.
+#include "src/Core/util/Macros.h"
+
+// if alignment is disabled, then disable vectorization. Note: EIGEN_ALIGN is the proper check, it takes into
+// account both the user's will (EIGEN_DONT_ALIGN) and our own platform checks
+#if !EIGEN_ALIGN
+ #ifndef EIGEN_DONT_VECTORIZE
+ #define EIGEN_DONT_VECTORIZE
+ #endif
+#endif
+
+// disable vectorization on LLVM: it's not yet ready for that.
+#ifdef __clang__
+ #ifndef EIGEN_DONT_VECTORIZE
+ #define EIGEN_DONT_VECTORIZE
+ #endif
+#endif
+
#ifdef _MSC_VER
#include <malloc.h> // for _aligned_malloc -- need it regardless of whether vectorization is enabled
#if (_MSC_VER >= 1500) // 2008 or later
@@ -40,26 +60,13 @@
#endif
#endif
-#ifdef __GNUC__
- #define EIGEN_GNUC_AT_LEAST(x,y) ((__GNUC__>=x && __GNUC_MINOR__>=y) || __GNUC__>x)
-#else
- #define EIGEN_GNUC_AT_LEAST(x,y) 0
-#endif
-
// Remember that usage of defined() in a #define is undefined by the standard
#if (defined __SSE2__) && ( (!defined __GNUC__) || EIGEN_GNUC_AT_LEAST(4,2) )
#define EIGEN_SSE2_BUT_NOT_OLD_GCC
#endif
-#ifdef EIGEN_DONT_ALIGN
- #define EIGEN_DONT_VECTORIZE
-#endif
-
-#ifdef __clang__
-#define EIGEN_DONT_VECTORIZE
-#endif
-
#ifndef EIGEN_DONT_VECTORIZE
+
#if defined (EIGEN_SSE2_BUT_NOT_OLD_GCC) || defined(EIGEN_SSE2_ON_MSVC_2008_OR_LATER)
// Defines symbols for compile-time detection of which instructions are
@@ -201,7 +208,6 @@ using std::size_t;
/** The type used to identify a dense storage. */
struct Dense {};
-#include "src/Core/util/Macros.h"
#include "src/Core/util/Constants.h"
#include "src/Core/util/ForwardDeclarations.h"
#include "src/Core/util/Meta.h"
diff --git a/Eigen/src/Core/util/Macros.h b/Eigen/src/Core/util/Macros.h
index 7236b42f2..df4ee5b35 100644
--- a/Eigen/src/Core/util/Macros.h
+++ b/Eigen/src/Core/util/Macros.h
@@ -35,6 +35,17 @@
#define EIGEN_VERSION_AT_LEAST(x,y,z) (EIGEN_WORLD_VERSION>x || (EIGEN_WORLD_VERSION>=x && \
(EIGEN_MAJOR_VERSION>y || (EIGEN_MAJOR_VERSION>=y && \
EIGEN_MINOR_VERSION>=z))))
+#ifdef __GNUC__
+ #define EIGEN_GNUC_AT_LEAST(x,y) ((__GNUC__>=x && __GNUC_MINOR__>=y) || __GNUC__>x)
+#else
+ #define EIGEN_GNUC_AT_LEAST(x,y) 0
+#endif
+
+#if defined(__GNUC__) && (__GNUC__ <= 3)
+#define EIGEN_GCC3_OR_OLDER 1
+#else
+#define EIGEN_GCC3_OR_OLDER 0
+#endif
// 16 byte alignment is only useful for vectorization. Since it affects the ABI, we need to enable
// 16 byte alignment on all platforms where vectorization might be enabled. In theory we could always
@@ -49,12 +60,6 @@
#define EIGEN_GCC_AND_ARCH_DOESNT_WANT_STACK_ALIGNMENT 0
#endif
-#if defined(__GNUC__) && (__GNUC__ <= 3)
-#define EIGEN_GCC3_OR_OLDER 1
-#else
-#define EIGEN_GCC3_OR_OLDER 0
-#endif
-
// FIXME vectorization + stack alignment is completely disabled with sun studio
#if !EIGEN_GCC_AND_ARCH_DOESNT_WANT_STACK_ALIGNMENT && !EIGEN_GCC3_OR_OLDER && !defined(__SUNPRO_CC)
#define EIGEN_ARCH_WANTS_STACK_ALIGNMENT 1
@@ -63,20 +68,20 @@
#endif
#ifdef EIGEN_DONT_ALIGN
- #ifndef EIGEN_DONT_ALIGN_STACK
- #define EIGEN_DONT_ALIGN_STACK
- #endif
- #ifndef EIGEN_DONT_ALIGN_HEAP
- #define EIGEN_DONT_ALIGN_HEAP
+ #ifndef EIGEN_DONT_ALIGN_STATICALLY
+ #define EIGEN_DONT_ALIGN_STATICALLY
#endif
+ #define EIGEN_ALIGN 0
+#else
+ #define EIGEN_ALIGN 1
#endif
-// EIGEN_ALIGN_STACK is the true test whether we want to align arrays on the stack or not. It takes into account both the user choice to explicitly disable
-// alignment (EIGEN_DONT_ALIGN_STACK) and the architecture config (EIGEN_ARCH_WANTS_STACK_ALIGNMENT). Henceforth, only EIGEN_ALIGN_STACK should be used.
-#if EIGEN_ARCH_WANTS_STACK_ALIGNMENT && !defined(EIGEN_DONT_ALIGN_STACK)
- #define EIGEN_ALIGN_STACK 1
+// EIGEN_ALIGN_STATICALLY is the true test whether we want to align arrays on the stack or not. It takes into account both the user choice to explicitly disable
+// alignment (EIGEN_DONT_ALIGN_STATICALLY) and the architecture config (EIGEN_ARCH_WANTS_STACK_ALIGNMENT). Henceforth, only EIGEN_ALIGN_STATICALLY should be used.
+#if EIGEN_ARCH_WANTS_STACK_ALIGNMENT && !defined(EIGEN_DONT_ALIGN_STATICALLY)
+ #define EIGEN_ALIGN_STATICALLY 1
#else
- #define EIGEN_ALIGN_STACK 0
+ #define EIGEN_ALIGN_STATICALLY 0
#ifdef EIGEN_VECTORIZE
#error "Vectorization enabled, but our platform checks say that we don't do 16 byte stack alignment on this platform. If you added vectorization for another architecture, you also need to edit this platform check."
#endif
@@ -85,12 +90,6 @@
#endif
#endif
-#ifndef EIGEN_DONT_ALIGN_HEAP
- #define EIGEN_ALIGN_HEAP 1
-#else
- #define EIGEN_ALIGN_HEAP 0
-#endif
-
#ifdef EIGEN_DEFAULT_TO_ROW_MAJOR
#define EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION RowMajor
#else
@@ -204,7 +203,7 @@ using Eigen::ei_cos;
* If we made alignment depend on whether or not EIGEN_VECTORIZE is defined, it would be impossible to link
* vectorized and non-vectorized code.
*/
-#if !EIGEN_ALIGN_STACK
+#if !EIGEN_ALIGN_STATICALLY
#define EIGEN_ALIGN_TO_BOUNDARY(n)
#elif (defined __GNUC__) || (defined __PGI)
#define EIGEN_ALIGN_TO_BOUNDARY(n) __attribute__((aligned(n)))
diff --git a/Eigen/src/Core/util/Memory.h b/Eigen/src/Core/util/Memory.h
index 9442dffb6..aa0073d44 100644
--- a/Eigen/src/Core/util/Memory.h
+++ b/Eigen/src/Core/util/Memory.h
@@ -172,7 +172,7 @@ inline void* ei_aligned_malloc(size_t size)
#endif
void *result;
- #if !EIGEN_ALIGN_HEAP
+ #if !EIGEN_ALIGN
result = std::malloc(size);
#elif EIGEN_MALLOC_ALREADY_ALIGNED
result = std::malloc(size);
@@ -196,7 +196,7 @@ inline void* ei_aligned_malloc(size_t size)
/** \internal Frees memory allocated with ei_aligned_malloc. */
inline void ei_aligned_free(void *ptr)
{
- #if !EIGEN_ALIGN_HEAP
+ #if !EIGEN_ALIGN
std::free(ptr);
#elif EIGEN_MALLOC_ALREADY_ALIGNED
std::free(ptr);
@@ -221,7 +221,7 @@ inline void* ei_aligned_realloc(void *ptr, size_t new_size, size_t old_size)
(void)old_size; // Suppress 'unused variable' warning. Seen in boost tee.
void *result;
-#if !EIGEN_ALIGN_HEAP
+#if !EIGEN_ALIGN
result = std::realloc(ptr,new_size);
#elif EIGEN_MALLOC_ALREADY_ALIGNED
result = std::realloc(ptr,new_size);
@@ -443,7 +443,7 @@ inline static Integer ei_first_aligned(const Scalar* array, Integer size)
*** Implementation of EIGEN_MAKE_ALIGNED_OPERATOR_NEW [_IF] ***
*****************************************************************************/
-#if EIGEN_ALIGN_HEAP
+#if EIGEN_ALIGN
#ifdef EIGEN_EXCEPTIONS
#define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_NOTHROW(NeedsToAlign) \
void* operator new(size_t size, const std::nothrow_t&) throw() { \
diff --git a/Eigen/src/Core/util/XprHelper.h b/Eigen/src/Core/util/XprHelper.h
index b4f72b62c..4259ebb92 100644
--- a/Eigen/src/Core/util/XprHelper.h
+++ b/Eigen/src/Core/util/XprHelper.h
@@ -88,21 +88,38 @@ class ei_compute_matrix_flags
enum {
row_major_bit = Options&RowMajor ? RowMajorBit : 0,
is_dynamic_size_storage = MaxRows==Dynamic || MaxCols==Dynamic,
-#if EIGEN_ALIGN_STACK
+#if EIGEN_ALIGN_STATICALLY
is_fixed_size_aligned
= (!is_dynamic_size_storage) && (((MaxCols*MaxRows) % ei_packet_traits<Scalar>::size) == 0),
#else
is_fixed_size_aligned = 0,
#endif
-#if EIGEN_ALIGN_HEAP
+#if EIGEN_ALIGN
is_dynamic_size_aligned = is_dynamic_size_storage,
#else
is_dynamic_size_aligned = 0,
#endif
- aligned_bit = (((Options&DontAlign)==0)
- && (is_dynamic_size_aligned || is_fixed_size_aligned))
- ? AlignedBit : 0,
+ aligned_bit =
+ (
+ ((Options&DontAlign)==0)
+ && (
+#if EIGEN_ALIGN_STATICALLY
+ ((!is_dynamic_size_storage) && (((MaxCols*MaxRows) % ei_packet_traits<Scalar>::size) == 0))
+#else
+ 0
+#endif
+
+ ||
+
+#if EIGEN_ALIGN
+ is_dynamic_size_storage
+#else
+ 0
+#endif
+
+ )
+ ) ? AlignedBit : 0,
packet_access_bit = ei_packet_traits<Scalar>::size > 1 && aligned_bit ? PacketAccessBit : 0
};
diff --git a/doc/D11_UnalignedArrayAssert.dox b/doc/D11_UnalignedArrayAssert.dox
index e9fb2a69f..23ab3a94d 100644
--- a/doc/D11_UnalignedArrayAssert.dox
+++ b/doc/D11_UnalignedArrayAssert.dox
@@ -107,8 +107,11 @@ However there are a few corner cases where these alignment settings get overridd
Two possibilities:
<ul>
- <li>Define EIGEN_DONT_ALIGN. That disables all 128-bit alignment code, and in particular everything vectorization-related. But do note that this in particular breaks ABI compatibility with vectorized code.</li>
- <li>Or define both EIGEN_DONT_VECTORIZE and EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT. This keeps the 128-bit alignment code and thus preserves ABI compatibility.</li>
+ <li>Define EIGEN_DONT_ALIGN_STATICALLY. That disables all 128-bit static alignment code, while keeping 128-bit heap alignment. This has the effect of
+ disabling vectorization for fixed-size objects (like Matrix4d) while keeping vectorization of dynamic-size objects
+ (like MatrixXd). But do note that this breaks ABI compatibility with the default behavior of 128-bit static alignment.</li>
+ <li>Or define both EIGEN_DONT_VECTORIZE and EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT. This keeps the
+ 128-bit alignment code and thus preserves ABI compatibility, but completely disables vectorization.</li>
</ul>
For more information, see <a href="http://eigen.tuxfamily.org/index.php?title=FAQ#I_disabled_vectorization.2C_but_I.27m_still_getting_annoyed_about_alignment_issues.21">this FAQ</a>.
diff --git a/test/dynalloc.cpp b/test/dynalloc.cpp
index 85a39ec83..e0a9f9f86 100644
--- a/test/dynalloc.cpp
+++ b/test/dynalloc.cpp
@@ -24,7 +24,7 @@
#include "main.h"
-#if EIGEN_ALIGN_HEAP
+#if EIGEN_ALIGN
#define ALIGNMENT 16
#else
#define ALIGNMENT 1
diff --git a/test/unalignedassert.cpp b/test/unalignedassert.cpp
index 497c5a5aa..5782ab20e 100644
--- a/test/unalignedassert.cpp
+++ b/test/unalignedassert.cpp
@@ -78,7 +78,7 @@ void check_unalignedassert_good()
delete[] y;
}
-#if EIGEN_ALIGN_STACK
+#if EIGEN_ALIGN_STATICALLY
template<typename T>
void construct_at_boundary(int boundary)
{
@@ -94,7 +94,7 @@ void construct_at_boundary(int boundary)
void unalignedassert()
{
- #if EIGEN_ALIGN_STACK
+ #if EIGEN_ALIGN_STATICALLY
construct_at_boundary<Vector2f>(4);
construct_at_boundary<Vector3f>(4);
construct_at_boundary<Vector4f>(16);
@@ -124,7 +124,7 @@ void unalignedassert()
check_unalignedassert_good<TestNew6>();
check_unalignedassert_good<Depends<true> >();
-#if EIGEN_ALIGN_STACK
+#if EIGEN_ALIGN_STATICALLY
VERIFY_RAISES_ASSERT(construct_at_boundary<Vector4f>(8));
VERIFY_RAISES_ASSERT(construct_at_boundary<Matrix4f>(8));
VERIFY_RAISES_ASSERT(construct_at_boundary<Vector2d>(8));