/* Change pseudos by memory.
   Copyright (C) 2010-2019 Free Software Foundation, Inc.
   Contributed by Vladimir Makarov <vmakarov@redhat.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/>.	 */


/* This file contains code for a pass to change spilled pseudos into
   memory.

   The pass creates necessary stack slots and assigns spilled pseudos
   to the stack slots in following way:

   for all spilled pseudos P most frequently used first do
     for all stack slots S do
       if P doesn't conflict with pseudos assigned to S then
	 assign S to P and goto to the next pseudo process
       end
     end
     create new stack slot S and assign P to S
   end

   The actual algorithm is bit more complicated because of different
   pseudo sizes.

   After that the code changes spilled pseudos (except ones created
   from scratches) by corresponding stack slot memory in RTL.

   If at least one stack slot was created, we need to run more passes
   because we have new addresses which should be checked and because
   the old address displacements might change and address constraints
   (or insn memory constraints) might not be satisfied any more.

   For some targets, the pass can spill some pseudos into hard
   registers of different class (usually into vector registers)
   instead of spilling them into memory if it is possible and
   profitable.  Spilling GENERAL_REGS pseudo into SSE registers for
   Intel Corei7 is an example of such optimization.  And this is
   actually recommended by Intel optimization guide.

   The file also contains code for final change of pseudos on hard
   regs correspondingly assigned to them.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "target.h"
#include "rtl.h"
#include "df.h"
#include "insn-config.h"
#include "regs.h"
#include "memmodel.h"
#include "ira.h"
#include "recog.h"
#include "output.h"
#include "cfgrtl.h"
#include "lra.h"
#include "lra-int.h"


/* Max regno at the start of the pass.	*/
static int regs_num;

/* Map spilled regno -> hard regno used instead of memory for
   spilling.  */
static rtx *spill_hard_reg;

/* The structure describes stack slot of a spilled pseudo.  */
struct pseudo_slot
{
  /* Number (0, 1, ...) of the stack slot to which given pseudo
     belongs.  */
  int slot_num;
  /* First or next slot with the same slot number.  */
  struct pseudo_slot *next, *first;
  /* Memory representing the spilled pseudo.  */
  rtx mem;
};

/* The stack slots for each spilled pseudo.  Indexed by regnos.	 */
static struct pseudo_slot *pseudo_slots;

/* The structure describes a register or a stack slot which can be
   used for several spilled pseudos.  */
struct slot
{
  /* First pseudo with given stack slot.  */
  int regno;
  /* Hard reg into which the slot pseudos are spilled.	The value is
     negative for pseudos spilled into memory.	*/
  int hard_regno;
  /* Maximum alignment required by all users of the slot.  */
  unsigned int align;
  /* Maximum size required by all users of the slot.  */
  poly_int64 size;
  /* Memory representing the all stack slot.  It can be different from
     memory representing a pseudo belonging to give stack slot because
     pseudo can be placed in a part of the corresponding stack slot.
     The value is NULL for pseudos spilled into a hard reg.  */
  rtx mem;
  /* Combined live ranges of all pseudos belonging to given slot.  It
     is used to figure out that a new spilled pseudo can use given
     stack slot.  */
  lra_live_range_t live_ranges;
};

/* Array containing info about the stack slots.	 The array element is
   indexed by the stack slot number in the range [0..slots_num).  */
static struct slot *slots;
/* The number of the stack slots currently existing.  */
static int slots_num;

/* Set up memory of the spilled pseudo I.  The function can allocate
   the corresponding stack slot if it is not done yet.	*/
