Patchwork patch to fix reported worsening allocno class choice on the 2nd pass of ira reg costs on MIPS

login
register
mail settings
Submitter Vladimir Makarov
Date June 4, 2012, 6:34 p.m.
Message ID <4FCCFFAA.80406@redhat.com>
Download mbox | patch
Permalink /patch/162851/
State New
Headers show

Comments

Vladimir Makarov - June 4, 2012, 6:34 p.m.
The following patch solves the problem.  Instead of pressure classes 
which are focused on relation register moves with memory costs, we use 
an uniform classes whose register move costs are the same for all their 
sublcasses.  The unifrom classes is used not to slow down the 2nd pass.

   The patch does not changed the generated code on x86/x86-64 and does 
not slow IRA down (I've tried it on variety of tests) while it does 
solve the reported problem.  The patch also adds priniting debug info 
about uniform and important classes.

   The patch was successfully bootstrapped on x86/x86-64.

   Committed as rev. 188199.

  2012-06-04  Vladimir Makarov <vmakarov@redhat.com>

         * ira-int.h (struct target_ira_int): Add member
         x_ira_uniform_class_p.
         (ira_uniform_class_p): New macro.

         * ira.c (setup_uniform_class_p): New function.
         (setup_allocno_and_important_classes): Call the function.
         (print_unform_and_important_classes): New function.
         (print_classes): Rename to print_translated_classes.
         (ira_debug_allocno_classes): Add call of
         print_unform_and_important_classes.

         * ira-costs.c (setup_regno_cost_classes_by_aclass): Use uniform
         classes instead of pressure classes.

Patch

Index: ira.c
===================================================================
--- ira.c	(revision 188124)
+++ ira.c	(working copy)
@@ -903,6 +903,45 @@  setup_pressure_classes (void)
   setup_stack_reg_pressure_class ();
 }
 
+/* Set up IRA_UNIFORM_CLASS_P.  Uniform class is a register class
+   whose register move cost between any registers of the class is the
+   same as for all its subclasses.  We use the data to speed up the
+   2nd pass of calculations of allocno costs.  */
+static void
+setup_uniform_class_p (void)
+{
+  int i, cl, cl2, m;
+
+  for (cl = 0; cl < N_REG_CLASSES; cl++)
+    {
+      ira_uniform_class_p[cl] = false;
+      if (ira_class_hard_regs_num[cl] == 0)
+	continue;
+      /* We can not use alloc_reg_class_subclasses here because move
+	 cost hooks does not take into account that some registers are
+	 unavailable for the subtarget.  E.g. for i686, INT_SSE_REGS
+	 is element of alloc_reg_class_subclasses for GENERAL_REGS
+	 because SSE regs are unavailable.  */
+      for (i = 0; (cl2 = reg_class_subclasses[cl][i]) != LIM_REG_CLASSES; i++)
+	{
+	  if (ira_class_hard_regs_num[cl2] == 0)
+	    continue;
+      	  for (m = 0; m < NUM_MACHINE_MODES; m++)
+	    if (contains_reg_of_mode[cl][m] && contains_reg_of_mode[cl2][m])
+	      {
+		ira_init_register_move_cost_if_necessary ((enum machine_mode) m);
+		if (ira_register_move_cost[m][cl][cl]
+		    != ira_register_move_cost[m][cl2][cl2])
+		  break;
+	      }
+	  if (m < NUM_MACHINE_MODES)
+	    break;
+	}
+      if (cl2 == LIM_REG_CLASSES)
+	ira_uniform_class_p[cl] = true;
+    }
+}
+
 /* Set up IRA_ALLOCNO_CLASSES, IRA_ALLOCNO_CLASSES_NUM,
    IRA_IMPORTANT_CLASSES, and IRA_IMPORTANT_CLASSES_NUM.
 
@@ -1008,6 +1047,7 @@  setup_allocno_and_important_classes (voi
   for (j = 0; j < ira_allocno_classes_num; j++)
     ira_reg_allocno_class_p[ira_allocno_classes[j]] = true;
   setup_pressure_classes ();
+  setup_uniform_class_p ();
 }
 
 /* Setup translation in CLASS_TRANSLATE of all classes into a class
@@ -1292,10 +1332,27 @@  setup_reg_class_relations (void)
     }
 }
 
-/* Output all possible allocno classes and the translation map into
-   file F.  */
+/* Output all unifrom and important classes into file F.  */
+static void
+print_unform_and_important_classes (FILE *f)
+{
+  static const char *const reg_class_names[] = REG_CLASS_NAMES;
+  int i, cl;
+
+  fprintf (f, "Uniform classes:\n");
+  for (cl = 0; cl < N_REG_CLASSES; cl++)
+    if (ira_uniform_class_p[cl])
+      fprintf (f, " %s", reg_class_names[cl]);
+  fprintf (f, "\nImportant classes:\n");
+  for (i = 0; i < ira_important_classes_num; i++)
+    fprintf (f, " %s", reg_class_names[ira_important_classes[i]]);
+  fprintf (f, "\n");
+}
+
+/* Output all possible allocno or pressure classes and their
+   translation map into file F.  */
 static void
