From 746378868a6d19656c09ad8288a7b862d588253f Mon Sep 17 00:00:00 2001 From: Jitse Niesen Date: Fri, 29 Jun 2012 13:54:09 +0100 Subject: Implement A.noalias() = B * C without temporaries * Wrap expression inside EvalToTemp in copy_using_evaluators() if we assume aliasing for that expression (that is, for products) * Remove temporary kludge of evaluating expression to temporary in AllAtOnce traversal * Implement EvalToTemp expression object --- Eigen/src/Core/AssignEvaluator.h | 30 +++++++++++++++++----- Eigen/src/Core/CoreEvaluators.h | 51 +++++++++++++++++++++++++++++++++++++- Eigen/src/Core/ProductEvaluators.h | 4 ++- 3 files changed, 77 insertions(+), 8 deletions(-) (limited to 'Eigen/src/Core') diff --git a/Eigen/src/Core/AssignEvaluator.h b/Eigen/src/Core/AssignEvaluator.h index 9be00067d..9f5deb8e7 100644 --- a/Eigen/src/Core/AssignEvaluator.h +++ b/Eigen/src/Core/AssignEvaluator.h @@ -617,12 +617,8 @@ struct copy_using_evaluator_impl::type tmpEvaluator(tmp); - srcEvaluator.evalTo(tmpEvaluator, tmp); - copy_using_evaluator(dst, tmp); + srcEvaluator.evalTo(dstEvaluator, dst); } }; @@ -640,11 +636,33 @@ const DstXprType& copy_using_evaluator(const NoAlias& d return noalias_copy_using_evaluator(dst.expression(), src.derived()); } +template::AssumeAliasing> +struct AddEvalIfAssumingAliasing; + +template +struct AddEvalIfAssumingAliasing +{ + static const XprType& run(const XprType& xpr) + { + return xpr; + } +}; + +template +struct AddEvalIfAssumingAliasing +{ + static const EvalToTemp run(const XprType& xpr) + { + return EvalToTemp(xpr); + } +}; + template EIGEN_STRONG_INLINE const DstXprType& copy_using_evaluator(const EigenBase& dst, const EigenBase& src) { - return noalias_copy_using_evaluator(dst.const_cast_derived(), src.derived()); + return noalias_copy_using_evaluator(dst.const_cast_derived(), + AddEvalIfAssumingAliasing::run(src.derived())); } template diff --git a/Eigen/src/Core/CoreEvaluators.h b/Eigen/src/Core/CoreEvaluators.h index 808546ec1..906df2af7 100644 --- a/Eigen/src/Core/CoreEvaluators.h +++ b/Eigen/src/Core/CoreEvaluators.h @@ -40,6 +40,10 @@ struct evaluator_traits // 1 if evaluator_impl::evalTo() exists // 0 if evaluator_impl allows coefficient-based access static const int HasEvalTo = 0; + + // 1 if assignment A = B assumes aliasing when B is of type T and thus B needs to be evaluated into a + // temporary; 0 if not. + static const int AssumeAliasing = 0; }; // expression class for evaluating nested expression to a temporary @@ -245,17 +249,62 @@ struct evaluator_impl > // -------------------- EvalToTemp -------------------- +template +struct traits > + : public traits +{ }; + +template +class EvalToTemp + : public dense_xpr_base >::type +{ + public: + + typedef typename dense_xpr_base::type Base; + EIGEN_GENERIC_PUBLIC_INTERFACE(EvalToTemp) + + EvalToTemp(const ArgType& arg) + : m_arg(arg) + { } + + const ArgType& arg() const + { + return m_arg; + } + + Index rows() const + { + return m_arg.rows(); + } + + Index cols() const + { + return m_arg.cols(); + } + + private: + const ArgType& m_arg; +}; + template struct evaluator_impl > : evaluator_impl { + typedef EvalToTemp XprType; typedef typename ArgType::PlainObject PlainObject; typedef evaluator_impl BaseType; + evaluator_impl(const XprType& xpr) + : BaseType(m_result) + { + noalias_copy_using_evaluator(m_result, xpr.arg()); + }; + + // this constructor is used when nesting an EvalTo evaluator in another evaluator evaluator_impl(const ArgType& arg) : BaseType(m_result) { - copy_using_evaluator(m_result, arg); + noalias_copy_using_evaluator(m_result, arg); }; protected: diff --git a/Eigen/src/Core/ProductEvaluators.h b/Eigen/src/Core/ProductEvaluators.h index e814a4710..3804113f8 100644 --- a/Eigen/src/Core/ProductEvaluators.h +++ b/Eigen/src/Core/ProductEvaluators.h @@ -56,7 +56,9 @@ struct product_evaluator_traits_dispatcher; template struct evaluator_traits > : product_evaluator_traits_dispatcher, typename ProductReturnType::Type> -{ }; +{ + static const int AssumeAliasing = 1; +}; // Case 1: Evaluate all at once // -- cgit v1.2.3