static void
assign_mem_slot (int i)
{
  rtx x = NULL_RTX;
  machine_mode mode = GET_MODE (regno_reg_rtx[i]);
  poly_int64 inherent_size = PSEUDO_REGNO_BYTES (i);
  machine_mode wider_mode
    = wider_subreg_mode (mode, lra_reg_info[i].biggest_mode);
  poly_int64 total_size = GET_MODE_SIZE (wider_mode);
  poly_int64 adjust = 0;

  lra_assert (regno_reg_rtx[i] != NULL_RTX && REG_P (regno_reg_rtx[i])
	      && lra_reg_info[i].nrefs != 0 && reg_renumber[i] < 0);

  unsigned int slot_num = pseudo_slots[i].slot_num;
  x = slots[slot_num].mem;
  if (!x)
    {
      x = assign_stack_local (BLKmode, slots[slot_num].size,
			      slots[slot_num].align);
      slots[slot_num].mem = x;
    }

  /* On a big endian machine, the "address" of the slot is the address
     of the low part that fits its inherent mode.  */
  adjust += subreg_size_lowpart_offset (inherent_size, total_size);
  x = adjust_address_nv (x, GET_MODE (regno_reg_rtx[i]), adjust);

  /* Set all of the memory attributes as appropriate for a spill.  */
  set_mem_attrs_for_spill (x);
  pseudo_slots[i].mem = x;
}

/* Sort pseudos according their usage frequencies.  */
static int
regno_freq_compare (const void *v1p, const void *v2p)
{
  const int regno1 = *(const int *) v1p;
  const int regno2 = *(const int *) v2p;
  int diff;

  if ((diff = lra_reg_info[regno2].freq - lra_reg_info[regno1].freq) != 0)
    return diff;
  return regno1 - regno2;
}

/* Sort pseudos according to their slots, putting the slots in the order
   that they should be allocated.

   First prefer to group slots with variable sizes together and slots
   with constant sizes together, since that usually makes them easier
   to address from a common anchor point.  E.g. loads of polynomial-sized
   registers tend to take polynomial offsets while loads of constant-sized
   registers tend to take constant (non-polynomial) offsets.

   Next, slots with lower numbers have the highest priority and should
   get the smallest displacement from the stack or frame pointer
   (whichever is being used).

   The first allocated slot is always closest to the frame pointer,
   so prefer lower slot numbers when frame_pointer_needed.  If the stack
   and frame grow in the same direction, then the first allocated slot is
   always closest to the initial stack pointer and furthest away from the
   final stack pointer, so allocate higher numbers first when using the
   stack pointer in that case.  The reverse is true if the stack and
   frame grow in opposite directions.  */
static int
pseudo_reg_slot_compare (const void *v1p, const void *v2p)
{
  const int regno1 = *(const int *) v1p;
  const int regno2 = *(const int *) v2p;
  int diff, slot_num1, slot_num2;

  slot_num1 = pseudo_slots[regno1].slot_num;
  slot_num2 = pseudo_slots[regno2].slot_num;
  diff = (int (slots[slot_num1].size.is_constant ())
	  - int (slots[slot_num2].size.is_constant ()));
  if (diff != 0)
    return diff;
  if ((diff = slot_num1 - slot_num2) != 0)
    return (frame_pointer_needed
	    || (!FRAME_GROWS_DOWNWARD) == STACK_GROWS_DOWNWARD ? diff : -diff);
  poly_int64 total_size1 = GET_MODE_SIZE (lra_reg_info[regno1].biggest_mode);
  poly_int64 total_size2 = GET_MODE_SIZE (lra_reg_info[regno2].biggest_mode);
  if ((diff = compare_sizes_for_sort (total_size2, total_size1)) != 0)
    return diff;
  return regno1 - regno2;
}

/* Assign spill hard registers to N pseudos in PSEUDO_REGNOS which is
   sorted in order of highest frequency first.  Put the pseudos which
   did not get a spill hard register at the beginning of array
   PSEUDO_REGNOS.  Return the number of such pseudos.  */
