/* IRA hard register and memory cost calculation for allocnos or pseudos.
   Copyright (C) 2006-2023 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/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "target.h"
#include "rtl.h"
#include "tree.h"
#include "predict.h"
#include "memmodel.h"
#include "tm_p.h"
#include "insn-config.h"
#include "regs.h"
#include "ira.h"
#include "ira-int.h"
#include "addresses.h"
#include "reload.h"
#include "print-rtl.h"

/* The flags is set up every time when we calculate pseudo register
   classes through function ira_set_pseudo_classes.  */
static bool pseudo_classes_defined_p = false;

/* TRUE if we work with allocnos.  Otherwise we work with pseudos.  */
static bool allocno_p;

/* Number of elements in array `costs'.  */
static int cost_elements_num;

/* The `costs' struct records the cost of using hard registers of each
   class considered for the calculation and of using memory for each
   allocno or pseudo.  */
struct costs
{
  int mem_cost;
  /* Costs for register classes start here.  We process only some
     allocno classes.  */
  int cost[1];
};

#define max_struct_costs_size \
  (this_target_ira_int->x_max_struct_costs_size)
#define init_cost \
  (this_target_ira_int->x_init_cost)
#define temp_costs \
  (this_target_ira_int->x_temp_costs)
#define op_costs \
  (this_target_ira_int->x_op_costs)
#define this_op_costs \
  (this_target_ira_int->x_this_op_costs)

/* Costs of each class for each allocno or pseudo.  */
static struct costs *costs;

/* Accumulated costs of each class for each allocno.  */
static struct costs *total_allocno_costs;

/* It is the current size of struct costs.  */
static size_t struct_costs_size;

/* Return pointer to structure containing costs of allocno or pseudo
   with given NUM in array ARR.  */
#define COSTS(arr, num) \
  ((struct costs *) ((char *) (arr) + (num) * struct_costs_size))

/* Return index in COSTS when processing reg with REGNO.  */
#define COST_INDEX(regno) (allocno_p 					     \
                           ? ALLOCNO_NUM (ira_curr_regno_allocno_map[regno]) \
			   : (int) regno)

/* Record register class preferences of each allocno or pseudo.  Null
   value means no preferences.  It happens on the 1st iteration of the
   cost calculation.  */
static enum reg_class *pref;

/* Allocated buffers for pref.  */
static enum reg_class *pref_buffer;

/* Record allocno class of each allocno with the same regno.  */
static enum reg_class *regno_aclass;

/* Record cost gains for not allocating a register with an invariant
   equivalence.  */
static int *regno_equiv_gains;

/* Execution frequency of the current insn.  */
static int frequency;



/* Info about reg classes whose costs are calculated for a pseudo.  */
struct cost_classes
{
  /* Number of the cost classes in the subsequent array.  */
  int num;
  /* Container of the cost classes.  */
  enum reg_class classes[N_REG_CLASSES];
  /* Map reg class -> index of the reg class in the previous array.
     -1 if it is not a cost class.  */
  int index[N_REG_CLASSES];
  /* Map hard regno index of first class in array CLASSES containing
     the hard regno, -1 otherwise.  */
  int hard_regno_index[FIRST_PSEUDO_REGISTER];
};

/* Types of pointers to the structure above.  */
typedef struct cost_classes *cost_classes_t;
typedef const struct cost_classes *const_cost_classes_t;

/* Info about cost classes for each pseudo.  */
static cost_classes_t *regno_cost_classes;

/* Helper for cost_classes hashing.  */

struct cost_classes_hasher : pointer_hash <cost_classes>
{
  static inline hashval_t hash (const cost_classes *);
  static inline bool equal (const cost_classes *, const cost_classes *);
  static inline void remove (cost_classes *);
};

/* Returns hash value for cost classes info HV.  */
inline hashval_t
cost_classes_hasher::hash (const cost_classes *hv)
{
  return iterative_hash (&hv->classes, sizeof (enum reg_class) * hv->num, 0);
}

/* Compares cost classes info HV1 and HV2.  */
inline bool
cost_classes_hasher::equal (const cost_classes *hv1, const cost_classes *hv2)
{
  return (hv1->num == hv2->num
	  && memcmp (hv1->classes, hv2->classes,
		     sizeof (enum reg_class) * hv1->num) == 0);
}

/* Delete cost classes info V from the hash table.  */
inline void
cost_classes_hasher::remove (cost_classes *v)
{
  ira_free (v);
}

/* Hash table of unique cost classes.  */
static hash_table<cost_classes_hasher> *cost_classes_htab;

/* Map allocno class -> cost classes for pseudo of given allocno
   class.  */
static cost_classes_t cost_classes_aclass_cache[N_REG_CLASSES];

/* Map mode -> cost classes for pseudo of give mode.  */
static cost_classes_t cost_classes_mode_cache[MAX_MACHINE_MODE];

/* Cost classes that include all classes in ira_important_classes.  */
static cost_classes all_cost_classes;

/* Use the array of classes in CLASSES_PTR to fill out the rest of
   the structure.  */
static void
complete_cost_classes (cost_classes_t classes_ptr)
{
  for (int i = 0; i < N_REG_CLASSES; i++)
    classes_ptr->index[i] = -1;
  for (int i = 0; i < FIRST_PSEUDO_REGISTER; i++)
    classes_ptr->hard_regno_index[i] = -1;
  for (int i = 0; i < classes_ptr->num; i++)
    {
      enum reg_class cl = classes_ptr->classes[i];
      classes_ptr->index[cl] = i;
      for (int j = ira_class_hard_regs_num[cl] - 1; j >= 0; j--)
	{
	  unsigned int hard_regno = ira_class_hard_regs[cl][j];
	  if (classes_ptr->hard_regno_index[hard_regno] < 0)
	    classes_ptr->hard_regno_index[hard_regno] = i;
	}
    }
}

/* Initialize info about the cost classes for each pseudo.  */
static void
initiate_regno_cost_classes (void)
{
  int size = sizeof (cost_classes_t) * max_reg_num ();

  regno_cost_classes = (cost_classes_t *) ira_allocate (size);
  memset (regno_cost_classes, 0, size);
  memset (cost_classes_aclass_cache, 0,
	  sizeof (cost_classes_t) * N_REG_CLASSES);
  memset (cost_classes_mode_cache, 0,
	  sizeof (cost_classes_t) * MAX_MACHINE_MODE);
  cost_classes_htab = new hash_table<cost_classes_hasher> (200);
  all_cost_classes.num = ira_important_classes_num;
  for (int i = 0; i < ira_important_classes_num; i++)
    all_cost_classes.classes[i] = ira_important_classes[i];
  complete_cost_classes (&all_cost_classes);
}

/* Create new cost classes from cost classes FROM and set up members
   index and hard_regno_index.  Return the new classes.  The function
   implements some common code of two functions
   setup_regno_cost_classes_by_aclass and
   setup_regno_cost_classes_by_mode.  */
static cost_classes_t
setup_cost_classes (cost_classes_t from)
{
  cost_classes_t classes_ptr;

  classes_ptr = (cost_classes_t) ira_allocate (sizeof (struct cost_classes));
  classes_ptr->num = from->num;
  for (int i = 0; i < from->num; i++)
    classes_ptr->classes[i] = from->classes[i];
  complete_cost_classes (classes_ptr);
  return classes_ptr;
}

/* Return a version of FULL that only considers registers in REGS that are
   valid for mode MODE.  Both FULL and the returned class are globally
   allocated.  */
static cost_classes_t
restrict_cost_classes (cost_classes_t full, machine_mode mode,
		       const_hard_reg_set regs)
{
  static struct cost_classes narrow;
  int map[N_REG_CLASSES];
  narrow.num = 0;
  for (int i = 0; i < full->num; i++)
    {
      /* Assume that we'll drop the class.  */
      map[i] = -1;

      /* Ignore classes that are too small for the mode.  */
      enum reg_class cl = full->classes[i];
      if (!contains_reg_of_mode[cl][mode])
	continue;

      /* Calculate the set of registers in CL that belong to REGS and
	 are valid for MODE.  */
      HARD_REG_SET valid_for_cl = reg_class_contents[cl] & regs;
      valid_for_cl &= ~(ira_prohibited_class_mode_regs[cl][mode]
			| ira_no_alloc_regs);
      if (hard_reg_set_empty_p (valid_for_cl))
	continue;

      /* Don't use this class if the set of valid registers is a subset
	 of an existing class.  For example, suppose we have two classes
	 GR_REGS and FR_REGS and a union class GR_AND_FR_REGS.  Suppose
	 that the mode changes allowed by FR_REGS are not as general as
	 the mode changes allowed by GR_REGS.

	 In this situation, the mode changes for GR_AND_FR_REGS could
	 either be seen as the union or the intersection of the mode
	 changes allowed by the two subclasses.  The justification for
	 the union-based definition would be that, if you want a mode
	 change that's only allowed by GR_REGS, you can pick a register
	 from the GR_REGS subclass.  The justification for the
	 intersection-based definition would be that every register
	 from the class would allow the mode change.

	 However, if we have a register that needs to be in GR_REGS,
	 using GR_AND_FR_REGS with the intersection-based definition
	 would be too pessimistic, since it would bring in restrictions
	 that only apply to FR_REGS.  Conversely, if we have a register
	 that needs to be in FR_REGS, using GR_AND_FR_REGS with the
	 union-based definition would lose the extra restrictions
	 placed on FR_REGS.  GR_AND_FR_REGS is therefore only useful
	 for cases where GR_REGS and FP_REGS are both valid.  */
      int pos;
      for (pos = 0; pos < narrow.num; ++pos)
	{
	  enum reg_class cl2 = narrow.classes[pos];
	  if (hard_reg_set_subset_p (valid_for_cl, reg_class_contents[cl2]))
	    break;
	}
      map[i] = pos;
      if (pos == narrow.num)
	{
	  /* If several classes are equivalent, prefer to use the one
	     that was chosen as the allocno class.  */
	  enum reg_class cl2 = ira_allocno_class_translate[cl];
	  if (ira_class_hard_regs_num[cl] == ira_class_hard_regs_num[cl2])
	    cl = cl2;
	  narrow.classes[narrow.num++] = cl;
	}
    }
  if (narrow.num == full->num)
    return full;

  cost_classes **slot = cost_classes_htab->find_slot (&narrow, INSERT);
  if (*slot == NULL)
    {
      cost_classes_t classes = setup_cost_classes (&narrow);
      /* Map equivalent classes to the representative that we chose above.  */
      for (int i = 0; i < ira_important_classes_num; i++)
	{
	  enum reg_class cl = ira_important_classes[i];
	  int index = full->index[cl];
	  if (index >= 0)
	    classes->index[cl] = map[index];
	}
      *slot = classes;
    }
  return *slot;
}

/* Setup cost classes for pseudo REGNO whose allocno class is ACLASS.
   This function is used when we know an initial approximation of
   allocno class of the pseudo already, e.g. on the second iteration
   of class cost calculation or after class cost calculation in
   register-pressure sensitive insn scheduling or register-pressure
   sensitive loop-invariant motion.  */
