/* 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 = 2,	/* Move the iterator to the first statement added.  */
  GSI_LAST_NEW_STMT,	/* Move the iterator to the last statement added.  */
  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 */
