/* Iterator routines for GIMPLE statements.
   Copyright (C) 2007-2018 Free Software Foundation, Inc.
   Contributed by Aldy Hernandez  <aldy@quesejoda.com>

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/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "tree.h"
#include "gimple.h"
#include "cfghooks.h"
#include "ssa.h"
#include "cgraph.h"
#include "tree-eh.h"
#include "gimple-iterator.h"
#include "tree-cfg.h"
#include "tree-ssa.h"
#include "value-prof.h"


/* Mark the statement STMT as modified, and update it.  */

static inline void
update_modified_stmt (gimple *stmt)
{
  if (!ssa_operands_active (cfun))
    return;
  update_stmt_if_modified (stmt);
}


/* Mark the statements in SEQ as modified, and update them.  */

void
update_modified_stmts (gimple_seq seq)
{
  gimple_stmt_iterator gsi;

  if (!ssa_operands_active (cfun))
    return;
  for (gsi = gsi_start (seq); !gsi_end_p (gsi); gsi_next (&gsi))
    update_stmt_if_modified (gsi_stmt (gsi));
}


/* Set BB to be the basic block for all the statements in the list
   starting at FIRST and LAST.  */

static void
update_bb_for_stmts (gimple_seq_node first, gimple_seq_node last,
		     basic_block bb)
{
  gimple_seq_node n;

  for (n = first; n; n = n->next)
    {
      gimple_set_bb (n, bb);
      if (n == last)
	break;
    }
}

/* Set the frequencies for the cgraph_edges for each of the calls
   starting at FIRST for their new position within BB.  */

static void
update_call_edge_frequencies (gimple_seq_node first, basic_block bb)
{
  struct cgraph_node *cfun_node = NULL;
  gimple_seq_node n;

  for (n = first; n ; n = n->next)
    if (is_gimple_call (n))
      {
	struct cgraph_edge *e;

	/* These function calls are expensive enough that we want
	   to avoid calling them if we never see any calls.  */
	if (cfun_node == NULL)
	  cfun_node = cgraph_node::get (current_function_decl);

	e = cfun_node->get_edge (n);
	if (e != NULL)
	  e->count = bb->count;
      }
}

/* Insert the sequence delimited by nodes FIRST and LAST before
   iterator I.  M specifies how to update iterator I after insertion
   (see enum gsi_iterator_update).

   This routine assumes that there is a forward and backward path
   between FIRST and LAST (i.e., they are linked in a doubly-linked
   list).  Additionally, if FIRST == LAST, this routine will properly
   insert a single node.  */

static void
gsi_insert_seq_nodes_before (gimple_stmt_iterator *i,
			     gimple_seq_node first,
			     gimple_seq_node last,
			     enum gsi_iterator_update mode)
{
  basic_block bb;
  gimple_seq_node cur = i->ptr;

  gcc_assert (!cur || cur->prev);

  if ((bb = gsi_bb (*i)) != NULL)
    update_bb_for_stmts (first, last, bb);

  /* Link SEQ before CUR in the sequence.  */
  if (cur)
    {
      first->prev = cur->prev;
      if (first->prev->next)
	first->prev->next = first;
      else
	gimple_seq_set_first (i->seq, first);
      last->next = cur;
      cur->prev = last;
    }
  else
    {
      gimple_seq_node itlast = gimple_seq_last (*i->seq);

      /* If CUR is NULL, we link at the end of the sequence (this case happens
	 when gsi_after_labels is called for a basic block that contains only
	 labels, so it returns an iterator after the end of the block, and
	 we need to insert before it; it might be cleaner to add a flag to the
	 iterator saying whether we are at the start or end of the list).  */
      last->next = NULL;
      if (itlast)
	{
	  first->prev = itlast;
	  itlast->next = first;
	}
      else
	gimple_seq_set_first (i->seq, first);
      gimple_seq_set_last (i->seq, last);
    }