static void
setup_regno_cost_classes_by_aclass (int regno, enum reg_class aclass)
{
  static struct cost_classes classes;
  cost_classes_t classes_ptr;
  enum reg_class cl;
  int i;
  cost_classes **slot;
  HARD_REG_SET temp, temp2;
  bool exclude_p;

  if ((classes_ptr = cost_classes_aclass_cache[aclass]) == NULL)
    {
      temp = reg_class_contents[aclass] & ~ira_no_alloc_regs;
      /* We exclude classes from consideration which are subsets of
	 ACLASS only if ACLASS is an uniform class.  */
      exclude_p = ira_uniform_class_p[aclass];
      classes.num = 0;
      for (i = 0; i < ira_important_classes_num; i++)
	{
	  cl = ira_important_classes[i];
	  if (exclude_p)
	    {
	      /* Exclude non-uniform classes which are subsets of
		 ACLASS.  */
	      temp2 = reg_class_contents[cl] & ~ira_no_alloc_regs;
	      if (hard_reg_set_subset_p (temp2, temp) && cl != aclass)
		continue;
	    }
	  classes.classes[classes.num++] = cl;
	}
      slot = cost_classes_htab->find_slot (&classes, INSERT);
      if (*slot == NULL)
	{
	  classes_ptr = setup_cost_classes (&classes);
	  *slot = classes_ptr;
	}
      classes_ptr = cost_classes_aclass_cache[aclass] = (cost_classes_t) *slot;
    }
  if (regno_reg_rtx[regno] != NULL_RTX)
    {
      /* Restrict the classes to those that are valid for REGNO's mode
	 (which might for example exclude singleton classes if the mode
	 requires two registers).  Also restrict the classes to those that
	 are valid for subregs of REGNO.  */
      const HARD_REG_SET *valid_regs = valid_mode_changes_for_regno (regno);
      if (!valid_regs)
	valid_regs = &reg_class_contents[ALL_REGS];
      classes_ptr = restrict_cost_classes (classes_ptr,
					   PSEUDO_REGNO_MODE (regno),
					   *valid_regs);
    }
  regno_cost_classes[regno] = classes_ptr;
}

/* Setup cost classes for pseudo REGNO with MODE.  Usage of MODE can
   decrease number of cost classes for the pseudo, if hard registers
   of some important classes cannot hold a value of MODE.  So the
   pseudo cannot get hard register of some important classes and cost
   calculation for such important classes is only wasting CPU
   time.  */
static void
setup_regno_cost_classes_by_mode (int regno, machine_mode mode)
{
  if (const HARD_REG_SET *valid_regs = valid_mode_changes_for_regno (regno))
    regno_cost_classes[regno] = restrict_cost_classes (&all_cost_classes,
						       mode, *valid_regs);
  else
    {
      if (cost_classes_mode_cache[mode] == NULL)
	cost_classes_mode_cache[mode]
	  = restrict_cost_classes (&all_cost_classes, mode,
				   reg_class_contents[ALL_REGS]);
      regno_cost_classes[regno] = cost_classes_mode_cache[mode];
    }
}

/* Finalize info about the cost classes for each pseudo.  */
static void
finish_regno_cost_classes (void)
{
  ira_free (regno_cost_classes);
  delete cost_classes_htab;
  cost_classes_htab = NULL;
}



/* Compute the cost of loading X into (if TO_P is TRUE) or from (if
   TO_P is FALSE) a register of class RCLASS in mode MODE.  X must not
   be a pseudo register.  */
static int
copy_cost (rtx x, machine_mode mode, reg_class_t rclass, bool to_p,
	   secondary_reload_info *prev_sri)
{
  secondary_reload_info sri;
  reg_class_t secondary_class = NO_REGS;

  /* If X is a SCRATCH, there is actually nothing to move since we are
     assuming optimal allocation.  */
  if (GET_CODE (x) == SCRATCH)
    return 0;

  /* Get the class we will actually use for a reload.  */
  rclass = targetm.preferred_reload_class (x, rclass);

  /* If we need a secondary reload for an intermediate, the cost is
     that to load the input into the intermediate register, then to
     copy it.  */
  sri.prev_sri = prev_sri;
  sri.extra_cost = 0;
  /* PR 68770: Secondary reload might examine the t_icode field.  */
  sri.t_icode = CODE_FOR_nothing;

  secondary_class = targetm.secondary_reload (to_p, x, rclass, mode, &sri);

  if (secondary_class != NO_REGS)
    {
      ira_init_register_move_cost_if_necessary (mode);
      return (ira_register_move_cost[mode][(int) secondary_class][(int) rclass]
	      + sri.extra_cost
	      + copy_cost (x, mode, secondary_class, to_p, &sri));
    }

  /* For memory, use the memory move cost, for (hard) registers, use
     the cost to move between the register classes, and use 2 for
     everything else (constants).  */
  if (MEM_P (x) || rclass == NO_REGS)
    return sri.extra_cost
	   + ira_memory_move_cost[mode][(int) rclass][to_p != 0];
  else if (REG_P (x))
    {
      reg_class_t x_class = REGNO_REG_CLASS (REGNO (x));

      ira_init_register_move_cost_if_necessary (mode);
      return (sri.extra_cost
	      + ira_register_move_cost[mode][(int) x_class][(int) rclass]);
    }
  else
    /* If this is a constant, we may eventually want to call rtx_cost
       here.  */
    return sri.extra_cost + COSTS_N_INSNS (1);
}



/* Record the cost of using memory or hard registers of various
   classes for the operands in INSN.

   N_ALTS is the number of alternatives.
   N_OPS is the number of operands.
   OPS is an array of the operands.
   MODES are the modes of the operands, in case any are VOIDmode.
   CONSTRAINTS are the constraints to use for the operands.  This array
   is modified by this procedure.

   This procedure works alternative by alternative.  For each
   alternative we assume that we will be able to allocate all allocnos
   to their ideal register class and calculate the cost of using that
   alternative.  Then we compute, for each operand that is a
   pseudo-register, the cost of having the allocno allocated to each
   register class and using it in that alternative.  To this cost is
   added the cost of the alternative.

   The cost of each class for this insn is its lowest cost among all
   the alternatives.  */
