/* Shrink-wrapping related optimizations.
   Copyright (C) 1987-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/>.  */

/* This file handles shrink-wrapping related optimizations.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "target.h"
#include "rtl.h"
#include "tree.h"
#include "cfghooks.h"
#include "df.h"
#include "memmodel.h"
#include "tm_p.h"
#include "regs.h"
#include "insn-config.h"
#include "emit-rtl.h"
#include "output.h"
#include "tree-pass.h"
#include "cfgrtl.h"
#include "cfgbuild.h"
#include "bb-reorder.h"
#include "shrink-wrap.h"
#include "regcprop.h"
#include "rtl-iter.h"
#include "valtrack.h"
#include "function-abi.h"
#include "print-rtl.h"

/* Return true if INSN requires the stack frame to be set up.
   PROLOGUE_USED contains the hard registers used in the function
   prologue.  SET_UP_BY_PROLOGUE is the set of registers we expect the
   prologue to set up for the function.  */
bool
requires_stack_frame_p (rtx_insn *insn, HARD_REG_SET prologue_used,
			HARD_REG_SET set_up_by_prologue)
{
  df_ref def, use;
  HARD_REG_SET hardregs;
  unsigned regno;

  if (CALL_P (insn))
    return !SIBLING_CALL_P (insn);

  /* We need a frame to get the unique CFA expected by the unwinder.  */
  if (cfun->can_throw_non_call_exceptions && can_throw_internal (insn))
    return true;

  CLEAR_HARD_REG_SET (hardregs);
  FOR_EACH_INSN_DEF (def, insn)
    {
      rtx dreg = DF_REF_REG (def);

      if (!REG_P (dreg))
	continue;

      add_to_hard_reg_set (&hardregs, GET_MODE (dreg), REGNO (dreg));
    }
  if (hard_reg_set_intersect_p (hardregs, prologue_used))
    return true;
  hardregs &= ~crtl->abi->full_reg_clobbers ();
  for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
    if (TEST_HARD_REG_BIT (hardregs, regno)
	&& df_regs_ever_live_p (regno))
      return true;

  FOR_EACH_INSN_USE (use, insn)
    {
      rtx reg = DF_REF_REG (use);

      if (!REG_P (reg))
	continue;

      add_to_hard_reg_set (&hardregs, GET_MODE (reg),
			   REGNO (reg));
    }
  if (hard_reg_set_intersect_p (hardregs, set_up_by_prologue))
    return true;

  return false;
}

/* See whether there has a single live edge from BB, which dest uses
   [REGNO, END_REGNO).  Return the live edge if its dest bb has
   one or two predecessors.  Otherwise return NULL.  */

static edge
live_edge_for_reg (basic_block bb, int regno, int end_regno)
{
  edge e, live_edge;
  edge_iterator ei;
  bitmap live;
  int i;

  live_edge = NULL;
  FOR_EACH_EDGE (e, ei, bb->succs)
    {
      live = df_get_live_in (e->dest);
      for (i = regno; i < end_regno; i++)
	if (REGNO_REG_SET_P (live, i))
	  {
	    if (live_edge && live_edge != e)
	      return NULL;
	    live_edge = e;
	  }
    }

  /* We can sometimes encounter dead code.  Don't try to move it
     into the exit block.  */
  if (!live_edge || live_edge->dest == EXIT_BLOCK_PTR_FOR_FN (cfun))
    return NULL;

  /* Reject targets of abnormal edges.  This is needed for correctness
     on ports like Alpha and MIPS, whose pic_offset_table_rtx can die on
     exception edges even though it is generally treated as call-saved
     for the majority of the compilation.  Moving across abnormal edges
     isn't going to be interesting for shrink-wrap usage anyway.  */
  if (live_edge->flags & EDGE_ABNORMAL)
    return NULL;

  /* When live_edge->dest->preds == 2, we can create a new block on
     the edge to make it meet the requirement.  */
  if (EDGE_COUNT (live_edge->dest->preds) > 2)
    return NULL;

  return live_edge;
}

/* Try to move INSN from BB to a successor.  Return true on success.
   USES and DEFS are the set of registers that are used and defined
   after INSN in BB.  SPLIT_P indicates whether a live edge from BB
   is splitted or not.  */

static bool
move_insn_for_shrink_wrap (basic_block bb, rtx_insn *insn,
			   const_hard_reg_set uses,
			   const_hard_reg_set defs,
			   bool *split_p,
			   struct dead_debug_local *debug)
{
  rtx set, src, dest;
  bitmap live_out, live_in, bb_uses = NULL, bb_defs = NULL;
  unsigned int i, dregno, end_dregno;
  unsigned int sregno = FIRST_PSEUDO_REGISTER;
  unsigned int end_sregno = FIRST_PSEUDO_REGISTER;
  basic_block next_block;
  edge live_edge;
  rtx_insn *dinsn;
  df_ref def;

  /* Look for a simple register assignment.  We don't use single_set here
     because we can't deal with any CLOBBERs, USEs, or REG_UNUSED secondary
     destinations.  */
  if (!INSN_P (insn))
    return false;
  set = PATTERN (insn);
  if (GET_CODE (set) != SET)
    return false;
  src = SET_SRC (set);
  dest = SET_DEST (set);

  /* For the destination, we want only a register.  Also disallow STACK
     or FRAME related adjustments.  They are likely part of the prologue,
     so keep them in the entry block.  */
  if (!REG_P (dest)
      || dest == stack_pointer_rtx
      || dest == frame_pointer_rtx
      || dest == hard_frame_pointer_rtx)
    return false;

  /* For the source, we want one of:
      (1) A (non-overlapping) register
      (2) A constant,
      (3) An expression involving no more than one register.

     That last point comes from the code following, which was originally
     written to handle only register move operations, and still only handles
     a single source register when checking for overlaps.  Happily, the
     same checks can be applied to expressions like (plus reg const).  */

  if (CONSTANT_P (src))
    ;
  else if (!REG_P (src))
    {
      rtx src_inner = NULL_RTX;

      if (can_throw_internal (insn))
	return false;

      subrtx_var_iterator::array_type array;
      FOR_EACH_SUBRTX_VAR (iter, array, src, ALL)
	{
	  rtx x = *iter;
	  switch (GET_RTX_CLASS (GET_CODE (x)))
	    {
	    case RTX_CONST_OBJ:
	    case RTX_COMPARE:
	    case RTX_COMM_COMPARE:
	    case RTX_BIN_ARITH:
	    case RTX_COMM_ARITH:
	    case RTX_UNARY:
	    case RTX_TERNARY:
	      /* Constant or expression.  Continue.  */
	      break;

	    case RTX_OBJ:
	    case RTX_EXTRA:
	      switch (GET_CODE (x))
		{
		case UNSPEC:
		case SUBREG:
		case STRICT_LOW_PART:
		case PC:
		case LO_SUM:
		  /* Ok.  Continue.  */
		  break;

		case REG:
		  /* Fail if we see a second inner register.  */
		  if (src_inner != NULL)
		    return false;
		  src_inner = x;
		  break;

		default:
		  return false;
		}
	      break;

	    default:
	      return false;
	    }
	}

      if (src_inner != NULL)
	src = src_inner;
    }

  /* Make sure that the source register isn't defined later in BB.  */
  if (REG_P (src))
    {
      sregno = REGNO (src);
      end_sregno = END_REGNO (src);
      if (overlaps_hard_reg_set_p (defs, GET_MODE (src), sregno))
	return false;
    }

  /* Make sure that the destination register isn't referenced later in BB.  */
  dregno = REGNO (dest);
  end_dregno = END_REGNO (dest);
  if (overlaps_hard_reg_set_p (uses, GET_MODE (dest), dregno)
      || overlaps_hard_reg_set_p (defs, GET_MODE (dest), dregno))
    return false;

  /* See whether there is a successor block to which we could move INSN.  */
  live_edge = live_edge_for_reg (bb, dregno, end_dregno);
  if (!live_edge)
    return false;

