From ebb300d0b4340104dcade3afa656a57da2b7660c Mon Sep 17 00:00:00 2001 From: Antonio Sanchez Date: Sun, 23 May 2021 12:35:38 -0700 Subject: Modify Unary/Binary/TernaryOp evaluators to work for non-class types. This used to work for non-class types (e.g. raw function pointers) in Eigen 3.3. This was changed in commit 11f55b29 to optimize the evaluator: > `sizeof((A-B).cwiseAbs2())` with A,B Vector4f is now 16 bytes, instead of 48 before this optimization. though I cannot reproduce the 16 byte result. Both before the change and after, with multiple compilers/versions, I always get a result of 40 bytes. https://godbolt.org/z/MsjTc1PGe This change modifies the code slightly to allow non-class types. The final generated code is identical, and the expression remains 40 bytes for the `abs2` sample case. Fixes #2251 --- Eigen/src/Core/CoreEvaluators.h | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/Eigen/src/Core/CoreEvaluators.h b/Eigen/src/Core/CoreEvaluators.h index 90c552f13..66e030b1c 100644 --- a/Eigen/src/Core/CoreEvaluators.h +++ b/Eigen/src/Core/CoreEvaluators.h @@ -606,13 +606,13 @@ struct unary_evaluator, IndexBased > protected: // this helper permits to completely eliminate the functor if it is empty - class Data : private UnaryOp + struct Data { - public: EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE - Data(const XprType& xpr) : UnaryOp(xpr.functor()), argImpl(xpr.nestedExpression()) {} + Data(const XprType& xpr) : op(xpr.functor()), argImpl(xpr.nestedExpression()) {} EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE - const UnaryOp& func() const { return static_cast(*this); } + const UnaryOp& func() const { return op; } + UnaryOp op; evaluator argImpl; }; @@ -700,12 +700,13 @@ struct ternary_evaluator, IndexBased protected: // this helper permits to completely eliminate the functor if it is empty - struct Data : private TernaryOp + struct Data { EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE - Data(const XprType& xpr) : TernaryOp(xpr.functor()), arg1Impl(xpr.arg1()), arg2Impl(xpr.arg2()), arg3Impl(xpr.arg3()) {} + Data(const XprType& xpr) : op(xpr.functor()), arg1Impl(xpr.arg1()), arg2Impl(xpr.arg2()), arg3Impl(xpr.arg3()) {} EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE - const TernaryOp& func() const { return static_cast(*this); } + const TernaryOp& func() const { return op; } + TernaryOp op; evaluator arg1Impl; evaluator arg2Impl; evaluator arg3Impl; @@ -793,12 +794,13 @@ struct binary_evaluator, IndexBased, IndexBase protected: // this helper permits to completely eliminate the functor if it is empty - struct Data : private BinaryOp + struct Data { EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE - Data(const XprType& xpr) : BinaryOp(xpr.functor()), lhsImpl(xpr.lhs()), rhsImpl(xpr.rhs()) {} + Data(const XprType& xpr) : op(xpr.functor()), lhsImpl(xpr.lhs()), rhsImpl(xpr.rhs()) {} EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE - const BinaryOp& func() const { return static_cast(*this); } + const BinaryOp& func() const { return op; } + BinaryOp op; evaluator lhsImpl; evaluator rhsImpl; }; @@ -858,12 +860,13 @@ struct unary_evaluator, IndexBased> protected: // this helper permits to completely eliminate the functor if it is empty - struct Data : private UnaryOp + struct Data { EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE - Data(const XprType& xpr) : UnaryOp(xpr.functor()), argImpl(xpr.nestedExpression()) {} + Data(const XprType& xpr) : op(xpr.functor()), argImpl(xpr.nestedExpression()) {} EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE - const UnaryOp& func() const { return static_cast(*this); } + const UnaryOp& func() const { return op; } + UnaryOp op; evaluator argImpl; }; -- cgit v1.2.3