Ejemplo n.º 1
0
gimple_seq
gsi_split_seq_before (gimple_stmt_iterator *i)
{
  gimple_seq_node cur, prev;
  gimple_seq old_seq, new_seq;

  cur = i->ptr;

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

  old_seq = i->seq;
  new_seq = gimple_seq_alloc ();
  i->seq = new_seq;

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

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

  return new_seq;
}
Ejemplo n.º 2
0
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 ();
    }
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
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);

  gimple_seq_set_first (seq, NULL);
  gimple_seq_set_last (seq, NULL);
  gimple_seq_free (seq);

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

  gsi_insert_seq_nodes_after (i, first, last, mode);
}
Ejemplo n.º 5
0
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 ();
    }
}
Ejemplo n.º 6
0
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;
}
Ejemplo n.º 7
0
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)
    {
      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;

  if (prev)
    prev->next = next;
  else
    gimple_seq_set_first (i->seq, next);

  if (next)
    next->prev = prev;
  else
    gimple_seq_set_last (i->seq, prev);

  i->ptr = next;

  return require_eh_edge_purge;
}
Ejemplo n.º 8
0
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;
}