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