static void
record_reg_classes (int n_alts, int n_ops, rtx *ops,
		    machine_mode *modes, const char **constraints,
		    rtx_insn *insn, enum reg_class *pref)
{
  int alt;
  int i, j, k;
  int insn_allows_mem[MAX_RECOG_OPERANDS];
  move_table *move_in_cost, *move_out_cost;
  short (*mem_cost)[2];
  const char *p;

  if (ira_dump_file != NULL && internal_flag_ira_verbose > 5)
    {
      fprintf (ira_dump_file, "    Processing insn %u", INSN_UID (insn));
      if (INSN_CODE (insn) >= 0
	  && (p = get_insn_name (INSN_CODE (insn))) != NULL)
	fprintf (ira_dump_file, " {%s}", p);
      fprintf (ira_dump_file, " (freq=%d)\n",
	       REG_FREQ_FROM_BB (BLOCK_FOR_INSN (insn)));
      dump_insn_slim (ira_dump_file, insn);
  }

  for (i = 0; i < n_ops; i++)
    insn_allows_mem[i] = 0;

  /* Process each alternative, each time minimizing an operand's cost
     with the cost for each operand in that alternative.  */
  alternative_mask preferred = get_preferred_alternatives (insn);
  for (alt = 0; alt < n_alts; alt++)
    {
      enum reg_class classes[MAX_RECOG_OPERANDS];
      int allows_mem[MAX_RECOG_OPERANDS];
      enum reg_class rclass;
      int alt_fail = 0;
      int alt_cost = 0, op_cost_add;

      if (!TEST_BIT (preferred, alt))
	{
	  for (i = 0; i < recog_data.n_operands; i++)
	    constraints[i] = skip_alternative (constraints[i]);

	  continue;
	}

      if (ira_dump_file != NULL && internal_flag_ira_verbose > 5)
	{
	  fprintf (ira_dump_file, "      Alt %d:", alt);
	  for (i = 0; i < n_ops; i++)
	    {
	      p = constraints[i];
	      if (*p == '\0')
		continue;
	      fprintf (ira_dump_file, "  (%d) ", i);
	      for (; *p != '\0' && *p != ',' && *p != '#'; p++)
		fputc (*p, ira_dump_file);
	    }
	  fprintf (ira_dump_file, "\n");
	}

      for (i = 0; i < n_ops; i++)
	{
	  unsigned char c;
	  const char *p = constraints[i];
	  rtx op = ops[i];
	  machine_mode mode = modes[i];
	  int allows_addr = 0;
	  int win = 0;

	  /* Initially show we know nothing about the register class.  */
	  classes[i] = NO_REGS;
	  allows_mem[i] = 0;

	  /* If this operand has no constraints at all, we can
	     conclude nothing about it since anything is valid.  */
	  if (*p == 0)
	    {
	      if (REG_P (op) && REGNO (op) >= FIRST_PSEUDO_REGISTER)
		memset (this_op_costs[i], 0, struct_costs_size);
	      continue;
	    }

	  /* If this alternative is only relevant when this operand
	     matches a previous operand, we do different things
	     depending on whether this operand is a allocno-reg or not.
	     We must process any modifiers for the operand before we
	     can make this test.  */
	  while (*p == '%' || *p == '=' || *p == '+' || *p == '&')
	    p++;

	  if (p[0] >= '0' && p[0] <= '0' + i)
	    {
	      /* Copy class and whether memory is allowed from the
		 matching alternative.  Then perform any needed cost
		 computations and/or adjustments.  */
	      j = p[0] - '0';
	      classes[i] = classes[j];
	      allows_mem[i] = allows_mem[j];
	      if (allows_mem[i])
		insn_allows_mem[i] = 1;

	      if (! REG_P (op) || REGNO (op) < FIRST_PSEUDO_REGISTER)
		{
		  /* If this matches the other operand, we have no
		     added cost and we win.  */
		  if (rtx_equal_p (ops[j], op))
		    win = 1;
		  /* If we can put the other operand into a register,
		     add to the cost of this alternative the cost to
		     copy this operand to the register used for the
		     other operand.  */
		  else if (classes[j] != NO_REGS)
		    {
		      alt_cost += copy_cost (op, mode, classes[j], 1, NULL);
		      win = 1;
		    }
		}
	      else if (! REG_P (ops[j])
		       || REGNO (ops[j]) < FIRST_PSEUDO_REGISTER)
		{
		  /* This op is an allocno but the one it matches is
		     not.  */

		  /* If we can't put the other operand into a
		     register, this alternative can't be used.  */

		  if (classes[j] == NO_REGS)
		    {
		      alt_fail = 1;
		    }
		  else
		    /* Otherwise, add to the cost of this alternative the cost
		       to copy the other operand to the hard register used for
		       this operand.  */
		    {
		      alt_cost += copy_cost (ops[j], mode, classes[j], 1, NULL);
		    }
		}
	      else
		{
		  /* The costs of this operand are not the same as the
		     other operand since move costs are not symmetric.
		     Moreover, if we cannot tie them, this alternative
		     needs to do a copy, which is one insn.  */
		  struct costs *pp = this_op_costs[i];
		  int *pp_costs = pp->cost;
		  cost_classes_t cost_classes_ptr
		    = regno_cost_classes[REGNO (op)];
		  enum reg_class *cost_classes = cost_classes_ptr->classes;
		  bool in_p = recog_data.operand_type[i] != OP_OUT;
		  bool out_p = recog_data.operand_type[i] != OP_IN;
		  enum reg_class op_class = classes[i];

		  ira_init_register_move_cost_if_necessary (mode);
		  if (! in_p)
		    {
		      ira_assert (out_p);
		      if (op_class == NO_REGS)
			{
			  mem_cost = ira_memory_move_cost[mode];
			  for (k = cost_classes_ptr->num - 1; k >= 0; k--)
			    {
			      rclass = cost_classes[k];
			      pp_costs[k] = mem_cost[rclass][0] * frequency;
			    }
			}
		      else
			{
			  move_out_cost = ira_may_move_out_cost[mode];
			  for (k = cost_classes_ptr->num - 1; k >= 0; k--)
			    {
			      rclass = cost_classes[k];
			      pp_costs[k]
				= move_out_cost[op_class][rclass] * frequency;
			    }
			}
		    }
		  else if (! out_p)
		    {
		      ira_assert (in_p);
		      if (op_class == NO_REGS)
			{
			  mem_cost = ira_memory_move_cost[mode];
			  for (k = cost_classes_ptr->num - 1; k >= 0; k--)
			    {
			      rclass = cost_classes[k];
			      pp_costs[k] = mem_cost[rclass][1] * frequency;
			    }
			}
		      else
			{
			  move_in_cost = ira_may_move_in_cost[mode];
			  for (k = cost_classes_ptr->num - 1; k >= 0; k--)
			    {
			      rclass = cost_classes[k];
			      pp_costs[k]
				= move_in_cost[rclass][op_class] * frequency;
			    }
			}
		    }
		  else
		    {
		      if (op_class == NO_REGS)
			{
			  mem_cost = ira_memory_move_cost[mode];
			  for (k = cost_classes_ptr->num - 1; k >= 0; k--)
			    {
			      rclass = cost_classes[k];
			      pp_costs[k] = ((mem_cost[rclass][0]
					      + mem_cost[rclass][1])
					     * frequency);
			    }
			}
		      else
			{
			  move_in_cost = ira_may_move_in_cost[mode];
			  move_out_cost = ira_may_move_out_cost[mode];
			  for (k = cost_classes_ptr->num - 1; k >= 0; k--)
			    {
			      rclass = cost_classes[k];
			      pp_costs[k] = ((move_in_cost[rclass][op_class]
					      + move_out_cost[op_class][rclass])
					     * frequency);
			    }
			}
		    }

		  /* If the alternative actually allows memory, make
		     things a bit cheaper since we won't need an extra
		     insn to load it.  */
		  pp->mem_cost
		    = ((out_p ? ira_memory_move_cost[mode][op_class][0] : 0)
		       + (in_p ? ira_memory_move_cost[mode][op_class][1] : 0)
		       - allows_mem[i]) * frequency;

		  /* If we have assigned a class to this allocno in
		     our first pass, add a cost to this alternative
		     corresponding to what we would add if this
		     allocno were not in the appropriate class.  */
		  if (pref)
		    {
		      enum reg_class pref_class = pref[COST_INDEX (REGNO (op))];

		      if (pref_class == NO_REGS)
			alt_cost
			  += ((out_p
			       ? ira_memory_move_cost[mode][op_class][0] : 0)
			      + (in_p
				 ? ira_memory_move_cost[mode][op_class][1]
				 : 0));
		      else if (ira_reg_class_intersect
			       [pref_class][op_class] == NO_REGS)
			alt_cost
			  += ira_register_move_cost[mode][pref_class][op_class];
		    }
		  if (REGNO (ops[i]) != REGNO (ops[j])
		      && ! find_reg_note (insn, REG_DEAD, op))
		    alt_cost += 2;

		  p++;
		}
	    }

	  /* Scan all the constraint letters.  See if the operand
	     matches any of the constraints.  Collect the valid
	     register classes and see if this operand accepts
	     memory.  */
	  while ((c = *p))
	    {
	      switch (c)
		{
		case '*':
		  /* Ignore the next letter for this pass.  */
		  c = *++p;
		  break;

		case '^':
		  alt_cost += 2;
		  break;

		case '?':
		  alt_cost += 2;
		  break;

		case 'g':
		  if (MEM_P (op)
		      || (CONSTANT_P (op)
			  && (! flag_pic || LEGITIMATE_PIC_OPERAND_P (op))))
		    win = 1;
		  insn_allows_mem[i] = allows_mem[i] = 1;
		  classes[i] = ira_reg_class_subunion[classes[i]][GENERAL_REGS];
		  break;

		default:
		  enum constraint_num cn = lookup_constraint (p);
		  enum reg_class cl;
		  switch (get_constraint_type (cn))
		    {
		    case CT_REGISTER:
		      cl = reg_class_for_constraint (cn);
		      if (cl != NO_REGS)
			classes[i] = ira_reg_class_subunion[classes[i]][cl];
		      break;

		    case CT_CONST_INT:
		      if (CONST_INT_P (op)
			  && insn_const_int_ok_for_constraint (INTVAL (op), cn))
			win = 1;
		      break;

		    case CT_MEMORY:
		    case CT_RELAXED_MEMORY:
		      /* Every MEM can be reloaded to fit.  */
		      insn_allows_mem[i] = allows_mem[i] = 1;
		      if (MEM_P (op))
			win = 1;
		      break;

		    case CT_SPECIAL_MEMORY:
		      insn_allows_mem[i] = allows_mem[i] = 1;
		      if (MEM_P (extract_mem_from_operand (op))
			  && constraint_satisfied_p (op, cn))
			win = 1;
		      break;

		    case CT_ADDRESS:
		      /* Every address can be reloaded to fit.  */
		      allows_addr = 1;
		      if (address_operand (op, GET_MODE (op))
			  || constraint_satisfied_p (op, cn))
			win = 1;
		      /* We know this operand is an address, so we
			 want it to be allocated to a hard register
			 that can be the base of an address,
			 i.e. BASE_REG_CLASS.  */
		      classes[i]
			= ira_reg_class_subunion[classes[i]]
			  [base_reg_class (VOIDmode, ADDR_SPACE_GENERIC,
					   ADDRESS, SCRATCH)];
		      break;

		    case CT_FIXED_FORM:
		      if (constraint_satisfied_p (op, cn))
			win = 1;
		      break;
		    }
		  break;
		}
	      p += CONSTRAINT_LEN (c, p);
	      if (c == ',')
		break;
	    }

	  constraints[i] = p;

	  if (alt_fail)
	    break;

	  /* How we account for this operand now depends on whether it
	     is a pseudo register or not.  If it is, we first check if
	     any register classes are valid.  If not, we ignore this
	     alternative, since we want to assume that all allocnos get
	     allocated for register preferencing.  If some register
	     class is valid, compute the costs of moving the allocno
	     into that class.  */
	  if (REG_P (op) && REGNO (op) >= FIRST_PSEUDO_REGISTER)
	    {
	      if (classes[i] == NO_REGS && ! allows_mem[i])
		{
		  /* We must always fail if the operand is a REG, but
		     we did not find a suitable class and memory is
		     not allowed.

		     Otherwise we may perform an uninitialized read
		     from this_op_costs after the `continue' statement
		     below.  */
		  alt_fail = 1;
		}
	      else
		{
		  unsigned int regno = REGNO (op);
		  struct costs *pp = this_op_costs[i];
		  int *pp_costs = pp->cost;
		  cost_classes_t cost_classes_ptr = regno_cost_classes[regno];
		  enum reg_class *cost_classes = cost_classes_ptr->classes;
		  bool in_p = recog_data.operand_type[i] != OP_OUT;
		  bool out_p = recog_data.operand_type[i] != OP_IN;
		  enum reg_class op_class = classes[i];

		  ira_init_register_move_cost_if_necessary (mode);
		  if (! in_p)
		    {
		      ira_assert (out_p);
		      if (op_class == NO_REGS)
			{
			  mem_cost = ira_memory_move_cost[mode];
			  for (k = cost_classes_ptr->num - 1; k >= 0; k--)
			    {
			      rclass = cost_classes[k];
			      pp_costs[k] = mem_cost[rclass][0] * frequency;
			    }
			}
		      else
			{
			  move_out_cost = ira_may_move_out_cost[mode];
			  for (k = cost_classes_ptr->num - 1; k >= 0; k--)
			    {
			      rclass = cost_classes[k];
			      pp_costs[k]
				= move_out_cost[op_class][rclass] * frequency;
			    }
			}
		    }
		  else if (! out_p)
		    {
		      ira_assert (in_p);
		      if (op_class == NO_REGS)
			{
			  mem_cost = ira_memory_move_cost[mode];
			  for (k = cost_classes_ptr->num - 1; k >= 0; k--)
			    {
			      rclass = cost_classes[k];
			      pp_costs[k] = mem_cost[rclass][1] * frequency;
			    }
			}
		      else
			{
			  move_in_cost = ira_may_move_in_cost[mode];
			  for (k = cost_classes_ptr->num - 1; k >= 0; k--)
			    {
			      rclass = cost_classes[k];
			      pp_costs[k]
				= move_in_cost[rclass][op_class] * frequency;
			    }
			}
		    }
		  else
		    {
		      if (op_class == NO_REGS)
			{
			  mem_cost = ira_memory_move_cost[mode];
			  for (k = cost_classes_ptr->num - 1; k >= 0; k--)
			    {
			      rclass = cost_classes[k];
			      pp_costs[k] = ((mem_cost[rclass][0]
					      + mem_cost[rclass][1])
					     * frequency);
			    }
			}
		      else
			{
			  move_in_cost = ira_may_move_in_cost[mode];
			  move_out_cost = ira_may_move_out_cost[mode];
			  for (k = cost_classes_ptr->num - 1; k >= 0; k--)
			    {
			      rclass = cost_classes[k];
			      pp_costs[k] = ((move_in_cost[rclass][op_class]
					      + move_out_cost[op_class][rclass])
					     * frequency);
			    }
			}
		    }

		  if (op_class == NO_REGS)
		    /* Although we don't need insn to reload from
		       memory, still accessing memory is usually more
		       expensive than a register.  */
		    pp->mem_cost = frequency;
		  else
		    /* If the alternative actually allows memory, make
		       things a bit cheaper since we won't need an
		       extra insn to load it.  */
		    pp->mem_cost
		      = ((out_p ? ira_memory_move_cost[mode][op_class][0] : 0)
			 + (in_p ? ira_memory_move_cost[mode][op_class][1] : 0)
			 - allows_mem[i]) * frequency;
		  /* If we have assigned a class to this allocno in
		     our first pass, add a cost to this alternative
		     corresponding to what we would add if this
		     allocno were not in the appropriate class.  */
		  if (pref)
		    {
		      enum reg_class pref_class = pref[COST_INDEX (REGNO (op))];

		      if (pref_class == NO_REGS)
			{
			  if (op_class != NO_REGS)
			    alt_cost
			      += ((out_p
				   ? ira_memory_move_cost[mode][op_class][0]
				   : 0)
				  + (in_p
				     ? ira_memory_move_cost[mode][op_class][1]
				     : 0));
			}
		      else if (op_class == NO_REGS)
			alt_cost
			  += ((out_p
			       ? ira_memory_move_cost[mode][pref_class][1]
			       : 0)
			      + (in_p
				 ? ira_memory_move_cost[mode][pref_class][0]
				 : 0));
		      else if (ira_reg_class_intersect[pref_class][op_class]
			       == NO_REGS)
			alt_cost += (ira_register_move_cost
				     [mode][pref_class][op_class]);
		    }
		}
	    }

	  /* Otherwise, if this alternative wins, either because we
	     have already determined that or if we have a hard
	     register of the proper class, there is no cost for this
	     alternative.  */
	  else if (win || (REG_P (op)
			   && reg_fits_class_p (op, classes[i],
						0, GET_MODE (op))))
	    ;

	  /* If registers are valid, the cost of this alternative
	     includes copying the object to and/or from a
	     register.  */
	  else if (classes[i] != NO_REGS)
	    {
	      if (recog_data.operand_type[i] != OP_OUT)
		alt_cost += copy_cost (op, mode, classes[i], 1, NULL);

	      if (recog_data.operand_type[i] != OP_IN)
		alt_cost += copy_cost (op, mode, classes[i], 0, NULL);
	    }
	  /* The only other way this alternative can be used is if
	     this is a constant that could be placed into memory.  */
	  else if (CONSTANT_P (op) && (allows_addr || allows_mem[i]))
	    alt_cost += ira_memory_move_cost[mode][classes[i]][1];
	  else
	    alt_fail = 1;

	  if (alt_fail)
	    break;
	}

      if (alt_fail)
	{
	  /* The loop above might have exited early once the failure
	     was seen.  Skip over the constraints for the remaining
	     operands.  */
	  i += 1;
	  for (; i < n_ops; ++i)
	    constraints[i] = skip_alternative (constraints[i]);
	  continue;
	}

      op_cost_add = alt_cost * frequency;
      /* Finally, update the costs with the information we've
	 calculated about this alternative.  */
      for (i = 0; i < n_ops; i++)
	if (REG_P (ops[i]) && REGNO (ops[i]) >= FIRST_PSEUDO_REGISTER)
	  {
	    int old_cost;
	    bool cost_change_p = false;
	    struct costs *pp = op_costs[i], *qq = this_op_costs[i];
	    int *pp_costs = pp->cost, *qq_costs = qq->cost;
	    int scale = 1 + (recog_data.operand_type[i] == OP_INOUT);
	    cost_classes_t cost_classes_ptr
	      = regno_cost_classes[REGNO (ops[i])];

	    old_cost = pp->mem_cost;
	    pp->mem_cost = MIN (old_cost,
				(qq->mem_cost + op_cost_add) * scale);

	    if (ira_dump_file != NULL && internal_flag_ira_verbose > 5
		&& pp->mem_cost < old_cost)
	      {
		cost_change_p = true;
		fprintf (ira_dump_file, "        op %d(r=%u) new costs MEM:%d",
			 i, REGNO(ops[i]), pp->mem_cost);
	      }
	    for (k = cost_classes_ptr->num - 1; k >= 0; k--)
	      {
		old_cost = pp_costs[k];
		pp_costs[k]
		  = MIN (old_cost, (qq_costs[k] + op_cost_add) * scale);
		if (ira_dump_file != NULL && internal_flag_ira_verbose > 5
		    && pp_costs[k] < old_cost)
		  {
		    if (!cost_change_p)
		      fprintf (ira_dump_file, "        op %d(r=%u) new costs",
			       i, REGNO(ops[i]));
		    cost_change_p = true;
		    fprintf (ira_dump_file, " %s:%d",
			     reg_class_names[cost_classes_ptr->classes[k]],
			     pp_costs[k]);
		  }
	      }
	    if (ira_dump_file != NULL && internal_flag_ira_verbose > 5
		&& cost_change_p)
	      fprintf (ira_dump_file, "\n");
	  }
    }

  if (allocno_p)
    for (i = 0; i < n_ops; i++)
      {
	ira_allocno_t a;
	rtx op = ops[i];

	if (! REG_P (op) || REGNO (op) < FIRST_PSEUDO_REGISTER)
	  continue;
	a = ira_curr_regno_allocno_map [REGNO (op)];
	if (! ALLOCNO_BAD_SPILL_P (a) && insn_allows_mem[i] == 0)
	  ALLOCNO_BAD_SPILL_P (a) = true;
      }

}