  /* Update the iterator, if requested.  */
  switch (mode)
    {
    case GSI_NEW_STMT:
    case GSI_CONTINUE_LINKING:
      i->ptr = first;
      break;
    case GSI_SAME_STMT:
      break;
    default:
      gcc_unreachable ();
    }
}


/* Inserts the sequence of statements SEQ before the statement pointed
   by iterator I.  MODE indicates what to do with the iterator after
   insertion (see enum gsi_iterator_update).

   This function does not scan for new operands.  It is provided for
   the use of the gimplifier, which manipulates statements for which
   def/use information has not yet been constructed.  Most callers
   should use gsi_insert_seq_before.  */

void
gsi_insert_seq_before_without_update (gimple_stmt_iterator *i, gimple_seq seq,
                                      enum gsi_iterator_update mode)
{
  gimple_seq_node first, last;

  if (seq == NULL)
    return;

  /* Don't allow inserting a sequence into itself.  */
  gcc_assert (seq != *i->seq);

  first = gimple_seq_first (seq);
  last = gimple_seq_last (seq);

  /* Empty sequences need no work.  */
  if (!first || !last)
    {
      gcc_assert (first == last);
      return;
    }

  gsi_insert_seq_nodes_before (i, first, last, mode);
}


/* Inserts the sequence of statements SEQ before the statement pointed
   by iterator I.  MODE indicates what to do with the iterator after
   insertion (see enum gsi_iterator_update). Scan the statements in SEQ
   for new operands.  */

void
gsi_insert_seq_before (gimple_stmt_iterator *i, gimple_seq seq,
		       enum gsi_iterator_update mode)
{
  update_modified_stmts (seq);
  gsi_insert_seq_before_without_update (i, seq, mode);
}


/* Insert the sequence delimited by nodes FIRST and LAST after
   iterator I.  M specifies how to update iterator I after insertion
   (see enum gsi_iterator_update).

   This routine assumes that there is a forward and backward path
   between FIRST and LAST (i.e., they are linked in a doubly-linked
   list).  Additionally, if FIRST == LAST, this routine will properly
   insert a single node.  */

static void
gsi_insert_seq_nodes_after (gimple_stmt_iterator *i,
			    gimple_seq_node first,
			    gimple_seq_node last,
			    enum gsi_iterator_update m)
{
  basic_block bb;
  gimple_seq_node cur = i->ptr;

  gcc_assert (!cur || cur->prev);

  /* If the iterator is inside a basic block, we need to update the
     basic block information for all the nodes between FIRST and LAST.  */
  if ((bb = gsi_bb (*i)) != NULL)
    update_bb_for_stmts (first, last, bb);

  /* Link SEQ after CUR.  */
  if (cur)
    {
      last->next = cur->next;
      if (last->next)
	{
	  last->next->prev = last;
	}
      else
	gimple_seq_set_last (i->seq, last);
      first->prev = cur;
      cur->next = first;
    }
  else
    {
      gcc_assert (!gimple_seq_last (*i->seq));
      last->next = NULL;
      gimple_seq_set_first (i->seq, first);
      gimple_seq_set_last (i->seq, last);
    }

  /* Update the iterator, if requested.  */
  switch (m)
    {
    case GSI_NEW_STMT:
      i->ptr = first;
      break;
    case GSI_CONTINUE_LINKING:
      i->ptr = last;
      break;
    case GSI_SAME_STMT:
      gcc_assert (cur);
      break;
    default:
      gcc_unreachable ();
    }
}


/* Links sequence SEQ after the statement pointed-to by iterator I.
   MODE is as in gsi_insert_after.

   This function does not scan for new operands.  It is provided for
   the use of the gimplifier, which manipulates statements for which
   def/use information has not yet been constructed.  Most callers
   should use gsi_insert_seq_after.  */

