diff mbox

[ira-improv] patch to fix some branch problems

Message ID 4C1A8874.7090203@redhat.com
State New
Headers show

Commit Message

Vladimir Makarov June 17, 2010, 8:41 p.m. UTC
The following patch fixes the branch compiler crashes on bootstrap (in 
debug mode) and on SPEC2006 gamess.  The problem was in wrong integer 
overflow check code and assertion became wrong after making cost 
calculation classes are specific for each pseudo.

Committed as revision 160946.

2010-06-16  Vladimir Makarov  <vmakarov@redhat.com>

    * ira.c (ira_class_hard_regs_num): Fix the comment.

    * ira-costs.c (struct cost_classes): New member hard_regno_index.
    (setup_cost_classes): New.
    (setup_regno_cost_classes_by_aclass): Call setup_cost_classes.
    (setup_regno_cost_classes_by_mode): Ditto.
    (record_address_regs): Fix overflow code.
    (scan_one_insn): Ditto.
    (find_costs_and_classes): Ditto.  Move setting cost classes to the
    loop start.
    (setup_allocno_class_and_costs): Use member hard_regno_index.
    (ira_tune_allocno_costs): Fix overflow code.
diff mbox

Patch

Index: ira.c
===================================================================
--- ira.c	(revision 160634)
+++ ira.c	(working copy)
@@ -461,7 +461,7 @@  short ira_class_hard_regs[N_REG_CLASSES]
    the hard register numbers.  */
 short ira_non_ordered_class_hard_regs[N_REG_CLASSES][FIRST_PSEUDO_REGISTER];
 
-/* The number of elements of the above array for given register
+/* The number of elements of the two above arrays for given register
    class.  */
 int ira_class_hard_regs_num[N_REG_CLASSES];
 
Index: ira-costs.c
===================================================================
--- ira-costs.c	(revision 160634)
+++ ira-costs.c	(working copy)
@@ -125,6 +125,9 @@  struct cost_classes
   /* Map reg class -> index of the reg class in the previous array.
      -1 if it is not a cost classe.  */
   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.  */
@@ -187,6 +190,35 @@  initiate_regno_cost_classes (void)
     = htab_create (200, cost_classes_hash, cost_classes_eq, cost_classes_del);
 }
 
+/* Create new classes from FROM and set up memebrs index and
+   hard_regno_index.  Return the new classes.  */
+static cost_classes_t
+setup_cost_classes (cost_classes_t from)
+{
+  cost_classes_t classes_ptr;
+  enum reg_class cl;
+  int i, j, hard_regno;
+
+  classes_ptr = (cost_classes_t) ira_allocate (sizeof (struct cost_classes));
+  classes_ptr->num = from->num;
+  for (i = 0; i < N_REG_CLASSES; i++)
+    classes_ptr->index[i] = -1;
+  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+    classes_ptr->hard_regno_index[i] = -1;
+  for (i = 0; i < from->num; i++)
+    {
+      cl = classes_ptr->classes[i] = from->classes[i];
+      classes_ptr->index[cl] = i;
+      for (j = ira_class_hard_regs_num[cl] - 1; j >= 0; j--)
+	{
+	  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;
+	}
+    }
+  return classes_ptr;
+}
+
 /* Setup cost classes for REGNO whose allocno class ACLASS.  */
 static void
 setup_regno_cost_classes_by_aclass (int regno, enum reg_class aclass)
