Branch data Line data Source code
1 : : /* A class for building vector rtx constants.
2 : : Copyright (C) 2017-2024 Free Software Foundation, Inc.
3 : :
4 : : This file is part of GCC.
5 : :
6 : : GCC is free software; you can redistribute it and/or modify it under
7 : : the terms of the GNU General Public License as published by the Free
8 : : Software Foundation; either version 3, or (at your option) any later
9 : : version.
10 : :
11 : : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 : : WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 : : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 : : for more details.
15 : :
16 : : You should have received a copy of the GNU General Public License
17 : : along with GCC; see the file COPYING3. If not see
18 : : <http://www.gnu.org/licenses/>. */
19 : :
20 : : #ifndef GCC_RTX_VECTOR_BUILDER_H
21 : : #define GCC_RTX_VECTOR_BUILDER_H
22 : :
23 : : #include "vector-builder.h"
24 : :
25 : : /* This class is used to build VECTOR_CSTs from a sequence of elements.
26 : : See vector_builder for more details. */
27 : 45089004 : class rtx_vector_builder : public vector_builder<rtx, machine_mode,
28 : : rtx_vector_builder>
29 : : {
30 : : typedef vector_builder<rtx, machine_mode, rtx_vector_builder> parent;
31 : : friend class vector_builder<rtx, machine_mode, rtx_vector_builder>;
32 : :
33 : : public:
34 : 76495 : rtx_vector_builder () : m_mode (VOIDmode) {}
35 : : rtx_vector_builder (machine_mode, unsigned int, unsigned int);
36 : : rtx build (rtvec);
37 : : rtx build ();
38 : :
39 : : machine_mode mode () const { return m_mode; }
40 : :
41 : : void new_vector (machine_mode, unsigned int, unsigned int);
42 : :
43 : : private:
44 : : bool equal_p (rtx, rtx) const;
45 : : bool allow_steps_p () const;
46 : : bool integral_p (rtx) const;
47 : : poly_wide_int step (rtx, rtx) const;
48 : : rtx apply_step (rtx, unsigned int, const poly_wide_int &) const;
49 : : bool can_elide_p (rtx) const { return true; }
50 : : void note_representative (rtx *, rtx) {}
51 : :
52 : 76495 : static poly_uint64 shape_nelts (machine_mode mode)
53 : 152990 : { return GET_MODE_NUNITS (mode); }
54 : 102162 : static poly_uint64 nelts_of (const_rtx x)
55 : 102162 : { return CONST_VECTOR_NUNITS (x); }
56 : 102162 : static unsigned int npatterns_of (const_rtx x)
57 : 102162 : { return CONST_VECTOR_NPATTERNS (x); }
58 : 102162 : static unsigned int nelts_per_pattern_of (const_rtx x)
59 : 102162 : { return CONST_VECTOR_NELTS_PER_PATTERN (x); }
60 : :
61 : : rtx find_cached_value ();
62 : :
63 : : machine_mode m_mode;
64 : : };
65 : :
66 : : /* Create a new builder for a vector of mode MODE. Initially encode the
67 : : value as NPATTERNS interleaved patterns with NELTS_PER_PATTERN elements
68 : : each. */
69 : :
70 : : inline
71 : 45012705 : rtx_vector_builder::rtx_vector_builder (machine_mode mode,
72 : : unsigned int npatterns,
73 : 45012705 : unsigned int nelts_per_pattern)
74 : : {
75 : 45012705 : new_vector (mode, npatterns, nelts_per_pattern);
76 : 45012705 : }
77 : :
78 : : /* Start building a new vector of mode MODE. Initially encode the value
79 : : as NPATTERNS interleaved patterns with NELTS_PER_PATTERN elements each. */
80 : :
81 : : inline void
82 : 45089200 : rtx_vector_builder::new_vector (machine_mode mode, unsigned int npatterns,
83 : : unsigned int nelts_per_pattern)
84 : : {
85 : 45089200 : m_mode = mode;
86 : 90178400 : parent::new_vector (GET_MODE_NUNITS (mode), npatterns, nelts_per_pattern);
87 : 45089200 : }
88 : :
89 : : /* Return true if elements ELT1 and ELT2 are equal. */
90 : :
91 : : inline bool
92 : 820223 : rtx_vector_builder::equal_p (rtx elt1, rtx elt2) const
93 : : {
94 : 820223 : return rtx_equal_p (elt1, elt2);
95 : : }
96 : :
97 : : /* Return true if a stepped representation is OK. We don't allow
98 : : linear series for anything other than integers, to avoid problems
99 : : with rounding. */
100 : :
101 : : inline bool
102 : 93736 : rtx_vector_builder::allow_steps_p () const
103 : : {
104 : 93736 : return is_a <scalar_int_mode> (GET_MODE_INNER (m_mode));
105 : : }
106 : :
107 : : /* Return true if element ELT can be interpreted as an integer. */
108 : :
109 : : inline bool
110 : 466131 : rtx_vector_builder::integral_p (rtx elt) const
111 : : {
112 : 155377 : return CONST_SCALAR_INT_P (elt);
113 : : }
114 : :
115 : : /* Return the value of element ELT2 minus the value of element ELT1.
116 : : Both elements are known to be CONST_SCALAR_INT_Ps. */
117 : :
118 : : inline poly_wide_int
119 : 442886 : rtx_vector_builder::step (rtx elt1, rtx elt2) const
120 : : {
121 : 442886 : return (wi::to_poly_wide (elt2, GET_MODE_INNER (m_mode))
122 : 1328658 : - wi::to_poly_wide (elt1, GET_MODE_INNER (m_mode)));
123 : : }
124 : :
125 : : #endif
|