void
gsi_insert_seq_after_without_update (gimple_stmt_iterator *i, gimple_seq seq,
                                     enum gsi_iterator_update mode)
{
  gimple_seq_node first, last;

  if (seq == NULL)
    return;

  /* Don't allow inserting a sequence into itself.  */
  gcc_assert (seq != *i->seq);

  first = gimple_seq_first (seq);
  last = gimple_seq_last (seq);

  /* Empty sequences need no work.  */
  if (!first || !last)
    {
      gcc_assert (first == last);
      return;
    }

  gsi_insert_seq_nodes_after (i, first, last, mode);
}


/* Links sequence SEQ after the statement pointed-to by iterator I.
   MODE is as in gsi_insert_after.  Scan the statements in SEQ
   for new operands.  */

void
gsi_insert_seq_after (gimple_stmt_iterator *i, gimple_seq seq,
		      enum gsi_iterator_update mode)
{
  update_modified_stmts (seq);
  gsi_insert_seq_after_without_update (i, seq, mode);
}


/* Move all statements in the sequence after I to a new sequence.
   Return this new sequence.  */

gimple_seq
gsi_split_seq_after (gimple_stmt_iterator i)
{
  gimple_seq_node cur, next;
  gimple_seq *pold_seq, new_seq;

  cur = i.ptr;

  /* How can we possibly split after the end, or before the beginning?  */
  gcc_assert (cur && cur->next);
  next = cur->next;

  pold_seq = i.seq;

  gimple_seq_set_first (&new_seq, next);
  gimple_seq_set_last (&new_seq, gimple_seq_last (*pold_seq));
  gimple_seq_set_last (pold_seq, cur);
  cur->next = NULL;

  return new_seq;
}


/* Set the statement to which GSI points to STMT.  This only updates
   the iterator and the gimple sequence, it doesn't do the bookkeeping
   of gsi_replace.  */

void
gsi_set_stmt (gimple_stmt_iterator *gsi, gimple *stmt)
{
  gimple *orig_stmt = gsi_stmt (*gsi);
  gimple *prev, *next;

  stmt->next = next = orig_stmt->next;
  stmt->prev = prev = orig_stmt->prev;
  /* Note how we don't clear next/prev of orig_stmt.  This is so that
     copies of *GSI our callers might still hold (to orig_stmt)
     can be advanced as if they too were replaced.  */
  if (prev->next)
    prev->next = stmt;
  else
    gimple_seq_set_first (gsi->seq, stmt);
  if (next)
    next->prev = stmt;
  else
    gimple_seq_set_last (gsi->seq, stmt);

  gsi->ptr = stmt;
}


/* Move all statements in the sequence before I to a new sequence.
   Return this new sequence.  I is set to the head of the new list.  */

void
gsi_split_seq_before (gimple_stmt_iterator *i, gimple_seq *pnew_seq)
{
  gimple_seq_node cur, prev;
  gimple_seq old_seq;

  cur = i->ptr;

  /* How can we possibly split after the end?  */
  gcc_assert (cur);
  prev = cur->prev;

  old_seq = *i->seq;
  if (!prev->next)
    *i->seq = NULL;
  i->seq = pnew_seq;

  /* Set the limits on NEW_SEQ.  */
  gimple_seq_set_first (pnew_seq, cur);
  gimple_seq_set_last (pnew_seq, gimple_seq_last (old_seq));

  /* Cut OLD_SEQ before I.  */
  gimple_seq_set_last (&old_seq, prev);
  if (prev->next)
    prev->next = NULL;
}


/* Replace the statement pointed-to by GSI to STMT.  If UPDATE_EH_INFO
   is true, the exception handling information of the original
   statement is moved to the new statement.  Assignments must only be
   replaced with assignments to the same LHS.  Returns whether EH edge
   cleanup is required.  */

