diff gcc/ira-costs.c @ 55:77e2b8dfacca gcc-4.4.5

update it from 4.4.3 to 4.5.0
author ryoma <e075725@ie.u-ryukyu.ac.jp>
date Fri, 12 Feb 2010 23:39:51 +0900
parents 58ad6c70ea60
children b7f97abdc517
line wrap: on
line diff
--- a/gcc/ira-costs.c	Sun Feb 07 18:28:00 2010 +0900
+++ b/gcc/ira-costs.c	Fri Feb 12 23:39:51 2010 +0900
@@ -1,5 +1,5 @@
-/* IRA hard register and memory cost calculation for allocnos.
-   Copyright (C) 2006, 2007, 2008
+/* IRA hard register and memory cost calculation for allocnos or pseudos.
+   Copyright (C) 2006, 2007, 2008, 2009
    Free Software Foundation, Inc.
    Contributed by Vladimir Makarov <vmakarov@redhat.com>.
 
@@ -38,18 +38,25 @@
 #include "params.h"
 #include "ira-int.h"
 
-/* The file contains code is similar to one in regclass but the code
-   works on the allocno basis.  */
+/* 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 arrays `in_inc_dec' and `costs'.  */
+static int cost_elements_num;
 
 #ifdef FORBIDDEN_INC_DEC_CLASSES
-/* Indexed by n, is TRUE if allocno with number N is used in an
-   auto-inc or auto-dec context.  */
+/* Indexed by n, is TRUE if allocno or pseudo with number N is used in
+   an auto-inc or auto-dec context.  */
 static bool *in_inc_dec;
 #endif
 
 /* The `costs' struct records the cost of using hard registers of each
    class considered for the calculation and of using memory for each
-   allocno.  */
+   allocno or pseudo.  */
 struct costs
 {
   int mem_cost;
@@ -74,8 +81,11 @@
 static struct costs *op_costs[MAX_RECOG_OPERANDS];
 static struct costs *this_op_costs[MAX_RECOG_OPERANDS];
 
-/* Original and accumulated costs of each class for each allocno.  */
-static struct costs *allocno_costs, *total_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;
 
 /* Classes used for cost calculation.  They may be different on
    different iterations of the cost calculations or in different
@@ -92,21 +102,26 @@
 /* It is the current size of struct costs.  */
 static int struct_costs_size;
 
-/* Return pointer to structure containing costs of allocno with given
-   NUM in array ARR.  */
-#define COSTS_OF_ALLOCNO(arr, num) \
+/* 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))
 
-/* Record register class preferences of each allocno.  Null value
-   means no preferences.  It happens on the 1st iteration of the cost
-   calculation.  */
-static enum reg_class *allocno_pref;
+/* 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)
 
-/* Allocated buffers for allocno_pref.  */
-static enum reg_class *allocno_pref_buffer;
+/* 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;
 
-/* Record register class of each allocno with the same regno.  */
-static enum reg_class *common_classes;
+/* Allocated buffers for pref.  */
+static enum reg_class *pref_buffer;
+
+/* Record cover register class of each allocno with the same regno.  */
+static enum reg_class *regno_cover_class;
 
 /* Execution frequency of the current insn.  */
 static int frequency;
@@ -189,7 +204,7 @@
 record_reg_classes (int n_alts, int n_ops, rtx *ops,
 		    enum machine_mode *modes, const char **constraints,
 		    rtx insn, struct costs **op_costs,
-		    enum reg_class *allocno_pref)
+		    enum reg_class *pref)
 {
   int alt;
   int i, j, k;
@@ -205,7 +220,7 @@
     {
       enum reg_class classes[MAX_RECOG_OPERANDS];
       int allows_mem[MAX_RECOG_OPERANDS];
-      int rclass;
+      enum reg_class rclass;
       int alt_fail = 0;
       int alt_cost = 0, op_cost_add;
 
@@ -320,12 +335,9 @@
 		     were not in the appropriate class.  We could use
 		     cover class here but it is less accurate
 		     approximation.  */
-		  if (allocno_pref)
+		  if (pref)
 		    {
-		      enum reg_class pref_class
-			= allocno_pref[ALLOCNO_NUM
-				       (ira_curr_regno_allocno_map
-					[REGNO (op)])];
+		      enum reg_class pref_class = pref[COST_INDEX (REGNO (op))];
 
 		      if (pref_class == NO_REGS)
 			alt_cost
@@ -355,7 +367,7 @@
 		  continue;
 		}
 	    }
-	  
+
 	  /* 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
@@ -429,7 +441,7 @@
 		  break;
 
 		case 's':
-		  if (GET_CODE (op) == CONST_INT
+		  if (CONST_INT_P (op)
 		      || (GET_CODE (op) == CONST_DOUBLE
 			  && GET_MODE (op) == VOIDmode))
 		    break;
@@ -441,7 +453,7 @@
 		  break;
 
 		case 'n':
-		  if (GET_CODE (op) == CONST_INT
+		  if (CONST_INT_P (op)
 		      || (GET_CODE (op) == CONST_DOUBLE
 			  && GET_MODE (op) == VOIDmode))
 		    win = 1;
@@ -455,7 +467,7 @@
 		case 'N':
 		case 'O':
 		case 'P':
-		  if (GET_CODE (op) == CONST_INT
+		  if (CONST_INT_P (op)
 		      && CONST_OK_FOR_CONSTRAINT_P (INTVAL (op), c, p))
 		    win = 1;
 		  break;
@@ -564,12 +576,9 @@
 		     were not in the appropriate class.  We could use
 		     cover class here but it is less accurate
 		     approximation.  */
-		  if (allocno_pref)
+		  if (pref)
 		    {
-		      enum reg_class pref_class
-			= allocno_pref[ALLOCNO_NUM
-				       (ira_curr_regno_allocno_map
-					[REGNO (op)])];
+		      enum reg_class pref_class = pref[COST_INDEX (REGNO (op))];
 
 		      if (pref_class == NO_REGS)
 			alt_cost
@@ -637,17 +646,18 @@
 	  }
     }
 