  next_block = live_edge->dest;
  /* Create a new basic block on the edge.  */
  if (EDGE_COUNT (next_block->preds) == 2)
    {
      /* split_edge for a block with only one successor is meaningless.  */
      if (EDGE_COUNT (bb->succs) == 1)
	return false;

      /* If DF_LIVE doesn't exist, i.e. at -O1, just give up.  */
      if (!df_live)
	return false;

      basic_block old_dest = live_edge->dest;
      next_block = split_edge (live_edge);

      /* We create a new basic block.  Call df_grow_bb_info to make sure
	 all data structures are allocated.  */
      df_grow_bb_info (df_live);

      bitmap_and (df_get_live_in (next_block), df_get_live_out (bb),
		  df_get_live_in (old_dest));
      df_set_bb_dirty (next_block);

      /* We should not split more than once for a function.  */
      if (*split_p)
	return false;

      *split_p = true;
    }

  /* At this point we are committed to moving INSN, but let's try to
     move it as far as we can.  */
  do
    {
      if (MAY_HAVE_DEBUG_BIND_INSNS)
	{
	  FOR_BB_INSNS_REVERSE (bb, dinsn)
	    if (DEBUG_BIND_INSN_P (dinsn))
	      {
		df_ref use;
		FOR_EACH_INSN_USE (use, dinsn)
		  if (refers_to_regno_p (dregno, end_dregno,
					 DF_REF_REG (use), (rtx *) NULL))
		    dead_debug_add (debug, use, DF_REF_REGNO (use));
	      }
	    else if (dinsn == insn)
	      break;
	}
      live_out = df_get_live_out (bb);
      live_in = df_get_live_in (next_block);
      bb = next_block;

      /* Check whether BB uses DEST or clobbers DEST.  We need to add
	 INSN to BB if so.  Either way, DEST is no longer live on entry,
	 except for any part that overlaps SRC (next loop).  */
      if (!*split_p)
	{
	  bb_uses = &DF_LR_BB_INFO (bb)->use;
	  bb_defs = &DF_LR_BB_INFO (bb)->def;
	}
      if (df_live)
	{
	  for (i = dregno; i < end_dregno; i++)
	    {
	      if (*split_p
		  || REGNO_REG_SET_P (bb_uses, i)
		  || REGNO_REG_SET_P (bb_defs, i)
		  || REGNO_REG_SET_P (&DF_LIVE_BB_INFO (bb)->gen, i))
		next_block = NULL;
	      CLEAR_REGNO_REG_SET (live_out, i);
	      CLEAR_REGNO_REG_SET (live_in, i);
	    }

	  /* Check whether BB clobbers SRC.  We need to add INSN to BB if so.
	     Either way, SRC is now live on entry.  */
	  for (i = sregno; i < end_sregno; i++)
	    {
	      if (*split_p
		  || REGNO_REG_SET_P (bb_defs, i)
		  || REGNO_REG_SET_P (&DF_LIVE_BB_INFO (bb)->gen, i))
		next_block = NULL;
	      SET_REGNO_REG_SET (live_out, i);
	      SET_REGNO_REG_SET (live_in, i);
	    }
	}
      else
	{
	  /* DF_LR_BB_INFO (bb)->def does not comprise the DF_REF_PARTIAL and
	     DF_REF_CONDITIONAL defs.  So if DF_LIVE doesn't exist, i.e.
	     at -O1, just give up searching NEXT_BLOCK.  */
	  next_block = NULL;
	  for (i = dregno; i < end_dregno; i++)
	    {
	      CLEAR_REGNO_REG_SET (live_out, i);
	      CLEAR_REGNO_REG_SET (live_in, i);
	    }

	  for (i = sregno; i < end_sregno; i++)
	    {
	      SET_REGNO_REG_SET (live_out, i);
	      SET_REGNO_REG_SET (live_in, i);
	    }
	}

      /* If we don't need to add the move to BB, look for a single
	 successor block.  */
      if (next_block)
	{
	  live_edge = live_edge_for_reg (next_block, dregno, end_dregno);
	  if (!live_edge || EDGE_COUNT (live_edge->dest->preds) > 1)
	    break;
	  next_block = live_edge->dest;
	}
    }
  while (next_block);

  /* For the new created basic block, there is no dataflow info at all.
     So skip the following dataflow update and check.  */
  if (!(*split_p))
    {
      /* BB now defines DEST.  It only uses the parts of DEST that overlap SRC
	 (next loop).  */
      for (i = dregno; i < end_dregno; i++)
	{
	  CLEAR_REGNO_REG_SET (bb_uses, i);
	  SET_REGNO_REG_SET (bb_defs, i);
	}

      /* BB now uses SRC.  */
      for (i = sregno; i < end_sregno; i++)
	SET_REGNO_REG_SET (bb_uses, i);
    }

  /* Insert debug temps for dead REGs used in subsequent debug insns.  */
  if (debug->used && !bitmap_empty_p (debug->used))
    FOR_EACH_INSN_DEF (def, insn)
      dead_debug_insert_temp (debug, DF_REF_REGNO (def), insn,
			      DEBUG_TEMP_BEFORE_WITH_VALUE);

  rtx_insn *insn_copy = emit_insn_after (PATTERN (insn), bb_note (bb));
  /* Update the LABEL_NUSES count on any referenced labels. The ideal
     solution here would be to actually move the instruction instead
     of copying/deleting it as this loses some notations on the
     insn.  */
  mark_jump_label (PATTERN (insn), insn_copy, 0);
  delete_insn (insn);
  return true;
}

/* Look for register copies in the first block of the function, and move
   them down into successor blocks if the register is used only on one
   path.  This exposes more opportunities for shrink-wrapping.  These
   kinds of sets often occur when incoming argument registers are moved
   to call-saved registers because their values are live across one or
   more calls during the function.  */

static void
prepare_shrink_wrap (basic_block entry_block)
{
  rtx_insn *insn, *curr;
  rtx x;
  HARD_REG_SET uses, defs;
  df_ref def, use;
  bool split_p = false;
  unsigned int i;
  struct dead_debug_local debug;

  if (JUMP_P (BB_END (entry_block)))
    {
      /* To have more shrink-wrapping opportunities, prepare_shrink_wrap tries
	 to sink the copies from parameter to callee saved register out of
	 entry block.  copyprop_hardreg_forward_bb_without_debug_insn is called
	 to release some dependences.  */
      copyprop_hardreg_forward_bb_without_debug_insn (entry_block);
    }

  dead_debug_local_init (&debug, NULL, NULL);
  CLEAR_HARD_REG_SET (uses);
  CLEAR_HARD_REG_SET (defs);

  FOR_BB_INSNS_REVERSE_SAFE (entry_block, insn, curr)
    if (NONDEBUG_INSN_P (insn)
	&& !move_insn_for_shrink_wrap (entry_block, insn, uses, defs,
				       &split_p, &debug))
      {
	/* Add all defined registers to DEFs.  */
	FOR_EACH_INSN_DEF (def, insn)
	  {
	    x = DF_REF_REG (def);
	    if (REG_P (x) && HARD_REGISTER_P (x))
	      for (i = REGNO (x); i < END_REGNO (x); i++)
		SET_HARD_REG_BIT (defs, i);
	  }

	/* Add all used registers to USESs.  */
	FOR_EACH_INSN_USE (use, insn)
	  {
	    x = DF_REF_REG (use);
	    if (REG_P (x) && HARD_REGISTER_P (x))
	      for (i = REGNO (x); i < END_REGNO (x); i++)
		SET_HARD_REG_BIT (uses, i);
	  }
      }

  dead_debug_local_finish (&debug, NULL);
}

/* Return whether basic block PRO can get the prologue.  It cannot if it
   has incoming complex edges that need a prologue inserted (we make a new
   block for the prologue, so those edges would need to be redirected, which
   does not work).  It also cannot if there exist registers live on entry
   to PRO that are clobbered by the prologue.  */

