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

/* 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;
      COPY_HARD_REG_SET (valid_for_cl, reg_class_contents[cl]);
      AND_HARD_REG_SET (valid_for_cl, regs);
      AND_COMPL_HARD_REG_SET (valid_for_cl,
			      ira_prohibited_class_mode_regs[cl][mode]);
      AND_COMPL_HARD_REG_SET (valid_for_cl, 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)
    {
      COPY_HARD_REG_SET (temp, reg_class_contents[aclass]);
      AND_COMPL_HARD_REG_SET (temp, 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.  */
	      COPY_HARD_REG_SET (temp2, reg_class_contents[cl]);
	      AND_COMPL_HARD_REG_SET (temp2, 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 can not hold a value of MODE.  So the
   pseudo can not 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];

  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;
	}

      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;
		  /* Otherwise, add to the cost of this alternative
		     the cost to copy the other operand to the hard
		     register used for this operand.  */
		  else
		    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:
		      /* 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 (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)
	  {
	    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])];

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

	    for (k = cost_classes_ptr->num - 1; k >= 0; k--)
	      pp_costs[k]
		= MIN (pp_costs[k], (qq_costs[k] + op_cost_add) * scale);
	  }
    }

  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 CC0:
    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 ops[MAX_RECOG_OPERANDS];
  rtx set;
  int i;

  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++)
    {
      memcpy (op_costs[i], init_cost, struct_costs_size);

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

      if (MEM_P (recog_data.operand[i]))
	record_address_regs (GET_MODE (recog_data.operand[i]),
			     MEM_ADDR_SPACE (recog_data.operand[i]),
			     XEXP (recog_data.operand[i], 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);

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

     Also avoid the adjustment if a copy between hard registers of the
     class is expensive (ten times the cost of a default copy is
     considered arbitrarily expensive).  This avoids losing when the
     preferred class is very expensive as the source of a copy
     instruction.  */
  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
      && ops[0] == SET_DEST (set) && ops[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)
	  && find_regno_note (insn, REG_DEAD, REGNO (src))
	  && (((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 (src);
	  cost_classes_t cost_classes_ptr = regno_cost_classes[regno];
	  enum reg_class *cost_classes = cost_classes_ptr->classes;
	  reg_class_t rclass;
	  int k;

	  i = regno == (int) REGNO (src) ? 1 : 0;
	  for (k = cost_classes_ptr->num - 1; k >= 0; k--)
	    {
	      rclass = cost_classes[k];
	      if (TEST_HARD_REG_BIT (reg_class_contents[rclass], other_regno)
		  && (reg_class_size[(int) rclass]
		      == ira_reg_class_max_nregs [(int) rclass][(int) mode]))
		{
		  if (reg_class_size[rclass] == 1)
		    op_costs[i]->cost[k] = -frequency;
		  else if (in_hard_reg_set_p (reg_class_contents[rclass],
					      mode, other_regno))
		    op_costs[i]->cost[k] = -frequency;
		}
	    }
	}
    }
}



/* 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 (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);

  /* Now add the cost for each operand to the total costs for its
     allocno.  */
  for (i = 0; i < recog_data.n_operands; i++)
    if (REG_P (recog_data.operand[i])
	&& REGNO (recog_data.operand[i]) >= FIRST_PSEUDO_REGISTER)
      {
	int regno = REGNO (recog_data.operand[i]);
	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;

	/* 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;
	  }
	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;
	  }
      }

  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 ((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;
      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, rclass;
  machine_mode mode;
  ira_allocno_t a;
  ira_allocno_iterator ai;
  ira_allocno_object_iterator oi;
  ira_object_t obj;
  bool skip_p;
  HARD_REG_SET *crossed_calls_clobber_regs;

  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;
	      rclass = REGNO_REG_CLASS (regno);
	      cost = 0;
	      crossed_calls_clobber_regs
		= &(ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (a));
	      if (ira_hard_reg_set_intersection_p (regno, mode,
						   *crossed_calls_clobber_regs)
		  && (ira_hard_reg_set_intersection_p (regno, mode,
						       call_used_reg_set)
		      || targetm.hard_regno_call_part_clobbered (regno,
								 mode)))
		cost += (ALLOCNO_CALL_FREQ (a)
			 * (ira_memory_move_cost[mode][rclass][0]
			    + ira_memory_move_cost[mode][rclass][1]));
#ifdef IRA_HARD_REGNO_ADD_COST_MULTIPLIER
	      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_c_finalize (void)
{
  this_target_ira_int->free_ira_costs ();
}
