diff gcc/ira-costs.c @ 67:f6334be47118

update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
author nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
date Tue, 22 Mar 2011 17:18:12 +0900
parents b7f97abdc517
children 04ced10e8804
line wrap: on
line diff
--- a/gcc/ira-costs.c	Tue May 25 18:58:51 2010 +0900
+++ b/gcc/ira-costs.c	Tue Mar 22 17:18:12 2011 +0900
@@ -1,5 +1,5 @@
 /* IRA hard register and memory cost calculation for allocnos or pseudos.
-   Copyright (C) 2006, 2007, 2008, 2009
+   Copyright (C) 2006, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
    Contributed by Vladimir Makarov <vmakarov@redhat.com>.
 
@@ -33,7 +33,8 @@
 #include "addresses.h"
 #include "insn-config.h"
 #include "recog.h"
-#include "toplev.h"
+#include "reload.h"
+#include "diagnostic-core.h"
 #include "target.h"
 #include "params.h"
 #include "ira-int.h"
@@ -66,20 +67,18 @@
   int cost[1];
 };
 
-/* Initialized once.  It is a maximal possible size of the allocated
-   struct costs.  */
-static int max_struct_costs_size;
-
-/* Allocated and initialized once, and used to initialize cost values
-   for each insn.  */
-static struct costs *init_cost;
-
-/* Allocated once, and used for temporary purposes.  */
-static struct costs *temp_costs;
-
-/* Allocated once, and used for the cost calculation.  */
-static struct costs *op_costs[MAX_RECOG_OPERANDS];
-static struct costs *this_op_costs[MAX_RECOG_OPERANDS];
+#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)
+#define cost_classes \
+  (this_target_ira_int->x_cost_classes)
 
 /* Costs of each class for each allocno or pseudo.  */
 static struct costs *costs;
@@ -87,11 +86,6 @@
 /* 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
-   optimization modes.  */
-static enum reg_class *cost_classes;
-
 /* The size of the previous array.  */
 static int cost_classes_num;
 
@@ -123,6 +117,10 @@
 /* Record cover register class of each allocno with the same regno.  */
 static enum reg_class *regno_cover_class;
 
+/* 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;
 
@@ -132,11 +130,11 @@
    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, enum machine_mode mode, enum reg_class rclass, bool to_p,
+copy_cost (rtx x, enum machine_mode mode, reg_class_t rclass, bool to_p,
 	   secondary_reload_info *prev_sri)
 {
   secondary_reload_info sri;
-  enum reg_class secondary_class = NO_REGS;
+  reg_class_t secondary_class = NO_REGS;
 
   /* If X is a SCRATCH, there is actually nothing to move since we are
      assuming optimal allocation.  */
@@ -144,7 +142,7 @@
     return 0;
 
   /* Get the class we will actually use for a reload.  */
-  rclass = PREFERRED_RELOAD_CLASS (x, rclass);
+  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
@@ -157,7 +155,8 @@
     {
       if (!move_cost[mode])
         init_move_cost (mode);
-      return (move_cost[mode][secondary_class][rclass] + sri.extra_cost
+      return (move_cost[mode][(int) secondary_class][(int) rclass]
+	      + sri.extra_cost
 	      + copy_cost (x, mode, secondary_class, to_p, &sri));
     }
 
@@ -165,12 +164,14 @@
      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][rclass][to_p != 0];
+    return sri.extra_cost
+	   + ira_memory_move_cost[mode][(int) rclass][to_p != 0];
   else if (REG_P (x))
     {
       if (!move_cost[mode])
         init_move_cost (mode);
-      return (sri.extra_cost + move_cost[mode][REGNO_REG_CLASS (REGNO (x))][rclass]);
+      return (sri.extra_cost
+	      + move_cost[mode][REGNO_REG_CLASS (REGNO (x))][(int) rclass]);
     }
   else
     /* If this is a constant, we may eventually want to call rtx_cost
@@ -203,8 +204,7 @@
 static void
 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 *pref)
+		    rtx insn, enum reg_class *pref)
 {
   int alt;
   int i, j, k;
@@ -938,7 +938,7 @@
 
 /* Calculate the costs of insn operands.  */
 static void
-record_operand_costs (rtx insn, struct costs **op_costs, enum reg_class *pref)
+record_operand_costs (rtx insn, enum reg_class *pref)
 {
   const char *constraints[MAX_RECOG_OPERANDS];
   enum machine_mode modes[MAX_RECOG_OPERANDS];
@@ -991,11 +991,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, pref);
+			    xconstraints, insn, pref);
       }
   record_reg_classes (recog_data.n_alternatives, recog_data.n_operands,
 		      recog_data.operand, modes,
-		      constraints, insn, op_costs, pref);
+		      constraints, insn, pref);
 }
 
 