static bool
can_get_prologue (basic_block pro, HARD_REG_SET prologue_clobbered)
{
  edge e;
  edge_iterator ei;
  FOR_EACH_EDGE (e, ei, pro->preds)
    if (e->flags & EDGE_COMPLEX
	&& !dominated_by_p (CDI_DOMINATORS, e->src, pro))
      return false;

  HARD_REG_SET live;
  REG_SET_TO_HARD_REG_SET (live, df_get_live_in (pro));
  if (hard_reg_set_intersect_p (live, prologue_clobbered))
    return false;

  return true;
}

/* Return whether we can duplicate basic block BB for shrink wrapping.  We
   cannot if the block cannot be duplicated at all, or if any of its incoming
   edges are complex and come from a block that does not require a prologue
   (we cannot redirect such edges), or if the block is too big to copy.
   PRO is the basic block before which we would put the prologue, MAX_SIZE is
   the maximum size block we allow to be copied.  */

static bool
can_dup_for_shrink_wrapping (basic_block bb, basic_block pro, unsigned max_size)
{
  if (!can_duplicate_block_p (bb))
    return false;

  edge e;
  edge_iterator ei;
  FOR_EACH_EDGE (e, ei, bb->preds)
    if (e->flags & (EDGE_COMPLEX | EDGE_CROSSING)
	&& !dominated_by_p (CDI_DOMINATORS, e->src, pro))
      return false;

  unsigned size = 0;

  rtx_insn *insn;
  FOR_BB_INSNS (bb, insn)
    if (NONDEBUG_INSN_P (insn))
      {
	size += get_attr_min_length (insn);
	if (size > max_size)
	  return false;
      }

  return true;
}

/* Do whatever needs to be done for exits that run without prologue.
   Sibcalls need nothing done.  Normal exits get a simple_return inserted.  */

static void
handle_simple_exit (edge e)
{

  if (e->flags & EDGE_SIBCALL)
    {
      /* Tell function.c to take no further action on this edge.  */
      e->flags |= EDGE_IGNORE;

      e->flags &= ~EDGE_FALLTHRU;
      emit_barrier_after_bb (e->src);
      return;
    }

  /* If the basic block the edge comes from has multiple successors,
     split the edge.  */
  if (EDGE_COUNT (e->src->succs) > 1)
    {
      basic_block old_bb = e->src;
      rtx_insn *end = BB_END (old_bb);
      rtx_note *note = emit_note_after (NOTE_INSN_DELETED, end);
      basic_block new_bb = create_basic_block (note, note, old_bb);
      BB_COPY_PARTITION (new_bb, old_bb);
      BB_END (old_bb) = end;

      redirect_edge_succ (e, new_bb);
      new_bb->count = e->count ();
      e->flags |= EDGE_FALLTHRU;

      e = make_single_succ_edge (new_bb, EXIT_BLOCK_PTR_FOR_FN (cfun), 0);
    }

  e->flags &= ~EDGE_FALLTHRU;
  rtx_jump_insn *ret = emit_jump_insn_after (targetm.gen_simple_return (),
					     BB_END (e->src));
  JUMP_LABEL (ret) = simple_return_rtx;
  emit_barrier_after_bb (e->src);

  if (dump_file)
    fprintf (dump_file, "Made simple_return with UID %d in bb %d\n",
	     INSN_UID (ret), e->src->index);
}

/* Try to perform a kind of shrink-wrapping, making sure the
   prologue/epilogue is emitted only around those parts of the
   function that require it.

   There will be exactly one prologue, and it will be executed either
   zero or one time, on any path.  Depending on where the prologue is
   placed, some of the basic blocks can be reached via both paths with
   and without a prologue.  Such blocks will be duplicated here, and the
   edges changed to match.

   Paths that go to the exit without going through the prologue will use
   a simple_return instead of the epilogue.  We maximize the number of
   those, making sure to only duplicate blocks that can be duplicated.
   If the prologue can then still be placed in multiple locations, we
   place it as early as possible.

   An example, where we duplicate blocks with control flow (legend:
   _B_egin, _R_eturn and _S_imple_return; edges without arrowhead should
   be taken to point down or to the right, to simplify the diagram; here,
   block 3 needs a prologue, the rest does not):


       B                 B
       |                 |
       2                 2
       |\                |\
       | 3    becomes    | 3
       |/                |  \
       4                 7   4
       |\                |\  |\
       | 5               | 8 | 5
       |/                |/  |/
       6                 9   6
       |                 |   |
       R                 S   R


   (bb 4 is duplicated to 7, and so on; the prologue is inserted on the
   edge 2->3).

   Another example, where part of a loop is duplicated (again, bb 3 is
   the only block that needs a prologue):


       B   3<--              B       ->3<--
       |   |   |             |      |  |   |
       |   v   |   becomes   |      |  v   |
       2---4---              2---5--   4---
           |                     |     |
           R                     S     R


   (bb 4 is duplicated to 5; the prologue is inserted on the edge 5->3).

   ENTRY_EDGE is the edge where the prologue will be placed, possibly
   changed by this function.  PROLOGUE_SEQ is the prologue we will insert.  */