static int
assign_spill_hard_regs (int *pseudo_regnos, int n)
{
  int i, k, p, regno, res, spill_class_size, hard_regno, nr;
  enum reg_class rclass, spill_class;
  machine_mode mode;
  lra_live_range_t r;
  rtx_insn *insn;
  rtx set;
  basic_block bb;
  HARD_REG_SET conflict_hard_regs;
  bitmap setjump_crosses = regstat_get_setjmp_crosses ();
  /* Hard registers which cannot be used for any purpose at given
     program point because they are unallocatable or already allocated
     for other pseudos.	 */
  HARD_REG_SET *reserved_hard_regs;

  if (! lra_reg_spill_p)
    return n;
  /* Set up reserved hard regs for every program point.	 */
  reserved_hard_regs = XNEWVEC (HARD_REG_SET, lra_live_max_point);
  for (p = 0; p < lra_live_max_point; p++)
    COPY_HARD_REG_SET (reserved_hard_regs[p], lra_no_alloc_regs);
  for (i = FIRST_PSEUDO_REGISTER; i < regs_num; i++)
    if (lra_reg_info[i].nrefs != 0
	&& (hard_regno = lra_get_regno_hard_regno (i)) >= 0)
      for (r = lra_reg_info[i].live_ranges; r != NULL; r = r->next)
	for (p = r->start; p <= r->finish; p++)
	  add_to_hard_reg_set (&reserved_hard_regs[p],
			       lra_reg_info[i].biggest_mode, hard_regno);
  auto_bitmap ok_insn_bitmap (&reg_obstack);
  FOR_EACH_BB_FN (bb, cfun)
    FOR_BB_INSNS (bb, insn)
      if (DEBUG_INSN_P (insn)
	  || ((set = single_set (insn)) != NULL_RTX
	      && REG_P (SET_SRC (set)) && REG_P (SET_DEST (set))))
	bitmap_set_bit (ok_insn_bitmap, INSN_UID (insn));
  for (res = i = 0; i < n; i++)
    {
      regno = pseudo_regnos[i];
      rclass = lra_get_allocno_class (regno);
      if (bitmap_bit_p (setjump_crosses, regno)
	  || (spill_class
	      = ((enum reg_class)
		 targetm.spill_class ((reg_class_t) rclass,
				      PSEUDO_REGNO_MODE (regno)))) == NO_REGS
	  || bitmap_intersect_compl_p (&lra_reg_info[regno].insn_bitmap,
				       ok_insn_bitmap))
	{
	  pseudo_regnos[res++] = regno;
	  continue;
	}
      lra_assert (spill_class != NO_REGS);
      COPY_HARD_REG_SET (conflict_hard_regs,
			 lra_reg_info[regno].conflict_hard_regs);
      for (r = lra_reg_info[regno].live_ranges; r != NULL; r = r->next)
	for (p = r->start; p <= r->finish; p++)
	  IOR_HARD_REG_SET (conflict_hard_regs, reserved_hard_regs[p]);
      spill_class_size = ira_class_hard_regs_num[spill_class];
      mode = lra_reg_info[regno].biggest_mode;
      for (k = 0; k < spill_class_size; k++)
	{
	  hard_regno = ira_class_hard_regs[spill_class][k];
	  if (! overlaps_hard_reg_set_p (conflict_hard_regs, mode, hard_regno))
	    break;
	}
      if (k >= spill_class_size)
	{
	   /* There is no available regs -- assign memory later.  */
	  pseudo_regnos[res++] = regno;
	  continue;
	}
      if (lra_dump_file != NULL)
	fprintf (lra_dump_file, "  Spill r%d into hr%d\n", regno, hard_regno);
      add_to_hard_reg_set (&hard_regs_spilled_into,
			   lra_reg_info[regno].biggest_mode, hard_regno);
      /* Update reserved_hard_regs.  */
      for (r = lra_reg_info[regno].live_ranges; r != NULL; r = r->next)
	for (p = r->start; p <= r->finish; p++)
	  add_to_hard_reg_set (&reserved_hard_regs[p],
			       lra_reg_info[regno].biggest_mode, hard_regno);
      spill_hard_reg[regno]
	= gen_raw_REG (PSEUDO_REGNO_MODE (regno), hard_regno);
      for (nr = 0;
	   nr < hard_regno_nregs (hard_regno,
				  lra_reg_info[regno].biggest_mode);
	   nr++)
	/* Just loop.  */
	df_set_regs_ever_live (hard_regno + nr, true);
    }
  free (reserved_hard_regs);
  return res;
}

