Home | History | Annotate | Line # | Download | only in gcc
gimple-iterator.h revision 1.1.1.1.4.2
      1          1.1       mrg /* Header file for gimple iterators.
      2  1.1.1.1.4.2    martin    Copyright (C) 2013-2017 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 #ifndef GCC_GIMPLE_ITERATOR_H
     21          1.1       mrg #define GCC_GIMPLE_ITERATOR_H
     22          1.1       mrg 
     23          1.1       mrg /* Iterator object for GIMPLE statement sequences.  */
     24          1.1       mrg 
     25          1.1       mrg struct gimple_stmt_iterator
     26          1.1       mrg {
     27          1.1       mrg   /* Sequence node holding the current statement.  */
     28          1.1       mrg   gimple_seq_node ptr;
     29          1.1       mrg 
     30          1.1       mrg   /* Sequence and basic block holding the statement.  These fields
     31          1.1       mrg      are necessary to handle edge cases such as when statement is
     32          1.1       mrg      added to an empty basic block or when the last statement of a
     33          1.1       mrg      block/sequence is removed.  */
     34          1.1       mrg   gimple_seq *seq;
     35          1.1       mrg   basic_block bb;
     36          1.1       mrg };
     37          1.1       mrg 
     38          1.1       mrg /* Iterator over GIMPLE_PHI statements.  */
     39          1.1       mrg struct gphi_iterator : public gimple_stmt_iterator
     40          1.1       mrg {
     41          1.1       mrg   gphi *phi () const
     42          1.1       mrg   {
     43          1.1       mrg     return as_a <gphi *> (ptr);
     44          1.1       mrg   }
     45          1.1       mrg };
     46          1.1       mrg 
     47          1.1       mrg enum gsi_iterator_update
     48          1.1       mrg {
     49          1.1       mrg   GSI_NEW_STMT,		/* Only valid when single statement is added, move
     50          1.1       mrg 			   iterator to it.  */
     51          1.1       mrg   GSI_SAME_STMT,	/* Leave the iterator at the same statement.  */
     52          1.1       mrg   GSI_CONTINUE_LINKING	/* Move iterator to whatever position is suitable
     53          1.1       mrg 			   for linking other statements in the same
     54          1.1       mrg 			   direction.  */
     55          1.1       mrg };
     56          1.1       mrg 
     57          1.1       mrg extern void gsi_insert_seq_before_without_update (gimple_stmt_iterator *,
     58          1.1       mrg 						  gimple_seq,
     59          1.1       mrg 						  enum gsi_iterator_update);
     60          1.1       mrg extern void gsi_insert_seq_before (gimple_stmt_iterator *, gimple_seq,
     61          1.1       mrg 				   enum gsi_iterator_update);
     62          1.1       mrg extern void gsi_insert_seq_after_without_update (gimple_stmt_iterator *,
     63          1.1       mrg 						 gimple_seq,
     64          1.1       mrg 						 enum gsi_iterator_update);
     65          1.1       mrg extern void gsi_insert_seq_after (gimple_stmt_iterator *, gimple_seq,
     66          1.1       mrg 				  enum gsi_iterator_update);
     67          1.1       mrg extern gimple_seq gsi_split_seq_after (gimple_stmt_iterator);
     68  1.1.1.1.4.1  christos extern void gsi_set_stmt (gimple_stmt_iterator *, gimple *);
     69          1.1       mrg extern void gsi_split_seq_before (gimple_stmt_iterator *, gimple_seq *);
     70  1.1.1.1.4.1  christos extern bool gsi_replace (gimple_stmt_iterator *, gimple *, bool);
     71          1.1       mrg extern void gsi_replace_with_seq (gimple_stmt_iterator *, gimple_seq, bool);
     72  1.1.1.1.4.1  christos extern void gsi_insert_before_without_update (gimple_stmt_iterator *, gimple *,
     73          1.1       mrg 					      enum gsi_iterator_update);
     74  1.1.1.1.4.1  christos extern void gsi_insert_before (gimple_stmt_iterator *, gimple *,
     75          1.1       mrg 			       enum gsi_iterator_update);
     76  1.1.1.1.4.1  christos extern void gsi_insert_after_without_update (gimple_stmt_iterator *, gimple *,
     77          1.1       mrg 					     enum gsi_iterator_update);
     78  1.1.1.1.4.1  christos extern void gsi_insert_after (gimple_stmt_iterator *, gimple *,
     79          1.1       mrg 			      enum gsi_iterator_update);
     80          1.1       mrg extern bool gsi_remove (gimple_stmt_iterator *, bool);
     81  1.1.1.1.4.1  christos extern gimple_stmt_iterator gsi_for_stmt (gimple *);
     82          1.1       mrg extern gphi_iterator gsi_for_phi (gphi *);
     83          1.1       mrg extern void gsi_move_after (gimple_stmt_iterator *, gimple_stmt_iterator *);
     84          1.1       mrg extern void gsi_move_before (gimple_stmt_iterator *, gimple_stmt_iterator *);
     85          1.1       mrg extern void gsi_move_to_bb_end (gimple_stmt_iterator *, basic_block);
     86  1.1.1.1.4.1  christos extern void gsi_insert_on_edge (edge, gimple *);
     87          1.1       mrg extern void gsi_insert_seq_on_edge (edge, gimple_seq);
     88  1.1.1.1.4.1  christos extern basic_block gsi_insert_on_edge_immediate (edge, gimple *);
     89          1.1       mrg extern basic_block gsi_insert_seq_on_edge_immediate (edge, gimple_seq);
     90          1.1       mrg extern void gsi_commit_edge_inserts (void);
     91          1.1       mrg extern void gsi_commit_one_edge_insert (edge, basic_block *);
     92          1.1       mrg extern gphi_iterator gsi_start_phis (basic_block);
     93  1.1.1.1.4.1  christos extern void update_modified_stmts (gimple_seq);
     94          1.1       mrg 
     95          1.1       mrg /* Return a new iterator pointing to GIMPLE_SEQ's first statement.  */
     96          1.1       mrg 
     97          1.1       mrg static inline gimple_stmt_iterator
     98          1.1       mrg gsi_start_1 (gimple_seq *seq)
     99          1.1       mrg {
    100          1.1       mrg   gimple_stmt_iterator i;
    101          1.1       mrg 
    102          1.1       mrg   i.ptr = gimple_seq_first (*seq);
    103          1.1       mrg   i.seq = seq;
    104          1.1       mrg   i.bb = i.ptr ? gimple_bb (i.ptr) : NULL;
    105          1.1       mrg 
    106          1.1       mrg   return i;
    107          1.1       mrg }
    108          1.1       mrg 
    109          1.1       mrg #define gsi_start(x) gsi_start_1 (&(x))
    110          1.1       mrg 
    111          1.1       mrg static inline gimple_stmt_iterator
    112          1.1       mrg gsi_none (void)
    113          1.1       mrg {
    114          1.1       mrg   gimple_stmt_iterator i;
    115          1.1       mrg   i.ptr = NULL;
    116          1.1       mrg   i.seq = NULL;
    117          1.1       mrg   i.bb = NULL;
    118          1.1       mrg   return i;
    119          1.1       mrg }
    120          1.1       mrg 
    121          1.1       mrg /* Return a new iterator pointing to the first statement in basic block BB.  */
    122          1.1       mrg 
    123          1.1       mrg static inline gimple_stmt_iterator
    124          1.1       mrg gsi_start_bb (basic_block bb)
    125          1.1       mrg {
    126          1.1       mrg   gimple_stmt_iterator i;
    127          1.1       mrg   gimple_seq *seq;
    128          1.1       mrg 
    129          1.1       mrg   seq = bb_seq_addr (bb);
    130          1.1       mrg   i.ptr = gimple_seq_first (*seq);
    131          1.1       mrg   i.seq = seq;
    132          1.1       mrg   i.bb = bb;
    133          1.1       mrg 
    134          1.1       mrg   return i;
    135          1.1       mrg }
    136          1.1       mrg 
    137          1.1       mrg gimple_stmt_iterator gsi_start_edge (edge e);
    138          1.1       mrg 
    139          1.1       mrg /* Return a new iterator initially pointing to GIMPLE_SEQ's last statement.  */
    140          1.1       mrg 
    141          1.1       mrg static inline gimple_stmt_iterator
    142          1.1       mrg gsi_last_1 (gimple_seq *seq)
    143          1.1       mrg {
    144          1.1       mrg   gimple_stmt_iterator i;
    145          1.1       mrg 
    146          1.1       mrg   i.ptr = gimple_seq_last (*seq);
    147          1.1       mrg   i.seq = seq;
    148          1.1       mrg   i.bb = i.ptr ? gimple_bb (i.ptr) : NULL;
    149          1.1       mrg 
    150          1.1       mrg   return i;
    151          1.1       mrg }
    152          1.1       mrg 
    153          1.1       mrg #define gsi_last(x) gsi_last_1 (&(x))
    154          1.1       mrg 
    155          1.1       mrg /* Return a new iterator pointing to the last statement in basic block BB.  */
    156          1.1       mrg 
    157          1.1       mrg static inline gimple_stmt_iterator
    158          1.1       mrg gsi_last_bb (basic_block bb)
    159          1.1       mrg {
    160          1.1       mrg   gimple_stmt_iterator i;
    161          1.1       mrg   gimple_seq *seq;
    162          1.1       mrg 
    163          1.1       mrg   seq = bb_seq_addr (bb);
    164          1.1       mrg   i.ptr = gimple_seq_last (*seq);
    165          1.1       mrg   i.seq = seq;
    166          1.1       mrg   i.bb = bb;
    167          1.1       mrg 
    168          1.1       mrg   return i;
    169          1.1       mrg }
    170          1.1       mrg 
    171          1.1       mrg /* Return true if I is at the end of its sequence.  */
    172          1.1       mrg 
    173          1.1       mrg static inline bool
    174          1.1       mrg gsi_end_p (gimple_stmt_iterator i)
    175          1.1       mrg {
    176          1.1       mrg   return i.ptr == NULL;
    177          1.1       mrg }
    178          1.1       mrg 
    179          1.1       mrg /* Return true if I is one statement before the end of its sequence.  */
    180          1.1       mrg 
    181          1.1       mrg static inline bool
    182          1.1       mrg gsi_one_before_end_p (gimple_stmt_iterator i)
    183          1.1       mrg {
    184          1.1       mrg   return i.ptr != NULL && i.ptr->next == NULL;
    185          1.1       mrg }
    186          1.1       mrg 
    187          1.1       mrg /* Advance the iterator to the next gimple statement.  */
    188          1.1       mrg 
    189          1.1       mrg static inline void
    190          1.1       mrg gsi_next (gimple_stmt_iterator *i)
    191          1.1       mrg {
    192          1.1       mrg   i->ptr = i->ptr->next;
    193          1.1       mrg }
    194          1.1       mrg 
    195          1.1       mrg /* Advance the iterator to the previous gimple statement.  */
    196          1.1       mrg 
    197          1.1       mrg static inline void
    198          1.1       mrg gsi_prev (gimple_stmt_iterator *i)
    199          1.1       mrg {
    200  1.1.1.1.4.1  christos   gimple *prev = i->ptr->prev;
    201          1.1       mrg   if (prev->next)
    202          1.1       mrg     i->ptr = prev;
    203          1.1       mrg   else
    204          1.1       mrg     i->ptr = NULL;
    205          1.1       mrg }
    206          1.1       mrg 
    207          1.1       mrg /* Return the current stmt.  */
    208          1.1       mrg 
    209  1.1.1.1.4.1  christos static inline gimple *
    210          1.1       mrg gsi_stmt (gimple_stmt_iterator i)
    211          1.1       mrg {
    212          1.1       mrg   return i.ptr;
    213          1.1       mrg }
    214          1.1       mrg 
    215          1.1       mrg /* Return a new iterator pointing to the first non-debug statement
    216          1.1       mrg    in basic block BB.  */
    217          1.1       mrg 
    218          1.1       mrg static inline gimple_stmt_iterator
    219          1.1       mrg gsi_start_bb_nondebug (basic_block bb)
    220          1.1       mrg {
    221          1.1       mrg   gimple_stmt_iterator gsi = gsi_start_bb (bb);
    222          1.1       mrg   while (!gsi_end_p (gsi) && is_gimple_debug (gsi_stmt (gsi)))
    223          1.1       mrg     gsi_next (&gsi);
    224          1.1       mrg 
    225          1.1       mrg   return gsi;
    226          1.1       mrg }
    227          1.1       mrg 
    228          1.1       mrg /* Return a block statement iterator that points to the first non-label
    229          1.1       mrg    statement in block BB.  */
    230          1.1       mrg 
    231          1.1       mrg static inline gimple_stmt_iterator
    232          1.1       mrg gsi_after_labels (basic_block bb)
    233          1.1       mrg {
    234          1.1       mrg   gimple_stmt_iterator gsi = gsi_start_bb (bb);
    235          1.1       mrg 
    236          1.1       mrg   while (!gsi_end_p (gsi) && gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL)
    237          1.1       mrg     gsi_next (&gsi);
    238          1.1       mrg 
    239          1.1       mrg   return gsi;
    240          1.1       mrg }
    241          1.1       mrg 
    242          1.1       mrg /* Advance the iterator to the next non-debug gimple statement.  */
    243          1.1       mrg 
    244          1.1       mrg static inline void
    245          1.1       mrg gsi_next_nondebug (gimple_stmt_iterator *i)
    246          1.1       mrg {
    247          1.1       mrg   do
    248          1.1       mrg     {
    249          1.1       mrg       gsi_next (i);
    250          1.1       mrg     }
    251          1.1       mrg   while (!gsi_end_p (*i) && is_gimple_debug (gsi_stmt (*i)));
    252          1.1       mrg }
    253          1.1       mrg 
    254          1.1       mrg /* Advance the iterator to the previous non-debug gimple statement.  */
    255          1.1       mrg 
    256          1.1       mrg static inline void
    257          1.1       mrg gsi_prev_nondebug (gimple_stmt_iterator *i)
    258          1.1       mrg {
    259          1.1       mrg   do
    260          1.1       mrg     {
    261          1.1       mrg       gsi_prev (i);
    262          1.1       mrg     }
    263          1.1       mrg   while (!gsi_end_p (*i) && is_gimple_debug (gsi_stmt (*i)));
    264          1.1       mrg }
    265          1.1       mrg 
    266          1.1       mrg /* Return a new iterator pointing to the first non-debug statement in
    267          1.1       mrg    basic block BB.  */
    268          1.1       mrg 
    269          1.1       mrg static inline gimple_stmt_iterator
    270          1.1       mrg gsi_start_nondebug_bb (basic_block bb)
    271          1.1       mrg {
    272          1.1       mrg   gimple_stmt_iterator i = gsi_start_bb (bb);
    273          1.1       mrg 
    274          1.1       mrg   if (!gsi_end_p (i) && is_gimple_debug (gsi_stmt (i)))
    275          1.1       mrg     gsi_next_nondebug (&i);
    276          1.1       mrg 
    277          1.1       mrg   return i;
    278          1.1       mrg }
    279          1.1       mrg 
    280          1.1       mrg /* Return a new iterator pointing to the first non-debug non-label statement in
    281          1.1       mrg    basic block BB.  */
    282          1.1       mrg 
    283          1.1       mrg static inline gimple_stmt_iterator
    284          1.1       mrg gsi_start_nondebug_after_labels_bb (basic_block bb)
    285          1.1       mrg {
    286          1.1       mrg   gimple_stmt_iterator i = gsi_after_labels (bb);
    287          1.1       mrg 
    288          1.1       mrg   if (!gsi_end_p (i) && is_gimple_debug (gsi_stmt (i)))
    289          1.1       mrg     gsi_next_nondebug (&i);
    290          1.1       mrg 
    291          1.1       mrg   return i;
    292          1.1       mrg }
    293          1.1       mrg 
    294          1.1       mrg /* Return a new iterator pointing to the last non-debug statement in
    295          1.1       mrg    basic block BB.  */
    296          1.1       mrg 
    297          1.1       mrg static inline gimple_stmt_iterator
    298          1.1       mrg gsi_last_nondebug_bb (basic_block bb)
    299          1.1       mrg {
    300          1.1       mrg   gimple_stmt_iterator i = gsi_last_bb (bb);
    301          1.1       mrg 
    302          1.1       mrg   if (!gsi_end_p (i) && is_gimple_debug (gsi_stmt (i)))
    303          1.1       mrg     gsi_prev_nondebug (&i);
    304          1.1       mrg 
    305          1.1       mrg   return i;
    306          1.1       mrg }
    307          1.1       mrg 
    308  1.1.1.1.4.2    martin /* Return true if I is followed only by debug statements in its
    309  1.1.1.1.4.2    martin    sequence.  */
    310  1.1.1.1.4.2    martin 
    311  1.1.1.1.4.2    martin static inline bool
    312  1.1.1.1.4.2    martin gsi_one_nondebug_before_end_p (gimple_stmt_iterator i)
    313  1.1.1.1.4.2    martin {
    314  1.1.1.1.4.2    martin   if (gsi_one_before_end_p (i))
    315  1.1.1.1.4.2    martin     return true;
    316  1.1.1.1.4.2    martin   if (gsi_end_p (i))
    317  1.1.1.1.4.2    martin     return false;
    318  1.1.1.1.4.2    martin   gsi_next_nondebug (&i);
    319  1.1.1.1.4.2    martin   return gsi_end_p (i);
    320  1.1.1.1.4.2    martin }
    321  1.1.1.1.4.2    martin 
    322          1.1       mrg /* Iterates I statement iterator to the next non-virtual statement.  */
    323          1.1       mrg 
    324          1.1       mrg static inline void
    325          1.1       mrg gsi_next_nonvirtual_phi (gphi_iterator *i)
    326          1.1       mrg {
    327          1.1       mrg   gphi *phi;
    328          1.1       mrg 
    329          1.1       mrg   if (gsi_end_p (*i))
    330          1.1       mrg     return;
    331          1.1       mrg 
    332          1.1       mrg   phi = i->phi ();
    333          1.1       mrg   gcc_assert (phi != NULL);
    334          1.1       mrg 
    335          1.1       mrg   while (virtual_operand_p (gimple_phi_result (phi)))
    336          1.1       mrg     {
    337          1.1       mrg       gsi_next (i);
    338          1.1       mrg 
    339          1.1       mrg       if (gsi_end_p (*i))
    340          1.1       mrg 	return;
    341          1.1       mrg 
    342          1.1       mrg       phi = i->phi ();
    343          1.1       mrg     }
    344          1.1       mrg }
    345          1.1       mrg 
    346          1.1       mrg /* Return the basic block associated with this iterator.  */
    347          1.1       mrg 
    348          1.1       mrg static inline basic_block
    349          1.1       mrg gsi_bb (gimple_stmt_iterator i)
    350          1.1       mrg {
    351          1.1       mrg   return i.bb;
    352          1.1       mrg }
    353          1.1       mrg 
    354          1.1       mrg /* Return the sequence associated with this iterator.  */
    355          1.1       mrg 
    356          1.1       mrg static inline gimple_seq
    357          1.1       mrg gsi_seq (gimple_stmt_iterator i)
    358          1.1       mrg {
    359          1.1       mrg   return *i.seq;
    360          1.1       mrg }
    361          1.1       mrg 
    362  1.1.1.1.4.1  christos /* Determine whether SEQ is a nondebug singleton.  */
    363  1.1.1.1.4.1  christos 
    364  1.1.1.1.4.1  christos static inline bool
    365  1.1.1.1.4.1  christos gimple_seq_nondebug_singleton_p (gimple_seq seq)
    366  1.1.1.1.4.1  christos {
    367  1.1.1.1.4.1  christos   gimple_stmt_iterator gsi;
    368  1.1.1.1.4.1  christos 
    369  1.1.1.1.4.1  christos   /* Find a nondebug gimple.  */
    370  1.1.1.1.4.1  christos   gsi.ptr = gimple_seq_first (seq);
    371  1.1.1.1.4.1  christos   gsi.seq = &seq;
    372  1.1.1.1.4.1  christos   gsi.bb = NULL;
    373  1.1.1.1.4.1  christos   while (!gsi_end_p (gsi)
    374  1.1.1.1.4.1  christos 	 && is_gimple_debug (gsi_stmt (gsi)))
    375  1.1.1.1.4.1  christos     gsi_next (&gsi);
    376  1.1.1.1.4.1  christos 
    377  1.1.1.1.4.1  christos   /* No nondebug gimple found, not a singleton.  */
    378  1.1.1.1.4.1  christos   if (gsi_end_p (gsi))
    379  1.1.1.1.4.1  christos     return false;
    380  1.1.1.1.4.1  christos 
    381  1.1.1.1.4.1  christos   /* Find a next nondebug gimple.  */
    382  1.1.1.1.4.1  christos   gsi_next (&gsi);
    383  1.1.1.1.4.1  christos   while (!gsi_end_p (gsi)
    384  1.1.1.1.4.1  christos 	 && is_gimple_debug (gsi_stmt (gsi)))
    385  1.1.1.1.4.1  christos     gsi_next (&gsi);
    386  1.1.1.1.4.1  christos 
    387  1.1.1.1.4.1  christos   /* Only a singleton if there's no next nondebug gimple.  */
    388  1.1.1.1.4.1  christos   return gsi_end_p (gsi);
    389  1.1.1.1.4.1  christos }
    390  1.1.1.1.4.1  christos 
    391          1.1       mrg #endif /* GCC_GIMPLE_ITERATOR_H */
    392