-  for (i = 0; i < n_ops; i++)
-    {
-      ira_allocno_t a;
-      rtx op = ops[i];
+  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;
-    }
+	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;
+      }
 
   /* 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
@@ -672,7 +682,7 @@
 	{
 	  unsigned int regno = REGNO (ops[!i]);
 	  enum machine_mode mode = GET_MODE (ops[!i]);
-	  int rclass;
+	  enum reg_class rclass;
 	  unsigned int nr;
 
 	  if (regno < FIRST_PSEUDO_REGISTER)
@@ -693,7 +703,7 @@
 			  if (! TEST_HARD_REG_BIT (reg_class_contents[rclass],
 						   regno + nr))
 			    break;
-			
+
 			if (nr == (unsigned) hard_regno_nregs[regno][mode])
 			  op_costs[i]->cost[k] = -frequency;
 		      }
@@ -877,8 +887,7 @@
 #ifdef FORBIDDEN_INC_DEC_CLASSES
       if (REG_P (XEXP (x, 0))
 	  && REGNO (XEXP (x, 0)) >= FIRST_PSEUDO_REGISTER)
-	in_inc_dec[ALLOCNO_NUM (ira_curr_regno_allocno_map
-				[REGNO (XEXP (x, 0))])] = true;
+	in_inc_dec[COST_INDEX (REGNO (XEXP (x, 0)))] = true;
 #endif
       record_address_regs (mode, XEXP (x, 0), 0, code, SCRATCH, 2 * scale);
       break;
@@ -886,15 +895,15 @@
     case REG:
       {
 	struct costs *pp;
-	int i, k;
+	enum reg_class i;
+	int k;
 
 	if (REGNO (x) < FIRST_PSEUDO_REGISTER)
 	  break;
 
-	ALLOCNO_BAD_SPILL_P (ira_curr_regno_allocno_map[REGNO (x)]) = true;
-	pp = COSTS_OF_ALLOCNO (allocno_costs,
-			       ALLOCNO_NUM (ira_curr_regno_allocno_map
-					    [REGNO (x)]));
+	if (allocno_p)
+	  ALLOCNO_BAD_SPILL_P (ira_curr_regno_allocno_map[REGNO (x)]) = true;
+	pp = COSTS (costs, COST_INDEX (REGNO (x)));
 	pp->mem_cost += (ira_memory_move_cost[Pmode][rclass][1] * scale) / 2;
 	for (k = 0; k < cost_classes_num; k++)
 	  {
@@ -921,8 +930,7 @@
 
 /* Calculate the costs of insn operands.  */
 static void
