/* Header file for gimple iterators.
   Copyright (C) 2013-2021 Free Software Foundation, Inc.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#ifndef GCC_GIMPLE_ITERATOR_H
#define GCC_GIMPLE_ITERATOR_H

/* Iterator object for GIMPLE statement sequences.  */

struct gimple_stmt_iterator
{
  /* Sequence node holding the current statement.  */
  gimple_seq_node ptr;

  /* Sequence and basic block holding the statement.  These fields
     are necessary to handle edge cases such as when statement is
     added to an empty basic block or when the last statement of a
     block/sequence is removed.  */
  gimple_seq *seq;
  basic_block bb;
};

/* Iterator over GIMPLE_PHI statements.  */
struct gphi_iterator : public gimple_stmt_iterator
{
  gphi *phi () const
  {
    return as_a <gphi *> (ptr);
  }
};
 
enum gsi_iterator_update
{
  GSI_NEW_STMT,		/* Only valid when single statement is added, move
			   iterator to it.  */
  GSI_SAME_STMT,	/* Leave the iterator at the same statement.  */
  GSI_CONTINUE_LINKING	/* Move iterator to whatever position is suitable
			   for linking other statements in the same
			   direction.  */
};

extern void gsi_insert_seq_before_without_update (gimple_stmt_iterator *,
						  gimple_seq,
						  enum gsi_iterator_update);
extern void gsi_insert_seq_before (gimple_stmt_iterator *, gimple_seq,
				   enum gsi_iterator_update);
extern void gsi_insert_seq_after_without_update (gimple_stmt_iterator *,
						 gimple_seq,
						 enum gsi_iterator_update);
extern void gsi_insert_seq_after (gimple_stmt_iterator *, gimple_seq,
				  enum gsi_iterator_update);
extern gimple_seq gsi_split_seq_after (gimple_stmt_iterator);
extern void gsi_set_stmt (gimple_stmt_iterator *, gimple *);
extern void gsi_split_seq_before (gimple_stmt_iterator *, gimple_seq *);
extern bool gsi_replace (gimple_stmt_iterator *, gimple *, bool);
extern void gsi_replace_with_seq (gimple_stmt_iterator *, gimple_seq, bool);
extern void gsi_insert_before_without_update (gimple_stmt_iterator *, gimple *,
					      enum gsi_iterator_update);
extern void gsi_insert_before (gimple_stmt_iterator *, gimple *,
			       enum gsi_iterator_update);
extern void gsi_insert_after_without_update (gimple_stmt_iterator *, gimple *,
					     enum gsi_iterator_update);
extern void gsi_insert_after (gimple_stmt_iterator *, gimple *,
			      enum gsi_iterator_update);
extern bool gsi_remove (gimple_stmt_iterator *, bool);
extern gimple_stmt_iterator gsi_for_stmt (gimple *);
extern gimple_stmt_iterator gsi_for_stmt (gimple *, gimple_seq *);
extern gphi_iterator gsi_for_phi (gphi *);
extern void gsi_move_after (gimple_stmt_iterator *, gimple_stmt_iterator *);
extern void gsi_move_before (gimple_stmt_iterator *, gimple_stmt_iterator *);
extern void gsi_move_to_bb_end (gimple_stmt_iterator *, basic_block);
extern void gsi_insert_on_edge (edge, gimple *);
extern void gsi_insert_seq_on_edge (edge, gimple_seq);
extern basic_block gsi_insert_on_edge_immediate (edge, gimple *);
extern basic_block gsi_insert_seq_on_edge_immediate (edge, gimple_seq);
extern void gsi_commit_edge_inserts (void);
extern void gsi_commit_one_edge_insert (edge, basic_block *);
extern gphi_iterator gsi_start_phis (basic_block);
extern void update_modified_stmts (gimple_seq);

/* Return a new iterator pointing to GIMPLE_SEQ's first statement.  */

