(root)/
gcc-13.2.0/
gcc/
gimple-iterator.h
       1  /* Header file for gimple iterators.
       2     Copyright (C) 2013-2023 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 = 2,	/* Move the iterator to the first statement added.  */
      50    GSI_LAST_NEW_STMT,	/* Move the iterator to the last statement added.  */
      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 gimple_stmt_iterator gsi_for_stmt (gimple *, gimple_seq *);
      83  extern gphi_iterator gsi_for_phi (gphi *);
      84  extern void gsi_move_after (gimple_stmt_iterator *, gimple_stmt_iterator *);
      85  extern void gsi_move_before (gimple_stmt_iterator *, gimple_stmt_iterator *);
      86  extern void gsi_move_to_bb_end (gimple_stmt_iterator *, basic_block);
      87  extern void gsi_insert_on_edge (edge, gimple *);
      88  extern void gsi_insert_seq_on_edge (edge, gimple_seq);
      89  extern basic_block gsi_insert_on_edge_immediate (edge, gimple *);
      90  extern basic_block gsi_insert_seq_on_edge_immediate (edge, gimple_seq);
      91  extern void gsi_commit_edge_inserts (void);
      92  extern void gsi_commit_one_edge_insert (edge, basic_block *);
      93  extern gphi_iterator gsi_start_phis (basic_block);
      94  extern void update_modified_stmts (gimple_seq);
      95  
      96  /* Return a new iterator pointing to GIMPLE_SEQ's first statement.  */
      97  
      98  inline gimple_stmt_iterator
      99  gsi_start (gimple_seq &seq)
     100  {
     101    gimple_stmt_iterator i;
     102  
     103    i.ptr = gimple_seq_first (seq);
     104    i.seq = &seq;
     105    i.bb = i.ptr ? gimple_bb (i.ptr) : NULL;
     106  
     107    return i;
     108  }
     109  
     110  inline gimple_stmt_iterator
     111  gsi_none (void)
     112  {
     113    gimple_stmt_iterator i;
     114    i.ptr = NULL;
     115    i.seq = NULL;
     116    i.bb = NULL;
     117    return i;
     118  }
     119  
     120  /* Return a new iterator pointing to the first statement in basic block BB.  */
     121  
     122  inline gimple_stmt_iterator
     123  gsi_start_bb (basic_block bb)
     124  {
     125    gimple_stmt_iterator i;
     126    gimple_seq *seq;
     127  
     128    seq = bb_seq_addr (bb);
     129    i.ptr = gimple_seq_first (*seq);
     130    i.seq = seq;
     131    i.bb = bb;
     132  
     133    return i;
     134  }
     135  
     136  gimple_stmt_iterator gsi_start_edge (edge e);
     137  
     138  /* Return a new iterator initially pointing to GIMPLE_SEQ's last statement.  */
     139  
     140  inline gimple_stmt_iterator
     141  gsi_last (gimple_seq &seq)
     142  {
     143    gimple_stmt_iterator i;
     144  
     145    i.ptr = gimple_seq_last (seq);
     146    i.seq = &seq;
     147    i.bb = i.ptr ? gimple_bb (i.ptr) : NULL;
     148  
     149    return i;
     150  }
     151  
     152  /* Return a new iterator pointing to the last statement in basic block BB.  */
     153  
     154  inline gimple_stmt_iterator
     155  gsi_last_bb (basic_block bb)
     156  {
     157    gimple_stmt_iterator i;
     158    gimple_seq *seq;
     159  
     160    seq = bb_seq_addr (bb);
     161    i.ptr = gimple_seq_last (*seq);
     162    i.seq = seq;
     163    i.bb = bb;
     164  
     165    return i;
     166  }
     167  
     168  /* Return true if I is at the end of its sequence.  */
     169  
     170  inline bool
     171  gsi_end_p (gimple_stmt_iterator i)
     172  {
     173    return i.ptr == NULL;
     174  }
     175  
     176  /* Return true if I is one statement before the end of its sequence.  */
     177  
     178  inline bool
     179  gsi_one_before_end_p (gimple_stmt_iterator i)
     180  {
     181    return i.ptr != NULL && i.ptr->next == NULL;
     182  }
     183  
     184  /* Advance the iterator to the next gimple statement.  */
     185  
     186  inline void
     187  gsi_next (gimple_stmt_iterator *i)
     188  {
     189    i->ptr = i->ptr->next;
     190  }
     191  
     192  /* Advance the iterator to the previous gimple statement.  */
     193  
     194  inline void
     195  gsi_prev (gimple_stmt_iterator *i)
     196  {
     197    gimple *prev = i->ptr->prev;
     198    if (prev->next)
     199      i->ptr = prev;
     200    else
     201      i->ptr = NULL;
     202  }
     203  
     204  /* Return the current stmt.  */
     205  
     206  inline gimple *
     207  gsi_stmt (gimple_stmt_iterator i)
     208  {
     209    return i.ptr;
     210  }
     211  
     212  /* Return a block statement iterator that points to the first
     213     non-label statement in block BB.  */
     214  
     215  inline gimple_stmt_iterator
     216  gsi_after_labels (basic_block bb)
     217  {
     218    gimple_stmt_iterator gsi = gsi_start_bb (bb);
     219  
     220    for (; !gsi_end_p (gsi); )
     221      {
     222        if (gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL)
     223  	gsi_next (&gsi);
     224        else
     225  	break;
     226      }
     227  
     228    return gsi;
     229  }
     230  
     231  /* Return a statement iterator that points to the first
     232     non-label statement in sequence SEQ.  */
     233  
     234  inline gimple_stmt_iterator
     235  gsi_after_labels (gimple_seq &seq)
     236  {
     237    gimple_stmt_iterator gsi = gsi_start (seq);
     238  
     239    for (; !gsi_end_p (gsi); )
     240      {
     241        if (gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL)
     242  	gsi_next (&gsi);
     243        else
     244  	break;
     245      }
     246  
     247    return gsi;
     248  }
     249  
     250  /* Advance the iterator to the next non-debug gimple statement.  */
     251  
     252  inline void
     253  gsi_next_nondebug (gimple_stmt_iterator *i)
     254  {
     255    do
     256      {
     257        gsi_next (i);
     258      }
     259    while (!gsi_end_p (*i) && is_gimple_debug (gsi_stmt (*i)));
     260  }
     261  
     262  /* Advance the iterator to the previous non-debug gimple statement.  */
     263  
     264  inline void
     265  gsi_prev_nondebug (gimple_stmt_iterator *i)
     266  {
     267    do
     268      {
     269        gsi_prev (i);
     270      }
     271    while (!gsi_end_p (*i) && is_gimple_debug (gsi_stmt (*i)));
     272  }
     273  
     274  /* Return a new iterator pointing to the first non-debug statement in
     275     SEQ.  */
     276  
     277  inline gimple_stmt_iterator
     278  gsi_start_nondebug (gimple_seq seq)
     279  {
     280    gimple_stmt_iterator gsi = gsi_start (seq);
     281    if (!gsi_end_p (gsi) && is_gimple_debug (gsi_stmt (gsi)))
     282      gsi_next_nondebug (&gsi);
     283  
     284    return gsi;
     285  }
     286  
     287  /* Return a new iterator pointing to the first non-debug statement in
     288     basic block BB.  */
     289  
     290  inline gimple_stmt_iterator
     291  gsi_start_nondebug_bb (basic_block bb)
     292  {
     293    gimple_stmt_iterator i = gsi_start_bb (bb);
     294  
     295    if (!gsi_end_p (i) && is_gimple_debug (gsi_stmt (i)))
     296      gsi_next_nondebug (&i);
     297  
     298    return i;
     299  }
     300  
     301  /* Return a new iterator pointing to the first non-debug non-label statement in
     302     basic block BB.  */
     303  
     304  inline gimple_stmt_iterator
     305  gsi_start_nondebug_after_labels_bb (basic_block bb)
     306  {
     307    gimple_stmt_iterator i = gsi_after_labels (bb);
     308  
     309    if (!gsi_end_p (i) && is_gimple_debug (gsi_stmt (i)))
     310      gsi_next_nondebug (&i);
     311  
     312    return i;
     313  }
     314  
     315  /* Return a new iterator pointing to the last non-debug statement in
     316     basic block BB.  */
     317  
     318  inline gimple_stmt_iterator
     319  gsi_last_nondebug_bb (basic_block bb)
     320  {
     321    gimple_stmt_iterator i = gsi_last_bb (bb);
     322  
     323    if (!gsi_end_p (i) && is_gimple_debug (gsi_stmt (i)))
     324      gsi_prev_nondebug (&i);
     325  
     326    return i;
     327  }
     328  
     329  /* Return true if I is followed only by debug statements in its
     330     sequence.  */
     331  
     332  inline bool
     333  gsi_one_nondebug_before_end_p (gimple_stmt_iterator i)
     334  {
     335    if (gsi_one_before_end_p (i))
     336      return true;
     337    if (gsi_end_p (i))
     338      return false;
     339    gsi_next_nondebug (&i);
     340    return gsi_end_p (i);
     341  }
     342  
     343  /* Advance I statement iterator to the next non-virtual GIMPLE_PHI
     344     statement.  */
     345  
     346  inline void
     347  gsi_next_nonvirtual_phi (gphi_iterator *i)
     348  {
     349    do
     350      {
     351        gsi_next (i);
     352      }
     353    while (!gsi_end_p (*i) && virtual_operand_p (gimple_phi_result (i->phi ())));
     354  }
     355  
     356  /* Return a new iterator pointing to the first non-virtual phi statement in
     357     basic block BB.  */
     358  
     359  inline gphi_iterator
     360  gsi_start_nonvirtual_phis (basic_block bb)
     361  {
     362    gphi_iterator i = gsi_start_phis (bb);
     363  
     364    if (!gsi_end_p (i) && virtual_operand_p (gimple_phi_result (i.phi ())))
     365      gsi_next_nonvirtual_phi (&i);
     366  
     367    return i;
     368  }
     369  
     370  /* Return the basic block associated with this iterator.  */
     371  
     372  inline basic_block
     373  gsi_bb (gimple_stmt_iterator i)
     374  {
     375    return i.bb;
     376  }
     377  
     378  /* Return the sequence associated with this iterator.  */
     379  
     380  inline gimple_seq
     381  gsi_seq (gimple_stmt_iterator i)
     382  {
     383    return *i.seq;
     384  }
     385  
     386  /* Determine whether SEQ is a nondebug singleton.  */
     387  
     388  inline bool
     389  gimple_seq_nondebug_singleton_p (gimple_seq seq)
     390  {
     391    gimple_stmt_iterator gsi;
     392  
     393    /* Find a nondebug gimple.  */
     394    gsi.ptr = gimple_seq_first (seq);
     395    gsi.seq = &seq;
     396    gsi.bb = NULL;
     397    while (!gsi_end_p (gsi)
     398  	 && is_gimple_debug (gsi_stmt (gsi)))
     399      gsi_next (&gsi);
     400  
     401    /* No nondebug gimple found, not a singleton.  */
     402    if (gsi_end_p (gsi))
     403      return false;
     404  
     405    /* Find a next nondebug gimple.  */
     406    gsi_next (&gsi);
     407    while (!gsi_end_p (gsi)
     408  	 && is_gimple_debug (gsi_stmt (gsi)))
     409      gsi_next (&gsi);
     410  
     411    /* Only a singleton if there's no next nondebug gimple.  */
     412    return gsi_end_p (gsi);
     413  }
     414  
     415  #endif /* GCC_GIMPLE_ITERATOR_H */