-record_operand_costs (rtx insn, struct costs **op_costs,
-		      enum reg_class *allocno_pref)
+record_operand_costs (rtx insn, struct costs **op_costs, enum reg_class *pref)
 {
   const char *constraints[MAX_RECOG_OPERANDS];
   enum machine_mode modes[MAX_RECOG_OPERANDS];
@@ -975,11 +983,11 @@
 	xconstraints[i+1] = constraints[i];
 	record_reg_classes (recog_data.n_alternatives, recog_data.n_operands,
 			    recog_data.operand, modes,
-			    xconstraints, insn, op_costs, allocno_pref);
+			    xconstraints, insn, op_costs, pref);
       }
   record_reg_classes (recog_data.n_alternatives, recog_data.n_operands,
 		      recog_data.operand, modes,
-		      constraints, insn, op_costs, allocno_pref);
+		      constraints, insn, op_costs, pref);
 }
 
 
@@ -994,7 +1002,7 @@
   rtx set, note;
   int i, k;
 
-  if (!INSN_P (insn))
+  if (!NONDEBUG_INSN_P (insn))
     return insn;
 
   pat_code = GET_CODE (PATTERN (insn));
@@ -1014,17 +1022,17 @@
     {
       enum reg_class cl = GENERAL_REGS;
       rtx reg = SET_DEST (set);
-      int num = ALLOCNO_NUM (ira_curr_regno_allocno_map[REGNO (reg)]);
+      int num = COST_INDEX (REGNO (reg));
 
-      if (allocno_pref)
-	cl = allocno_pref[num];
-      COSTS_OF_ALLOCNO (allocno_costs, num)->mem_cost
+      if (pref)
+	cl = pref[num];
+      COSTS (costs, num)->mem_cost
 	-= ira_memory_move_cost[GET_MODE (reg)][cl][1] * frequency;
       record_address_regs (GET_MODE (SET_SRC (set)), XEXP (SET_SRC (set), 0),
 			   0, MEM, SCRATCH, frequency * 2);
     }
 
-  record_operand_costs (insn, op_costs, allocno_pref);
+  record_operand_costs (insn, op_costs, pref);
 
   /* Now add the cost for each operand to the total costs for its
      allocno.  */
@@ -1033,9 +1041,7 @@
 	&& REGNO (recog_data.operand[i]) >= FIRST_PSEUDO_REGISTER)
       {
 	int regno = REGNO (recog_data.operand[i]);
-	struct costs *p
-	  = COSTS_OF_ALLOCNO (allocno_costs,
-			      ALLOCNO_NUM (ira_curr_regno_allocno_map[regno]));
+	struct costs *p = COSTS (costs, COST_INDEX (regno));
 	struct costs *q = op_costs[i];
 
 	p->mem_cost += q->mem_cost;
@@ -1050,12 +1056,13 @@
 
 /* Print allocnos costs to file F.  */
 static void
-print_costs (FILE *f)
+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)
     {
@@ -1084,57 +1091,114 @@
 	      )
 	    {
 	      fprintf (f, " %s:%d", reg_class_names[rclass],
-		       COSTS_OF_ALLOCNO (allocno_costs, i)->cost[k]);
+		       COSTS (costs, i)->cost[k]);
 	      if (flag_ira_region == IRA_REGION_ALL
 		  || flag_ira_region == IRA_REGION_MIXED)