/* Wrapper around REGNO_OK_FOR_INDEX_P, to allow pseudo registers.  */
static inline bool
ok_for_index_p_nonstrict (rtx reg)
{
  unsigned regno = REGNO (reg);

  return regno >= FIRST_PSEUDO_REGISTER || REGNO_OK_FOR_INDEX_P (regno);
}

/* A version of regno_ok_for_base_p for use here, when all
   pseudo-registers should count as OK.  Arguments as for
   regno_ok_for_base_p.  */
static inline bool
ok_for_base_p_nonstrict (rtx reg, machine_mode mode, addr_space_t as,
			 enum rtx_code outer_code, enum rtx_code index_code)
{
  unsigned regno = REGNO (reg);

  if (regno >= FIRST_PSEUDO_REGISTER)
    return true;
  return ok_for_base_p_1 (regno, mode, as, outer_code, index_code);
}

/* Record the pseudo registers we must reload into hard registers in a
   subexpression of a memory address, X.

   If CONTEXT is 0, we are looking at the base part of an address,
   otherwise we are looking at the index part.

   MODE and AS are the mode and address space of the memory reference;
   OUTER_CODE and INDEX_CODE give the context that the rtx appears in.
   These four arguments are passed down to base_reg_class.

   SCALE is twice the amount to multiply the cost by (it is twice so
   we can represent half-cost adjustments).  */
static void
record_address_regs (machine_mode mode, addr_space_t as, rtx x,
		     int context, enum rtx_code outer_code,
		     enum rtx_code index_code, int scale)
{
  enum rtx_code code = GET_CODE (x);
  enum reg_class rclass;

  if (context == 1)
    rclass = INDEX_REG_CLASS;
  else
    rclass = base_reg_class (mode, as, outer_code, index_code);

  switch (code)
    {
    case CONST_INT:
    case CONST:
    case PC:
    case SYMBOL_REF:
    case LABEL_REF:
      return;

    case PLUS:
      /* When we have an address that is a sum, we must determine
	 whether registers are "base" or "index" regs.  If there is a
	 sum of two registers, we must choose one to be the "base".
	 Luckily, we can use the REG_POINTER to make a good choice
	 most of the time.  We only need to do this on machines that
	 can have two registers in an address and where the base and
	 index register classes are different.

	 ??? This code used to set REGNO_POINTER_FLAG in some cases,
	 but that seems bogus since it should only be set when we are
	 sure the register is being used as a pointer.  */
      {
	rtx arg0 = XEXP (x, 0);
	rtx arg1 = XEXP (x, 1);
	enum rtx_code code0 = GET_CODE (arg0);
	enum rtx_code code1 = GET_CODE (arg1);

	/* Look inside subregs.  */
	if (code0 == SUBREG)
	  arg0 = SUBREG_REG (arg0), code0 = GET_CODE (arg0);
	if (code1 == SUBREG)
	  arg1 = SUBREG_REG (arg1), code1 = GET_CODE (arg1);

	/* If index registers do not appear, or coincide with base registers,
	   just record registers in any non-constant operands.  We
	   assume here, as well as in the tests below, that all
	   addresses are in canonical form.  */
	if (MAX_REGS_PER_ADDRESS == 1
	    || INDEX_REG_CLASS == base_reg_class (VOIDmode, as, PLUS, SCRATCH))
	  {
	    record_address_regs (mode, as, arg0, context, PLUS, code1, scale);
	    if (! CONSTANT_P (arg1))
	      record_address_regs (mode, as, arg1, context, PLUS, code0, scale);
	  }

	/* If the second operand is a constant integer, it doesn't
	   change what class the first operand must be.  */
	else if (CONST_SCALAR_INT_P (arg1))
	  record_address_regs (mode, as, arg0, context, PLUS, code1, scale);
	/* If the second operand is a symbolic constant, the first
	   operand must be an index register.  */
	else if (code1 == SYMBOL_REF || code1 == CONST || code1 == LABEL_REF)
	  record_address_regs (mode, as, arg0, 1, PLUS, code1, scale);
	/* If both operands are registers but one is already a hard
	   register of index or reg-base class, give the other the
	   class that the hard register is not.  */
	else if (code0 == REG && code1 == REG
		 && REGNO (arg0) < FIRST_PSEUDO_REGISTER
		 && (ok_for_base_p_nonstrict (arg0, mode, as, PLUS, REG)
		     || ok_for_index_p_nonstrict (arg0)))
	  record_address_regs (mode, as, arg1,
			       ok_for_base_p_nonstrict (arg0, mode, as,
							PLUS, REG) ? 1 : 0,
			       PLUS, REG, scale);
	else if (code0 == REG && code1 == REG
		 && REGNO (arg1) < FIRST_PSEUDO_REGISTER
		 && (ok_for_base_p_nonstrict (arg1, mode, as, PLUS, REG)
		     || ok_for_index_p_nonstrict (arg1)))
	  record_address_regs (mode, as, arg0,
			       ok_for_base_p_nonstrict (arg1, mode, as,
							PLUS, REG) ? 1 : 0,
			       PLUS, REG, scale);
	/* If one operand is known to be a pointer, it must be the
	   base with the other operand the index.  Likewise if the
	   other operand is a MULT.  */
	else if ((code0 == REG && REG_POINTER (arg0)) || code1 == MULT)
	  {
	    record_address_regs (mode, as, arg0, 0, PLUS, code1, scale);
	    record_address_regs (mode, as, arg1, 1, PLUS, code0, scale);
	  }
	else if ((code1 == REG && REG_POINTER (arg1)) || code0 == MULT)
	  {
	    record_address_regs (mode, as, arg0, 1, PLUS, code1, scale);
	    record_address_regs (mode, as, arg1, 0, PLUS, code0, scale);
	  }
	/* Otherwise, count equal chances that each might be a base or
	   index register.  This case should be rare.  */
	else
	  {
	    record_address_regs (mode, as, arg0, 0, PLUS, code1, scale / 2);
	    record_address_regs (mode, as, arg0, 1, PLUS, code1, scale / 2);
	    record_address_regs (mode, as, arg1, 0, PLUS, code0, scale / 2);
	    record_address_regs (mode, as, arg1, 1, PLUS, code0, scale / 2);
	  }
      }
      break;

      /* Double the importance of an allocno that is incremented or
	 decremented, since it would take two extra insns if it ends
	 up in the wrong place.  */
    case POST_MODIFY:
    case PRE_MODIFY:
      record_address_regs (mode, as, XEXP (x, 0), 0, code,
			   GET_CODE (XEXP (XEXP (x, 1), 1)), 2 * scale);
      if (REG_P (XEXP (XEXP (x, 1), 1)))
	record_address_regs (mode, as, XEXP (XEXP (x, 1), 1), 1, code, REG,
			     2 * scale);
      break;

    case POST_INC:
    case PRE_INC:
    case POST_DEC:
    case PRE_DEC:
      /* Double the importance of an allocno that is incremented or
	 decremented, since it would take two extra insns if it ends
	 up in the wrong place.  */
      record_address_regs (mode, as, XEXP (x, 0), 0, code, SCRATCH, 2 * scale);
      break;

    case REG:
      {
	struct costs *pp;
	int *pp_costs;
	enum reg_class i;
	int k, regno, add_cost;
	cost_classes_t cost_classes_ptr;
	enum reg_class *cost_classes;
	move_table *move_in_cost;

	if (REGNO (x) < FIRST_PSEUDO_REGISTER)
	  break;

	regno = REGNO (x);
	if (allocno_p)
	  ALLOCNO_BAD_SPILL_P (ira_curr_regno_allocno_map[regno]) = true;
	pp = COSTS (costs, COST_INDEX (regno));
	add_cost = (ira_memory_move_cost[Pmode][rclass][1] * scale) / 2;
	if (INT_MAX - add_cost < pp->mem_cost)
	  pp->mem_cost = INT_MAX;
	else
	  pp->mem_cost += add_cost;
	cost_classes_ptr = regno_cost_classes[regno];
	cost_classes = cost_classes_ptr->classes;
	pp_costs = pp->cost;
	ira_init_register_move_cost_if_necessary (Pmode);
	move_in_cost = ira_may_move_in_cost[Pmode];
	for (k = cost_classes_ptr->num - 1; k >= 0; k--)
	  {
	    i = cost_classes[k];
	    add_cost = (move_in_cost[i][rclass] * scale) / 2;
	    if (INT_MAX - add_cost < pp_costs[k])
	      pp_costs[k] = INT_MAX;
	    else
	      pp_costs[k] += add_cost;
	  }
      }
      break;

    default:
      {
	const char *fmt = GET_RTX_FORMAT (code);
	int i;
	for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
	  if (fmt[i] == 'e')
	    record_address_regs (mode, as, XEXP (x, i), context, code, SCRATCH,
				 scale);
      }
    }
}