bool
gsi_replace (gimple_stmt_iterator *gsi, gimple *stmt, bool update_eh_info)
{
  gimple *orig_stmt = gsi_stmt (*gsi);
  bool require_eh_edge_purge = false;

  if (stmt == orig_stmt)
    return false;

  gcc_assert (!gimple_has_lhs (orig_stmt) || !gimple_has_lhs (stmt)
	      || gimple_get_lhs (orig_stmt) == gimple_get_lhs (stmt));

  gimple_set_location (stmt, gimple_location (orig_stmt));
  gimple_set_bb (stmt, gsi_bb (*gsi));

  /* Preserve EH region information from the original statement, if
     requested by the caller.  */
  if (update_eh_info)
    require_eh_edge_purge = maybe_clean_or_replace_eh_stmt (orig_stmt, stmt);

  gimple_duplicate_stmt_histograms (cfun, stmt, cfun, orig_stmt);

  /* Free all the data flow information for ORIG_STMT.  */
  gimple_set_bb (orig_stmt, NULL);
  gimple_remove_stmt_histograms (cfun, orig_stmt);
  delink_stmt_imm_use (orig_stmt);

  gsi_set_stmt (gsi, stmt);
  gimple_set_modified (stmt, true);
  update_modified_stmt (stmt);
  return require_eh_edge_purge;
}


/* Replace the statement pointed-to by GSI with the sequence SEQ.
   If UPDATE_EH_INFO is true, the exception handling information of
   the original statement is moved to the last statement of the new
   sequence.  If the old statement is an assignment, then so must
   be the last statement of the new sequence, and they must have the
   same LHS.  */

void
gsi_replace_with_seq (gimple_stmt_iterator *gsi, gimple_seq seq,
		      bool update_eh_info)
{
  gimple_stmt_iterator seqi;
  gimple *last;
  if (gimple_seq_empty_p (seq))
    {
      gsi_remove (gsi, true);
      return;
    }
  seqi = gsi_last (seq);
  last = gsi_stmt (seqi);
  gsi_remove (&seqi, false);
  gsi_insert_seq_before (gsi, seq, GSI_SAME_STMT);
  gsi_replace (gsi, last, update_eh_info);
}


/* Insert statement STMT before the statement pointed-to by iterator I.
   M specifies how to update iterator I after insertion (see enum
   gsi_iterator_update).

   This function does not scan for new operands.  It is provided for
   the use of the gimplifier, which manipulates statements for which
   def/use information has not yet been constructed.  Most callers
   should use gsi_insert_before.  */

void
gsi_insert_before_without_update (gimple_stmt_iterator *i, gimple *stmt,
                                  enum gsi_iterator_update m)
{
  gsi_insert_seq_nodes_before (i, stmt, stmt, m);
}

/* Insert statement STMT before the statement pointed-to by iterator I.
   Update STMT's basic block and scan it for new operands.  M
   specifies how to update iterator I after insertion (see enum
   gsi_iterator_update).  */

void
gsi_insert_before (gimple_stmt_iterator *i, gimple *stmt,
                   enum gsi_iterator_update m)
{
  update_modified_stmt (stmt);
  gsi_insert_before_without_update (i, stmt, m);
}


/* Insert statement STMT after the statement pointed-to by iterator I.
   M specifies how to update iterator I after insertion (see enum
   gsi_iterator_update).

   This function does not scan for new operands.  It is provided for
   the use of the gimplifier, which manipulates statements for which
   def/use information has not yet been constructed.  Most callers
   should use gsi_insert_after.  */

void
gsi_insert_after_without_update (gimple_stmt_iterator *i, gimple *stmt,
                                 enum gsi_iterator_update m)
{
  gsi_insert_seq_nodes_after (i, stmt, stmt, m);
}


/* Insert statement STMT after the statement pointed-to by iterator I.
   Update STMT's basic block and scan it for new operands.  M
   specifies how to update iterator I after insertion (see enum
   gsi_iterator_update).  */