-		fprintf (f, ",%d", COSTS_OF_ALLOCNO (total_costs, i)->cost[k]);
+		fprintf (f, ",%d", COSTS (total_allocno_costs, i)->cost[k]);
 	    }
 	}
-      fprintf (f, " MEM:%i\n", COSTS_OF_ALLOCNO (allocno_costs, i)->mem_cost);
+      fprintf (f, " MEM:%i\n", COSTS (costs, i)->mem_cost);
     }
 }
 
+/* Print pseudo costs to file F.  */
+static void
+print_pseudo_costs (FILE *f)
+{
+  int regno, k;
+  int rclass;
+
+  ira_assert (! allocno_p);
+  fprintf (f, "\n");
+  for (regno = max_reg_num () - 1; regno >= FIRST_PSEUDO_REGISTER; regno--)
+    {
+      if (regno_reg_rtx[regno] == NULL_RTX)
+	continue;
+      fprintf (f, "  r%d costs:", regno);
+      for (k = 0; k < cost_classes_num; k++)
+	{
+	  rclass = cost_classes[k];
+	  if (contains_reg_of_mode[rclass][PSEUDO_REGNO_MODE (regno)]
+#ifdef FORBIDDEN_INC_DEC_CLASSES
+	      && (! in_inc_dec[regno] || ! forbidden_inc_dec_class[rclass])
+#endif
+#ifdef CANNOT_CHANGE_MODE_CLASS
+	      && ! invalid_mode_change_p (regno, (enum reg_class) rclass,
+					  PSEUDO_REGNO_MODE (regno))
+#endif
+	      )
+	    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;
+
+  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;
-  rtx insn;
 
   bb = loop_tree_node->bb;
-  if (bb == NULL)
-    return;
-  frequency = REG_FREQ_FROM_BB (bb);
-  if (frequency == 0)
-    frequency = 1;
-  FOR_BB_INSNS (bb, insn)
-    insn = scan_one_insn (insn);
+  if (bb != NULL)
+    process_bb_for_costs (bb);
 }
 
-/* Find costs of register classes and memory for allocnos and their
-   best costs. */
+/* Find costs of register classes and memory for allocnos or pseudos
+   and their best costs.  Set up preferred, alternative and cover
+   classes for pseudos.  */
 static void
-find_allocno_class_costs (void)
+find_costs_and_classes (FILE *dump_file)
 {
-  int i, k;
+  int i, k, start;
   int pass;
   basic_block bb;
 
   init_recog ();
 #ifdef FORBIDDEN_INC_DEC_CLASSES
-  in_inc_dec = ira_allocate (sizeof (bool) * ira_allocnos_num);
+  in_inc_dec = ira_allocate (sizeof (bool) * cost_elements_num);
 #endif /* FORBIDDEN_INC_DEC_CLASSES */
-  allocno_pref = NULL;
+  pref = NULL;
+  start = 0;
+  if (!resize_reg_info () && allocno_p && pseudo_classes_defined_p)
+    {
+      ira_allocno_t a;
+      ira_allocno_iterator ai;
+
+      pref = pref_buffer;
+      FOR_EACH_ALLOCNO (a, ai)
+	pref[ALLOCNO_NUM (a)] = reg_preferred_class (ALLOCNO_REGNO (a));
+      if (flag_expensive_optimizations)
+	start = 1;
+    }
+  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 = 0; pass <= flag_expensive_optimizations; pass++)
+  for (pass = start; pass <= flag_expensive_optimizations; pass++)
     {
-      if (internal_flag_ira_verbose > 0 && ira_dump_file)
-	fprintf (ira_dump_file, "\nPass %i for finding allocno costs\n\n",
-		 pass);
+      if ((!allocno_p || internal_flag_ira_verbose > 0) && dump_file)
+	fprintf (dump_file,
+		 "\nPass %i for finding pseudo/allocno costs\n\n", pass);
       /* We could use only cover classes.  Unfortunately it does not
 	 work well for some targets where some subclass of cover class
 	 is costly and wrong cover class is chosen.  */
@@ -1153,20 +1217,31 @@
 	= sizeof (struct costs) + sizeof (int) * (cost_classes_num - 1);
       /* Zero out our accumulation of the cost of each class for each
 	 allocno.  */
-      memset (allocno_costs, 0, ira_allocnos_num * struct_costs_size);
+      memset (costs, 0, cost_elements_num * struct_costs_size);
 #ifdef FORBIDDEN_INC_DEC_CLASSES
-      memset (in_inc_dec, 0, ira_allocnos_num * sizeof (bool));
+      memset (in_inc_dec, 0, cost_elements_num * sizeof (bool));
 #endif
 
-      /* 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);
+      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_costs, allocno_costs,
-	      max_struct_costs_size * ira_allocnos_num);
+	  memcpy (total_allocno_costs, costs,
+		  max_struct_costs_size * ira_allocnos_num);
+	}
+      else
+	{
+	  basic_block bb;
+
+	  FOR_EACH_BB (bb)
+	    process_bb_for_costs (bb);
+	}
+
       if (pass == 0)
-	allocno_pref = allocno_pref_buffer;
+	pref = pref_buffer;
 
       /* Now for each allocno look at how desirable each class is and
 	 find which class is preferred.  */
@@ -1181,41 +1256,52 @@
 	  int inc_dec_p = false;
 #endif
 
-	  if (ira_regno_allocno_map[i] == NULL)
-	    continue;
-	  memset (temp_costs, 0, struct_costs_size);
-	  /* Find cost of all allocnos with the same regno.  */
-	  for (a = ira_regno_allocno_map[i];
-	       a != NULL;
-	       a = ALLOCNO_NEXT_REGNO_ALLOCNO (a))
+	  if (! allocno_p)
 	    {
-	      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)))
+	      if (regno_reg_rtx[i] == NULL_RTX)
+		continue;
+#ifdef FORBIDDEN_INC_DEC_CLASSES
+	      inc_dec_p = in_inc_dec[i];
+#endif
+	      memcpy (temp_costs, COSTS (costs, i), struct_costs_size);
+	    }
+	  else
+	    {
+	      if (ira_regno_allocno_map[i] == NULL)
+		continue;
+	      memset (temp_costs, 0, struct_costs_size);
+	      /* Find cost of all allocnos with the same regno.  */
+	      for (a = ira_regno_allocno_map[i];
+		   a != NULL;
+		   a = ALLOCNO_NEXT_REGNO_ALLOCNO (a))
 		{
-		  /* Propagate costs to upper levels in the region
-		     tree.  */
-		  parent_a_num = ALLOCNO_NUM (parent_a);
+		  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);
+		      for (k = 0; k < cost_classes_num; k++)
+			COSTS (total_allocno_costs, parent_a_num)->cost[k]
+			  += COSTS (total_allocno_costs, a_num)->cost[k];
+		      COSTS (total_allocno_costs, parent_a_num)->mem_cost
+			+= COSTS (total_allocno_costs, a_num)->mem_cost;
+		    }
 		  for (k = 0; k < cost_classes_num; k++)