static inline gimple_stmt_iterator
gsi_start_1 (gimple_seq *seq)
{
  gimple_stmt_iterator i;

  i.ptr = gimple_seq_first (*seq);
  i.seq = seq;
  i.bb = i.ptr ? gimple_bb (i.ptr) : NULL;

  return i;
}

#define gsi_start(x) gsi_start_1 (&(x))

static inline gimple_stmt_iterator
gsi_none (void)
{
  gimple_stmt_iterator i;
  i.ptr = NULL;
  i.seq = NULL;
  i.bb = NULL;
  return i;
}

/* Return a new iterator pointing to the first statement in basic block BB.  */

static inline gimple_stmt_iterator
gsi_start_bb (basic_block bb)
{
  gimple_stmt_iterator i;
  gimple_seq *seq;

  seq = bb_seq_addr (bb);
  i.ptr = gimple_seq_first (*seq);
  i.seq = seq;
  i.bb = bb;

  return i;
}

gimple_stmt_iterator gsi_start_edge (edge e);

/* Return a new iterator initially pointing to GIMPLE_SEQ's last statement.  */

static inline gimple_stmt_iterator
gsi_last_1 (gimple_seq *seq)
{
  gimple_stmt_iterator i;

  i.ptr = gimple_seq_last (*seq);
  i.seq = seq;
  i.bb = i.ptr ? gimple_bb (i.ptr) : NULL;

  return i;
}

#define gsi_last(x) gsi_last_1 (&(x))

/* Return a new iterator pointing to the last statement in basic block BB.  */

static inline gimple_stmt_iterator
gsi_last_bb (basic_block bb)
{
  gimple_stmt_iterator i;
  gimple_seq *seq;

  seq = bb_seq_addr (bb);
  i.ptr = gimple_seq_last (*seq);
  i.seq = seq;
  i.bb = bb;

  return i;
}

/* Return true if I is at the end of its sequence.  */

static inline bool
gsi_end_p (gimple_stmt_iterator i)
{
  return i.ptr == NULL;
}

/* Return true if I is one statement before the end of its sequence.  */

static inline bool
gsi_one_before_end_p (gimple_stmt_iterator i)
{
  return i.ptr != NULL && i.ptr->next == NULL;
}

/* Advance the iterator to the next gimple statement.  */

static inline void
gsi_next (gimple_stmt_iterator *i)
{
  i->ptr = i->ptr->next;
}

/* Advance the iterator to the previous gimple statement.  */

static inline void
gsi_prev (gimple_stmt_iterator *i)
{
  gimple *prev = i->ptr->prev;
  if (prev->next)
    i->ptr = prev;
  else
    i->ptr = NULL;
}

/* Return the current stmt.  */

static inline gimple *
gsi_stmt (gimple_stmt_iterator i)
{
  return i.ptr;
}

/* Return a block statement iterator that points to the first
   non-label statement in block BB.  */

static inline gimple_stmt_iterator
gsi_after_labels (basic_block bb)
{
  gimple_stmt_iterator gsi = gsi_start_bb (bb);

  for (; !gsi_end_p (gsi); )
    {
      if (gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL)
	gsi_next (&gsi);
      else
	break;
    }

  return gsi;
}

/* Advance the iterator to the next non-debug gimple statement.  */

static inline void
gsi_next_nondebug (gimple_stmt_iterator *i)
{
  do
    {
      gsi_next (i);
    }
  while (!gsi_end_p (*i) && is_gimple_debug (gsi_stmt (*i)));
}

/* Advance the iterator to the previous non-debug gimple statement.  */

static inline void
gsi_prev_nondebug (gimple_stmt_iterator *i)
{
  do
    {
      gsi_prev (i);
    }
  while (!gsi_end_p (*i) && is_gimple_debug (gsi_stmt (*i)));
}

/* Return a new iterator pointing to the first non-debug statement in
   SEQ.  */