/* Calculate the costs of insn operands.  */
static void
record_operand_costs (rtx_insn *insn, enum reg_class *pref)
{
  const char *constraints[MAX_RECOG_OPERANDS];
  machine_mode modes[MAX_RECOG_OPERANDS];
  rtx set;
  int i;

  if ((set = single_set (insn)) != NULL_RTX
      /* In rare cases the single set insn might have less 2 operands
	 as the source can be a fixed special reg.  */
      && recog_data.n_operands > 1
      && recog_data.operand[0] == SET_DEST (set)
      && recog_data.operand[1] == SET_SRC (set))
    {
      int regno, other_regno;
      rtx dest = SET_DEST (set);
      rtx src = SET_SRC (set);

      if (GET_CODE (dest) == SUBREG
	  && known_eq (GET_MODE_SIZE (GET_MODE (dest)),
		       GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest)))))
	dest = SUBREG_REG (dest);
      if (GET_CODE (src) == SUBREG
	  && known_eq (GET_MODE_SIZE (GET_MODE (src)),
		       GET_MODE_SIZE (GET_MODE (SUBREG_REG (src)))))
	src = SUBREG_REG (src);
      if (REG_P (src) && REG_P (dest)
	  && (((regno = REGNO (src)) >= FIRST_PSEUDO_REGISTER
	       && (other_regno = REGNO (dest)) < FIRST_PSEUDO_REGISTER)
	      || ((regno = REGNO (dest)) >= FIRST_PSEUDO_REGISTER
		  && (other_regno = REGNO (src)) < FIRST_PSEUDO_REGISTER)))
	{
	  machine_mode mode = GET_MODE (SET_SRC (set)), cost_mode = mode;
	  machine_mode hard_reg_mode = GET_MODE(regno_reg_rtx[other_regno]);
	  poly_int64 pmode_size = GET_MODE_SIZE (mode);
	  poly_int64 phard_reg_mode_size = GET_MODE_SIZE (hard_reg_mode);
	  HOST_WIDE_INT mode_size, hard_reg_mode_size;
	  cost_classes_t cost_classes_ptr = regno_cost_classes[regno];
	  enum reg_class *cost_classes = cost_classes_ptr->classes;
	  reg_class_t rclass, hard_reg_class, bigger_hard_reg_class;
	  int cost_factor = 1, cost, k;
	  move_table *move_costs;
	  bool dead_p = find_regno_note (insn, REG_DEAD, REGNO (src));

	  hard_reg_class = REGNO_REG_CLASS (other_regno);
          bigger_hard_reg_class = ira_pressure_class_translate[hard_reg_class];
          /* Target code may return any cost for mode which does not fit the
             hard reg class (e.g. DImode for AREG on i386).  Check this and use
             a bigger class to get the right cost.  */
          if (bigger_hard_reg_class != NO_REGS
              && ! ira_hard_reg_in_set_p (other_regno, mode,
                                          reg_class_contents[hard_reg_class]))
            hard_reg_class = bigger_hard_reg_class;
          ira_init_register_move_cost_if_necessary (mode);
          ira_init_register_move_cost_if_necessary (hard_reg_mode);
	  /* Use smaller movement cost for natural hard reg mode or its mode as
	     operand.  */
          if (pmode_size.is_constant (&mode_size)
              && phard_reg_mode_size.is_constant (&hard_reg_mode_size))
            {
	      /* Assume we are moving in the natural modes: */
              cost_factor = mode_size / hard_reg_mode_size;
              if (mode_size % hard_reg_mode_size != 0)
		cost_factor++;
	      if (cost_factor
		  * (ira_register_move_cost
		     [hard_reg_mode][hard_reg_class][hard_reg_class])
		  < (ira_register_move_cost
		     [mode][hard_reg_class][hard_reg_class]))
		cost_mode = hard_reg_mode;
	      else
		cost_factor = 1;
            }
          move_costs = ira_register_move_cost[cost_mode];
	  i = regno == (int) REGNO (src) ? 1 : 0;
	  for (k = cost_classes_ptr->num - 1; k >= 0; k--)
	    {
	      rclass = cost_classes[k];
	      cost = (i == 0
		      ? move_costs[hard_reg_class][rclass]
		      : move_costs[rclass][hard_reg_class]);
	      cost *= cost_factor;
	      op_costs[i]->cost[k] = cost * frequency;
	      /* If this insn is a single set copying operand 1 to
		 operand 0 and one operand is an allocno with the
		 other a hard reg or an allocno that prefers a hard
		 register that is in its own register class then we
		 may want to adjust the cost of that register class to
		 -1.

		 Avoid the adjustment if the source does not die to
		 avoid stressing of register allocator by preferencing
		 two colliding registers into single class.  */
	      if (dead_p
		  && TEST_HARD_REG_BIT (reg_class_contents[rclass], other_regno)
		  && (reg_class_size[(int) rclass]
		      == (ira_reg_class_max_nregs
			  [(int) rclass][(int) GET_MODE(src)])))
		{
		  if (reg_class_size[rclass] == 1)
		    op_costs[i]->cost[k] = -frequency;
		  else if (in_hard_reg_set_p (reg_class_contents[rclass],
					      GET_MODE(src), other_regno))
		    op_costs[i]->cost[k] = -frequency;
		}
	    }
	  op_costs[i]->mem_cost
	    = ira_memory_move_cost[mode][hard_reg_class][i] * frequency;
	  return;
	}
    }

  for (i = 0; i < recog_data.n_operands; i++)
    {
      constraints[i] = recog_data.constraints[i];
      modes[i] = recog_data.operand_mode[i];
    }

  /* If we get here, we are set up to record the costs of all the
     operands for this insn.  Start by initializing the costs.  Then
     handle any address registers.  Finally record the desired classes
     for any allocnos, doing it twice if some pair of operands are
     commutative.  */
  for (i = 0; i < recog_data.n_operands; i++)
    {
      rtx op_mem = extract_mem_from_operand (recog_data.operand[i]);
      memcpy (op_costs[i], init_cost, struct_costs_size);

      if (GET_CODE (recog_data.operand[i]) == SUBREG)
	recog_data.operand[i] = SUBREG_REG (recog_data.operand[i]);

      if (MEM_P (op_mem))
	record_address_regs (GET_MODE (op_mem),
			     MEM_ADDR_SPACE (op_mem),
			     XEXP (op_mem, 0),
			     0, MEM, SCRATCH, frequency * 2);
      else if (constraints[i][0] == 'p'
	       || (insn_extra_address_constraint
		   (lookup_constraint (constraints[i]))))
	record_address_regs (VOIDmode, ADDR_SPACE_GENERIC,
			     recog_data.operand[i], 0, ADDRESS, SCRATCH,
			     frequency * 2);
    }

  /* Check for commutative in a separate loop so everything will have
     been initialized.  We must do this even if one operand is a
     constant--see addsi3 in m68k.md.  */
  for (i = 0; i < (int) recog_data.n_operands - 1; i++)
    if (constraints[i][0] == '%')
      {
	const char *xconstraints[MAX_RECOG_OPERANDS];
	int j;

	/* Handle commutative operands by swapping the
	   constraints.  We assume the modes are the same.  */
	for (j = 0; j < recog_data.n_operands; j++)
	  xconstraints[j] = constraints[j];

	xconstraints[i] = constraints[i+1];
	xconstraints[i+1] = constraints[i];
	record_reg_classes (recog_data.n_alternatives, recog_data.n_operands,
			    recog_data.operand, modes,
			    xconstraints, insn, pref);
      }
  record_reg_classes (recog_data.n_alternatives, recog_data.n_operands,
		      recog_data.operand, modes,
		      constraints, insn, pref);
}



/* Process one insn INSN.  Scan it and record each time it would save
   code to put a certain allocnos in a certain class.  Return the last
   insn processed, so that the scan can be continued from there.  */
static rtx_insn *
scan_one_insn (rtx_insn *insn)
{
  enum rtx_code pat_code;
  rtx set, note;
  int i, k;
  bool counted_mem;

  if (!NONDEBUG_INSN_P (insn))
    return insn;

  pat_code = GET_CODE (PATTERN (insn));
  if (pat_code == ASM_INPUT)
    return insn;

  /* If INSN is a USE/CLOBBER of a pseudo in a mode M then go ahead
     and initialize the register move costs of mode M.

     The pseudo may be related to another pseudo via a copy (implicit or
     explicit) and if there are no mode M uses/sets of the original
     pseudo, then we may leave the register move costs uninitialized for
     mode M. */
  if (pat_code == USE || pat_code == CLOBBER)
    {
      rtx x = XEXP (PATTERN (insn), 0);
      if (GET_CODE (x) == REG
	  && REGNO (x) >= FIRST_PSEUDO_REGISTER
	  && have_regs_of_mode[GET_MODE (x)])
        ira_init_register_move_cost_if_necessary (GET_MODE (x));
      return insn;
    }

  counted_mem = false;
  set = single_set (insn);
  extract_insn (insn);

  /* If this insn loads a parameter from its stack slot, then it
     represents a savings, rather than a cost, if the parameter is
     stored in memory.  Record this fact.

     Similarly if we're loading other constants from memory (constant
     pool, TOC references, small data areas, etc) and this is the only
     assignment to the destination pseudo.

     Don't do this if SET_SRC (set) isn't a general operand, if it is
     a memory requiring special instructions to load it, decreasing
     mem_cost might result in it being loaded using the specialized
     instruction into a register, then stored into stack and loaded
     again from the stack.  See PR52208.

     Don't do this if SET_SRC (set) has side effect.  See PR56124.  */
  if (set != 0 && REG_P (SET_DEST (set)) && MEM_P (SET_SRC (set))
      && (note = find_reg_note (insn, REG_EQUIV, NULL_RTX)) != NULL_RTX
      && ((MEM_P (XEXP (note, 0))
	   && !side_effects_p (SET_SRC (set)))
	  || (CONSTANT_P (XEXP (note, 0))
	      && targetm.legitimate_constant_p (GET_MODE (SET_DEST (set)),
						XEXP (note, 0))
	      && REG_N_SETS (REGNO (SET_DEST (set))) == 1))
      && general_operand (SET_SRC (set), GET_MODE (SET_SRC (set)))
      /* LRA does not use equiv with a symbol for PIC code.  */
      && (! ira_use_lra_p || ! pic_offset_table_rtx
	  || ! contains_symbol_ref_p (XEXP (note, 0))))
    {
      enum reg_class cl = GENERAL_REGS;
      rtx reg = SET_DEST (set);
      int num = COST_INDEX (REGNO (reg));
      /* Costs for NO_REGS are used in cost calculation on the
	 1st pass when the preferred register classes are not
	 known yet.  In this case we take the best scenario when
	 mode can't be put into GENERAL_REGS.  */
      if (!targetm.hard_regno_mode_ok (ira_class_hard_regs[cl][0],
				       GET_MODE (reg)))
	cl = NO_REGS;

      COSTS (costs, num)->mem_cost
	-= ira_memory_move_cost[GET_MODE (reg)][cl][1] * frequency;
      record_address_regs (GET_MODE (SET_SRC (set)),
			   MEM_ADDR_SPACE (SET_SRC (set)),
			   XEXP (SET_SRC (set), 0), 0, MEM, SCRATCH,
			   frequency * 2);
      counted_mem = true;
    }

  record_operand_costs (insn, pref);

  if (ira_dump_file != NULL && internal_flag_ira_verbose > 5)
    {
      const char *p;
      fprintf (ira_dump_file, "    Final costs after insn %u", INSN_UID (insn));
      if (INSN_CODE (insn) >= 0
	  && (p = get_insn_name (INSN_CODE (insn))) != NULL)
	fprintf (ira_dump_file, " {%s}", p);
      fprintf (ira_dump_file, " (freq=%d)\n",
	       REG_FREQ_FROM_BB (BLOCK_FOR_INSN (insn)));
      dump_insn_slim (ira_dump_file, insn);
    }

  /* Now add the cost for each operand to the total costs for its
     allocno.  */
  for (i = 0; i < recog_data.n_operands; i++)
    {
      rtx op = recog_data.operand[i];

      if (GET_CODE (op) == SUBREG)
	op = SUBREG_REG (op);
      if (REG_P (op) && REGNO (op) >= FIRST_PSEUDO_REGISTER)
	{
	  int regno = REGNO (op);
	  struct costs *p = COSTS (costs, COST_INDEX (regno));
	  struct costs *q = op_costs[i];
	  int *p_costs = p->cost, *q_costs = q->cost;
	  cost_classes_t cost_classes_ptr = regno_cost_classes[regno];
	  int add_cost = 0;

	  /* If the already accounted for the memory "cost" above, don't
	     do so again.  */
	  if (!counted_mem)
	    {
	      add_cost = q->mem_cost;
	      if (add_cost > 0 && INT_MAX - add_cost < p->mem_cost)
		p->mem_cost = INT_MAX;
	      else
		p->mem_cost += add_cost;
	    }
	  if (ira_dump_file != NULL && internal_flag_ira_verbose > 5)
	    {
	      fprintf (ira_dump_file, "        op %d(r=%u) MEM:%d(+%d)",
		       i, REGNO(op), p->mem_cost, add_cost);
	    }
	  for (k = cost_classes_ptr->num - 1; k >= 0; k--)
	    {
	      add_cost = q_costs[k];
	      if (add_cost > 0 && INT_MAX - add_cost < p_costs[k])
		p_costs[k] = INT_MAX;
	      else
		p_costs[k] += add_cost;
	      if (ira_dump_file != NULL && internal_flag_ira_verbose > 5)
		{
		  fprintf (ira_dump_file, " %s:%d(+%d)",
			   reg_class_names[cost_classes_ptr->classes[k]],
			   p_costs[k], add_cost);
		}
	    }
	  if (ira_dump_file != NULL && internal_flag_ira_verbose > 5)
	    fprintf (ira_dump_file, "\n");
	}
    }
  return insn;
}



