diff --git a/Eigen/src/Core/Coeffs.h b/Eigen/src/Core/Coeffs.h index 2618f0dce..eda36b7bb 100644 --- a/Eigen/src/Core/Coeffs.h +++ b/Eigen/src/Core/Coeffs.h @@ -379,6 +379,38 @@ EIGEN_STRONG_INLINE void MatrixBase::copyPacket(int index, const Matrix other.derived().template packet(index)); } + +template +struct ei_alignmentOffset_impl +{ + inline static Integer run(const MatrixBase&, Integer) + { return 0; } +}; + +template +struct ei_alignmentOffset_impl +{ + inline static Integer run(const MatrixBase& m, Integer maxOffset) + { + return ei_alignmentOffset(&m.const_cast_derived().coeffRef(0,0), maxOffset); + } +}; + +/** \internal \returns the number of elements which have to be skipped, starting + * from the address of coeffRef(0,0), to find the first 16-byte aligned element. + * + * \note If the expression doesn't have the DirectAccessBit, this function returns 0. + * + * There is also the variant ei_alignmentOffset(const Scalar*, Integer) defined in Memory.h. + */ +template +inline static Integer ei_alignmentOffset(const MatrixBase& m, Integer maxOffset) +{ + return ei_alignmentOffset_impl + ::run(m, maxOffset); +} + #endif #endif // EIGEN_COEFFS_H diff --git a/Eigen/src/Core/Redux.h b/Eigen/src/Core/Redux.h index 171f6dcf5..ae6b01f57 100644 --- a/Eigen/src/Core/Redux.h +++ b/Eigen/src/Core/Redux.h @@ -209,10 +209,7 @@ struct ei_redux_impl { const int size = mat.size(); const int packetSize = ei_packet_traits::size; - const int alignedStart = (Derived::Flags & AlignedBit) - || !(Derived::Flags & DirectAccessBit) - ? 0 - : ei_alignmentOffset(&mat.const_cast_derived().coeffRef(0), size); + const int alignedStart = ei_alignmentOffset(mat,size); enum { alignment = (Derived::Flags & DirectAccessBit) || (Derived::Flags & AlignedBit) ? Aligned : Unaligned diff --git a/Eigen/src/Core/util/Memory.h b/Eigen/src/Core/util/Memory.h index ebeb55ddd..524bec2fc 100644 --- a/Eigen/src/Core/util/Memory.h +++ b/Eigen/src/Core/util/Memory.h @@ -209,7 +209,11 @@ template inline void ei_conditional_aligned_delete(T *pt ei_conditional_aligned_free(ptr); } -/** \internal \returns the number of elements which have to be skipped such that data are 16 bytes aligned */ +/** \internal \returns the number of elements which have to be skipped to + * find the first 16-byte aligned element + * + * There is also the variant ei_alignmentOffset(const MatrixBase&, Integer) defined in Coeffs.h. + */ template inline static Integer ei_alignmentOffset(const Scalar* ptr, Integer maxOffset) {