rtl-iter.h revision 1.7 1 1.1 mrg /* RTL iterators
2 1.7 mrg Copyright (C) 2014-2022 Free Software Foundation, Inc.
3 1.1 mrg
4 1.1 mrg This file is part of GCC.
5 1.1 mrg
6 1.1 mrg GCC is free software; you can redistribute it and/or modify it under
7 1.1 mrg the terms of the GNU General Public License as published by the Free
8 1.1 mrg Software Foundation; either version 3, or (at your option) any later
9 1.1 mrg version.
10 1.1 mrg
11 1.1 mrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 1.1 mrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 1.1 mrg FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 1.1 mrg for more details.
15 1.1 mrg
16 1.1 mrg You should have received a copy of the GNU General Public License
17 1.1 mrg along with GCC; see the file COPYING3. If not see
18 1.1 mrg <http://www.gnu.org/licenses/>. */
19 1.1 mrg
20 1.1 mrg /* This structure describes the subrtxes of an rtx as follows:
21 1.1 mrg
22 1.1 mrg - if the rtx has no subrtxes, START and COUNT are both 0.
23 1.1 mrg
24 1.1 mrg - if all the subrtxes of an rtx are stored in a contiguous block
25 1.1 mrg of XEXPs ("e"s), START is the index of the first XEXP and COUNT
26 1.1 mrg is the number of them.
27 1.1 mrg
28 1.1 mrg - otherwise START is arbitrary and COUNT is UCHAR_MAX.
29 1.1 mrg
30 1.1 mrg rtx_all_subrtx_bounds applies to all codes. rtx_nonconst_subrtx_bounds
31 1.1 mrg is like rtx_all_subrtx_bounds except that all constant rtxes are treated
32 1.1 mrg as having no subrtxes. */
33 1.1 mrg struct rtx_subrtx_bound_info {
34 1.1 mrg unsigned char start;
35 1.1 mrg unsigned char count;
36 1.1 mrg };
37 1.1 mrg extern rtx_subrtx_bound_info rtx_all_subrtx_bounds[];
38 1.1 mrg extern rtx_subrtx_bound_info rtx_nonconst_subrtx_bounds[];
39 1.1 mrg
40 1.1 mrg /* Return true if CODE has no subrtxes. */
41 1.1 mrg
42 1.1 mrg static inline bool
43 1.1 mrg leaf_code_p (enum rtx_code code)
44 1.1 mrg {
45 1.1 mrg return rtx_all_subrtx_bounds[code].count == 0;
46 1.1 mrg }
47 1.1 mrg
48 1.1 mrg /* Used to iterate over subrtxes of an rtx. T abstracts the type of
49 1.1 mrg access. */
50 1.1 mrg template <typename T>
51 1.1 mrg class generic_subrtx_iterator
52 1.1 mrg {
53 1.1 mrg static const size_t LOCAL_ELEMS = 16;
54 1.1 mrg typedef typename T::value_type value_type;
55 1.1 mrg typedef typename T::rtx_type rtx_type;
56 1.1 mrg typedef typename T::rtunion_type rtunion_type;
57 1.1 mrg
58 1.1 mrg public:
59 1.6 mrg class array_type
60 1.1 mrg {
61 1.6 mrg public:
62 1.1 mrg array_type ();
63 1.1 mrg ~array_type ();
64 1.1 mrg value_type stack[LOCAL_ELEMS];
65 1.1 mrg vec <value_type, va_heap, vl_embed> *heap;
66 1.1 mrg };
67 1.1 mrg generic_subrtx_iterator (array_type &, value_type,
68 1.1 mrg const rtx_subrtx_bound_info *);
69 1.1 mrg
70 1.1 mrg value_type operator * () const;
71 1.1 mrg bool at_end () const;
72 1.1 mrg void next ();
73 1.1 mrg void skip_subrtxes ();
74 1.1 mrg void substitute (value_type);
75 1.1 mrg
76 1.1 mrg private:
77 1.1 mrg /* The bounds to use for iterating over subrtxes. */
78 1.1 mrg const rtx_subrtx_bound_info *m_bounds;
79 1.1 mrg
80 1.1 mrg /* The storage used for the worklist. */
81 1.1 mrg array_type &m_array;
82 1.1 mrg
83 1.1 mrg /* The current rtx. */
84 1.1 mrg value_type m_current;
85 1.1 mrg
86 1.1 mrg /* The base of the current worklist. */
87 1.1 mrg value_type *m_base;
88 1.1 mrg
89 1.1 mrg /* The number of subrtxes in M_BASE. */
90 1.1 mrg size_t m_end;
91 1.1 mrg
92 1.1 mrg /* The following booleans shouldn't end up in registers or memory
93 1.1 mrg but just direct control flow. */
94 1.1 mrg
95 1.1 mrg /* True if the iteration is over. */
96 1.1 mrg bool m_done;
97 1.1 mrg
98 1.1 mrg /* True if we should skip the subrtxes of M_CURRENT. */
99 1.1 mrg bool m_skip;
100 1.1 mrg
101 1.1 mrg /* True if M_CURRENT has been replaced with a different rtx. */
102 1.1 mrg bool m_substitute;
103 1.1 mrg
104 1.1 mrg static void free_array (array_type &);
105 1.1 mrg static size_t add_subrtxes_to_queue (array_type &, value_type *, size_t,
106 1.1 mrg rtx_type);
107 1.1 mrg static value_type *add_single_to_queue (array_type &, value_type *, size_t,
108 1.1 mrg value_type);
109 1.1 mrg };
110 1.1 mrg
111 1.1 mrg template <typename T>
112 1.1 mrg inline generic_subrtx_iterator <T>::array_type::array_type () : heap (0) {}
113 1.1 mrg
114 1.1 mrg template <typename T>
115 1.1 mrg inline generic_subrtx_iterator <T>::array_type::~array_type ()
116 1.1 mrg {
117 1.1 mrg if (__builtin_expect (heap != 0, false))
118 1.1 mrg free_array (*this);
119 1.1 mrg }
120 1.1 mrg
121 1.1 mrg /* Iterate over X and its subrtxes, in arbitrary order. Use ARRAY to
122 1.1 mrg store the worklist. We use an external array in order to avoid
123 1.1 mrg capturing the fields of this structure when taking the address of
124 1.1 mrg the array. Use BOUNDS to find the bounds of simple "e"-string codes. */
125 1.1 mrg
126 1.1 mrg template <typename T>
127 1.1 mrg inline generic_subrtx_iterator <T>::
128 1.1 mrg generic_subrtx_iterator (array_type &array, value_type x,
129 1.1 mrg const rtx_subrtx_bound_info *bounds)
130 1.1 mrg : m_bounds (bounds),
131 1.1 mrg m_array (array),
132 1.1 mrg m_current (x),
133 1.1 mrg m_base (m_array.stack),
134 1.1 mrg m_end (0),
135 1.1 mrg m_done (false),
136 1.1 mrg m_skip (false),
137 1.1 mrg m_substitute (false)
138 1.1 mrg {
139 1.1 mrg }
140 1.1 mrg
141 1.1 mrg /* Return the current subrtx. */
142 1.1 mrg
143 1.1 mrg template <typename T>
144 1.1 mrg inline typename T::value_type
145 1.1 mrg generic_subrtx_iterator <T>::operator * () const
146 1.1 mrg {
147 1.1 mrg return m_current;
148 1.1 mrg }
149 1.1 mrg
150 1.1 mrg /* Return true if the iteration has finished. */
151 1.1 mrg
152 1.1 mrg template <typename T>
153 1.1 mrg inline bool
154 1.1 mrg generic_subrtx_iterator <T>::at_end () const
155 1.1 mrg {
156 1.1 mrg return m_done;
157 1.1 mrg }
158 1.1 mrg
159 1.1 mrg /* Move on to the next subrtx. */
160 1.1 mrg
161 1.1 mrg template <typename T>
162 1.1 mrg inline void
163 1.1 mrg generic_subrtx_iterator <T>::next ()
164 1.1 mrg {
165 1.1 mrg if (m_substitute)
166 1.1 mrg {
167 1.1 mrg m_substitute = false;
168 1.1 mrg m_skip = false;
169 1.1 mrg return;
170 1.1 mrg }
171 1.1 mrg if (!m_skip)
172 1.1 mrg {
173 1.1 mrg /* Add the subrtxes of M_CURRENT. */
174 1.1 mrg rtx_type x = T::get_rtx (m_current);
175 1.1 mrg if (__builtin_expect (x != 0, true))
176 1.1 mrg {
177 1.1 mrg enum rtx_code code = GET_CODE (x);
178 1.1 mrg ssize_t count = m_bounds[code].count;
179 1.1 mrg if (count > 0)
180 1.1 mrg {
181 1.1 mrg /* Handle the simple case of a single "e" block that is known
182 1.1 mrg to fit into the current array. */
183 1.1 mrg if (__builtin_expect (m_end + count <= LOCAL_ELEMS + 1, true))
184 1.1 mrg {
185 1.1 mrg /* Set M_CURRENT to the first subrtx and queue the rest. */
186 1.1 mrg ssize_t start = m_bounds[code].start;
187 1.1 mrg rtunion_type *src = &x->u.fld[start];
188 1.1 mrg if (__builtin_expect (count > 2, false))
189 1.1 mrg m_base[m_end++] = T::get_value (src[2].rt_rtx);
190 1.1 mrg if (count > 1)
191 1.1 mrg m_base[m_end++] = T::get_value (src[1].rt_rtx);
192 1.1 mrg m_current = T::get_value (src[0].rt_rtx);
193 1.1 mrg return;
194 1.1 mrg }
195 1.1 mrg /* Handle cases which aren't simple "e" sequences or where
196 1.1 mrg the sequence might overrun M_BASE. */
197 1.1 mrg count = add_subrtxes_to_queue (m_array, m_base, m_end, x);
198 1.1 mrg if (count > 0)
199 1.1 mrg {
200 1.1 mrg m_end += count;
201 1.1 mrg if (m_end > LOCAL_ELEMS)
202 1.1 mrg m_base = m_array.heap->address ();
203 1.1 mrg m_current = m_base[--m_end];
204 1.1 mrg return;
205 1.1 mrg }
206 1.1 mrg }
207 1.1 mrg }
208 1.1 mrg }
209 1.1 mrg else
210 1.1 mrg m_skip = false;
211 1.1 mrg if (m_end == 0)
212 1.1 mrg m_done = true;
213 1.1 mrg else
214 1.1 mrg m_current = m_base[--m_end];
215 1.1 mrg }
216 1.1 mrg
217 1.1 mrg /* Skip the subrtxes of the current rtx. */
218 1.1 mrg
219 1.1 mrg template <typename T>
220 1.1 mrg inline void
221 1.1 mrg generic_subrtx_iterator <T>::skip_subrtxes ()
222 1.1 mrg {
223 1.1 mrg m_skip = true;
224 1.1 mrg }
225 1.1 mrg
226 1.1 mrg /* Ignore the subrtxes of the current rtx and look at X instead. */
227 1.1 mrg
228 1.1 mrg template <typename T>
229 1.1 mrg inline void
230 1.1 mrg generic_subrtx_iterator <T>::substitute (value_type x)
231 1.1 mrg {
232 1.1 mrg m_substitute = true;
233 1.1 mrg m_current = x;
234 1.1 mrg }
235 1.1 mrg
236 1.1 mrg /* Iterators for const_rtx. */
237 1.1 mrg struct const_rtx_accessor
238 1.1 mrg {
239 1.1 mrg typedef const_rtx value_type;
240 1.1 mrg typedef const_rtx rtx_type;
241 1.1 mrg typedef const rtunion rtunion_type;
242 1.1 mrg static rtx_type get_rtx (value_type x) { return x; }
243 1.1 mrg static value_type get_value (rtx_type x) { return x; }
244 1.1 mrg };
245 1.1 mrg typedef generic_subrtx_iterator <const_rtx_accessor> subrtx_iterator;
246 1.1 mrg
247 1.1 mrg /* Iterators for non-constant rtx. */
248 1.1 mrg struct rtx_var_accessor
249 1.1 mrg {
250 1.1 mrg typedef rtx value_type;
251 1.1 mrg typedef rtx rtx_type;
252 1.1 mrg typedef rtunion rtunion_type;
253 1.1 mrg static rtx_type get_rtx (value_type x) { return x; }
254 1.1 mrg static value_type get_value (rtx_type x) { return x; }
255 1.1 mrg };
256 1.1 mrg typedef generic_subrtx_iterator <rtx_var_accessor> subrtx_var_iterator;
257 1.1 mrg
258 1.1 mrg /* Iterators for rtx *. */
259 1.1 mrg struct rtx_ptr_accessor
260 1.1 mrg {
261 1.1 mrg typedef rtx *value_type;
262 1.1 mrg typedef rtx rtx_type;
263 1.1 mrg typedef rtunion rtunion_type;
264 1.1 mrg static rtx_type get_rtx (value_type ptr) { return *ptr; }
265 1.1 mrg static value_type get_value (rtx_type &x) { return &x; }
266 1.1 mrg };
267 1.1 mrg typedef generic_subrtx_iterator <rtx_ptr_accessor> subrtx_ptr_iterator;
268 1.1 mrg
269 1.1 mrg #define ALL_BOUNDS rtx_all_subrtx_bounds
270 1.1 mrg #define NONCONST_BOUNDS rtx_nonconst_subrtx_bounds
271 1.1 mrg
272 1.1 mrg /* Use ITER to iterate over const_rtx X and its recursive subrtxes,
273 1.1 mrg using subrtx_iterator::array ARRAY as the storage for the worklist.
274 1.1 mrg ARRAY can be reused for multiple consecutive iterations but shouldn't
275 1.1 mrg be shared by two concurrent iterations. TYPE is ALL if all subrtxes
276 1.1 mrg are of interest or NONCONST if it is safe to ignore subrtxes of
277 1.1 mrg constants. */
278 1.1 mrg #define FOR_EACH_SUBRTX(ITER, ARRAY, X, TYPE) \
279 1.1 mrg for (subrtx_iterator ITER (ARRAY, X, TYPE##_BOUNDS); !ITER.at_end (); \
280 1.1 mrg ITER.next ())
281 1.1 mrg
282 1.1 mrg /* Like FOR_EACH_SUBRTX, but iterate over subrtxes of an rtx X. */
283 1.1 mrg #define FOR_EACH_SUBRTX_VAR(ITER, ARRAY, X, TYPE) \
284 1.1 mrg for (subrtx_var_iterator ITER (ARRAY, X, TYPE##_BOUNDS); !ITER.at_end (); \
285 1.1 mrg ITER.next ())
286 1.1 mrg
287 1.1 mrg /* Like FOR_EACH_SUBRTX, but iterate over subrtx pointers of rtx pointer X.
288 1.1 mrg For example, if X is &PATTERN (insn) and the pattern is a SET, iterate
289 1.1 mrg over &PATTERN (insn), &SET_DEST (PATTERN (insn)), etc. */
290 1.1 mrg #define FOR_EACH_SUBRTX_PTR(ITER, ARRAY, X, TYPE) \
291 1.1 mrg for (subrtx_ptr_iterator ITER (ARRAY, X, TYPE##_BOUNDS); !ITER.at_end (); \
292 1.1 mrg ITER.next ())
293