/* Print allocnos costs to file F.  */
static void
print_allocno_costs (FILE *f)
{
  int k;
  ira_allocno_t a;
  ira_allocno_iterator ai;

  ira_assert (allocno_p);
  fprintf (f, "\n");
  FOR_EACH_ALLOCNO (a, ai)
    {
      int i, rclass;
      basic_block bb;
      int regno = ALLOCNO_REGNO (a);
      cost_classes_t cost_classes_ptr = regno_cost_classes[regno];
      enum reg_class *cost_classes = cost_classes_ptr->classes;

      i = ALLOCNO_NUM (a);
      fprintf (f, "  a%d(r%d,", i, regno);
      if ((bb = ALLOCNO_LOOP_TREE_NODE (a)->bb) != NULL)
	fprintf (f, "b%d", bb->index);
      else
	fprintf (f, "l%d", ALLOCNO_LOOP_TREE_NODE (a)->loop_num);
      fprintf (f, ") costs:");
      for (k = 0; k < cost_classes_ptr->num; k++)
	{
	  rclass = cost_classes[k];
	  fprintf (f, " %s:%d", reg_class_names[rclass],
		   COSTS (costs, i)->cost[k]);
	  if (flag_ira_region == IRA_REGION_ALL
	      || flag_ira_region == IRA_REGION_MIXED)
	    fprintf (f, ",%d", COSTS (total_allocno_costs, i)->cost[k]);
	}
      fprintf (f, " MEM:%i", COSTS (costs, i)->mem_cost);
      if (flag_ira_region == IRA_REGION_ALL
	  || flag_ira_region == IRA_REGION_MIXED)
	fprintf (f, ",%d", COSTS (total_allocno_costs, i)->mem_cost);
      fprintf (f, "\n");
    }
}

/* Print pseudo costs to file F.  */
static void
print_pseudo_costs (FILE *f)
{
  int regno, k;
  int rclass;
  cost_classes_t cost_classes_ptr;
  enum reg_class *cost_classes;

  ira_assert (! allocno_p);
  fprintf (f, "\n");
  for (regno = max_reg_num () - 1; regno >= FIRST_PSEUDO_REGISTER; regno--)
    {
      if (REG_N_REFS (regno) <= 0)
	continue;
      cost_classes_ptr = regno_cost_classes[regno];
      cost_classes = cost_classes_ptr->classes;
      fprintf (f, "  r%d costs:", regno);
      for (k = 0; k < cost_classes_ptr->num; k++)
	{
	  rclass = cost_classes[k];
	  fprintf (f, " %s:%d", reg_class_names[rclass],
		   COSTS (costs, regno)->cost[k]);
	}
      fprintf (f, " MEM:%i\n", COSTS (costs, regno)->mem_cost);
    }
}

/* Traverse the BB represented by LOOP_TREE_NODE to update the allocno
   costs.  */
static void
process_bb_for_costs (basic_block bb)
{
  rtx_insn *insn;

  frequency = REG_FREQ_FROM_BB (bb);
  if (frequency == 0)
    frequency = 1;
  FOR_BB_INSNS (bb, insn)
    insn = scan_one_insn (insn);
}

/* Traverse the BB represented by LOOP_TREE_NODE to update the allocno
   costs.  */
static void
process_bb_node_for_costs (ira_loop_tree_node_t loop_tree_node)
{
  basic_block bb;

  bb = loop_tree_node->bb;
  if (bb != NULL)
    process_bb_for_costs (bb);
}

/* Find costs of register classes and memory for allocnos or pseudos
   and their best costs.  Set up preferred, alternative and allocno
   classes for pseudos.  */