/* Add pseudo REGNO to slot SLOT_NUM.  */
static void
add_pseudo_to_slot (int regno, int slot_num)
{
  struct pseudo_slot *first;

  /* Each pseudo has an inherent size which comes from its own mode,
     and a total size which provides room for paradoxical subregs.
     We need to make sure the size and alignment of the slot are
     sufficient for both.  */
  machine_mode mode = wider_subreg_mode (PSEUDO_REGNO_MODE (regno),
					 lra_reg_info[regno].biggest_mode);
  unsigned int align = spill_slot_alignment (mode);
  slots[slot_num].align = MAX (slots[slot_num].align, align);
  slots[slot_num].size = upper_bound (slots[slot_num].size,
				      GET_MODE_SIZE (mode));

  if (slots[slot_num].regno < 0)
    {
      /* It is the first pseudo in the slot.  */
      slots[slot_num].regno = regno;
      pseudo_slots[regno].first = &pseudo_slots[regno];
      pseudo_slots[regno].next = NULL;
    }
  else
    {
      first = pseudo_slots[regno].first = &pseudo_slots[slots[slot_num].regno];
      pseudo_slots[regno].next = first->next;
      first->next = &pseudo_slots[regno];
    }
  pseudo_slots[regno].mem = NULL_RTX;
  pseudo_slots[regno].slot_num = slot_num;
  slots[slot_num].live_ranges
    = lra_merge_live_ranges (slots[slot_num].live_ranges,
			     lra_copy_live_range_list
			     (lra_reg_info[regno].live_ranges));
}

/* Assign stack slot numbers to pseudos in array PSEUDO_REGNOS of
   length N.  Sort pseudos in PSEUDO_REGNOS for subsequent assigning
   memory stack slots.	*/
static void
assign_stack_slot_num_and_sort_pseudos (int *pseudo_regnos, int n)
{
  int i, j, regno;

  slots_num = 0;
  /* Assign stack slot numbers to spilled pseudos, use smaller numbers
     for most frequently used pseudos.	*/
  for (i = 0; i < n; i++)
    {
      regno = pseudo_regnos[i];
      if (! flag_ira_share_spill_slots)
	j = slots_num;
      else
	{
	  machine_mode mode
	    = wider_subreg_mode (PSEUDO_REGNO_MODE (regno),
				 lra_reg_info[regno].biggest_mode);
	  for (j = 0; j < slots_num; j++)
	    if (slots[j].hard_regno < 0
		/* Although it's possible to share slots between modes
		   with constant and non-constant widths, we usually
		   get better spill code by keeping the constant and
		   non-constant areas separate.  */
		&& (GET_MODE_SIZE (mode).is_constant ()
		    == slots[j].size.is_constant ())
		&& ! (lra_intersected_live_ranges_p
		      (slots[j].live_ranges,
		       lra_reg_info[regno].live_ranges)))
	      break;
	}
      if (j >= slots_num)
	{
	  /* New slot.	*/
	  slots[j].live_ranges = NULL;
	  slots[j].size = 0;
	  slots[j].align = BITS_PER_UNIT;
	  slots[j].regno = slots[j].hard_regno = -1;
	  slots[j].mem = NULL_RTX;
	  slots_num++;
	}
      add_pseudo_to_slot (regno, j);
    }
  /* Sort regnos according to their slot numbers.  */
  qsort (pseudo_regnos, n, sizeof (int), pseudo_reg_slot_compare);
}

/* Recursively process LOC in INSN and change spilled pseudos to the
   corresponding memory or spilled hard reg.  Ignore spilled pseudos
   created from the scratches.  Return true if the pseudo nrefs equal
   to 0 (don't change the pseudo in this case).  Otherwise return false.  */
