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