@@ -1040,7 +1040,7 @@
 			   0, MEM, SCRATCH, frequency * 2);
     }
 
-  record_operand_costs (insn, op_costs, pref);
+  record_operand_costs (insn, pref);
 
   /* Now add the cost for each operand to the total costs for its
      allocno.  */
@@ -1093,8 +1093,7 @@
 	      && (! in_inc_dec[i] || ! forbidden_inc_dec_class[rclass])
 #endif
 #ifdef CANNOT_CHANGE_MODE_CLASS
-	      && ! invalid_mode_change_p (regno, (enum reg_class) rclass,
-					  PSEUDO_REGNO_MODE (regno))
+	      && ! invalid_mode_change_p (regno, (enum reg_class) rclass)
 #endif
 	      )
 	    {
@@ -1131,8 +1130,7 @@
 	      && (! 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))
+	      && ! invalid_mode_change_p (regno, (enum reg_class) rclass)
 #endif
 	      )
 	    fprintf (f, " %s:%d", reg_class_names[rclass],
@@ -1263,6 +1261,7 @@
 #ifdef FORBIDDEN_INC_DEC_CLASSES
 	  int inc_dec_p = false;
 #endif
+	  int equiv_savings = regno_equiv_gains[i];
 
 	  if (! allocno_p)
 	    {
@@ -1311,6 +1310,15 @@
 #endif
 		}
 	    }
+	  if (equiv_savings < 0)
+	    temp_costs->mem_cost = -equiv_savings;
+	  else if (equiv_savings > 0)
+	    {
+	      temp_costs->mem_cost = 0;
+	      for (k = 0; k < cost_classes_num; k++)
+		temp_costs->cost[k] += equiv_savings;
+	    }
+
 	  best_cost = (1 << (HOST_BITS_PER_INT - 2)) - 1;
 	  best = ALL_REGS;
 	  alt_class = NO_REGS;
@@ -1326,8 +1334,7 @@
 		  || (inc_dec_p && forbidden_inc_dec_class[rclass])
 #endif
 #ifdef CANNOT_CHANGE_MODE_CLASS
-		  || invalid_mode_change_p (i, (enum reg_class) rclass,
-					    PSEUDO_REGNO_MODE (i))
+		  || invalid_mode_change_p (i, (enum reg_class) rclass)
 #endif
 		  )
 		continue;
@@ -1402,8 +1409,7 @@
 			  || (inc_dec_p && forbidden_inc_dec_class[rclass])
 #endif
 #ifdef CANNOT_CHANGE_MODE_CLASS
-			  || invalid_mode_change_p (i, (enum reg_class) rclass,
-						    PSEUDO_REGNO_MODE (i))
+			  || invalid_mode_change_p (i, (enum reg_class) rclass)
 #endif
 			  )
 			;
@@ -1680,6 +1686,8 @@
   regno_cover_class
     = (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
@@ -1687,6 +1695,8 @@
 static void
 finish_costs (void)
 {
+  finish_subregs_of_mode ();
+  ira_free (regno_equiv_gains);
   ira_free (regno_cover_class);
   ira_free (pref_buffer);
   ira_free (costs);
@@ -1702,6 +1712,7 @@
   init_costs ();
   total_allocno_costs = (struct costs *) ira_allocate (max_struct_costs_size
 						       * ira_allocnos_num);
+  calculate_elim_costs_all_insns ();
   find_costs_and_classes (ira_dump_file);
   setup_allocno_cover_class_and_costs ();
   finish_costs ();
@@ -1774,15 +1785,14 @@
       if (min_cost != INT_MAX)
 	ALLOCNO_COVER_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.  */
+      /* 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.  */
       {
-	int nregs, index;
+	const int nregs = ira_reg_class_nregs[cover_class][ALLOCNO_MODE (a)];
 
-	if ((nregs = ira_reg_class_nregs[cover_class][ALLOCNO_MODE (a)]) > 1)
+	if (nregs > 1)
 	  {
 	    ira_allocate_and_set_costs
 	      (&ALLOCNO_HARD_REG_COSTS (a), cover_class,
@@ -1790,10 +1800,10 @@
 	    reg_costs = ALLOCNO_HARD_REG_COSTS (a);
 	    for (j = n - 1; j >= 0; j--)
 	      {
-		if (j % nregs != 0)
+		regno = ira_non_ordered_class_hard_regs[cover_class][j];
+		if ((regno % nregs) != 0)
 		  {
-		    regno = ira_non_ordered_class_hard_regs[cover_class][j];
-		    index = ira_class_hard_reg_index[cover_class][regno];
+		    int index = ira_class_hard_reg_index[cover_class][regno];
 		    ira_assert (index != -1);
 		    reg_costs[index] += ALLOCNO_FREQ (a);
 		  }
@@ -1802,3 +1812,16 @@
       }
     }
 }
+
+/* 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;
+}