static bool
remove_pseudos (rtx *loc, rtx_insn *insn)
{
  int i;
  rtx hard_reg;
  const char *fmt;
  enum rtx_code code;
  bool res = false;
  
  if (*loc == NULL_RTX)
    return res;
  code = GET_CODE (*loc);
  if (code == REG && (i = REGNO (*loc)) >= FIRST_PSEUDO_REGISTER
      && lra_get_regno_hard_regno (i) < 0
      /* We do not want to assign memory for former scratches because
	 it might result in an address reload for some targets.	 In
	 any case we transform such pseudos not getting hard registers
	 into scratches back.  */
      && ! lra_former_scratch_p (i))
    {
      if (lra_reg_info[i].nrefs == 0
	  && pseudo_slots[i].mem == NULL && spill_hard_reg[i] == NULL)
	return true;
      if ((hard_reg = spill_hard_reg[i]) != NULL_RTX)
	*loc = copy_rtx (hard_reg);
      else
	{
	  rtx x = lra_eliminate_regs_1 (insn, pseudo_slots[i].mem,
					GET_MODE (pseudo_slots[i].mem),
					false, false, 0, true);
	  *loc = x != pseudo_slots[i].mem ? x : copy_rtx (x);
	}
      return res;
    }

  fmt = GET_RTX_FORMAT (code);
  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
    {
      if (fmt[i] == 'e')
	res = remove_pseudos (&XEXP (*loc, i), insn) || res;
      else if (fmt[i] == 'E')
	{
	  int j;

	  for (j = XVECLEN (*loc, i) - 1; j >= 0; j--)
	    res = remove_pseudos (&XVECEXP (*loc, i, j), insn) || res;
	}
    }
  return res;
}

/* Convert spilled pseudos into their stack slots or spill hard regs,
   put insns to process on the constraint stack (that is all insns in
   which pseudos were changed to memory or spill hard regs).   */
static void
spill_pseudos (void)
{
  basic_block bb;
  rtx_insn *insn, *curr;
  int i;

  auto_bitmap spilled_pseudos (&reg_obstack);
  auto_bitmap changed_insns (&reg_obstack);
  for (i = FIRST_PSEUDO_REGISTER; i < regs_num; i++)
    {
      if (lra_reg_info[i].nrefs != 0 && lra_get_regno_hard_regno (i) < 0
	  && ! lra_former_scratch_p (i))
	{
	  bitmap_set_bit (spilled_pseudos, i);
	  bitmap_ior_into (changed_insns, &lra_reg_info[i].insn_bitmap);
	}
    }
  FOR_EACH_BB_FN (bb, cfun)
    {
      FOR_BB_INSNS_SAFE (bb, insn, curr)
	{
	  bool removed_pseudo_p = false;
	  
	  if (bitmap_bit_p (changed_insns, INSN_UID (insn)))
	    {
	      rtx *link_loc, link;

	      removed_pseudo_p = remove_pseudos (&PATTERN (insn), insn);
	      if (CALL_P (insn)
		  && remove_pseudos (&CALL_INSN_FUNCTION_USAGE (insn), insn))
		removed_pseudo_p = true;
	      for (link_loc = &REG_NOTES (insn);
		   (link = *link_loc) != NULL_RTX;
		   link_loc = &XEXP (link, 1))
		{
		  switch (REG_NOTE_KIND (link))
		    {
		    case REG_FRAME_RELATED_EXPR:
		    case REG_CFA_DEF_CFA:
		    case REG_CFA_ADJUST_CFA:
		    case REG_CFA_OFFSET:
		    case REG_CFA_REGISTER:
		    case REG_CFA_EXPRESSION:
		    case REG_CFA_RESTORE:
		    case REG_CFA_SET_VDRAP:
		      if (remove_pseudos (&XEXP (link, 0), insn))
			removed_pseudo_p = true;
		      break;
		    default:
		      break;
		    }
		}
	      if (lra_dump_file != NULL)
		fprintf (lra_dump_file,
			 "Changing spilled pseudos to memory in insn #%u\n",
			 INSN_UID (insn));
	      lra_push_insn (insn);
	      if (lra_reg_spill_p || targetm.different_addr_displacement_p ())
		lra_set_used_insn_alternative (insn, LRA_UNKNOWN_ALT);
	    }
	  else if (CALL_P (insn)
		   /* Presence of any pseudo in CALL_INSN_FUNCTION_USAGE
		      does not affect value of insn_bitmap of the
		      corresponding lra_reg_info.  That is because we
		      don't need to reload pseudos in
		      CALL_INSN_FUNCTION_USAGEs.  So if we process only
		      insns in the insn_bitmap of given pseudo here, we
		      can miss the pseudo in some
		      CALL_INSN_FUNCTION_USAGEs.  */
		   && remove_pseudos (&CALL_INSN_FUNCTION_USAGE (insn), insn))
	    removed_pseudo_p = true;
	  if (removed_pseudo_p)
	    {
	      lra_assert (DEBUG_INSN_P (insn));
	      lra_invalidate_insn_data (insn);
	      INSN_VAR_LOCATION_LOC (insn) = gen_rtx_UNKNOWN_VAR_LOC ();
	      if (lra_dump_file != NULL)
		fprintf (lra_dump_file,
			 "Debug insn #%u is reset because it referenced "
			 "removed pseudo\n", INSN_UID (insn));
	    }
	  bitmap_and_compl_into (df_get_live_in (bb), spilled_pseudos);
	  bitmap_and_compl_into (df_get_live_out (bb), spilled_pseudos);
	}
    }
}