@@ -216,16 +248,7 @@  setup_regno_cost_classes_by_aclass (int 
       slot = htab_find_slot (cost_classes_htab, &classes, INSERT);
       if (*slot == NULL)
 	{
-	  classes_ptr
-	    = (cost_classes_t) ira_allocate (sizeof (struct cost_classes));
-	  classes_ptr->num = classes.num;
-	  for (i = 0; i < N_REG_CLASSES; i++)
-	    classes_ptr->index[i] = -1;
-	  for (i = 0; i < classes.num; i++)
-	    {
-	      cl = classes_ptr->classes[i] = classes.classes[i];
-	      classes_ptr->index[cl] = i;
-	    }
+	  classes_ptr = setup_cost_classes (&classes);
 	  *slot = classes_ptr;
 	}
       cost_classes_aclass_cache[aclass] = (cost_classes_t) *slot;
@@ -259,16 +282,7 @@  setup_regno_cost_classes_by_mode (int re
       slot = htab_find_slot (cost_classes_htab, &classes, INSERT);
       if (*slot == NULL)
 	{
-	  classes_ptr
-	    = (cost_classes_t) ira_allocate (sizeof (struct cost_classes));
-	  classes_ptr->num = classes.num;
-	  for (i = 0; i < N_REG_CLASSES; i++)
-	    classes_ptr->index[i] = -1;
-	  for (i = 0; i < classes.num; i++)
-	    {
-	      cl = classes_ptr->classes[i] = classes.classes[i];
-	      classes_ptr->index[cl] = i;
-	    }
+	  classes_ptr = setup_cost_classes (&classes);
 	  *slot = classes_ptr;
 	}
       cost_classes_mode_cache[mode] = (cost_classes_t) *slot;
@@ -1114,8 +1128,7 @@  record_address_regs (enum machine_mode m
 	struct costs *pp;
 	int *pp_costs;
 	enum reg_class i;
-	int k, regno;
-	bool plus_p;
+	int k, regno, add_cost;
 	cost_classes_t cost_classes_ptr;
 	enum reg_class *cost_classes;
 	move_table *move_in_cost;
@@ -1126,10 +1139,11 @@  record_address_regs (enum machine_mode m
 	if (allocno_p)
 	  ALLOCNO_BAD_SPILL_P (ira_curr_regno_allocno_map[regno]) = true;
 	pp = COSTS (costs, COST_INDEX (regno));
-	plus_p = pp->mem_cost > 0;
-	pp->mem_cost += (ira_memory_move_cost[Pmode][rclass][1] * scale) / 2;
-	if (pp->mem_cost < 0 && plus_p)
+	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;
@@ -1138,10 +1152,11 @@  record_address_regs (enum machine_mode m
 	for (k = cost_classes_ptr->num - 1; k >= 0; k--)
 	  {
 	    i = cost_classes[k];
-	    plus_p = pp_costs[k] > 0;
-	    pp_costs[k] += (move_in_cost[i][rclass] * scale) / 2;
-	    if (pp_costs[k] < 0 && plus_p)
+	    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;
@@ -1274,18 +1289,20 @@  scan_one_insn (rtx insn)
 	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];
-	bool plus_p;
+	int add_cost;
 
-	plus_p = p->mem_cost > 0 && q->mem_cost > 0;
-	p->mem_cost += q->mem_cost;
-	if (p->mem_cost < 0 && plus_p)
+	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--)
 	  {
-	    plus_p = p_costs[k] > 0 && q_costs[k] > 0;
-	    p_costs[k] += q_costs[k];
-	    if (p_costs[k] < 0 && plus_p)
+	    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;
 	  }
       }
 
@@ -1419,13 +1436,17 @@  find_costs_and_classes (FILE *dump_file)
   int i, k, start, max_cost_classes_num;
   int pass;
   basic_block bb;
-  enum reg_class pref_cl;
+  enum reg_class *regno_best_class;
 
   init_recog ();
 #ifdef FORBIDDEN_INC_DEC_CLASSES
   in_inc_dec = ira_allocate (sizeof (bool) * cost_elements_num);
 #endif /* FORBIDDEN_INC_DEC_CLASSES */
-
+  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)
     {
@@ -1468,6 +1489,18 @@  find_costs_and_classes (FILE *dump_file)
       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
@@ -1477,7 +1510,6 @@  find_costs_and_classes (FILE *dump_file)
       memset (in_inc_dec, 0, cost_elements_num * sizeof (bool));
 #endif
 
-      max_cost_classes_num = 1;
       if (allocno_p)
 	{
 	  /* Scan the instructions and record each time it would save code
@@ -1504,14 +1536,13 @@  find_costs_and_classes (FILE *dump_file)
       for (i = max_reg_num () - 1; i >= FIRST_PSEUDO_REGISTER; i--)
 	{
 	  ira_allocno_t a, parent_a;
-	  int rclass, a_num, parent_a_num;
+	  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;
 #ifdef FORBIDDEN_INC_DEC_CLASSES
 	  int inc_dec_p = false;
 #endif
-	  bool plus_p;
 	  cost_classes_t cost_classes_ptr = regno_cost_classes[i];
 	  enum reg_class *cost_classes = cost_classes_ptr->classes;
 	  int *i_costs = temp_costs->cost;
@@ -1557,34 +1588,38 @@  find_costs_and_classes (FILE *dump_file)
 		      p_costs = COSTS (total_allocno_costs, parent_a_num)->cost;
 		      for (k = cost_classes_ptr->num - 1; k >= 0; k--)
 			{
-			  plus_p = p_costs[k] > 0 && a_costs[k] > 0;
-			  p_costs[k] += a_costs[k];
-			  if (p_costs[k] < 0 && plus_p)
+			  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;
 			}
-		      plus_p = (COSTS (total_allocno_costs,
-				       parent_a_num)->mem_cost > 0
-				&& COSTS (total_allocno_costs,
-					  a_num)->mem_cost > 0);
-		      COSTS (total_allocno_costs, parent_a_num)->mem_cost
-			+= COSTS (total_allocno_costs, a_num)->mem_cost;
-		      if (COSTS (total_allocno_costs, parent_a_num)->mem_cost < 0
-			  && plus_p)
+		      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;
+
 		    }
 		  a_costs = COSTS (costs, a_num)->cost;
 		  for (k = cost_classes_ptr->num - 1; k >= 0; k--)
 		    {
-		      plus_p = i_costs[k] > 0 && a_costs[k] > 0;
-		      i_costs[k] += a_costs[k];
-		      if (i_costs[k] < 0 && plus_p)
+		      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;
 		    }
-		  plus_p = i_mem_cost > 0 && COSTS (costs, a_num)->mem_cost > 0;
-		  i_mem_cost += COSTS (costs, a_num)->mem_cost;
-		  if (i_mem_cost < 0 && plus_p)
+		  add_cost = COSTS (costs, a_num)->mem_cost;
+		  if (add_cost && INT_MAX - add_cost < i_mem_cost)
 		    i_mem_cost = INT_MAX;
+		  else
+		    i_mem_cost += add_cost;
 #ifdef FORBIDDEN_INC_DEC_CLASSES
 		  if (in_inc_dec[a_num])
 		    inc_dec_p = true;
@@ -1650,16 +1685,10 @@  find_costs_and_classes (FILE *dump_file)
 			 i, reg_class_names[best], reg_class_names[alt_class],
 			 reg_class_names[regno_aclass[i]]);
 	    }
-	  pref_cl = best;
+	  regno_best_class[i] = best;
 	  if (! allocno_p)
 	    {
 	      pref[i] = best_cost > i_mem_cost ? NO_REGS : best;
-	      if (pass < flag_expensive_optimizations)
-		{
-		  setup_regno_cost_classes_by_aclass (i, pref_cl);
-		  max_cost_classes_num
-		    = MAX (max_cost_classes_num, regno_cost_classes[i]->num);
-		}
 	      continue;
 	    }
 	  for (a = ira_regno_allocno_map[i];
@@ -1673,7 +1702,7 @@  find_costs_and_classes (FILE *dump_file)
 		{
 		  int *total_a_costs = COSTS (total_allocno_costs, a_num)->cost;
 		  int *a_costs = COSTS (costs, a_num)->cost;
-
+		  
 		  /* Finding best class which is subset of the common
 		     class.  */
 		  best_cost = (1 << (HOST_BITS_PER_INT - 2)) - 1;
@@ -1726,11 +1755,8 @@  find_costs_and_classes (FILE *dump_file)
 		}
 	      pref[a_num] = best;
 	    }
-	  setup_regno_cost_classes_by_aclass (i, pref_cl);
-	  max_cost_classes_num
-	    = MAX (max_cost_classes_num, regno_cost_classes[i]->num);
 	}
-
+      
       if (internal_flag_ira_verbose > 4 && dump_file)
 	{
 	  if (allocno_p)
@@ -1740,6 +1766,7 @@  find_costs_and_classes (FILE *dump_file)
 	  fprintf (dump_file,"\n");
 	}
     }