void
gsi_insert_after (gimple_stmt_iterator *i, gimple *stmt,
		  enum gsi_iterator_update m)
{
  update_modified_stmt (stmt);
  gsi_insert_after_without_update (i, stmt, m);
}


/* Remove the current stmt from the sequence.  The iterator is updated
   to point to the next statement.

   REMOVE_PERMANENTLY is true when the statement is going to be removed
   from the IL and not reinserted elsewhere.  In that case we remove the
   statement pointed to by iterator I from the EH tables, and free its
   operand caches.  Otherwise we do not modify this information.  Returns
   true whether EH edge cleanup is required.  */

bool
gsi_remove (gimple_stmt_iterator *i, bool remove_permanently)
{
  gimple_seq_node cur, next, prev;
  gimple *stmt = gsi_stmt (*i);
  bool require_eh_edge_purge = false;

  if (gimple_code (stmt) != GIMPLE_PHI)
    insert_debug_temps_for_defs (i);

  /* Free all the data flow information for STMT.  */
  gimple_set_bb (stmt, NULL);
  delink_stmt_imm_use (stmt);
  gimple_set_modified (stmt, true);

  if (remove_permanently)
    {
      if (gimple_debug_nonbind_marker_p (stmt))
	/* We don't need this to be exact, but try to keep it at least
	   close.  */
	cfun->debug_marker_count--;
      require_eh_edge_purge = remove_stmt_from_eh_lp (stmt);
      gimple_remove_stmt_histograms (cfun, stmt);
    }

  /* Update the iterator and re-wire the links in I->SEQ.  */
  cur = i->ptr;
  next = cur->next;
  prev = cur->prev;
  /* See gsi_set_stmt for why we don't reset prev/next of STMT.  */

  if (next)
    /* Cur is not last.  */
    next->prev = prev;
  else if (prev->next)
    /* Cur is last but not first.  */
    gimple_seq_set_last (i->seq, prev);

  if (prev->next)
    /* Cur is not first.  */
    prev->next = next;
  else
    /* Cur is first.  */
    *i->seq = next;

  i->ptr = next;

  return require_eh_edge_purge;
}


/* Finds iterator for STMT.  */

gimple_stmt_iterator
gsi_for_stmt (gimple *stmt)
{
  gimple_stmt_iterator i;
  basic_block bb = gimple_bb (stmt);

  if (gimple_code (stmt) == GIMPLE_PHI)
    i = gsi_start_phis (bb);
  else
    i = gsi_start_bb (bb);

  i.ptr = stmt;
  return i;
}

/* Finds iterator for PHI.  */

gphi_iterator
gsi_for_phi (gphi *phi)
{
  gphi_iterator i;
  basic_block bb = gimple_bb (phi);

  i = gsi_start_phis (bb);
  i.ptr = phi;

  return i;
}

/* Move the statement at FROM so it comes right after the statement at TO.  */

void
gsi_move_after (gimple_stmt_iterator *from, gimple_stmt_iterator *to)
{
  gimple *stmt = gsi_stmt (*from);
  gsi_remove (from, false);

  /* We must have GSI_NEW_STMT here, as gsi_move_after is sometimes used to
     move statements to an empty block.  */
  gsi_insert_after (to, stmt, GSI_NEW_STMT);
}


/* Move the statement at FROM so it comes right before the statement
   at TO.  */

void
gsi_move_before (gimple_stmt_iterator *from, gimple_stmt_iterator *to)
{
  gimple *stmt = gsi_stmt (*from);
  gsi_remove (from, false);

  /* For consistency with gsi_move_after, it might be better to have
     GSI_NEW_STMT here; however, that breaks several places that expect
     that TO does not change.  */
  gsi_insert_before (to, stmt, GSI_SAME_STMT);
}


/* Move the statement at FROM to the end of basic block BB.  */

