| /* { dg-do compile } */ |
| /* { dg-options "-O2 -fdump-tree-optimized" } */ |
| extern void __assert_fail(const char*, const char*, int, const char*); |
| namespace Eigen { |
| enum { AutoAlign }; |
| template <int, typename> |
| struct conditional; |
| template <typename Else> |
| struct conditional<false, Else> { |
| typedef Else type; |
| }; |
| template <typename T> |
| struct remove_reference { |
| typedef T type; |
| }; |
| struct is_arithmetic { |
| enum { value }; |
| }; |
| template <typename> |
| struct traits; |
| template <typename T> |
| struct traits<const T> : traits<T> {}; |
| template <typename> |
| struct evaluator; |
| template <typename> |
| struct EigenBase; |
| template <typename> |
| class PlainObjectBase; |
| template <typename, int _Rows, int _Cols, int = AutoAlign, int = _Rows, |
| int = _Cols> |
| class Matrix; |
| template <typename> |
| class MatrixBase; |
| template <typename, typename> |
| class CwiseNullaryOp; |
| template <typename, typename, typename> |
| class CwiseBinaryOp; |
| template <typename> |
| struct scalar_constant_op; |
| template <int _Rows> |
| struct size_at_compile_time { |
| enum { ret = _Rows }; |
| }; |
| struct ref_selector { |
| typedef const Matrix<float, 3, 1>& type; |
| }; |
| template <typename Derived> |
| struct dense_xpr_base { |
| typedef MatrixBase<Derived> type; |
| }; |
| template <typename Derived, typename = typename traits<Derived>::XprKind> |
| struct generic_xpr_base { |
| typedef typename dense_xpr_base<Derived>::type type; |
| }; |
| template <typename Expr, typename Scalar = typename Expr::Scalar> |
| struct plain_constant_type { |
| ; |
| typedef CwiseNullaryOp<scalar_constant_op<Scalar>, |
| Matrix<Scalar, traits<Expr>::ColsAtCompileTime, |
| traits<Expr>::MaxRowsAtCompileTime, |
| traits<Expr>::MaxColsAtCompileTime>> |
| type; |
| }; |
| struct scalar_product_op { |
| float operator()(float a, float b) { return a * b; } |
| }; |
| template <typename> |
| struct scalar_constant_op { |
| scalar_constant_op(float other) : m_other(other) {} |
| float operator()() { return m_other; } |
| float m_other; |
| }; |
| struct assign_op { |
| void assignCoeff(float& a, float b) { a = b; } |
| }; |
| template <typename Derived> |
| class DenseCoeffsBase : public EigenBase<Derived> { |
| public: |
| typedef typename traits<Derived>::Scalar Scalar; |
| typedef |
| typename conditional<is_arithmetic::value, Scalar>::type CoeffReturnType; |
| }; |
| template <typename Derived> |
| class DenseBase : public DenseCoeffsBase<Derived> { |
| public: |
| enum { |
| RowsAtCompileTime = traits<Derived>::RowsAtCompileTime, |
| SizeAtCompileTime = size_at_compile_time<RowsAtCompileTime>::ret, |
| MaxSizeAtCompileTime |
| }; |
| }; |
| template <typename Derived> |
| class MatrixBase : public DenseBase<Derived> { |
| public: |
| using DenseBase<Derived>::derived; |
| template <typename T> |
| CwiseBinaryOp<scalar_product_op, const Derived, |
| const typename plain_constant_type<Derived, T>::type> |
| operator*(T& scalar) { |
| return CwiseBinaryOp<scalar_product_op, const Derived, |
| const typename plain_constant_type<Derived>::type>( |
| derived(), typename plain_constant_type<Derived>::type(derived().rows(), |
| 0, scalar)); |
| } |
| }; |
| template <typename Derived> |
| struct EigenBase { |
| const Derived& derived() const { return *static_cast<const Derived*>(this); } |
| Derived& const_cast_derived() const { |
| return *static_cast<Derived*>(const_cast<EigenBase*>(this)); |
| } |
| }; |
| template <typename> |
| struct binary_evaluator; |
| template <typename T> |
| struct evaluator<const T> : evaluator<T> { |
| evaluator(const T& xpr) : evaluator<T>(xpr) {} |
| }; |
| template <typename Derived> |
| struct evaluator { |
| typedef Derived PlainObjectType; |
| typedef typename PlainObjectType::Scalar Scalar; |
| evaluator(const PlainObjectType& m) : m_data(m.data()) {} |
| typename PlainObjectType::CoeffReturnType coeff(long row, long) { |
| return m_data[row]; |
| } |
| Scalar& coeffRef(long row, long) { return const_cast<Scalar*>(m_data)[row]; } |
| const Scalar* m_data; |
| }; |
| template <typename Scalar, int Rows, int Cols, int Options, int MaxRows, |
| int MaxCols> |
| struct evaluator<Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols>> |
| : evaluator<PlainObjectBase<Matrix<Scalar, Rows, Cols>>> { |
| typedef Matrix<Scalar, Rows, Cols> XprType; |
| evaluator(const XprType& m) : evaluator<PlainObjectBase<XprType>>(m) {} |
| }; |
| struct nullary_wrapper { |
| template <typename IndexType> |
| float operator()(scalar_constant_op<float> op, IndexType, IndexType) const { |
| return op(); |
| } |
| }; |
| template <typename NullaryOp, typename PlainObjectType> |
| struct evaluator<CwiseNullaryOp<NullaryOp, PlainObjectType>> { |
| typedef CwiseNullaryOp<NullaryOp, PlainObjectType> XprType; |
| evaluator(XprType n) : m_functor(n.functor()) {} |
| template <typename IndexType> |
| typename XprType::CoeffReturnType coeff(IndexType row, IndexType col) { |
| return m_wrapper(m_functor, row, col); |
| } |
| NullaryOp m_functor; |
| nullary_wrapper m_wrapper; |
| }; |
| template <typename BinaryOp, typename Lhs, typename Rhs> |
| struct evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs>> |
| : binary_evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs>> { |
| evaluator(CwiseBinaryOp<BinaryOp, Lhs, Rhs> xpr) |
| : binary_evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs>>(xpr) {} |
| }; |
| template <typename BinaryOp, typename Lhs, typename Rhs> |
| struct binary_evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs>> { |
| typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> XprType; |
| binary_evaluator(XprType xpr) : m_lhsImpl(xpr.lhs()), m_rhsImpl(xpr.rhs()) {} |
| typename XprType::CoeffReturnType coeff(long row, long col) { |
| return m_functor(m_lhsImpl.coeff(row, col), m_rhsImpl.coeff(row, col)); |
| } |
| BinaryOp m_functor; |
| evaluator<Lhs> m_lhsImpl; |
| evaluator<Rhs> m_rhsImpl; |
| }; |
| template <typename Kernel, int Index, int Stop> |
| struct copy_using_evaluator_DefaultTraversal_CompleteUnrolling { |
| enum { outer, inner = Index }; |
| static void run(Kernel kernel) { |
| kernel.assignCoeffByOuterInner(outer, inner); |
| copy_using_evaluator_DefaultTraversal_CompleteUnrolling<Kernel, Index + 1, |
| Stop>::run(kernel); |
| } |
| }; |
| template <typename Kernel, int Stop> |
| struct copy_using_evaluator_DefaultTraversal_CompleteUnrolling<Kernel, Stop, |
| Stop> { |
| static void run(Kernel) {} |
| }; |
| template <typename Kernel> |
| struct dense_assignment_loop { |
| static void run(Kernel kernel) { |
| typedef typename Kernel::DstEvaluatorType::XprType DstXprType; |
| enum { size = DstXprType::SizeAtCompileTime, alignedSize = 0 }; |
| copy_using_evaluator_DefaultTraversal_CompleteUnrolling<Kernel, alignedSize, |
| size>::run(kernel); |
| } |
| }; |
| template <typename DstEvaluatorTypeT, typename SrcEvaluatorTypeT, |
| typename Functor> |
| class generic_dense_assignment_kernel { |
| typedef typename DstEvaluatorTypeT::XprType DstXprType; |
| |
| public: |
| typedef DstEvaluatorTypeT DstEvaluatorType; |
| typedef SrcEvaluatorTypeT SrcEvaluatorType; |
| generic_dense_assignment_kernel(DstEvaluatorType dst, SrcEvaluatorType src, |
| Functor, DstXprType& dstExpr) |
| : m_dst(dst), m_src(src), m_dstExpr(dstExpr) {} |
| long assignCoeff_col; |
| void assignCoeffByOuterInner(long, long inner) { |
| long __trans_tmp_1 = inner; |
| m_functor.assignCoeff(m_dst.coeffRef(__trans_tmp_1, assignCoeff_col), |
| m_src.coeff(__trans_tmp_1, assignCoeff_col)); |
| } |
| DstEvaluatorType m_dst; |
| SrcEvaluatorType m_src; |
| Functor m_functor; |
| DstXprType& m_dstExpr; |
| }; |
| template <typename DstXprType, typename SrcXprType, typename Functor> |
| void call_dense_assignment_loop(DstXprType& dst, SrcXprType src, Functor func) { |
| typedef evaluator<DstXprType> DstEvaluatorType; |
| typedef evaluator<SrcXprType> SrcEvaluatorType; |
| SrcEvaluatorType srcEvaluator(src); |
| DstEvaluatorType dstEvaluator(dst); |
| typedef generic_dense_assignment_kernel<DstEvaluatorType, SrcEvaluatorType, |
| Functor> |
| Kernel; |
| Kernel kernel(dstEvaluator, srcEvaluator, func, dst.const_cast_derived()); |
| dense_assignment_loop<Kernel>::run(kernel); |
| } |
| template <typename Dst, typename Src, typename Func> |
| void call_assignment_no_alias(Dst& dst, Src src, Func func) { |
| enum { NeedToTranspose }; |
| typename conditional<NeedToTranspose, Dst&>::type actualDst(dst); |
| CwiseBinaryOp<scalar_product_op, const Matrix<float, 3, 1>, |
| const CwiseNullaryOp<scalar_constant_op<float>, |
| const Matrix<float, 3, 1, 0, 2, 3>>> |
| __trans_tmp_4 = src; |
| call_dense_assignment_loop(actualDst, __trans_tmp_4, func); |
| } |
| template <int Size> |
| struct plain_array { |
| float array[Size]; |
| }; |
| template <int Size, int _Rows> |
| class DenseStorage { |
| plain_array<Size> m_data; |
| |
| public: |
| DenseStorage() {} |
| DenseStorage(const DenseStorage&); |
| static long rows() { return _Rows; } |
| const float* data() const { return m_data.array; } |
| float* data() { return m_data.array; } |
| }; |
| template <typename Derived> |
| class PlainObjectBase : public dense_xpr_base<Derived>::type { |
| public: |
| typedef typename dense_xpr_base<Derived>::type Base; |
| typedef typename traits<Derived>::Scalar Scalar; |
| DenseStorage<Base::MaxSizeAtCompileTime, Base::RowsAtCompileTime> m_storage; |
| long rows() const { return m_storage.rows(); } |
| const Scalar* data() const { return m_storage.data(); } |
| PlainObjectBase() {} |
| template <typename OtherDerived> |
| PlainObjectBase(const DenseBase<OtherDerived>& other) { |
| _set_noalias(other); |
| } |
| template <typename OtherDerived> |
| void _set_noalias(const DenseBase<OtherDerived>& other) { |
| call_assignment_no_alias(this->derived(), other.derived(), assign_op()); |
| } |
| }; |
| template <typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, |
| int _MaxCols> |
| struct traits<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>> { |
| typedef _Scalar Scalar; |
| typedef int XprKind; |
| enum { |
| RowsAtCompileTime = _Rows, |
| ColsAtCompileTime, |
| MaxRowsAtCompileTime, |
| MaxColsAtCompileTime, |
| }; |
| }; |
| template <typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, |
| int _MaxCols> |
| class Matrix |
| : public PlainObjectBase< |
| Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>> { |
| public: |
| typedef PlainObjectBase<Matrix> Base; |
| typedef typename traits<Matrix>::Scalar Scalar; |
| Matrix(Scalar& x, Scalar& y, Scalar& z) { |
| m_storage.data()[0] = x; |
| m_storage.data()[1] = y; |
| m_storage.data()[2] = z; |
| } |
| template <typename OtherDerived> |
| Matrix(const EigenBase<OtherDerived>& other) : Base(other.derived()) {} |
| using Base::m_storage; |
| }; |
| template <typename BinaryOp, typename Lhs, typename Rhs> |
| struct traits<CwiseBinaryOp<BinaryOp, Lhs, Rhs>> { |
| typedef typename traits<Lhs>::XprKind XprKind; |
| enum { RowsAtCompileTime }; |
| typedef float Scalar; |
| }; |
| template <typename> |
| class CwiseBinaryOpImpl; |
| template <typename, typename, typename RhsType> |
| class CwiseBinaryOp : public CwiseBinaryOpImpl<RhsType> { |
| public: |
| typedef ref_selector::type LhsNested; |
| typedef RhsType RhsNested; |
| CwiseBinaryOp(const Matrix<float, 3, 1>& aLhs, RhsType& aRhs) |
| : m_lhs(aLhs), m_rhs(aRhs) {} |
| remove_reference<LhsNested>::type& lhs() { return m_lhs; } |
| typename remove_reference<RhsNested>::type& rhs() { return m_rhs; } |
| LhsNested m_lhs; |
| RhsNested m_rhs; |
| }; |
| template <typename> |
| class CwiseBinaryOpImpl |
| : public generic_xpr_base<CwiseBinaryOp< |
| scalar_product_op, const Matrix<float, 3, 1>, |
| const CwiseNullaryOp<scalar_constant_op<float>, |
| const Matrix<float, 3, 1, 0, 2, 3>>>>::type {}; |
| template <typename NullaryOp, typename PlainObjectType> |
| struct traits<CwiseNullaryOp<NullaryOp, PlainObjectType>> |
| : traits<PlainObjectType> {}; |
| template <typename, typename PlainObjectType> |
| class CwiseNullaryOp |
| : public dense_xpr_base<CwiseNullaryOp<int, PlainObjectType>>::type { |
| public: |
| CwiseNullaryOp(long rows, long, scalar_constant_op<float> func) |
| : m_functor(func) { |
| rows ? void() : __assert_fail("", "", 1, __PRETTY_FUNCTION__); |
| } |
| scalar_constant_op<float> functor() { return m_functor; } |
| scalar_constant_op<float> m_functor; |
| }; |
| } // namespace Eigen |
| Eigen::Matrix<float, 3, 1> should_inline(float x, float y, float z, |
| float scale) { |
| return Eigen::Matrix<float, 3, 1>(x, y, z) * scale; |
| } |
| |
| // We should inline everything to should_inline |
| |
| /* { dg-final { scan-tree-dump-times "Function" "optimized" } } */ |