-		    COSTS_OF_ALLOCNO (total_costs, parent_a_num)->cost[k]
-		      += COSTS_OF_ALLOCNO (total_costs, a_num)->cost[k];
-		  COSTS_OF_ALLOCNO (total_costs, parent_a_num)->mem_cost
-		    += COSTS_OF_ALLOCNO (total_costs, a_num)->mem_cost;
+		    temp_costs->cost[k] += COSTS (costs, a_num)->cost[k];
+		  temp_costs->mem_cost += COSTS (costs, a_num)->mem_cost;
+#ifdef FORBIDDEN_INC_DEC_CLASSES
+		  if (in_inc_dec[a_num])
+		    inc_dec_p = true;
+#endif
 		}
-	      for (k = 0; k < cost_classes_num; k++)
-		temp_costs->cost[k]
-		  += COSTS_OF_ALLOCNO (allocno_costs, a_num)->cost[k];
-	      temp_costs->mem_cost
-		+= COSTS_OF_ALLOCNO (allocno_costs, a_num)->mem_cost;
-#ifdef FORBIDDEN_INC_DEC_CLASSES
-	      if (in_inc_dec[a_num])
-		inc_dec_p = true;
-#endif
 	    }
 	  best_cost = (1 << (HOST_BITS_PER_INT - 2)) - 1;
 	  best = ALL_REGS;