static void
find_costs_and_classes (FILE *dump_file)
{
  int i, k, start, max_cost_classes_num;
  int pass;
  basic_block bb;
  enum reg_class *regno_best_class, new_class;

  init_recog ();
  regno_best_class
    = (enum reg_class *) ira_allocate (max_reg_num ()
				       * sizeof (enum reg_class));
  for (i = max_reg_num () - 1; i >= FIRST_PSEUDO_REGISTER; i--)
    regno_best_class[i] = NO_REGS;
  if (!resize_reg_info () && allocno_p
      && pseudo_classes_defined_p && flag_expensive_optimizations)
    {
      ira_allocno_t a;
      ira_allocno_iterator ai;

      pref = pref_buffer;
      max_cost_classes_num = 1;
      FOR_EACH_ALLOCNO (a, ai)
	{
	  pref[ALLOCNO_NUM (a)] = reg_preferred_class (ALLOCNO_REGNO (a));
	  setup_regno_cost_classes_by_aclass
	    (ALLOCNO_REGNO (a), pref[ALLOCNO_NUM (a)]);
	  max_cost_classes_num
	    = MAX (max_cost_classes_num,
		   regno_cost_classes[ALLOCNO_REGNO (a)]->num);
	}
      start = 1;
    }
  else
    {
      pref = NULL;
      max_cost_classes_num = ira_important_classes_num;
      for (i = max_reg_num () - 1; i >= FIRST_PSEUDO_REGISTER; i--)
	if (regno_reg_rtx[i] != NULL_RTX)
 	  setup_regno_cost_classes_by_mode (i, PSEUDO_REGNO_MODE (i));
	else
	  setup_regno_cost_classes_by_aclass (i, ALL_REGS);
      start = 0;
    }
  if (allocno_p)
    /* Clear the flag for the next compiled function.  */
    pseudo_classes_defined_p = false;
  /* Normally we scan the insns once and determine the best class to
     use for each allocno.  However, if -fexpensive-optimizations are
     on, we do so twice, the second time using the tentative best
     classes to guide the selection.  */
  for (pass = start; pass <= flag_expensive_optimizations; pass++)
    {
      if ((!allocno_p || internal_flag_ira_verbose > 0) && dump_file)
	fprintf (dump_file,
		 "\nPass %i for finding pseudo/allocno costs\n\n", pass);

      if (pass != start)
	{
	  max_cost_classes_num = 1;
	  for (i = max_reg_num () - 1; i >= FIRST_PSEUDO_REGISTER; i--)
	    {
	      setup_regno_cost_classes_by_aclass (i, regno_best_class[i]);
	      max_cost_classes_num
		= MAX (max_cost_classes_num, regno_cost_classes[i]->num);
	    }
	}

      struct_costs_size
	= sizeof (struct costs) + sizeof (int) * (max_cost_classes_num - 1);
      /* Zero out our accumulation of the cost of each class for each
	 allocno.  */
      memset (costs, 0, cost_elements_num * struct_costs_size);

      if (allocno_p)
	{
	  /* Scan the instructions and record each time it would save code
	     to put a certain allocno in a certain class.  */
	  ira_traverse_loop_tree (true, ira_loop_tree_root,
				  process_bb_node_for_costs, NULL);

	  memcpy (total_allocno_costs, costs,
		  max_struct_costs_size * ira_allocnos_num);
	}
      else
	{
	  basic_block bb;

	  FOR_EACH_BB_FN (bb, cfun)
	    process_bb_for_costs (bb);
	}

      if (pass == 0)
	pref = pref_buffer;

      /* Now for each allocno look at how desirable each class is and
	 find which class is preferred.  */
      for (i = max_reg_num () - 1; i >= FIRST_PSEUDO_REGISTER; i--)
	{
	  ira_allocno_t a, parent_a;
	  int rclass, a_num, parent_a_num, add_cost;
	  ira_loop_tree_node_t parent;
	  int best_cost, allocno_cost;
	  enum reg_class best, alt_class;
	  cost_classes_t cost_classes_ptr = regno_cost_classes[i];
	  enum reg_class *cost_classes;
	  int *i_costs = temp_costs->cost;
	  int i_mem_cost;
	  int equiv_savings = regno_equiv_gains[i];

	  if (! allocno_p)
	    {
	      if (regno_reg_rtx[i] == NULL_RTX)
		continue;
	      memcpy (temp_costs, COSTS (costs, i), struct_costs_size);
	      i_mem_cost = temp_costs->mem_cost;
	      cost_classes = cost_classes_ptr->classes;
	    }
	  else
	    {
	      if (ira_regno_allocno_map[i] == NULL)
		continue;
	      memset (temp_costs, 0, struct_costs_size);
	      i_mem_cost = 0;
	      cost_classes = cost_classes_ptr->classes;
	      /* Find cost of all allocnos with the same regno.  */
	      for (a = ira_regno_allocno_map[i];
		   a != NULL;
		   a = ALLOCNO_NEXT_REGNO_ALLOCNO (a))
		{
		  int *a_costs, *p_costs;

		  a_num = ALLOCNO_NUM (a);
		  if ((flag_ira_region == IRA_REGION_ALL
		       || flag_ira_region == IRA_REGION_MIXED)
		      && (parent = ALLOCNO_LOOP_TREE_NODE (a)->parent) != NULL
		      && (parent_a = parent->regno_allocno_map[i]) != NULL
		      /* There are no caps yet.  */
		      && bitmap_bit_p (ALLOCNO_LOOP_TREE_NODE
				       (a)->border_allocnos,
				       ALLOCNO_NUM (a)))
		    {
		      /* Propagate costs to upper levels in the region
			 tree.  */
		      parent_a_num = ALLOCNO_NUM (parent_a);
		      a_costs = COSTS (total_allocno_costs, a_num)->cost;
		      p_costs = COSTS (total_allocno_costs, parent_a_num)->cost;
		      for (k = cost_classes_ptr->num - 1; k >= 0; k--)
			{
			  add_cost = a_costs[k];
			  if (add_cost > 0 && INT_MAX - add_cost < p_costs[k])
			    p_costs[k] = INT_MAX;
			  else
			    p_costs[k] += add_cost;
			}
		      add_cost = COSTS (total_allocno_costs, a_num)->mem_cost;
		      if (add_cost > 0
			  && (INT_MAX - add_cost
			      < COSTS (total_allocno_costs,
				       parent_a_num)->mem_cost))
			COSTS (total_allocno_costs, parent_a_num)->mem_cost
			  = INT_MAX;
		      else
			COSTS (total_allocno_costs, parent_a_num)->mem_cost
			  += add_cost;

		      if (i >= first_moveable_pseudo && i < last_moveable_pseudo)
			COSTS (total_allocno_costs, parent_a_num)->mem_cost = 0;
		    }
		  a_costs = COSTS (costs, a_num)->cost;
		  for (k = cost_classes_ptr->num - 1; k >= 0; k--)
		    {
		      add_cost = a_costs[k];
		      if (add_cost > 0 && INT_MAX - add_cost < i_costs[k])
			i_costs[k] = INT_MAX;
		      else
			i_costs[k] += add_cost;
		    }
		  add_cost = COSTS (costs, a_num)->mem_cost;
		  if (add_cost > 0 && INT_MAX - add_cost < i_mem_cost)
		    i_mem_cost = INT_MAX;
		  else
		    i_mem_cost += add_cost;
		}
	    }
	  if (i >= first_moveable_pseudo && i < last_moveable_pseudo)
	    i_mem_cost = 0;
	  else if (equiv_savings < 0)
	    i_mem_cost = -equiv_savings;
	  else if (equiv_savings > 0)
	    {
	      i_mem_cost = 0;
	      for (k = cost_classes_ptr->num - 1; k >= 0; k--)
		i_costs[k] += equiv_savings;
	    }

	  best_cost = (1 << (HOST_BITS_PER_INT - 2)) - 1;
	  best = ALL_REGS;
	  alt_class = NO_REGS;
	  /* Find best common class for all allocnos with the same
	     regno.  */
	  for (k = 0; k < cost_classes_ptr->num; k++)
	    {
	      rclass = cost_classes[k];
	      if (i_costs[k] < best_cost)
		{
		  best_cost = i_costs[k];
		  best = (enum reg_class) rclass;
		}
	      else if (i_costs[k] == best_cost)
		best = ira_reg_class_subunion[best][rclass];
	      if (pass == flag_expensive_optimizations
		  /* We still prefer registers to memory even at this
		     stage if their costs are the same.  We will make
		     a final decision during assigning hard registers
		     when we have all info including more accurate
		     costs which might be affected by assigning hard
		     registers to other pseudos because the pseudos
		     involved in moves can be coalesced.  */
		  && i_costs[k] <= i_mem_cost
		  && (reg_class_size[reg_class_subunion[alt_class][rclass]]
		      > reg_class_size[alt_class]))
		alt_class = reg_class_subunion[alt_class][rclass];
	    }
	  alt_class = ira_allocno_class_translate[alt_class];
	  if (best_cost > i_mem_cost
	      && ! non_spilled_static_chain_regno_p (i))
	    regno_aclass[i] = NO_REGS;
	  else if (!optimize && !targetm.class_likely_spilled_p (best))
	    /* Registers in the alternative class are likely to need
	       longer or slower sequences than registers in the best class.
	       When optimizing we make some effort to use the best class
	       over the alternative class where possible, but at -O0 we
	       effectively give the alternative class equal weight.
	       We then run the risk of using slower alternative registers
	       when plenty of registers from the best class are still free.
	       This is especially true because live ranges tend to be very
	       short in -O0 code and so register pressure tends to be low.

	       Avoid that by ignoring the alternative class if the best
	       class has plenty of registers.

	       The union class arrays give important classes and only
	       part of it are allocno classes.  So translate them into
	       allocno classes.  */
	    regno_aclass[i] = ira_allocno_class_translate[best];
	  else
	    {
	      /* Make the common class the biggest class of best and
		 alt_class.  Translate the common class into an
		 allocno class too.  */
	      regno_aclass[i] = (ira_allocno_class_translate
				 [ira_reg_class_superunion[best][alt_class]]);
	      ira_assert (regno_aclass[i] != NO_REGS
			  && ira_reg_allocno_class_p[regno_aclass[i]]);
	    }
	  if (pic_offset_table_rtx != NULL
	      && i == (int) REGNO (pic_offset_table_rtx))
	    {
	      /* For some targets, integer pseudos can be assigned to fp
		 regs.  As we don't want reload pic offset table pseudo, we
		 should avoid using non-integer regs.  */
	      regno_aclass[i]
		= ira_reg_class_intersect[regno_aclass[i]][GENERAL_REGS];
	      alt_class = ira_reg_class_intersect[alt_class][GENERAL_REGS];
	    }
	  if ((new_class
	       = (reg_class) (targetm.ira_change_pseudo_allocno_class
			      (i, regno_aclass[i], best))) != regno_aclass[i])
	    {
	      regno_aclass[i] = new_class;
	      if (hard_reg_set_subset_p (reg_class_contents[new_class],
					 reg_class_contents[best]))
		best = new_class;
	      if (hard_reg_set_subset_p (reg_class_contents[new_class],
					 reg_class_contents[alt_class]))
		alt_class = new_class;
	    }
	  if (pass == flag_expensive_optimizations)
	    {
	      if (best_cost > i_mem_cost
		  /* Do not assign NO_REGS to static chain pointer
		     pseudo when non-local goto is used.  */
		  && ! non_spilled_static_chain_regno_p (i))
		best = alt_class = NO_REGS;
	      else if (best == alt_class)
		alt_class = NO_REGS;
	      setup_reg_classes (i, best, alt_class, regno_aclass[i]);
	      if ((!allocno_p || internal_flag_ira_verbose > 2)
		  && dump_file != NULL)
		fprintf (dump_file,
			 "    r%d: preferred %s, alternative %s, allocno %s\n",
			 i, reg_class_names[best], reg_class_names[alt_class],
			 reg_class_names[regno_aclass[i]]);
	    }
	  regno_best_class[i] = best;
	  if (! allocno_p)
	    {
	      pref[i] = (best_cost > i_mem_cost
			 && ! non_spilled_static_chain_regno_p (i)
			 ? NO_REGS : best);
	      continue;
	    }
	  for (a = ira_regno_allocno_map[i];
	       a != NULL;
	       a = ALLOCNO_NEXT_REGNO_ALLOCNO (a))
	    {
	      enum reg_class aclass = regno_aclass[i];
	      int a_num = ALLOCNO_NUM (a);
	      int *total_a_costs = COSTS (total_allocno_costs, a_num)->cost;
	      int *a_costs = COSTS (costs, a_num)->cost;

	      if (aclass == NO_REGS)
		best = NO_REGS;
	      else
		{
		  /* Finding best class which is subset of the common
		     class.  */
		  best_cost = (1 << (HOST_BITS_PER_INT - 2)) - 1;
		  allocno_cost = best_cost;
		  best = ALL_REGS;
		  for (k = 0; k < cost_classes_ptr->num; k++)
		    {
		      rclass = cost_classes[k];
		      if (! ira_class_subset_p[rclass][aclass])
			continue;
		      if (total_a_costs[k] < best_cost)
			{
			  best_cost = total_a_costs[k];
			  allocno_cost = a_costs[k];
			  best = (enum reg_class) rclass;
			}
		      else if (total_a_costs[k] == best_cost)
			{
			  best = ira_reg_class_subunion[best][rclass];
			  allocno_cost = MAX (allocno_cost, a_costs[k]);
			}
		    }
		  ALLOCNO_CLASS_COST (a) = allocno_cost;
		}
	      if (internal_flag_ira_verbose > 2 && dump_file != NULL
		  && (pass == 0 || pref[a_num] != best))
		{
		  fprintf (dump_file, "    a%d (r%d,", a_num, i);
		  if ((bb = ALLOCNO_LOOP_TREE_NODE (a)->bb) != NULL)
		    fprintf (dump_file, "b%d", bb->index);
		  else
		    fprintf (dump_file, "l%d",
			     ALLOCNO_LOOP_TREE_NODE (a)->loop_num);
		  fprintf (dump_file, ") best %s, allocno %s\n",
			   reg_class_names[best],
			   reg_class_names[aclass]);
		}
	      pref[a_num] = best;
	      if (pass == flag_expensive_optimizations && best != aclass
		  && ira_class_hard_regs_num[best] > 0
		  && (ira_reg_class_max_nregs[best][ALLOCNO_MODE (a)]
		      >= ira_class_hard_regs_num[best]))
		{
		  int ind = cost_classes_ptr->index[aclass];

		  ira_assert (ind >= 0);
		  ira_init_register_move_cost_if_necessary (ALLOCNO_MODE (a));
		  ira_add_allocno_pref (a, ira_class_hard_regs[best][0],
					(a_costs[ind] - ALLOCNO_CLASS_COST (a))
					/ (ira_register_move_cost
					   [ALLOCNO_MODE (a)][best][aclass]));
		  for (k = 0; k < cost_classes_ptr->num; k++)
		    if (ira_class_subset_p[cost_classes[k]][best])
		      a_costs[k] = a_costs[ind];
		}
	    }
	}

      if (internal_flag_ira_verbose > 4 && dump_file)
	{
	  if (allocno_p)
	    print_allocno_costs (dump_file);
	  else
	    print_pseudo_costs (dump_file);
	  fprintf (dump_file,"\n");
	}
    }
  ira_free (regno_best_class);
}



/* Process moves involving hard regs to modify allocno hard register
   costs.  We can do this only after determining allocno class.  If a
   hard register forms a register class, then moves with the hard
   register are already taken into account in class costs for the
   allocno.  */
static void
process_bb_node_for_hard_reg_moves (ira_loop_tree_node_t loop_tree_node)
{
  int i, freq, src_regno, dst_regno, hard_regno, a_regno;
  bool to_p;
  ira_allocno_t a, curr_a;
  ira_loop_tree_node_t curr_loop_tree_node;
  enum reg_class rclass;
  basic_block bb;
  rtx_insn *insn;
  rtx set, src, dst;

  bb = loop_tree_node->bb;
  if (bb == NULL)
    return;
  freq = REG_FREQ_FROM_BB (bb);
  if (freq == 0)
    freq = 1;
  FOR_BB_INSNS (bb, insn)
    {
      if (!NONDEBUG_INSN_P (insn))
	continue;
      set = single_set (insn);
      if (set == NULL_RTX)
	continue;
      dst = SET_DEST (set);
      src = SET_SRC (set);
      if (! REG_P (dst) || ! REG_P (src))
	continue;
      dst_regno = REGNO (dst);
      src_regno = REGNO (src);
      if (dst_regno >= FIRST_PSEUDO_REGISTER
	  && src_regno < FIRST_PSEUDO_REGISTER)
	{
	  hard_regno = src_regno;
	  a = ira_curr_regno_allocno_map[dst_regno];
	  to_p = true;
	}
      else if (src_regno >= FIRST_PSEUDO_REGISTER
	       && dst_regno < FIRST_PSEUDO_REGISTER)
	{
	  hard_regno = dst_regno;
	  a = ira_curr_regno_allocno_map[src_regno];
	  to_p = false;
	}
      else
	continue;
      if (reg_class_size[(int) REGNO_REG_CLASS (hard_regno)]
	  == (ira_reg_class_max_nregs
	      [REGNO_REG_CLASS (hard_regno)][(int) ALLOCNO_MODE(a)]))
	/* If the class can provide only one hard reg to the allocno,
	   we processed the insn record_operand_costs already and we
	   actually updated the hard reg cost there.  */
	continue;
      rclass = ALLOCNO_CLASS (a);
      if (! TEST_HARD_REG_BIT (reg_class_contents[rclass], hard_regno))
	continue;
      i = ira_class_hard_reg_index[rclass][hard_regno];
      if (i < 0)
	continue;
      a_regno = ALLOCNO_REGNO (a);
      for (curr_loop_tree_node = ALLOCNO_LOOP_TREE_NODE (a);
	   curr_loop_tree_node != NULL;
	   curr_loop_tree_node = curr_loop_tree_node->parent)
	if ((curr_a = curr_loop_tree_node->regno_allocno_map[a_regno]) != NULL)
	  ira_add_allocno_pref (curr_a, hard_regno, freq);
      {
	int cost;
	enum reg_class hard_reg_class;
	machine_mode mode;

	mode = ALLOCNO_MODE (a);
	hard_reg_class = REGNO_REG_CLASS (hard_regno);
	ira_init_register_move_cost_if_necessary (mode);
	cost = (to_p ? ira_register_move_cost[mode][hard_reg_class][rclass]
		: ira_register_move_cost[mode][rclass][hard_reg_class]) * freq;
	ira_allocate_and_set_costs (&ALLOCNO_HARD_REG_COSTS (a), rclass,
				    ALLOCNO_CLASS_COST (a));
	ira_allocate_and_set_costs (&ALLOCNO_CONFLICT_HARD_REG_COSTS (a),
				    rclass, 0);
	ALLOCNO_HARD_REG_COSTS (a)[i] -= cost;
	ALLOCNO_CONFLICT_HARD_REG_COSTS (a)[i] -= cost;
	ALLOCNO_CLASS_COST (a) = MIN (ALLOCNO_CLASS_COST (a),
				      ALLOCNO_HARD_REG_COSTS (a)[i]);
      }
    }
}