void
gsi_move_to_bb_end (gimple_stmt_iterator *from, basic_block bb)
{
  gimple_stmt_iterator last = gsi_last_bb (bb);
  gcc_checking_assert (gsi_bb (last) == bb);

  /* Have to check gsi_end_p because it could be an empty block.  */
  if (!gsi_end_p (last) && is_ctrl_stmt (gsi_stmt (last)))
    gsi_move_before (from, &last);
  else
    gsi_move_after (from, &last);
}


/* Add STMT to the pending list of edge E.  No actual insertion is
   made until a call to gsi_commit_edge_inserts () is made.  */

void
gsi_insert_on_edge (edge e, gimple *stmt)
{
  gimple_seq_add_stmt (&PENDING_STMT (e), stmt);
}

/* Add the sequence of statements SEQ to the pending list of edge E.
   No actual insertion is made until a call to gsi_commit_edge_inserts
   is made.  */

void
gsi_insert_seq_on_edge (edge e, gimple_seq seq)
{
  gimple_seq_add_seq (&PENDING_STMT (e), seq);
}

/* Return a new iterator pointing to the first statement in sequence of
   statements on edge E.  Such statements need to be subsequently moved into a
   basic block by calling gsi_commit_edge_inserts.  */

gimple_stmt_iterator
gsi_start_edge (edge e)
{
  return gsi_start (PENDING_STMT (e));
}

/* Insert the statement pointed-to by GSI into edge E.  Every attempt
   is made to place the statement in an existing basic block, but
   sometimes that isn't possible.  When it isn't possible, the edge is
   split and the statement is added to the new block.

   In all cases, the returned *GSI points to the correct location.  The
   return value is true if insertion should be done after the location,
   or false if it should be done before the location.  If a new basic block
   has to be created, it is stored in *NEW_BB.  */

static bool
gimple_find_edge_insert_loc (edge e, gimple_stmt_iterator *gsi,
			     basic_block *new_bb)
{
  basic_block dest, src;
  gimple *tmp;

  dest = e->dest;

  /* If the destination has one predecessor which has no PHI nodes,
     insert there.  Except for the exit block.

     The requirement for no PHI nodes could be relaxed.  Basically we
     would have to examine the PHIs to prove that none of them used
     the value set by the statement we want to insert on E.  That
     hardly seems worth the effort.  */
 restart:
  if (single_pred_p (dest)
      && gimple_seq_empty_p (phi_nodes (dest))
      && dest != EXIT_BLOCK_PTR_FOR_FN (cfun))
    {
      *gsi = gsi_start_bb (dest);
      if (gsi_end_p (*gsi))
	return true;

      /* Make sure we insert after any leading labels.  */
      tmp = gsi_stmt (*gsi);
      while (gimple_code (tmp) == GIMPLE_LABEL)
	{
	  gsi_next (gsi);
	  if (gsi_end_p (*gsi))
	    break;
	  tmp = gsi_stmt (*gsi);
	}

      if (gsi_end_p (*gsi))
	{
	  *gsi = gsi_last_bb (dest);
	  return true;
	}
      else
	return false;
    }

  /* If the source has one successor, the edge is not abnormal and
     the last statement does not end a basic block, insert there.
     Except for the entry block.  */
  src = e->src;
  if ((e->flags & EDGE_ABNORMAL) == 0
      && (single_succ_p (src)
	  /* Do not count a fake edge as successor as added to infinite
	     loops by connect_infinite_loops_to_exit.  */
	  || (EDGE_COUNT (src->succs) == 2
	      && (EDGE_SUCC (src, 0)->flags & EDGE_FAKE
		  || EDGE_SUCC (src, 1)->flags & EDGE_FAKE)))
      && src != ENTRY_BLOCK_PTR_FOR_FN (cfun))
    {
      *gsi = gsi_last_bb (src);
      if (gsi_end_p (*gsi))
	return true;

      tmp = gsi_stmt (*gsi);
      if (is_gimple_debug (tmp))
	{
	  gimple_stmt_iterator si = *gsi;
	  gsi_prev_nondebug (&si);
	  if (!gsi_end_p (si))
	    tmp = gsi_stmt (si);
	  /* If we don't have a BB-ending nondebug stmt, we want to
	     insert after the trailing debug stmts.  Otherwise, we may
	     insert before the BB-ending nondebug stmt, or split the
	     edge.  */
	  if (!stmt_ends_bb_p (tmp))
	    return true;
	  *gsi = si;
	}
      else if (!stmt_ends_bb_p (tmp))
	return true;

      switch (gimple_code (tmp))
	{
	case GIMPLE_RETURN:
	case GIMPLE_RESX:
	  return false;
	default:
	  break;
        }
    }

  /* Otherwise, create a new basic block, and split this edge.  */
  dest = split_edge (e);
  if (new_bb)
    *new_bb = dest;
  e = single_pred_edge (dest);
  goto restart;
}