void
try_shrink_wrapping (edge *entry_edge, rtx_insn *prologue_seq)
{
  /* If we cannot shrink-wrap, are told not to shrink-wrap, or it makes
     no sense to shrink-wrap: then do not shrink-wrap!  */

  if (!SHRINK_WRAPPING_ENABLED)
    return;

  if (crtl->profile && !targetm.profile_before_prologue ())
    return;

  if (crtl->calls_eh_return)
    return;

  bool empty_prologue = true;
  for (rtx_insn *insn = prologue_seq; insn; insn = NEXT_INSN (insn))
    if (!(NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_PROLOGUE_END))
      {
	empty_prologue = false;
	break;
      }
  if (empty_prologue)
    return;

  /* Move some code down to expose more shrink-wrapping opportunities.  */

  basic_block entry = (*entry_edge)->dest;
  prepare_shrink_wrap (entry);

  if (dump_file)
    fprintf (dump_file, "Attempting shrink-wrapping optimization.\n");

  /* Compute the registers set and used in the prologue.  */

  HARD_REG_SET prologue_clobbered, prologue_used;
  CLEAR_HARD_REG_SET (prologue_clobbered);
  CLEAR_HARD_REG_SET (prologue_used);
  for (rtx_insn *insn = prologue_seq; insn; insn = NEXT_INSN (insn))
    if (NONDEBUG_INSN_P (insn))
      {
	HARD_REG_SET this_used;
	CLEAR_HARD_REG_SET (this_used);
	note_uses (&PATTERN (insn), record_hard_reg_uses, &this_used);
	this_used &= ~prologue_clobbered;
	prologue_used |= this_used;
	note_stores (insn, record_hard_reg_sets, &prologue_clobbered);
      }
  CLEAR_HARD_REG_BIT (prologue_clobbered, STACK_POINTER_REGNUM);
  if (frame_pointer_needed)
    CLEAR_HARD_REG_BIT (prologue_clobbered, HARD_FRAME_POINTER_REGNUM);

  /* Find out what registers are set up by the prologue; any use of these
     cannot happen before the prologue.  */

  struct hard_reg_set_container set_up_by_prologue;
  CLEAR_HARD_REG_SET (set_up_by_prologue.set);
  add_to_hard_reg_set (&set_up_by_prologue.set, Pmode, STACK_POINTER_REGNUM);
  add_to_hard_reg_set (&set_up_by_prologue.set, Pmode, ARG_POINTER_REGNUM);
  if (frame_pointer_needed)
    add_to_hard_reg_set (&set_up_by_prologue.set, Pmode,
			 HARD_FRAME_POINTER_REGNUM);
  if (pic_offset_table_rtx 
      && (unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
    add_to_hard_reg_set (&set_up_by_prologue.set, Pmode,
			 PIC_OFFSET_TABLE_REGNUM);
  if (crtl->drap_reg)
    add_to_hard_reg_set (&set_up_by_prologue.set,
			 GET_MODE (crtl->drap_reg),
			 REGNO (crtl->drap_reg));
  if (targetm.set_up_by_prologue)
    targetm.set_up_by_prologue (&set_up_by_prologue);

  /* We will insert the prologue before the basic block PRO.  PRO should
     dominate all basic blocks that need the prologue to be executed
     before them.  First, make PRO the "tightest wrap" possible.  */

  calculate_dominance_info (CDI_DOMINATORS);

  basic_block pro = 0;

  basic_block bb;
  edge e;
  edge_iterator ei;
  FOR_EACH_BB_FN (bb, cfun)
    {
      rtx_insn *insn;
      FOR_BB_INSNS (bb, insn)
	if (NONDEBUG_INSN_P (insn)
	    && requires_stack_frame_p (insn, prologue_used,
				       set_up_by_prologue.set))
	  {
	    if (dump_file)
	      {
		fprintf (dump_file, "Block %d needs prologue due to insn %d:\n",
			 bb->index, INSN_UID (insn));
		print_rtl_single (dump_file, insn);
	      }
	    pro = nearest_common_dominator (CDI_DOMINATORS, pro, bb);
	    break;
	  }
    }

  /* If nothing needs a prologue, just put it at the start.  This really
     shouldn't happen, but we cannot fix it here.  */

  if (pro == 0)
    {
      if (dump_file)
	fprintf(dump_file, "Nothing needs a prologue, but it isn't empty; "
			   "putting it at the start.\n");
      pro = entry;
    }

  if (dump_file)
    fprintf (dump_file, "After wrapping required blocks, PRO is now %d\n",
	     pro->index);

  /* Now see if we can put the prologue at the start of PRO.  Putting it
     there might require duplicating a block that cannot be duplicated,
     or in some cases we cannot insert the prologue there at all.  If PRO
     wont't do, try again with the immediate dominator of PRO, and so on.

     The blocks that need duplicating are those reachable from PRO but
     not dominated by it.  We keep in BB_WITH a bitmap of the blocks
     reachable from PRO that we already found, and in VEC a stack of
     those we still need to consider (to find successors).  */

  auto_bitmap bb_with;
  bitmap_set_bit (bb_with, pro->index);

  vec<basic_block> vec;
  vec.create (n_basic_blocks_for_fn (cfun));
  vec.quick_push (pro);

  unsigned max_grow_size = get_uncond_jump_length ();
  max_grow_size *= param_max_grow_copy_bb_insns;

  while (pro != entry)
    {
      while (pro != entry && !can_get_prologue (pro, prologue_clobbered))
	{
	  pro = get_immediate_dominator (CDI_DOMINATORS, pro);

	  if (bitmap_set_bit (bb_with, pro->index))
	    vec.quick_push (pro);
	}

      if (vec.is_empty ())
	break;

      basic_block bb = vec.pop ();
      if (!can_dup_for_shrink_wrapping (bb, pro, max_grow_size))
	while (!dominated_by_p (CDI_DOMINATORS, bb, pro))
	  {
	    gcc_assert (pro != entry);

	    pro = get_immediate_dominator (CDI_DOMINATORS, pro);

	    if (bitmap_set_bit (bb_with, pro->index))
	      vec.quick_push (pro);
	  }

      FOR_EACH_EDGE (e, ei, bb->succs)
	if (e->dest != EXIT_BLOCK_PTR_FOR_FN (cfun)
	    && bitmap_set_bit (bb_with, e->dest->index))
	  vec.quick_push (e->dest);
    }

  if (dump_file)
    fprintf (dump_file, "Avoiding non-duplicatable blocks, PRO is now %d\n",
	     pro->index);

  /* If we can move PRO back without having to duplicate more blocks, do so.
     We do this because putting the prologue earlier is better for scheduling.

     We can move back to a block PRE if every path from PRE will eventually
     need a prologue, that is, PRO is a post-dominator of PRE.  PRE needs
     to dominate every block reachable from itself.  We keep in BB_TMP a
     bitmap of the blocks reachable from PRE that we already found, and in
     VEC a stack of those we still need to consider.

     Any block reachable from PRE is also reachable from all predecessors
     of PRE, so if we find we need to move PRE back further we can leave
     everything not considered so far on the stack.  Any block dominated
     by PRE is also dominated by all other dominators of PRE, so anything
     found good for some PRE does not need to be reconsidered later.

     We don't need to update BB_WITH because none of the new blocks found
     can jump to a block that does not need the prologue.  */

  if (pro != entry)
    {
      calculate_dominance_info (CDI_POST_DOMINATORS);

      auto_bitmap bb_tmp;
      bitmap_copy (bb_tmp, bb_with);
      basic_block last_ok = pro;
      vec.truncate (0);

      while (pro != entry)
	{
	  basic_block pre = get_immediate_dominator (CDI_DOMINATORS, pro);
	  if (!dominated_by_p (CDI_POST_DOMINATORS, pre, pro))
	    break;

	  if (bitmap_set_bit (bb_tmp, pre->index))
	    vec.quick_push (pre);

	  bool ok = true;
	  while (!vec.is_empty ())
	    {
	      if (!dominated_by_p (CDI_DOMINATORS, vec.last (), pre))
		{
		  ok = false;
		  break;
		}

	      basic_block bb = vec.pop ();
	      FOR_EACH_EDGE (e, ei, bb->succs)
		if (bitmap_set_bit (bb_tmp, e->dest->index))
		  vec.quick_push (e->dest);
	    }

	  if (ok && can_get_prologue (pre, prologue_clobbered))
	    last_ok = pre;

	  pro = pre;
	}

      pro = last_ok;

      free_dominance_info (CDI_POST_DOMINATORS);
    }

  vec.release ();

  if (dump_file)
    fprintf (dump_file, "Bumping back to anticipatable blocks, PRO is now %d\n",
	     pro->index);

  if (pro == entry)
    {
      free_dominance_info (CDI_DOMINATORS);
      return;
    }

  /* Compute what fraction of the frequency and count of the blocks that run
     both with and without prologue are for running with prologue.  This gives
     the correct answer for reducible flow graphs; for irreducible flow graphs
     our profile is messed up beyond repair anyway.  */

  profile_count num = profile_count::zero ();
  profile_count den = profile_count::zero ();

  FOR_EACH_EDGE (e, ei, pro->preds)
    if (!dominated_by_p (CDI_DOMINATORS, e->src, pro))
      {
	if (e->count ().initialized_p ())
	  num += e->count ();
	if (e->src->count.initialized_p ())
	  den += e->src->count;
      }

  /* All is okay, so do it.  */

  crtl->shrink_wrapped = true;
  if (dump_file)
    fprintf (dump_file, "Performing shrink-wrapping.\n");

  /* Copy the blocks that can run both with and without prologue.  The
     originals run with prologue, the copies without.  Store a pointer to
     the copy in the ->aux field of the original.  */

  FOR_EACH_BB_FN (bb, cfun)
    if (bitmap_bit_p (bb_with, bb->index)
	&& !dominated_by_p (CDI_DOMINATORS, bb, pro))
      {
	basic_block dup = duplicate_block (bb, 0, 0);

	bb->aux = dup;

	if (JUMP_P (BB_END (dup)) && !any_condjump_p (BB_END (dup)))
	  emit_barrier_after_bb (dup);

	if (EDGE_COUNT (dup->succs) == 0)
	  emit_barrier_after_bb (dup);

	if (dump_file)
	  fprintf (dump_file, "Duplicated %d to %d\n", bb->index, dup->index);
	
	if (num == profile_count::zero () || den.nonzero_p ())
	  bb->count = bb->count.apply_scale (num, den);
	dup->count -= bb->count;
      }

  /* Now change the edges to point to the copies, where appropriate.  */

  FOR_EACH_BB_FN (bb, cfun)
    if (!dominated_by_p (CDI_DOMINATORS, bb, pro))
      {
	basic_block src = bb;
	if (bitmap_bit_p (bb_with, bb->index))
	  src = (basic_block) bb->aux;

	FOR_EACH_EDGE (e, ei, src->succs)
	  {
	    if (e->dest == EXIT_BLOCK_PTR_FOR_FN (cfun))
	      continue;

	    if (bitmap_bit_p (bb_with, e->dest->index)
		&& !dominated_by_p (CDI_DOMINATORS, e->dest, pro))
	      {
		if (dump_file)
		  fprintf (dump_file, "Redirecting edge %d->%d to %d\n",
			   e->src->index, e->dest->index,
			   ((basic_block) e->dest->aux)->index);
		redirect_edge_and_branch_force (e, (basic_block) e->dest->aux);
	      }
	    else if (e->flags & EDGE_FALLTHRU
		     && bitmap_bit_p (bb_with, bb->index))
	      force_nonfallthru (e);
	  }
      }

  /* Also redirect the function entry edge if necessary.  */

  FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR_FOR_FN (cfun)->succs)
    if (bitmap_bit_p (bb_with, e->dest->index)
	&& !dominated_by_p (CDI_DOMINATORS, e->dest, pro))
      {
	basic_block split_bb = split_edge (e);
	e = single_succ_edge (split_bb);
	redirect_edge_and_branch_force (e, (basic_block) e->dest->aux);
      }

  /* Make a simple_return for those exits that run without prologue.  */

  FOR_EACH_BB_REVERSE_FN (bb, cfun)
    if (!bitmap_bit_p (bb_with, bb->index))
      FOR_EACH_EDGE (e, ei, bb->succs)
	if (e->dest == EXIT_BLOCK_PTR_FOR_FN (cfun))
	  handle_simple_exit (e);

  /* Finally, we want a single edge to put the prologue on.  Make a new
     block before the PRO block; the edge beteen them is the edge we want.
     Then redirect those edges into PRO that come from blocks without the
     prologue, to point to the new block instead.  The new prologue block
     is put at the end of the insn chain.  */

  basic_block new_bb = create_empty_bb (EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb);
  BB_COPY_PARTITION (new_bb, pro);
  new_bb->count = profile_count::zero ();
  if (dump_file)
    fprintf (dump_file, "Made prologue block %d\n", new_bb->index);

  for (ei = ei_start (pro->preds); (e = ei_safe_edge (ei)); )
    {
      if (bitmap_bit_p (bb_with, e->src->index)
	  || dominated_by_p (CDI_DOMINATORS, e->src, pro))
	{
	  ei_next (&ei);
	  continue;
	}

      new_bb->count += e->count ();

      redirect_edge_and_branch_force (e, new_bb);
      if (dump_file)
	fprintf (dump_file, "Redirected edge from %d\n", e->src->index);
    }

  *entry_edge = make_single_succ_edge (new_bb, pro, EDGE_FALLTHRU);
  force_nonfallthru (*entry_edge);

  free_dominance_info (CDI_DOMINATORS);
}

/* Separate shrink-wrapping

   Instead of putting all of the prologue and epilogue in one spot, we
   can put parts of it in places where those components are executed less
   frequently.  The following code does this, for prologue and epilogue
   components that can be put in more than one location, and where those
   components can be executed more than once (the epilogue component will
   always be executed before the prologue component is executed a second
   time).

   What exactly is a component is target-dependent.  The more usual
   components are simple saves/restores to/from the frame of callee-saved
   registers.  This code treats components abstractly (as an sbitmap),
   letting the target handle all details.

   Prologue components are placed in such a way that for every component
   the prologue is executed as infrequently as possible.  We do this by
   walking the dominator tree, comparing the cost of placing a prologue
   component before a block to the sum of costs determined for all subtrees
   of that block.

   From this placement, we then determine for each component all blocks
   where at least one of this block's dominators (including itself) will
   get a prologue inserted.  That then is how the components are placed.
   We could place the epilogue components a bit smarter (we can save a
   bit of code size sometimes); this is a possible future improvement.

   Prologues and epilogues are preferably placed into a block, either at
   the beginning or end of it, if it is needed for all predecessor resp.
   successor edges; or placed on the edge otherwise.

   If the placement of any prologue/epilogue leads to a situation we cannot
   handle (for example, an abnormal edge would need to be split, or some
   targets want to use some specific registers that may not be available
   where we want to put them), separate shrink-wrapping for the components
   in that prologue/epilogue is aborted.  */


/* Print the sbitmap COMPONENTS to the DUMP_FILE if not empty, with the
   label LABEL.  */
static void
dump_components (const char *label, sbitmap components)
{
  if (bitmap_empty_p (components))
    return;

  fprintf (dump_file, " [%s", label);

  for (unsigned int j = 0; j < components->n_bits; j++)
    if (bitmap_bit_p (components, j))
      fprintf (dump_file, " %u", j);

  fprintf (dump_file, "]");
}

/* The data we collect for each bb.  */
struct sw {
  /* What components does this BB need?  */
  sbitmap needs_components;

  /* What components does this BB have?  This is the main decision this
     pass makes.  */
  sbitmap has_components;

  /* The components for which we placed code at the start of the BB (instead
     of on all incoming edges).  */
  sbitmap head_components;

  /* The components for which we placed code at the end of the BB (instead
     of on all outgoing edges).  */
  sbitmap tail_components;

  /* The frequency of executing the prologue for this BB, if a prologue is
     placed on this BB.  This is a pessimistic estimate (no prologue is
     needed for edges from blocks that have the component under consideration
     active already).  */
  gcov_type own_cost;

  /* The frequency of executing the prologue for this BB and all BBs
     dominated by it.  */
  gcov_type total_cost;
};

/* A helper function for accessing the pass-specific info.  */
static inline struct sw *
SW (basic_block bb)
{
  gcc_assert (bb->aux);
  return (struct sw *) bb->aux;
}

/* Create the pass-specific data structures for separately shrink-wrapping
   with components COMPONENTS.  */
static void
init_separate_shrink_wrap (sbitmap components)
{
  basic_block bb;
  FOR_ALL_BB_FN (bb, cfun)
    {
      bb->aux = xcalloc (1, sizeof (struct sw));

      SW (bb)->needs_components = targetm.shrink_wrap.components_for_bb (bb);

      /* Mark all basic blocks without successor as needing all components.
	 This avoids problems in at least cfgcleanup, sel-sched, and
	 regrename (largely to do with all paths to such a block still
	 needing the same dwarf CFI info).  */
      if (EDGE_COUNT (bb->succs) == 0)
	bitmap_copy (SW (bb)->needs_components, components);

      if (dump_file)
	{
	  fprintf (dump_file, "bb %d components:", bb->index);
	  dump_components ("has", SW (bb)->needs_components);
	  fprintf (dump_file, "\n");
	}

      SW (bb)->has_components = sbitmap_alloc (SBITMAP_SIZE (components));
      SW (bb)->head_components = sbitmap_alloc (SBITMAP_SIZE (components));
      SW (bb)->tail_components = sbitmap_alloc (SBITMAP_SIZE (components));
      bitmap_clear (SW (bb)->has_components);
    }
}

/* Destroy the pass-specific data.  */
static void
fini_separate_shrink_wrap (void)
{
  basic_block bb;
  FOR_ALL_BB_FN (bb, cfun)
    if (bb->aux)
      {
	sbitmap_free (SW (bb)->needs_components);
	sbitmap_free (SW (bb)->has_components);
	sbitmap_free (SW (bb)->head_components);
	sbitmap_free (SW (bb)->tail_components);
	free (bb->aux);
	bb->aux = 0;
      }
}

/* Place the prologue for component WHICH, in the basic blocks dominated
   by HEAD.  Do a DFS over the dominator tree, and set bit WHICH in the
   HAS_COMPONENTS of a block if either the block has that bit set in
   NEEDS_COMPONENTS, or it is cheaper to place the prologue here than in all
   dominator subtrees separately.  */
static void
place_prologue_for_one_component (unsigned int which, basic_block head)
{
  /* The block we are currently dealing with.  */
  basic_block bb = head;
  /* Is this the first time we visit this block, i.e. have we just gone
     down the tree.  */
  bool first_visit = true;

  /* Walk the dominator tree, visit one block per iteration of this loop.
     Each basic block is visited twice: once before visiting any children
     of the block, and once after visiting all of them (leaf nodes are
     visited only once).  As an optimization, we do not visit subtrees
     that can no longer influence the prologue placement.  */
  for (;;)
    {
      /* First visit of a block: set the (children) cost accumulator to zero;
	 if the block does not have the component itself, walk down.  */
      if (first_visit)
	{
	  /* Initialize the cost.  The cost is the block execution frequency
	     that does not come from backedges.  Calculating this by simply
	     adding the cost of all edges that aren't backedges does not
	     work: this does not always add up to the block frequency at
	     all, and even if it does, rounding error makes for bad
	     decisions.  */
	  SW (bb)->own_cost = bb->count.to_frequency (cfun);

	  edge e;
	  edge_iterator ei;
	  FOR_EACH_EDGE (e, ei, bb->preds)
	    if (dominated_by_p (CDI_DOMINATORS, e->src, bb))
	      {
		if (SW (bb)->own_cost > EDGE_FREQUENCY (e))
		  SW (bb)->own_cost -= EDGE_FREQUENCY (e);
		else
		  SW (bb)->own_cost = 0;
	      }

	  SW (bb)->total_cost = 0;

	  if (!bitmap_bit_p (SW (bb)->needs_components, which)
	      && first_dom_son (CDI_DOMINATORS, bb))
	    {
	      bb = first_dom_son (CDI_DOMINATORS, bb);
	      continue;
	    }
	}

      /* If this block does need the component itself, or it is cheaper to
	 put the prologue here than in all the descendants that need it,
	 mark it so.  If this block's immediate post-dominator is dominated
	 by this block, and that needs the prologue, we can put it on this
	 block as well (earlier is better).  */
      if (bitmap_bit_p (SW (bb)->needs_components, which)
	  || SW (bb)->total_cost > SW (bb)->own_cost)
	{
	  SW (bb)->total_cost = SW (bb)->own_cost;
	  bitmap_set_bit (SW (bb)->has_components, which);
	}
      else
	{
	  basic_block kid = get_immediate_dominator (CDI_POST_DOMINATORS, bb);
	  if (dominated_by_p (CDI_DOMINATORS, kid, bb)
	      && bitmap_bit_p (SW (kid)->has_components, which))
	    {
	      SW (bb)->total_cost = SW (bb)->own_cost;
	      bitmap_set_bit (SW (bb)->has_components, which);
	    }
	}

      /* We are back where we started, so we are done now.  */
      if (bb == head)
	return;

      /* We now know the cost of the subtree rooted at the current block.
	 Accumulate this cost in the parent.  */
      basic_block parent = get_immediate_dominator (CDI_DOMINATORS, bb);
      SW (parent)->total_cost += SW (bb)->total_cost;

      /* Don't walk the tree down unless necessary.  */
      if (next_dom_son (CDI_DOMINATORS, bb)
          && SW (parent)->total_cost <= SW (parent)->own_cost)
	{
	  bb = next_dom_son (CDI_DOMINATORS, bb);
	  first_visit = true;
	}
      else
	{
	  bb = parent;
	  first_visit = false;
	}
    }
}

/* Set HAS_COMPONENTS in every block to the maximum it can be set to without
   setting it on any path from entry to exit where it was not already set
   somewhere (or, for blocks that have no path to the exit, consider only
   paths from the entry to the block itself).  Return whether any changes
   were made to some HAS_COMPONENTS.  */
static bool
spread_components (sbitmap components)
{
  basic_block entry_block = ENTRY_BLOCK_PTR_FOR_FN (cfun);
  basic_block exit_block = EXIT_BLOCK_PTR_FOR_FN (cfun);

  /* A stack of all blocks left to consider, and a bitmap of all blocks
     on that stack.  */
  vec<basic_block> todo;
  todo.create (n_basic_blocks_for_fn (cfun));
  auto_bitmap seen;

  auto_sbitmap old (SBITMAP_SIZE (components));

  /* Find for every block the components that are *not* needed on some path
     from the entry to that block.  Do this with a flood fill from the entry
     block.  Every block can be visited at most as often as the number of
     components (plus one), and usually much less often.  */

  if (dump_file)
    fprintf (dump_file, "Spreading down...\n");

  basic_block bb;
  FOR_ALL_BB_FN (bb, cfun)
    bitmap_clear (SW (bb)->head_components);

  bitmap_copy (SW (entry_block)->head_components, components);

  edge e;
  edge_iterator ei;

  todo.quick_push (single_succ (entry_block));
  bitmap_set_bit (seen, single_succ (entry_block)->index);
  while (!todo.is_empty ())
    {
      bb = todo.pop ();

      bitmap_copy (old, SW (bb)->head_components);

      FOR_EACH_EDGE (e, ei, bb->preds)
	bitmap_ior (SW (bb)->head_components, SW (bb)->head_components,
		    SW (e->src)->head_components);

      bitmap_and_compl (SW (bb)->head_components, SW (bb)->head_components,
			SW (bb)->has_components);

      if (!bitmap_equal_p (old, SW (bb)->head_components))
	FOR_EACH_EDGE (e, ei, bb->succs)
	  if (bitmap_set_bit (seen, e->dest->index))
	    todo.quick_push (e->dest);

      bitmap_clear_bit (seen, bb->index);
    }

  /* Find for every block the components that are *not* needed on some reverse
     path from the exit to that block.  */

  if (dump_file)
    fprintf (dump_file, "Spreading up...\n");

  /* First, mark all blocks not reachable from the exit block as not needing
     any component on any path to the exit.  Mark everything, and then clear
     again by a flood fill.  */

  FOR_ALL_BB_FN (bb, cfun)
    bitmap_copy (SW (bb)->tail_components, components);

  FOR_EACH_EDGE (e, ei, exit_block->preds)
    {
      todo.quick_push (e->src);
      bitmap_set_bit (seen, e->src->index);
    }

  while (!todo.is_empty ())
    {
      bb = todo.pop ();

      if (!bitmap_empty_p (SW (bb)->tail_components))
	FOR_EACH_EDGE (e, ei, bb->preds)
	  if (bitmap_set_bit (seen, e->src->index))
	    todo.quick_push (e->src);

      bitmap_clear (SW (bb)->tail_components);

      bitmap_clear_bit (seen, bb->index);
    }

  /* And then, flood fill backwards to find for every block the components
     not needed on some path to the exit.  */

  bitmap_copy (SW (exit_block)->tail_components, components);

  FOR_EACH_EDGE (e, ei, exit_block->preds)
    {
      todo.quick_push (e->src);
      bitmap_set_bit (seen, e->src->index);
    }

  while (!todo.is_empty ())
    {
      bb = todo.pop ();

      bitmap_copy (old, SW (bb)->tail_components);

      FOR_EACH_EDGE (e, ei, bb->succs)
	bitmap_ior (SW (bb)->tail_components, SW (bb)->tail_components,
		    SW (e->dest)->tail_components);

      bitmap_and_compl (SW (bb)->tail_components, SW (bb)->tail_components,
			SW (bb)->has_components);

      if (!bitmap_equal_p (old, SW (bb)->tail_components))
	FOR_EACH_EDGE (e, ei, bb->preds)
	  if (bitmap_set_bit (seen, e->src->index))
	    todo.quick_push (e->src);

      bitmap_clear_bit (seen, bb->index);
    }

  todo.release ();

  /* Finally, mark everything not needed both forwards and backwards.  */

  bool did_changes = false;

  FOR_EACH_BB_FN (bb, cfun)
    {
      bitmap_copy (old, SW (bb)->has_components);

      bitmap_and (SW (bb)->head_components, SW (bb)->head_components,
		  SW (bb)->tail_components);
      bitmap_and_compl (SW (bb)->has_components, components,
			SW (bb)->head_components);

      if (!did_changes && !bitmap_equal_p (old, SW (bb)->has_components))
	did_changes = true;
    }

  FOR_ALL_BB_FN (bb, cfun)
    {
      if (dump_file)
	{
	  fprintf (dump_file, "bb %d components:", bb->index);
	  dump_components ("has", SW (bb)->has_components);
	  fprintf (dump_file, "\n");
	}
    }

  return did_changes;
}

/* If we cannot handle placing some component's prologues or epilogues where
   we decided we should place them, unmark that component in COMPONENTS so
   that it is not wrapped separately.  */
static void
disqualify_problematic_components (sbitmap components)
{
  auto_sbitmap pro (SBITMAP_SIZE (components));
  auto_sbitmap epi (SBITMAP_SIZE (components));

  basic_block bb;
  FOR_EACH_BB_FN (bb, cfun)
    {
      edge e;
      edge_iterator ei;
      FOR_EACH_EDGE (e, ei, bb->succs)
	{
	  /* Find which components we want pro/epilogues for here.  */
	  bitmap_and_compl (epi, SW (e->src)->has_components,
			    SW (e->dest)->has_components);
	  bitmap_and_compl (pro, SW (e->dest)->has_components,
			    SW (e->src)->has_components);

	  /* Ask the target what it thinks about things.  */
	  if (!bitmap_empty_p (epi))
	    targetm.shrink_wrap.disqualify_components (components, e, epi,
						       false);
	  if (!bitmap_empty_p (pro))
	    targetm.shrink_wrap.disqualify_components (components, e, pro,
						       true);

	  /* If this edge doesn't need splitting, we're fine.  */
	  if (single_pred_p (e->dest)
	      && e->dest != EXIT_BLOCK_PTR_FOR_FN (cfun))
	    continue;

	  /* If the edge can be split, that is fine too.  */
	  if ((e->flags & EDGE_ABNORMAL) == 0)
	    continue;

	  /* We also can handle sibcalls.  */
	  if (e->dest == EXIT_BLOCK_PTR_FOR_FN (cfun))
	    {
	      gcc_assert (e->flags & EDGE_SIBCALL);
	      continue;
	    }

	  /* Remove from consideration those components we would need
	     pro/epilogues for on edges where we cannot insert them.  */
	  bitmap_and_compl (components, components, epi);
	  bitmap_and_compl (components, components, pro);

	  if (dump_file && !bitmap_subset_p (epi, components))
	    {
	      fprintf (dump_file, "  BAD epi %d->%d", e->src->index,
		       e->dest->index);
	      if (e->flags & EDGE_EH)
		fprintf (dump_file, " for EH");
	      dump_components ("epi", epi);
	      fprintf (dump_file, "\n");
	    }

	  if (dump_file && !bitmap_subset_p (pro, components))
	    {
	      fprintf (dump_file, "  BAD pro %d->%d", e->src->index,
		       e->dest->index);
	      if (e->flags & EDGE_EH)
		fprintf (dump_file, " for EH");
	      dump_components ("pro", pro);
	      fprintf (dump_file, "\n");
	    }
	}
    }
}

/* Place code for prologues and epilogues for COMPONENTS where we can put
   that code at the start of basic blocks.  */
static void
emit_common_heads_for_components (sbitmap components)
{
  auto_sbitmap pro (SBITMAP_SIZE (components));
  auto_sbitmap epi (SBITMAP_SIZE (components));
  auto_sbitmap tmp (SBITMAP_SIZE (components));

  basic_block bb;
  FOR_ALL_BB_FN (bb, cfun)
    bitmap_clear (SW (bb)->head_components);

  FOR_EACH_BB_FN (bb, cfun)
    {
      /* Find which prologue resp. epilogue components are needed for all
	 predecessor edges to this block.  */

      /* First, select all possible components.  */
      bitmap_copy (epi, components);
      bitmap_copy (pro, components);

      edge e;
      edge_iterator ei;
      FOR_EACH_EDGE (e, ei, bb->preds)
	{
	  if (e->flags & EDGE_ABNORMAL)
	    {
	      bitmap_clear (epi);
	      bitmap_clear (pro);
	      break;
	    }

	  /* Deselect those epilogue components that should not be inserted
	     for this edge.  */
	  bitmap_and_compl (tmp, SW (e->src)->has_components,
			    SW (e->dest)->has_components);
	  bitmap_and (epi, epi, tmp);

	  /* Similar, for the prologue.  */
	  bitmap_and_compl (tmp, SW (e->dest)->has_components,
			    SW (e->src)->has_components);
	  bitmap_and (pro, pro, tmp);
	}

      if (dump_file && !(bitmap_empty_p (epi) && bitmap_empty_p (pro)))
	fprintf (dump_file, "  bb %d", bb->index);

      if (dump_file && !bitmap_empty_p (epi))
	dump_components ("epi", epi);
      if (dump_file && !bitmap_empty_p (pro))
	dump_components ("pro", pro);

      if (dump_file && !(bitmap_empty_p (epi) && bitmap_empty_p (pro)))
	fprintf (dump_file, "\n");

      /* Place code after the BB note.  */
      if (!bitmap_empty_p (pro))
	{
	  start_sequence ();
	  targetm.shrink_wrap.emit_prologue_components (pro);
	  rtx_insn *seq = get_insns ();
	  end_sequence ();
	  record_prologue_seq (seq);

	  emit_insn_after (seq, bb_note (bb));

	  bitmap_ior (SW (bb)->head_components, SW (bb)->head_components, pro);
	}

      if (!bitmap_empty_p (epi))
	{
	  start_sequence ();
	  targetm.shrink_wrap.emit_epilogue_components (epi);
	  rtx_insn *seq = get_insns ();
	  end_sequence ();
	  record_epilogue_seq (seq);

	  emit_insn_after (seq, bb_note (bb));

	  bitmap_ior (SW (bb)->head_components, SW (bb)->head_components, epi);
	}
    }
}

/* Place code for prologues and epilogues for COMPONENTS where we can put
   that code at the end of basic blocks.  */
static void
emit_common_tails_for_components (sbitmap components)
{
  auto_sbitmap pro (SBITMAP_SIZE (components));
  auto_sbitmap epi (SBITMAP_SIZE (components));
  auto_sbitmap tmp (SBITMAP_SIZE (components));

  basic_block bb;
  FOR_ALL_BB_FN (bb, cfun)
    bitmap_clear (SW (bb)->tail_components);

  FOR_EACH_BB_FN (bb, cfun)
    {
      /* Find which prologue resp. epilogue components are needed for all
	 successor edges from this block.  */
      if (EDGE_COUNT (bb->succs) == 0)
	continue;

      /* First, select all possible components.  */
      bitmap_copy (epi, components);
      bitmap_copy (pro, components);

      edge e;
      edge_iterator ei;
      FOR_EACH_EDGE (e, ei, bb->succs)
	{
	  if (e->flags & EDGE_ABNORMAL)
	    {
	      bitmap_clear (epi);
	      bitmap_clear (pro);
	      break;
	    }

	  /* Deselect those epilogue components that should not be inserted
	     for this edge, and also those that are already put at the head
	     of the successor block.  */
	  bitmap_and_compl (tmp, SW (e->src)->has_components,
			    SW (e->dest)->has_components);
	  bitmap_and_compl (tmp, tmp, SW (e->dest)->head_components);
	  bitmap_and (epi, epi, tmp);

	  /* Similarly, for the prologue.  */
	  bitmap_and_compl (tmp, SW (e->dest)->has_components,
			    SW (e->src)->has_components);
	  bitmap_and_compl (tmp, tmp, SW (e->dest)->head_components);
	  bitmap_and (pro, pro, tmp);
	}

      /* If the last insn of this block is a control flow insn we cannot
	 put anything after it.  We can put our code before it instead,
	 but only if that jump insn is a simple jump.  */
      rtx_insn *last_insn = BB_END (bb);
      if (control_flow_insn_p (last_insn) && !simplejump_p (last_insn))
	{
	  bitmap_clear (epi);
	  bitmap_clear (pro);
	}

      if (dump_file && !(bitmap_empty_p (epi) && bitmap_empty_p (pro)))
	fprintf (dump_file, "  bb %d", bb->index);

      if (dump_file && !bitmap_empty_p (epi))
	dump_components ("epi", epi);
      if (dump_file && !bitmap_empty_p (pro))
	dump_components ("pro", pro);

      if (dump_file && !(bitmap_empty_p (epi) && bitmap_empty_p (pro)))
	fprintf (dump_file, "\n");

      /* Put the code at the end of the BB, but before any final jump.  */
      if (!bitmap_empty_p (epi))
	{
	  start_sequence ();
	  targetm.shrink_wrap.emit_epilogue_components (epi);
	  rtx_insn *seq = get_insns ();
	  end_sequence ();
	  record_epilogue_seq (seq);

	  if (control_flow_insn_p (last_insn))
	    emit_insn_before (seq, last_insn);
	  else
	    emit_insn_after (seq, last_insn);

	  bitmap_ior (SW (bb)->tail_components, SW (bb)->tail_components, epi);
	}

      if (!bitmap_empty_p (pro))
	{
	  start_sequence ();
	  targetm.shrink_wrap.emit_prologue_components (pro);
	  rtx_insn *seq = get_insns ();
	  end_sequence ();
	  record_prologue_seq (seq);

	  if (control_flow_insn_p (last_insn))
	    emit_insn_before (seq, last_insn);
	  else
	    emit_insn_after (seq, last_insn);

	  bitmap_ior (SW (bb)->tail_components, SW (bb)->tail_components, pro);
	}
    }
}

/* Place prologues and epilogues for COMPONENTS on edges, if we haven't already
   placed them inside blocks directly.  */
static void
insert_prologue_epilogue_for_components (sbitmap components)
{
  auto_sbitmap pro (SBITMAP_SIZE (components));
  auto_sbitmap epi (SBITMAP_SIZE (components));

  basic_block bb;
  FOR_EACH_BB_FN (bb, cfun)
    {
      if (!bb->aux)
	continue;

      edge e;
      edge_iterator ei;
      FOR_EACH_EDGE (e, ei, bb->succs)
	{
	  /* Find which pro/epilogue components are needed on this edge.  */
	  bitmap_and_compl (epi, SW (e->src)->has_components,
			    SW (e->dest)->has_components);
	  bitmap_and_compl (pro, SW (e->dest)->has_components,
			    SW (e->src)->has_components);
	  bitmap_and (epi, epi, components);
	  bitmap_and (pro, pro, components);

	  /* Deselect those we already have put at the head or tail of the
	     edge's dest resp. src.  */
	  bitmap_and_compl (epi, epi, SW (e->dest)->head_components);
	  bitmap_and_compl (pro, pro, SW (e->dest)->head_components);
	  bitmap_and_compl (epi, epi, SW (e->src)->tail_components);
	  bitmap_and_compl (pro, pro, SW (e->src)->tail_components);

	  if (!bitmap_empty_p (epi) || !bitmap_empty_p (pro))
	    {
	      if (dump_file)
		{
		  fprintf (dump_file, "  %d->%d", e->src->index,
			   e->dest->index);
		  dump_components ("epi", epi);
		  dump_components ("pro", pro);
		  if (e->flags & EDGE_SIBCALL)
		    fprintf (dump_file, "  (SIBCALL)");
		  else if (e->flags & EDGE_ABNORMAL)
		    fprintf (dump_file, "  (ABNORMAL)");
		  fprintf (dump_file, "\n");
		}

	      /* Put the epilogue components in place.  */
	      start_sequence ();
	      targetm.shrink_wrap.emit_epilogue_components (epi);
	      rtx_insn *seq = get_insns ();
	      end_sequence ();
	      record_epilogue_seq (seq);

	      if (e->flags & EDGE_SIBCALL)
		{
		  gcc_assert (e->dest == EXIT_BLOCK_PTR_FOR_FN (cfun));

		  rtx_insn *insn = BB_END (e->src);
		  gcc_assert (CALL_P (insn) && SIBLING_CALL_P (insn));
		  emit_insn_before (seq, insn);
		}
	      else if (e->dest == EXIT_BLOCK_PTR_FOR_FN (cfun))
		{
		  gcc_assert (e->flags & EDGE_FALLTHRU);
		  basic_block new_bb = split_edge (e);
		  emit_insn_after (seq, BB_END (new_bb));
		}
	      else
		insert_insn_on_edge (seq, e);

	      /* Put the prologue components in place.  */
	      start_sequence ();
	      targetm.shrink_wrap.emit_prologue_components (pro);
	      seq = get_insns ();
	      end_sequence ();
	      record_prologue_seq (seq);

	      insert_insn_on_edge (seq, e);
	    }
	}
    }

  commit_edge_insertions ();
}

/* The main entry point to this subpass.  FIRST_BB is where the prologue
   would be normally put.  */
void
try_shrink_wrapping_separate (basic_block first_bb)
{
  if (HAVE_cc0)
    return;

  if (!(SHRINK_WRAPPING_ENABLED
	&& flag_shrink_wrap_separate
	&& optimize_function_for_speed_p (cfun)
	&& targetm.shrink_wrap.get_separate_components))
    return;

  /* We don't handle "strange" functions.  */
  if (cfun->calls_alloca
      || cfun->calls_setjmp
      || cfun->can_throw_non_call_exceptions
      || crtl->calls_eh_return
      || crtl->has_nonlocal_goto
      || crtl->saves_all_registers)
    return;

  /* Ask the target what components there are.  If it returns NULL, don't
     do anything.  */
  sbitmap components = targetm.shrink_wrap.get_separate_components ();
  if (!components)
    return;

  /* We need LIVE info, not defining anything in the entry block and not
     using anything in the exit block.  A block then needs a component if
     the register for that component is in the IN or GEN or KILL set for
     that block.  */
  df_scan->local_flags |= DF_SCAN_EMPTY_ENTRY_EXIT;
  df_update_entry_exit_and_calls ();
  df_live_add_problem ();
  df_live_set_all_dirty ();
  df_analyze ();

  calculate_dominance_info (CDI_DOMINATORS);
  calculate_dominance_info (CDI_POST_DOMINATORS);

  init_separate_shrink_wrap (components);

  sbitmap_iterator sbi;
  unsigned int j;
  EXECUTE_IF_SET_IN_BITMAP (components, 0, j, sbi)
    place_prologue_for_one_component (j, first_bb);

  /* Try to minimize the number of saves and restores.  Do this as long as
     it changes anything.  This does not iterate more than a few times.  */
  int spread_times = 0;
  while (spread_components (components))
    {
      spread_times++;

      if (dump_file)
	fprintf (dump_file, "Now spread %d times.\n", spread_times);
    }

  disqualify_problematic_components (components);

  /* Don't separately shrink-wrap anything where the "main" prologue will
     go; the target code can often optimize things if it is presented with
     all components together (say, if it generates store-multiple insns).  */
  bitmap_and_compl (components, components, SW (first_bb)->has_components);

  if (bitmap_empty_p (components))
    {
      if (dump_file)
	fprintf (dump_file, "Not wrapping anything separately.\n");
    }
  else
    {
      if (dump_file)
	{
	  fprintf (dump_file, "The components we wrap separately are");
	  dump_components ("sep", components);
	  fprintf (dump_file, "\n");

	  fprintf (dump_file, "... Inserting common heads...\n");
	}

      emit_common_heads_for_components (components);

      if (dump_file)
	fprintf (dump_file, "... Inserting common tails...\n");

      emit_common_tails_for_components (components);

      if (dump_file)
	fprintf (dump_file, "... Inserting the more difficult ones...\n");

      insert_prologue_epilogue_for_components (components);

      if (dump_file)
	fprintf (dump_file, "... Done.\n");

      targetm.shrink_wrap.set_handled_components (components);

      crtl->shrink_wrapped_separate = true;
    }

  fini_separate_shrink_wrap ();

  sbitmap_free (components);
  free_dominance_info (CDI_DOMINATORS);
  free_dominance_info (CDI_POST_DOMINATORS);

  /* All done.  */
  df_scan->local_flags &= ~DF_SCAN_EMPTY_ENTRY_EXIT;
  df_update_entry_exit_and_calls ();
  df_live_set_all_dirty ();
  df_analyze ();
}