/* After we find hard register and memory costs for allocnos, define
   its class and modify hard register cost because insns moving
   allocno to/from hard registers.  */
static void
setup_allocno_class_and_costs (void)
{
  int i, j, n, regno, hard_regno, num;
  int *reg_costs;
  enum reg_class aclass, rclass;
  ira_allocno_t a;
  ira_allocno_iterator ai;
  cost_classes_t cost_classes_ptr;

  ira_assert (allocno_p);
  FOR_EACH_ALLOCNO (a, ai)
    {
      i = ALLOCNO_NUM (a);
      regno = ALLOCNO_REGNO (a);
      aclass = regno_aclass[regno];
      cost_classes_ptr = regno_cost_classes[regno];
      ira_assert (pref[i] == NO_REGS || aclass != NO_REGS);
      ALLOCNO_MEMORY_COST (a) = COSTS (costs, i)->mem_cost;
      ira_set_allocno_class (a, aclass);
      if (aclass == NO_REGS)
	continue;
      if (optimize && ALLOCNO_CLASS (a) != pref[i])
	{
	  n = ira_class_hard_regs_num[aclass];
	  ALLOCNO_HARD_REG_COSTS (a)
	    = reg_costs = ira_allocate_cost_vector (aclass);
	  for (j = n - 1; j >= 0; j--)
	    {
	      hard_regno = ira_class_hard_regs[aclass][j];
	      if (TEST_HARD_REG_BIT (reg_class_contents[pref[i]], hard_regno))
		reg_costs[j] = ALLOCNO_CLASS_COST (a);
	      else
		{
		  rclass = REGNO_REG_CLASS (hard_regno);
		  num = cost_classes_ptr->index[rclass];
		  if (num < 0)
		    {
		      num = cost_classes_ptr->hard_regno_index[hard_regno];
		      ira_assert (num >= 0);
		    }
		  reg_costs[j] = COSTS (costs, i)->cost[num];
		}
	    }
	}
    }
  if (optimize)
    ira_traverse_loop_tree (true, ira_loop_tree_root,
			    process_bb_node_for_hard_reg_moves, NULL);
}



/* Function called once during compiler work.  */
void
ira_init_costs_once (void)
{
  int i;

  init_cost = NULL;
  for (i = 0; i < MAX_RECOG_OPERANDS; i++)
    {
      op_costs[i] = NULL;
      this_op_costs[i] = NULL;
    }
  temp_costs = NULL;
}

/* Free allocated temporary cost vectors.  */
void
target_ira_int::free_ira_costs ()
{
  int i;

  free (x_init_cost);
  x_init_cost = NULL;
  for (i = 0; i < MAX_RECOG_OPERANDS; i++)
    {
      free (x_op_costs[i]);
      free (x_this_op_costs[i]);
      x_op_costs[i] = x_this_op_costs[i] = NULL;
    }
  free (x_temp_costs);
  x_temp_costs = NULL;
}

/* This is called each time register related information is
   changed.  */
void
ira_init_costs (void)
{
  int i;

  this_target_ira_int->free_ira_costs ();
  max_struct_costs_size
    = sizeof (struct costs) + sizeof (int) * (ira_important_classes_num - 1);
  /* Don't use ira_allocate because vectors live through several IRA
     calls.  */
  init_cost = (struct costs *) xmalloc (max_struct_costs_size);
  init_cost->mem_cost = 1000000;
  for (i = 0; i < ira_important_classes_num; i++)
    init_cost->cost[i] = 1000000;
  for (i = 0; i < MAX_RECOG_OPERANDS; i++)
    {
      op_costs[i] = (struct costs *) xmalloc (max_struct_costs_size);
      this_op_costs[i] = (struct costs *) xmalloc (max_struct_costs_size);
    }
  temp_costs = (struct costs *) xmalloc (max_struct_costs_size);
}



/* Common initialization function for ira_costs and
   ira_set_pseudo_classes.  */
static void
init_costs (void)
{
  init_subregs_of_mode ();
  costs = (struct costs *) ira_allocate (max_struct_costs_size
					 * cost_elements_num);
  pref_buffer = (enum reg_class *) ira_allocate (sizeof (enum reg_class)
						 * cost_elements_num);
  regno_aclass = (enum reg_class *) ira_allocate (sizeof (enum reg_class)
						 * max_reg_num ());
  regno_equiv_gains = (int *) ira_allocate (sizeof (int) * max_reg_num ());
  memset (regno_equiv_gains, 0, sizeof (int) * max_reg_num ());
}

/* Common finalization function for ira_costs and
   ira_set_pseudo_classes.  */
static void
finish_costs (void)
{
  finish_subregs_of_mode ();
  ira_free (regno_equiv_gains);
  ira_free (regno_aclass);
  ira_free (pref_buffer);
  ira_free (costs);
}

/* Entry function which defines register class, memory and hard
   register costs for each allocno.  */
void
ira_costs (void)
{
  allocno_p = true;
  cost_elements_num = ira_allocnos_num;
  init_costs ();
  total_allocno_costs = (struct costs *) ira_allocate (max_struct_costs_size
						       * ira_allocnos_num);
  initiate_regno_cost_classes ();
  calculate_elim_costs_all_insns ();
  find_costs_and_classes (ira_dump_file);
  setup_allocno_class_and_costs ();
  finish_regno_cost_classes ();
  finish_costs ();
  ira_free (total_allocno_costs);
}

/* Entry function which defines classes for pseudos.
   Set pseudo_classes_defined_p only if DEFINE_PSEUDO_CLASSES is true.  */
void
ira_set_pseudo_classes (bool define_pseudo_classes, FILE *dump_file)
{
  allocno_p = false;
  internal_flag_ira_verbose = flag_ira_verbose;
  cost_elements_num = max_reg_num ();
  init_costs ();
  initiate_regno_cost_classes ();
  find_costs_and_classes (dump_file);
  finish_regno_cost_classes ();
  if (define_pseudo_classes)
    pseudo_classes_defined_p = true;

  finish_costs ();
}



/* Change hard register costs for allocnos which lives through
   function calls.  This is called only when we found all intersected
   calls during building allocno live ranges.  */
void
ira_tune_allocno_costs (void)
{
  int j, n, regno;
  int cost, min_cost, *reg_costs;
  enum reg_class aclass;
  machine_mode mode;
  ira_allocno_t a;
  ira_allocno_iterator ai;
  ira_allocno_object_iterator oi;
  ira_object_t obj;
  bool skip_p;

  FOR_EACH_ALLOCNO (a, ai)
    {
      aclass = ALLOCNO_CLASS (a);
      if (aclass == NO_REGS)
	continue;
      mode = ALLOCNO_MODE (a);
      n = ira_class_hard_regs_num[aclass];
      min_cost = INT_MAX;
      if (ALLOCNO_CALLS_CROSSED_NUM (a)
	  != ALLOCNO_CHEAP_CALLS_CROSSED_NUM (a))
	{
	  ira_allocate_and_set_costs
	    (&ALLOCNO_HARD_REG_COSTS (a), aclass,
	     ALLOCNO_CLASS_COST (a));
	  reg_costs = ALLOCNO_HARD_REG_COSTS (a);
	  for (j = n - 1; j >= 0; j--)
	    {
	      regno = ira_class_hard_regs[aclass][j];
	      skip_p = false;
	      FOR_EACH_ALLOCNO_OBJECT (a, obj, oi)
		{
		  if (ira_hard_reg_set_intersection_p (regno, mode,
						       OBJECT_CONFLICT_HARD_REGS
						       (obj)))
		    {
		      skip_p = true;
		      break;
		    }
		}
	      if (skip_p)
		continue;
	      cost = 0;
	      if (ira_need_caller_save_p (a, regno))
		cost += ira_caller_save_cost (a);
#ifdef IRA_HARD_REGNO_ADD_COST_MULTIPLIER
	      {
		auto rclass = REGNO_REG_CLASS (regno);
		cost += ((ira_memory_move_cost[mode][rclass][0]
			  + ira_memory_move_cost[mode][rclass][1])
			 * ALLOCNO_FREQ (a)
			 * IRA_HARD_REGNO_ADD_COST_MULTIPLIER (regno) / 2);
	      }
#endif
	      if (INT_MAX - cost < reg_costs[j])
		reg_costs[j] = INT_MAX;
	      else
		reg_costs[j] += cost;
	      if (min_cost > reg_costs[j])
		min_cost = reg_costs[j];
	    }
	}
      if (min_cost != INT_MAX)
	ALLOCNO_CLASS_COST (a) = min_cost;

      /* Some targets allow pseudos to be allocated to unaligned sequences
	 of hard registers.  However, selecting an unaligned sequence can
	 unnecessarily restrict later allocations.  So increase the cost of
	 unaligned hard regs to encourage the use of aligned hard regs.  */
      {
	const int nregs = ira_reg_class_max_nregs[aclass][ALLOCNO_MODE (a)];

	if (nregs > 1)
	  {
	    ira_allocate_and_set_costs
	      (&ALLOCNO_HARD_REG_COSTS (a), aclass, ALLOCNO_CLASS_COST (a));
	    reg_costs = ALLOCNO_HARD_REG_COSTS (a);
	    for (j = n - 1; j >= 0; j--)
	      {
		regno = ira_non_ordered_class_hard_regs[aclass][j];
		if ((regno % nregs) != 0)
		  {
		    int index = ira_class_hard_reg_index[aclass][regno];
		    ira_assert (index != -1);
		    reg_costs[index] += ALLOCNO_FREQ (a);
		  }
	      }
	  }
      }
    }
}

/* Add COST to the estimated gain for eliminating REGNO with its
   equivalence.  If COST is zero, record that no such elimination is
   possible.  */

void
ira_adjust_equiv_reg_cost (unsigned regno, int cost)
{
  if (cost == 0)
    regno_equiv_gains[regno] = 0;
  else
    regno_equiv_gains[regno] += cost;
}

void
ira_costs_cc_finalize (void)
{
  this_target_ira_int->free_ira_costs ();
}