/* Return true if we need scratch reg assignments.  */
bool
lra_need_for_scratch_reg_p (void)
{
  int i; max_regno = max_reg_num ();

  for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
    if (lra_reg_info[i].nrefs != 0 && lra_get_regno_hard_regno (i) < 0
	&& lra_former_scratch_p (i))
      return true;
  return false;
}

/* Return true if we need to change some pseudos into memory.  */
bool
lra_need_for_spills_p (void)
{
  int i; max_regno = max_reg_num ();

  for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
    if (lra_reg_info[i].nrefs != 0 && lra_get_regno_hard_regno (i) < 0
	&& ! lra_former_scratch_p (i))
      return true;
  return false;
}

/* Change spilled pseudos into memory or spill hard regs.  Put changed
   insns on the constraint stack (these insns will be considered on
   the next constraint pass).  The changed insns are all insns in
   which pseudos were changed.  */
void
lra_spill (void)
{
  int i, n, curr_regno;
  int *pseudo_regnos;

  regs_num = max_reg_num ();
  spill_hard_reg = XNEWVEC (rtx, regs_num);
  pseudo_regnos = XNEWVEC (int, regs_num);
  for (n = 0, i = FIRST_PSEUDO_REGISTER; i < regs_num; i++)
    if (lra_reg_info[i].nrefs != 0 && lra_get_regno_hard_regno (i) < 0
	/* We do not want to assign memory for former scratches.  */
	&& ! lra_former_scratch_p (i))
      pseudo_regnos[n++] = i;
  lra_assert (n > 0);
  pseudo_slots = XNEWVEC (struct pseudo_slot, regs_num);
  for (i = FIRST_PSEUDO_REGISTER; i < regs_num; i++)
    {
      spill_hard_reg[i] = NULL_RTX;
      pseudo_slots[i].mem = NULL_RTX;
    }
  slots = XNEWVEC (struct slot, regs_num);
  /* Sort regnos according their usage frequencies.  */
  qsort (pseudo_regnos, n, sizeof (int), regno_freq_compare);
  n = assign_spill_hard_regs (pseudo_regnos, n);
  assign_stack_slot_num_and_sort_pseudos (pseudo_regnos, n);
  for (i = 0; i < n; i++)
    if (pseudo_slots[pseudo_regnos[i]].mem == NULL_RTX)
      assign_mem_slot (pseudo_regnos[i]);
  if (n > 0 && crtl->stack_alignment_needed)
    /* If we have a stack frame, we must align it now.  The stack size
       may be a part of the offset computation for register
       elimination.  */
    assign_stack_local (BLKmode, 0, crtl->stack_alignment_needed);
  if (lra_dump_file != NULL)
    {
      for (i = 0; i < slots_num; i++)
	{
	  fprintf (lra_dump_file, "  Slot %d regnos (width = ", i);
	  print_dec (GET_MODE_SIZE (GET_MODE (slots[i].mem)),
		     lra_dump_file, SIGNED);
	  fprintf (lra_dump_file, "):");
	  for (curr_regno = slots[i].regno;;
	       curr_regno = pseudo_slots[curr_regno].next - pseudo_slots)
	    {
	      fprintf (lra_dump_file, "	 %d", curr_regno);
	      if (pseudo_slots[curr_regno].next == NULL)
		break;
	    }
	  fprintf (lra_dump_file, "\n");
	}
    }
  spill_pseudos ();
  free (slots);
  free (pseudo_slots);
  free (pseudo_regnos);
  free (spill_hard_reg);
}

