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 : : #include "config.h"
21 : : #include "system.h"
22 : : #include "coretypes.h"
23 : : #include "tm.h"
24 : : #include "rtl.h"
25 : : #include "rtx-vector-builder.h"
26 : :
27 : : /* Return a CONST_VECTOR for the current constant. V is an existing
28 : : rtvec that contains all the elements. */
29 : :
30 : : rtx
31 : 110183 : rtx_vector_builder::build (rtvec v)
32 : : {
33 : 110183 : finalize ();
34 : :
35 : 110183 : rtx x = find_cached_value ();
36 : 110183 : if (x)
37 : : return x;
38 : :
39 : 110183 : x = gen_rtx_raw_CONST_VECTOR (m_mode, v);
40 : 110183 : CONST_VECTOR_NPATTERNS (x) = npatterns ();
41 : 110183 : CONST_VECTOR_NELTS_PER_PATTERN (x) = nelts_per_pattern ();
42 : 110183 : return x;
43 : : }
44 : :
45 : : /* Return a vector element with the value BASE + FACTOR * STEP. */
46 : :
47 : : rtx
48 : 123567 : rtx_vector_builder::apply_step (rtx base, unsigned int factor,
49 : : const poly_wide_int &step) const
50 : : {
51 : 247134 : scalar_int_mode int_mode = as_a <scalar_int_mode> (GET_MODE_INNER (m_mode));
52 : 123567 : return immed_wide_int_const (wi::to_poly_wide (base, int_mode)
53 : 247134 : + factor * step,
54 : 123567 : int_mode);
55 : : }
56 : :
57 : : /* Return a CONST_VECTOR for the current constant. */
58 : :
59 : : rtx
60 : 44887584 : rtx_vector_builder::build ()
61 : : {
62 : 44887584 : finalize ();
63 : :
64 : 44887584 : rtx x = find_cached_value ();
65 : 44887584 : if (x)
66 : : return x;
67 : :
68 : 44281584 : unsigned int nelts;
69 : 88563168 : if (!GET_MODE_NUNITS (m_mode).is_constant (&nelts))
70 : : nelts = encoded_nelts ();
71 : 44281584 : rtvec v = rtvec_alloc (nelts);
72 : 937267350 : for (unsigned int i = 0; i < nelts; ++i)
73 : 892985766 : RTVEC_ELT (v, i) = elt (i);
74 : 44281584 : x = gen_rtx_raw_CONST_VECTOR (m_mode, v);
75 : 44281584 : CONST_VECTOR_NPATTERNS (x) = npatterns ();
76 : 44281584 : CONST_VECTOR_NELTS_PER_PATTERN (x) = nelts_per_pattern ();
77 : 44281584 : return x;
78 : : }
79 : :
80 : : /* Check whether there is a global cached value for the vector.
81 : : Return it if so, otherwise return null. */
82 : :
83 : : rtx
84 : 44997767 : rtx_vector_builder::find_cached_value ()
85 : : {
86 : 44997767 : if (encoded_nelts () != 1)
87 : : return NULL_RTX;
88 : :
89 : 44616433 : rtx elt = (*this)[0];
90 : :
91 : 44616433 : if (GET_MODE_CLASS (m_mode) == MODE_VECTOR_BOOL)
92 : : {
93 : 0 : if (elt == const1_rtx)
94 : 0 : return CONST1_RTX (m_mode);
95 : 0 : else if (elt == constm1_rtx)
96 : 0 : return CONSTM1_RTX (m_mode);
97 : 0 : else if (elt == const0_rtx)
98 : 0 : return CONST0_RTX (m_mode);
99 : : else
100 : 0 : gcc_unreachable ();
101 : : }
102 : :
103 : : /* We can be called before the global vector constants are set up,
104 : : but in that case we'll just return null. */
105 : 44616433 : scalar_mode inner_mode = GET_MODE_INNER (m_mode);
106 : 44616433 : if (elt == CONST0_RTX (inner_mode))
107 : 17172952 : return CONST0_RTX (m_mode);
108 : 27443481 : else if (elt == CONST1_RTX (inner_mode))
109 : 17625361 : return CONST1_RTX (m_mode);
110 : 9818120 : else if (elt == CONSTM1_RTX (inner_mode))
111 : 8837635 : return CONSTM1_RTX (m_mode);
112 : :
113 : : return NULL_RTX;
114 : : }
|