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