-print_classes (FILE *f, bool pressure_p)
+print_translated_classes (FILE *f, bool pressure_p)
 {
   int classes_num = (pressure_p
 		     ? ira_pressure_classes_num : ira_allocno_classes_num);
@@ -1321,8 +1378,9 @@  print_classes (FILE *f, bool pressure_p)
 void
 ira_debug_allocno_classes (void)
 {
-  print_classes (stderr, false);
-  print_classes (stderr, true);
+  print_unform_and_important_classes (stderr);
+  print_translated_classes (stderr, false);
+  print_translated_classes (stderr, true);
 }
 
 /* Set up different arrays concerning class subsets, allocno and
Index: ira-costs.c
===================================================================
--- ira-costs.c	(revision 188124)
+++ ira-costs.c	(working copy)
@@ -239,33 +239,19 @@  setup_regno_cost_classes_by_aclass (int
       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 a pressure class or subset of a
-	 pressure class.  It means by the definition of pressure classes
-	 that cost of moving between susbets of ACLASS is cheaper than
-	 load or store.  */
-      for (i = 0; i < ira_pressure_classes_num; i++)
-	{
-	  cl = ira_pressure_classes[i];
-	  if (cl == aclass)
-	    break;
-	  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 (temp, temp2))
-	    break;
-	}
-      exclude_p = i < ira_pressure_classes_num;
+	 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 no-pressure classes which are subsets of
+	      /* 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 (! ira_reg_pressure_class_p[cl]
-		  && hard_reg_set_subset_p (temp2, temp) && cl != aclass)
+	      if (hard_reg_set_subset_p (temp2, temp) && cl != aclass)
 		continue;
 	    }
 	  classes.classes[classes.num++] = cl;
Index: ira-int.h
===================================================================
--- ira-int.h	(revision 188124)
+++ ira-int.h	(working copy)
@@ -828,6 +828,9 @@  struct target_ira_int {
      classes.  */
   int x_ira_important_class_nums[N_REG_CLASSES];
 
+  /* Map class->true if class is an uniform class, false otherwise.  */
+  bool x_ira_uniform_class_p[N_REG_CLASSES];
+
   /* The biggest important class inside of intersection of the two
      classes (that is calculated taking only hard registers available
      for allocation into account;.  If the both classes contain no hard
@@ -905,6 +908,8 @@  extern struct target_ira_int *this_targe
   (this_target_ira_int->x_ira_important_classes)
 #define ira_important_class_nums \
   (this_target_ira_int->x_ira_important_class_nums)
+#define ira_uniform_class_p \
+  (this_target_ira_int->x_ira_uniform_class_p)
 #define ira_reg_class_intersect \
   (this_target_ira_int->x_ira_reg_class_intersect)
 #define ira_reg_classes_intersect_p \