@@ -1251,38 +1337,45 @@
 		alt_class = reg_class_subunion[alt_class][rclass];
 	    }
 	  alt_class = ira_class_translate[alt_class];
+	  if (best_cost > temp_costs->mem_cost)
+	    regno_cover_class[i] = NO_REGS;
+	  else if (flag_ira_algorithm == IRA_ALGORITHM_PRIORITY)
+	    /* Make the common class the biggest class of best and
+	       alt_class.  */
+	    regno_cover_class[i] = alt_class == NO_REGS ? best : alt_class;
+	  else
+	    /* Make the common class a cover class.  Remember all
+	       allocnos with the same regno should have the same cover
+	       class.  */
+	    regno_cover_class[i] = ira_class_translate[best];
 	  if (pass == flag_expensive_optimizations)
 	    {
 	      if (best_cost > temp_costs->mem_cost)
 		best = alt_class = NO_REGS;
 	      else if (best == alt_class)
 		alt_class = NO_REGS;
-	      setup_reg_classes (i, best, alt_class);
-	      if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
-		fprintf (ira_dump_file,
-			 "    r%d: preferred %s, alternative %s\n",
-			 i, reg_class_names[best], reg_class_names[alt_class]);
+	      setup_reg_classes (i, best, alt_class, regno_cover_class[i]);
+	      if ((!allocno_p || internal_flag_ira_verbose > 2)
+		  && dump_file != NULL)
+		fprintf (dump_file,
+			 "    r%d: preferred %s, alternative %s, cover %s\n",
+			 i, reg_class_names[best], reg_class_names[alt_class],
+			 reg_class_names[regno_cover_class[i]]);
 	    }