/* Similar to gsi_insert_on_edge+gsi_commit_edge_inserts.  If a new
   block has to be created, it is returned.  */

basic_block
gsi_insert_on_edge_immediate (edge e, gimple *stmt)
{
  gimple_stmt_iterator gsi;
  basic_block new_bb = NULL;
  bool ins_after;

  gcc_assert (!PENDING_STMT (e));

  ins_after = gimple_find_edge_insert_loc (e, &gsi, &new_bb);

  update_call_edge_frequencies (stmt, gsi.bb);

  if (ins_after)
    gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
  else
    gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);

  return new_bb;
}

/* Insert STMTS on edge E.  If a new block has to be created, it
   is returned.  */

basic_block
gsi_insert_seq_on_edge_immediate (edge e, gimple_seq stmts)
{
  gimple_stmt_iterator gsi;
  basic_block new_bb = NULL;
  bool ins_after;

  gcc_assert (!PENDING_STMT (e));

  ins_after = gimple_find_edge_insert_loc (e, &gsi, &new_bb);
  update_call_edge_frequencies (gimple_seq_first (stmts), gsi.bb);

  if (ins_after)
    gsi_insert_seq_after (&gsi, stmts, GSI_NEW_STMT);
  else
    gsi_insert_seq_before (&gsi, stmts, GSI_NEW_STMT);

  return new_bb;
}

/* This routine will commit all pending edge insertions, creating any new
   basic blocks which are necessary.  */

void
gsi_commit_edge_inserts (void)
{
  basic_block bb;
  edge e;
  edge_iterator ei;

  gsi_commit_one_edge_insert (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun)),
			      NULL);

  FOR_EACH_BB_FN (bb, cfun)
    FOR_EACH_EDGE (e, ei, bb->succs)
      gsi_commit_one_edge_insert (e, NULL);
}


/* Commit insertions pending at edge E. If a new block is created, set NEW_BB
   to this block, otherwise set it to NULL.  */

void
gsi_commit_one_edge_insert (edge e, basic_block *new_bb)
{
  if (new_bb)
    *new_bb = NULL;

  if (PENDING_STMT (e))
    {
      gimple_stmt_iterator gsi;
      gimple_seq seq = PENDING_STMT (e);
      bool ins_after;

      PENDING_STMT (e) = NULL;

      ins_after = gimple_find_edge_insert_loc (e, &gsi, new_bb);
      update_call_edge_frequencies (gimple_seq_first (seq), gsi.bb);

      if (ins_after)
	gsi_insert_seq_after (&gsi, seq, GSI_NEW_STMT);
      else
	gsi_insert_seq_before (&gsi, seq, GSI_NEW_STMT);
    }
}

/* Returns iterator at the start of the list of phi nodes of BB.  */

gphi_iterator
gsi_start_phis (basic_block bb)
{
  gimple_seq *pseq = phi_nodes_ptr (bb);

  /* Adapted from gsi_start_1. */
  gphi_iterator i;

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

  return i;
}
