1 /* { dg-do compile } */
2 /* { dg-options "-O2 -fdump-tree-optimized" } */
3 extern void __assert_fail(const char*, const char*, int, const char*);
6 template <int, typename>
8 template <typename Else>
9 struct conditional<false, Else> {
13 struct remove_reference {
16 struct is_arithmetic {
22 struct traits<const T> : traits<T> {};
28 class PlainObjectBase;
29 template <typename, int _Rows, int _Cols, int = AutoAlign, int = _Rows,
34 template <typename, typename>
36 template <typename, typename, typename>
39 struct scalar_constant_op;
41 struct size_at_compile_time {
45 typedef const Matrix<float, 3, 1>& type;
47 template <typename Derived>
48 struct dense_xpr_base {
49 typedef MatrixBase<Derived> type;
51 template <typename Derived, typename = typename traits<Derived>::XprKind>
52 struct generic_xpr_base {
53 typedef typename dense_xpr_base<Derived>::type type;
55 template <typename Expr, typename Scalar = typename Expr::Scalar>
56 struct plain_constant_type {
58 typedef CwiseNullaryOp<scalar_constant_op<Scalar>,
59 Matrix<Scalar, traits<Expr>::ColsAtCompileTime,
60 traits<Expr>::MaxRowsAtCompileTime,
61 traits<Expr>::MaxColsAtCompileTime>>
64 struct scalar_product_op {
65 float operator()(float a, float b) { return a * b; }
68 struct scalar_constant_op {
69 scalar_constant_op(float other) : m_other(other) {}
70 float operator()() { return m_other; }
74 void assignCoeff(float& a, float b) { a = b; }
76 template <typename Derived>
77 class DenseCoeffsBase : public EigenBase<Derived> {
79 typedef typename traits<Derived>::Scalar Scalar;
81 typename conditional<is_arithmetic::value, Scalar>::type CoeffReturnType;
83 template <typename Derived>
84 class DenseBase : public DenseCoeffsBase<Derived> {
87 RowsAtCompileTime = traits<Derived>::RowsAtCompileTime,
88 SizeAtCompileTime = size_at_compile_time<RowsAtCompileTime>::ret,
92 template <typename Derived>
93 class MatrixBase : public DenseBase<Derived> {
95 using DenseBase<Derived>::derived;
97 CwiseBinaryOp<scalar_product_op, const Derived,
98 const typename plain_constant_type<Derived, T>::type>
99 operator*(T& scalar) {
100 return CwiseBinaryOp<scalar_product_op, const Derived,
101 const typename plain_constant_type<Derived>::type>(
102 derived(), typename plain_constant_type<Derived>::type(derived().rows(),
106 template <typename Derived>
108 const Derived& derived() const { return *static_cast<const Derived*>(this); }
109 Derived& const_cast_derived() const {
110 return *static_cast<Derived*>(const_cast<EigenBase*>(this));
114 struct binary_evaluator;
115 template <typename T>
116 struct evaluator<const T> : evaluator<T> {
117 evaluator(const T& xpr) : evaluator<T>(xpr) {}
119 template <typename Derived>
121 typedef Derived PlainObjectType;
122 typedef typename PlainObjectType::Scalar Scalar;
123 evaluator(const PlainObjectType& m) : m_data(m.data()) {}
124 typename PlainObjectType::CoeffReturnType coeff(long row, long) {
127 Scalar& coeffRef(long row, long) { return const_cast<Scalar*>(m_data)[row]; }
128 const Scalar* m_data;
130 template <typename Scalar, int Rows, int Cols, int Options, int MaxRows,
132 struct evaluator<Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols>>
133 : evaluator<PlainObjectBase<Matrix<Scalar, Rows, Cols>>> {
134 typedef Matrix<Scalar, Rows, Cols> XprType;
135 evaluator(const XprType& m) : evaluator<PlainObjectBase<XprType>>(m) {}
137 struct nullary_wrapper {
138 template <typename IndexType>
139 float operator()(scalar_constant_op<float> op, IndexType, IndexType) const {
143 template <typename NullaryOp, typename PlainObjectType>
144 struct evaluator<CwiseNullaryOp<NullaryOp, PlainObjectType>> {
145 typedef CwiseNullaryOp<NullaryOp, PlainObjectType> XprType;
146 evaluator(XprType n) : m_functor(n.functor()) {}
147 template <typename IndexType>
148 typename XprType::CoeffReturnType coeff(IndexType row, IndexType col) {
149 return m_wrapper(m_functor, row, col);
152 nullary_wrapper m_wrapper;
154 template <typename BinaryOp, typename Lhs, typename Rhs>
155 struct evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs>>
156 : binary_evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs>> {
157 evaluator(CwiseBinaryOp<BinaryOp, Lhs, Rhs> xpr)
158 : binary_evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs>>(xpr) {}
160 template <typename BinaryOp, typename Lhs, typename Rhs>
161 struct binary_evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs>> {
162 typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> XprType;
163 binary_evaluator(XprType xpr) : m_lhsImpl(xpr.lhs()), m_rhsImpl(xpr.rhs()) {}
164 typename XprType::CoeffReturnType coeff(long row, long col) {
165 return m_functor(m_lhsImpl.coeff(row, col), m_rhsImpl.coeff(row, col));
168 evaluator<Lhs> m_lhsImpl;
169 evaluator<Rhs> m_rhsImpl;
171 template <typename Kernel, int Index, int Stop>
172 struct copy_using_evaluator_DefaultTraversal_CompleteUnrolling {
173 enum { outer, inner = Index };
174 static void run(Kernel kernel) {
175 kernel.assignCoeffByOuterInner(outer, inner);
176 copy_using_evaluator_DefaultTraversal_CompleteUnrolling<Kernel, Index + 1,
180 template <typename Kernel, int Stop>
181 struct copy_using_evaluator_DefaultTraversal_CompleteUnrolling<Kernel, Stop,
183 static void run(Kernel) {}
185 template <typename Kernel>
186 struct dense_assignment_loop {
187 static void run(Kernel kernel) {
188 typedef typename Kernel::DstEvaluatorType::XprType DstXprType;
189 enum { size = DstXprType::SizeAtCompileTime, alignedSize = 0 };
190 copy_using_evaluator_DefaultTraversal_CompleteUnrolling<Kernel, alignedSize,
194 template <typename DstEvaluatorTypeT, typename SrcEvaluatorTypeT,
196 class generic_dense_assignment_kernel {
197 typedef typename DstEvaluatorTypeT::XprType DstXprType;
200 typedef DstEvaluatorTypeT DstEvaluatorType;
201 typedef SrcEvaluatorTypeT SrcEvaluatorType;
202 generic_dense_assignment_kernel(DstEvaluatorType dst, SrcEvaluatorType src,
203 Functor, DstXprType& dstExpr)
204 : m_dst(dst), m_src(src), m_dstExpr(dstExpr) {}
205 long assignCoeff_col;
206 void assignCoeffByOuterInner(long, long inner) {
207 long __trans_tmp_1 = inner;
208 m_functor.assignCoeff(m_dst.coeffRef(__trans_tmp_1, assignCoeff_col),
209 m_src.coeff(__trans_tmp_1, assignCoeff_col));
211 DstEvaluatorType m_dst;
212 SrcEvaluatorType m_src;
214 DstXprType& m_dstExpr;
216 template <typename DstXprType, typename SrcXprType, typename Functor>
217 void call_dense_assignment_loop(DstXprType& dst, SrcXprType src, Functor func) {
218 typedef evaluator<DstXprType> DstEvaluatorType;
219 typedef evaluator<SrcXprType> SrcEvaluatorType;
220 SrcEvaluatorType srcEvaluator(src);
221 DstEvaluatorType dstEvaluator(dst);
222 typedef generic_dense_assignment_kernel<DstEvaluatorType, SrcEvaluatorType,
225 Kernel kernel(dstEvaluator, srcEvaluator, func, dst.const_cast_derived());
226 dense_assignment_loop<Kernel>::run(kernel);
228 template <typename Dst, typename Src, typename Func>
229 void call_assignment_no_alias(Dst& dst, Src src, Func func) {
230 enum { NeedToTranspose };
231 typename conditional<NeedToTranspose, Dst&>::type actualDst(dst);
232 CwiseBinaryOp<scalar_product_op, const Matrix<float, 3, 1>,
233 const CwiseNullaryOp<scalar_constant_op<float>,
234 const Matrix<float, 3, 1, 0, 2, 3>>>
236 call_dense_assignment_loop(actualDst, __trans_tmp_4, func);
242 template <int Size, int _Rows>
244 plain_array<Size> m_data;
248 DenseStorage(const DenseStorage&);
249 static long rows() { return _Rows; }
250 const float* data() const { return m_data.array; }
251 float* data() { return m_data.array; }
253 template <typename Derived>
254 class PlainObjectBase : public dense_xpr_base<Derived>::type {
256 typedef typename dense_xpr_base<Derived>::type Base;
257 typedef typename traits<Derived>::Scalar Scalar;
258 DenseStorage<Base::MaxSizeAtCompileTime, Base::RowsAtCompileTime> m_storage;
259 long rows() const { return m_storage.rows(); }
260 const Scalar* data() const { return m_storage.data(); }
262 template <typename OtherDerived>
263 PlainObjectBase(const DenseBase<OtherDerived>& other) {
266 template <typename OtherDerived>
267 void _set_noalias(const DenseBase<OtherDerived>& other) {
268 call_assignment_no_alias(this->derived(), other.derived(), assign_op());
271 template <typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows,
273 struct traits<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>> {
274 typedef _Scalar Scalar;
277 RowsAtCompileTime = _Rows,
279 MaxRowsAtCompileTime,
280 MaxColsAtCompileTime,
283 template <typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows,
286 : public PlainObjectBase<
287 Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>> {
289 typedef PlainObjectBase<Matrix> Base;
290 typedef typename traits<Matrix>::Scalar Scalar;
291 Matrix(Scalar& x, Scalar& y, Scalar& z) {
292 m_storage.data()[0] = x;
293 m_storage.data()[1] = y;
294 m_storage.data()[2] = z;
296 template <typename OtherDerived>
297 Matrix(const EigenBase<OtherDerived>& other) : Base(other.derived()) {}
298 using Base::m_storage;
300 template <typename BinaryOp, typename Lhs, typename Rhs>
301 struct traits<CwiseBinaryOp<BinaryOp, Lhs, Rhs>> {
302 typedef typename traits<Lhs>::XprKind XprKind;
303 enum { RowsAtCompileTime };
304 typedef float Scalar;
307 class CwiseBinaryOpImpl;
308 template <typename, typename, typename RhsType>
309 class CwiseBinaryOp : public CwiseBinaryOpImpl<RhsType> {
311 typedef ref_selector::type LhsNested;
312 typedef RhsType RhsNested;
313 CwiseBinaryOp(const Matrix<float, 3, 1>& aLhs, RhsType& aRhs)
314 : m_lhs(aLhs), m_rhs(aRhs) {}
315 remove_reference<LhsNested>::type& lhs() { return m_lhs; }
316 typename remove_reference<RhsNested>::type& rhs() { return m_rhs; }
321 class CwiseBinaryOpImpl
322 : public generic_xpr_base<CwiseBinaryOp<
323 scalar_product_op, const Matrix<float, 3, 1>,
324 const CwiseNullaryOp<scalar_constant_op<float>,
325 const Matrix<float, 3, 1, 0, 2, 3>>>>::type {};
326 template <typename NullaryOp, typename PlainObjectType>
327 struct traits<CwiseNullaryOp<NullaryOp, PlainObjectType>>
328 : traits<PlainObjectType> {};
329 template <typename, typename PlainObjectType>
331 : public dense_xpr_base<CwiseNullaryOp<int, PlainObjectType>>::type {
333 CwiseNullaryOp(long rows, long, scalar_constant_op<float> func)
335 rows ? void() : __assert_fail("", "", 1, __PRETTY_FUNCTION__);
337 scalar_constant_op<float> functor() { return m_functor; }
338 scalar_constant_op<float> m_functor;
341 Eigen::Matrix<float, 3, 1> should_inline(float x, float y, float z,
343 return Eigen::Matrix<float, 3, 1>(x, y, z) * scale;
346 // We should inline everything to should_inline
348 /* { dg-final { scan-tree-dump-times "Function" "optimized" } } */