Branch data Line data Source code
1 : : /* A class for building vector rtx constants.
2 : : Copyright (C) 2017-2025 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 : 113244 : rtx_vector_builder::build (rtvec v)
32 : : {
33 : 113244 : finalize ();
34 : :
35 : 113244 : rtx x = find_cached_value ();
36 : 113244 : if (x)
37 : : return x;
38 : :
39 : 113244 : x = gen_rtx_raw_CONST_VECTOR (m_mode, v);
40 : 113244 : CONST_VECTOR_NPATTERNS (x) = npatterns ();
41 : 113244 : CONST_VECTOR_NELTS_PER_PATTERN (x) = nelts_per_pattern ();
42 : 113244 : return x;
43 : : }
44 : :
45 : : /* Return a vector element with the value BASE + FACTOR * STEP. */
46 : :
47 : : rtx
48 : 134293 : rtx_vector_builder::apply_step (rtx base, unsigned int factor,
49 : : const poly_wide_int &step) const
50 : : {
51 : 268586 : scalar_int_mode int_mode = as_a <scalar_int_mode> (GET_MODE_INNER (m_mode));
52 : 134293 : return immed_wide_int_const (wi::to_poly_wide (base, int_mode)
53 : 268586 : + factor * step,
54 : 134293 : int_mode);
55 : : }
56 : :
57 : : /* Return a CONST_VECTOR for the current constant. */
58 : :
59 : : rtx
60 : 44733013 : rtx_vector_builder::build ()
61 : : {
62 : 44733013 : finalize ();
63 : :
64 : 44733013 : rtx x = find_cached_value ();
65 : 44733013 : if (x)
66 : : return x;
67 : :
68 : 44070281 : unsigned int nelts;
69 : 88140562 : if (!GET_MODE_NUNITS (m_mode).is_constant (&nelts))
70 : : nelts = encoded_nelts ();
71 : 44070281 : rtvec v = rtvec_alloc (nelts);
72 : 930670575 : for (unsigned int i = 0; i < nelts; ++i)
73 : 886600294 : RTVEC_ELT (v, i) = elt (i);
74 : 44070281 : x = gen_rtx_raw_CONST_VECTOR (m_mode, v);
75 : 44070281 : CONST_VECTOR_NPATTERNS (x) = npatterns ();
76 : 44070281 : CONST_VECTOR_NELTS_PER_PATTERN (x) = nelts_per_pattern ();
77 : 44070281 : 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 : 44846257 : rtx_vector_builder::find_cached_value ()
85 : : {
86 : 44846257 : if (encoded_nelts () != 1)
87 : : return NULL_RTX;
88 : :
89 : 44422405 : rtx elt = (*this)[0];
90 : :
91 : 44422405 : 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 : 44422405 : scalar_mode inner_mode = GET_MODE_INNER (m_mode);
106 : 44422405 : if (elt == CONST0_RTX (inner_mode))
107 : 17058470 : return CONST0_RTX (m_mode);
108 : 27363935 : else if (elt == CONST1_RTX (inner_mode))
109 : 17535324 : return CONST1_RTX (m_mode);
110 : 9828611 : else if (elt == CONSTM1_RTX (inner_mode))
111 : 8770350 : return CONSTM1_RTX (m_mode);
112 : :
113 : : return NULL_RTX;
114 : : }
|