-	  if (best_cost > temp_costs->mem_cost)
-	    common_classes[i] = NO_REGS;
-	  else if (flag_ira_algorithm == IRA_ALGORITHM_PRIORITY)
-	    /* Make the common class the biggest class of best and
-	       alt_class.  */
-	    common_classes[i] = alt_class == NO_REGS ? best : alt_class;
-	  else
-	    /* Make the common class a cover class.  Remember all
-	       allocnos with the same regno should have the same cover
-	       class.  */
-	    common_classes[i] = ira_class_translate[best];
+	  if (! allocno_p)
+	    {
+	      pref[i] = best_cost > temp_costs->mem_cost ? NO_REGS : best;
+	      continue;
+	    }
 	  for (a = ira_regno_allocno_map[i];
 	       a != NULL;
 	       a = ALLOCNO_NEXT_REGNO_ALLOCNO (a))
 	    {
 	      a_num = ALLOCNO_NUM (a);
-	      if (common_classes[i] == NO_REGS)
+	      if (regno_cover_class[i] == 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;
@@ -1291,7 +1384,7 @@
 		  for (k = 0; k < cost_classes_num; k++)
 		    {
 		      rclass = cost_classes[k];
-		      if (! ira_class_subset_p[rclass][common_classes[i]])
+		      if (! ira_class_subset_p[rclass][regno_cover_class[i]])
 			continue;
 		      /* Ignore classes that are too small for this
 			 operand or invalid for an operand that was
@@ -1306,50 +1399,50 @@
 #endif
 			  )
 			;
-		      else if (COSTS_OF_ALLOCNO (total_costs, a_num)->cost[k]
+		      else if (COSTS (total_allocno_costs, a_num)->cost[k]
 			       < best_cost)
 			{
 			  best_cost
-			    = COSTS_OF_ALLOCNO (total_costs, a_num)->cost[k];
-			  allocno_cost
-			    = COSTS_OF_ALLOCNO (allocno_costs, a_num)->cost[k];
+			    = COSTS (total_allocno_costs, a_num)->cost[k];
+			  allocno_cost = COSTS (costs, a_num)->cost[k];
 			  best = (enum reg_class) rclass;
 			}
-		      else if (COSTS_OF_ALLOCNO (total_costs, a_num)->cost[k]
+		      else if (COSTS (total_allocno_costs, a_num)->cost[k]
 			       == best_cost)
 			{
 			  best = ira_reg_class_union[best][rclass];
 			  allocno_cost
-			    = MAX (allocno_cost,
-				   COSTS_OF_ALLOCNO (allocno_costs,
-						     a_num)->cost[k]);
+			    = MAX (allocno_cost, COSTS (costs, a_num)->cost[k]);
 			}
 		    }
 		  ALLOCNO_COVER_CLASS_COST (a) = allocno_cost;
 		}
 	      ira_assert (flag_ira_algorithm == IRA_ALGORITHM_PRIORITY
-			  || ira_class_translate[best] == common_classes[i]);
-	      if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL
-		  && (pass == 0 || allocno_pref[a_num] != best))
+			  || ira_class_translate[best] == regno_cover_class[i]);
+	      if (internal_flag_ira_verbose > 2 && dump_file != NULL
+		  && (pass == 0 || pref[a_num] != best))
 		{
-		  fprintf (ira_dump_file, "    a%d (r%d,", a_num, i);
+		  fprintf (dump_file, "    a%d (r%d,", a_num, i);
 		  if ((bb = ALLOCNO_LOOP_TREE_NODE (a)->bb) != NULL)
-		    fprintf (ira_dump_file, "b%d", bb->index);
+		    fprintf (dump_file, "b%d", bb->index);
 		  else
-		    fprintf (ira_dump_file, "l%d",
+		    fprintf (dump_file, "l%d",
 			     ALLOCNO_LOOP_TREE_NODE (a)->loop->num);
-		  fprintf (ira_dump_file, ") best %s, cover %s\n",
+		  fprintf (dump_file, ") best %s, cover %s\n",
 			   reg_class_names[best],
-			   reg_class_names[common_classes[i]]);
+			   reg_class_names[regno_cover_class[i]]);
 		}
-	      allocno_pref[a_num] = best;
+	      pref[a_num] = best;
 	    }
 	}
-      
-      if (internal_flag_ira_verbose > 4 && ira_dump_file)
+
+      if (internal_flag_ira_verbose > 4 && dump_file)
 	{
-	  print_costs (ira_dump_file);
-	  fprintf (ira_dump_file,"\n");
+	  if (allocno_p)
+	    print_allocno_costs (dump_file);
+	  else
+	    print_pseudo_costs (dump_file);
+	  fprintf (dump_file,"\n");
 	}
     }
 #ifdef FORBIDDEN_INC_DEC_CLASSES
@@ -1383,7 +1476,7 @@
     freq = 1;
   FOR_BB_INSNS (bb, insn)
     {
-      if (! INSN_P (insn))
+      if (!NONDEBUG_INSN_P (insn))
 	continue;
       set = single_set (insn);
       if (set == NULL_RTX)
@@ -1441,24 +1534,21 @@
   int i, j, n, regno, num;
   int *reg_costs;
   enum reg_class cover_class, rclass;
-  enum machine_mode mode;
-  HARD_REG_SET *pref;
   ira_allocno_t a;
   ira_allocno_iterator ai;
 
+  ira_assert (allocno_p);
   FOR_EACH_ALLOCNO (a, ai)
     {
       i = ALLOCNO_NUM (a);
-      mode = ALLOCNO_MODE (a);
-      cover_class = common_classes[ALLOCNO_REGNO (a)];
-      ira_assert (allocno_pref[i] == NO_REGS || cover_class != NO_REGS);
-      ALLOCNO_MEMORY_COST (a) = COSTS_OF_ALLOCNO (allocno_costs, i)->mem_cost;
+      cover_class = regno_cover_class[ALLOCNO_REGNO (a)];
+      ira_assert (pref[i] == NO_REGS || cover_class != NO_REGS);
+      ALLOCNO_MEMORY_COST (a) = COSTS (costs, i)->mem_cost;
       ira_set_allocno_cover_class (a, cover_class);
       if (cover_class == NO_REGS)
 	continue;
       ALLOCNO_AVAILABLE_REGS_NUM (a) = ira_available_class_regs[cover_class];
-      pref = &reg_class_contents[allocno_pref[i]];
-      if (optimize && ALLOCNO_COVER_CLASS (a) != allocno_pref[i])
+      if (optimize && ALLOCNO_COVER_CLASS (a) != pref[i])
 	{
 	  n = ira_class_hard_regs_num[cover_class];
 	  ALLOCNO_HARD_REG_COSTS (a)
@@ -1466,7 +1556,7 @@
 	  for (j = n - 1; j >= 0; j--)
 	    {
 	      regno = ira_class_hard_regs[cover_class][j];
-	      if (TEST_HARD_REG_BIT (*pref, regno))
+	      if (TEST_HARD_REG_BIT (reg_class_contents[pref[i]], regno))
 		reg_costs[j] = ALLOCNO_COVER_CLASS_COST (a);
 	      else
 		{
@@ -1481,7 +1571,7 @@
 				  == cover_class);
 		      num = cost_class_nums[cover_class];
 		    }
-		  reg_costs[j] = COSTS_OF_ALLOCNO (allocno_costs, i)->cost[num];
+		  reg_costs[j] = COSTS (costs, i)->cost[num];
 		}
 	    }
 	}
@@ -1568,27 +1658,59 @@
 
 
 
+/* 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_cover_class
+    = (enum reg_class *) ira_allocate (sizeof (enum reg_class)
+				       * max_reg_num ());
+}
+
+/* Common finalization function for ira_costs and
+   ira_set_pseudo_classes.  */
+static void
+finish_costs (void)
+{
+  ira_free (regno_cover_class);
+  ira_free (pref_buffer);
+  ira_free (costs);
+}
+
 /* Entry function which defines cover class, memory and hard register
    costs for each allocno.  */
 void
 ira_costs (void)
 {
-  allocno_costs = (struct costs *) ira_allocate (max_struct_costs_size
-					       * ira_allocnos_num);
-  total_costs = (struct costs *) ira_allocate (max_struct_costs_size
-					       * ira_allocnos_num);
-  allocno_pref_buffer
-    = (enum reg_class *) ira_allocate (sizeof (enum reg_class)
-				       * ira_allocnos_num);
-  common_classes
-    = (enum reg_class *) ira_allocate (sizeof (enum reg_class)
-				       * max_reg_num ());
-  find_allocno_class_costs ();
+  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);
+  find_costs_and_classes (ira_dump_file);
   setup_allocno_cover_class_and_costs ();
-  ira_free (common_classes);
-  ira_free (allocno_pref_buffer);
-  ira_free (total_costs);
-  ira_free (allocno_costs);
+  finish_costs ();
+  ira_free (total_allocno_costs);
+}
+
+/* Entry function which defines classes for pseudos.  */
+void
+ira_set_pseudo_classes (FILE *dump_file)
+{
+  allocno_p = false;
+  internal_flag_ira_verbose = flag_ira_verbose;
+  cost_elements_num = max_reg_num ();
+  init_costs ();
+  find_costs_and_classes (dump_file);
+  pseudo_classes_defined_p = true;
+  finish_costs ();
 }