/* Apply alter_subreg for subregs of regs in *LOC.  Use FINAL_P for
   alter_subreg calls. Return true if any subreg of reg is
   processed.  */
static bool
alter_subregs (rtx *loc, bool final_p)
{
  int i;
  rtx x = *loc;
  bool res;
  const char *fmt;
  enum rtx_code code;

  if (x == NULL_RTX)
    return false;
  code = GET_CODE (x);
  if (code == SUBREG && REG_P (SUBREG_REG (x)))
    {
      lra_assert (REGNO (SUBREG_REG (x)) < FIRST_PSEUDO_REGISTER);
      alter_subreg (loc, final_p);
      return true;
    }
  fmt = GET_RTX_FORMAT (code);
  res = false;
  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
    {
      if (fmt[i] == 'e')
	{
	  if (alter_subregs (&XEXP (x, i), final_p))
	    res = true;
	}
      else if (fmt[i] == 'E')
	{
	  int j;

	  for (j = XVECLEN (x, i) - 1; j >= 0; j--)
	    if (alter_subregs (&XVECEXP (x, i, j), final_p))
	      res = true;
	}
    }
  return res;
}

/* Return true if REGNO is used for return in the current
   function.  */
static bool
return_regno_p (unsigned int regno)
{
  rtx outgoing = crtl->return_rtx;

  if (! outgoing)
    return false;

  if (REG_P (outgoing))
    return REGNO (outgoing) == regno;
  else if (GET_CODE (outgoing) == PARALLEL)
    {
      int i;

      for (i = 0; i < XVECLEN (outgoing, 0); i++)
	{
	  rtx x = XEXP (XVECEXP (outgoing, 0, i), 0);

	  if (REG_P (x) && REGNO (x) == regno)
	    return true;
	}
    }
  return false;
}

/* Return true if REGNO is in one of subsequent USE after INSN in the
   same BB.  */
static bool
regno_in_use_p (rtx_insn *insn, unsigned int regno)
{
  static lra_insn_recog_data_t id;
  static struct lra_static_insn_data *static_id;
  struct lra_insn_reg *reg;
  int i, arg_regno;
  basic_block bb = BLOCK_FOR_INSN (insn);

  while ((insn = next_nondebug_insn (insn)) != NULL_RTX)
    {
      if (BARRIER_P (insn) || bb != BLOCK_FOR_INSN (insn))
	return false;
      if (! INSN_P (insn))
	continue;
      if (GET_CODE (PATTERN (insn)) == USE
	  && REG_P (XEXP (PATTERN (insn), 0))
	  && regno == REGNO (XEXP (PATTERN (insn), 0)))
	return true;
      /* Check that the regno is not modified.  */
      id = lra_get_insn_recog_data (insn);
      for (reg = id->regs; reg != NULL; reg = reg->next)
	if (reg->type != OP_IN && reg->regno == (int) regno)
	  return false;
      static_id = id->insn_static_data;
      for (reg = static_id->hard_regs; reg != NULL; reg = reg->next)
	if (reg->type != OP_IN && reg->regno == (int) regno)
	  return false;
      if (id->arg_hard_regs != NULL)
	for (i = 0; (arg_regno = id->arg_hard_regs[i]) >= 0; i++)
	  if ((int) regno == (arg_regno >= FIRST_PSEUDO_REGISTER
			      ? arg_regno : arg_regno - FIRST_PSEUDO_REGISTER))
	    return false;
    }
  return false;
}

/* Final change of pseudos got hard registers into the corresponding
   hard registers and removing temporary clobbers.  */