static inline gimple_stmt_iterator
gsi_start_nondebug (gimple_seq seq)
{
  gimple_stmt_iterator gsi = gsi_start (seq);
  if (!gsi_end_p (gsi) && is_gimple_debug (gsi_stmt (gsi)))
    gsi_next_nondebug (&gsi);

  return gsi;
}

/* Return a new iterator pointing to the first non-debug statement in
   basic block BB.  */

static inline gimple_stmt_iterator
gsi_start_nondebug_bb (basic_block bb)
{
  gimple_stmt_iterator i = gsi_start_bb (bb);

  if (!gsi_end_p (i) && is_gimple_debug (gsi_stmt (i)))
    gsi_next_nondebug (&i);

  return i;
}

/* Return a new iterator pointing to the first non-debug non-label statement in
   basic block BB.  */

static inline gimple_stmt_iterator
gsi_start_nondebug_after_labels_bb (basic_block bb)
{
  gimple_stmt_iterator i = gsi_after_labels (bb);

  if (!gsi_end_p (i) && is_gimple_debug (gsi_stmt (i)))
    gsi_next_nondebug (&i);

  return i;
}

/* Return a new iterator pointing to the last non-debug statement in
   basic block BB.  */

static inline gimple_stmt_iterator
gsi_last_nondebug_bb (basic_block bb)
{
  gimple_stmt_iterator i = gsi_last_bb (bb);

  if (!gsi_end_p (i) && is_gimple_debug (gsi_stmt (i)))
    gsi_prev_nondebug (&i);

  return i;
}

/* Return true if I is followed only by debug statements in its
   sequence.  */

static inline bool
gsi_one_nondebug_before_end_p (gimple_stmt_iterator i)
{
  if (gsi_one_before_end_p (i))
    return true;
  if (gsi_end_p (i))
    return false;
  gsi_next_nondebug (&i);
  return gsi_end_p (i);
}

/* Advance I statement iterator to the next non-virtual GIMPLE_PHI
   statement.  */

static inline void
gsi_next_nonvirtual_phi (gphi_iterator *i)
{
  do
    {
      gsi_next (i);
    }
  while (!gsi_end_p (*i) && virtual_operand_p (gimple_phi_result (i->phi ())));
}

/* Return a new iterator pointing to the first non-virtual phi statement in
   basic block BB.  */

static inline gphi_iterator
gsi_start_nonvirtual_phis (basic_block bb)
{
  gphi_iterator i = gsi_start_phis (bb);

  if (!gsi_end_p (i) && virtual_operand_p (gimple_phi_result (i.phi ())))
    gsi_next_nonvirtual_phi (&i);

  return i;
}

/* Return the basic block associated with this iterator.  */

static inline basic_block
gsi_bb (gimple_stmt_iterator i)
{
  return i.bb;
}

/* Return the sequence associated with this iterator.  */

static inline gimple_seq
gsi_seq (gimple_stmt_iterator i)
{
  return *i.seq;
}

/* Determine whether SEQ is a nondebug singleton.  */

static inline bool
gimple_seq_nondebug_singleton_p (gimple_seq seq)
{
  gimple_stmt_iterator gsi;

  /* Find a nondebug gimple.  */
  gsi.ptr = gimple_seq_first (seq);
  gsi.seq = &seq;
  gsi.bb = NULL;
  while (!gsi_end_p (gsi)
	 && is_gimple_debug (gsi_stmt (gsi)))
    gsi_next (&gsi);

  /* No nondebug gimple found, not a singleton.  */
  if (gsi_end_p (gsi))
    return false;

  /* Find a next nondebug gimple.  */
  gsi_next (&gsi);
  while (!gsi_end_p (gsi)
	 && is_gimple_debug (gsi_stmt (gsi)))
    gsi_next (&gsi);

  /* Only a singleton if there's no next nondebug gimple.  */
  return gsi_end_p (gsi);
}

#endif /* GCC_GIMPLE_ITERATOR_H */