+  ira_free (regno_best_class);
 #ifdef FORBIDDEN_INC_DEC_CLASSES
   ira_free (in_inc_dec);
 #endif
@@ -1862,12 +1889,8 @@  setup_allocno_class_and_costs (void)
 		  num = cost_classes_ptr->index[rclass];
 		  if (num < 0)
 		    {
-		      /* The hard register class is not an allocno
-			 class or a class not fully inside in an
-			 allocno class -- use the allocno class.  */
-		      ira_assert (ira_hard_regno_allocno_class[hard_regno]
-				  == aclass);
-		      num = cost_classes_ptr->index[aclass];
+		      num = cost_classes_ptr->hard_regno_index[hard_regno];
+		      ira_assert (num >= 0);
 		    }
 		  reg_costs[j] = COSTS (costs, i)->cost[num];
 		}
@@ -2022,7 +2045,6 @@  ira_tune_allocno_costs (void)
   enum machine_mode mode;
   ira_allocno_t a;
   ira_allocno_iterator ai;
-  bool plus_p;
 
   FOR_EACH_ALLOCNO (a, ai)
     {
@@ -2057,10 +2079,10 @@  ira_tune_allocno_costs (void)
 		       * ALLOCNO_FREQ (a)
 		       * IRA_HARD_REGNO_ADD_COST_MULTIPLIER (regno) / 2);
 #endif
-	      plus_p = reg_costs[j] > 0 && cost > 0;
-	      reg_costs[j] += cost;
-	      if (reg_costs[j] < 0 && plus_p)
+	      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];
 	    }