void
lra_final_code_change (void)
{
  int i, hard_regno;
  basic_block bb;
  rtx_insn *insn, *curr;
  rtx set;
  int max_regno = max_reg_num ();

  for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
    if (lra_reg_info[i].nrefs != 0
	&& (hard_regno = lra_get_regno_hard_regno (i)) >= 0)
      SET_REGNO (regno_reg_rtx[i], hard_regno);
  FOR_EACH_BB_FN (bb, cfun)
    FOR_BB_INSNS_SAFE (bb, insn, curr)
      if (INSN_P (insn))
	{
	  rtx pat = PATTERN (insn);

	  if (GET_CODE (pat) == CLOBBER && LRA_TEMP_CLOBBER_P (pat))
	    {
	      /* Remove clobbers temporarily created in LRA.  We don't
		 need them anymore and don't want to waste compiler
		 time processing them in a few subsequent passes.  */
	      lra_invalidate_insn_data (insn);
	      delete_insn (insn);
	      continue;
	    }

	  /* IRA can generate move insns involving pseudos.  It is
	     better remove them earlier to speed up compiler a bit.
	     It is also better to do it here as they might not pass
	     final RTL check in LRA, (e.g. insn moving a control
	     register into itself).  So remove an useless move insn
	     unless next insn is USE marking the return reg (we should
	     save this as some subsequent optimizations assume that
	     such original insns are saved).  */
	  if (NONJUMP_INSN_P (insn) && GET_CODE (pat) == SET
	      && REG_P (SET_SRC (pat)) && REG_P (SET_DEST (pat))
	      && REGNO (SET_SRC (pat)) == REGNO (SET_DEST (pat))
	      && (! return_regno_p (REGNO (SET_SRC (pat)))
		  || ! regno_in_use_p (insn, REGNO (SET_SRC (pat)))))
	    {
	      lra_invalidate_insn_data (insn);
	      delete_insn (insn);
	      continue;
	    }
	
	  lra_insn_recog_data_t id = lra_get_insn_recog_data (insn);
	  struct lra_insn_reg *reg;

	  for (reg = id->regs; reg != NULL; reg = reg->next)
	    if (reg->regno >= FIRST_PSEUDO_REGISTER
		&& lra_reg_info [reg->regno].nrefs == 0)
	      break;
	  
	  if (reg != NULL)
	    {
	      /* Pseudos still can be in debug insns in some very rare
		 and complicated cases, e.g. the pseudo was removed by
		 inheritance and the debug insn is not EBBs where the
		 inheritance happened.  It is difficult and time
		 consuming to find what hard register corresponds the
		 pseudo -- so just remove the debug insn.  Another
		 solution could be assigning hard reg/memory but it
		 would be a misleading info.  It is better not to have
		 info than have it wrong.  */
	      lra_assert (DEBUG_INSN_P (insn));
	      lra_invalidate_insn_data (insn);
	      delete_insn (insn);
	      continue;
	    }
	  
	  struct lra_static_insn_data *static_id = id->insn_static_data;
	  bool insn_change_p = false;

	  for (i = id->insn_static_data->n_operands - 1; i >= 0; i--)
	    if ((DEBUG_INSN_P (insn) || ! static_id->operand[i].is_operator)
		&& alter_subregs (id->operand_loc[i], ! DEBUG_INSN_P (insn)))
	      {
		lra_update_dup (id, i);
		insn_change_p = true;
	      }
	  if (insn_change_p)
	    lra_update_operator_dups (id);

	  if ((set = single_set (insn)) != NULL
	      && REG_P (SET_SRC (set)) && REG_P (SET_DEST (set))
	      && REGNO (SET_SRC (set)) == REGNO (SET_DEST (set)))
	    {
	      /* Remove an useless move insn.  IRA can generate move
		 insns involving pseudos.  It is better remove them
		 earlier to speed up compiler a bit.  It is also
		 better to do it here as they might not pass final RTL
		 check in LRA, (e.g. insn moving a control register
		 into itself).  */
	      lra_invalidate_insn_data (insn);
	      delete_insn (insn);
	    }
	}
}
