Home | History | Annotate | Line # | Download | only in gcc
      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