[PATCH 2/2] PR 63340: Avoid harmful union classes in ira-costs.c

Richard Sandiford richard.sandiford@arm.com
Tue Sep 30 13:07:00 GMT 2014


This part of the patch actually fixes the PR.  It takes the reginfo.c
"invalid mode changes" into account when computing the cost classes,
rather than when using them.  The code in the first patch then ensures
that we don't add X_AND_Y_REGS to the cost classes if only X or Y allow
the required mode changes.

Tested in the same way as patch 1.  OK to install?

Thanks,
Richard


gcc/
	PR rtl-optimization/63340 (part 2)
	* ira-costs.c (setup_regno_cost_classes_by_aclass): Restrict the
	classes to registers that are allowed by valid_mode_changes_for_regno.
	(setup_regno_cost_classes_by_mode): Likewise.
	(print_allocno_costs): Remove invalid_mode_change_p test.
	(print_pseudo_costs, find_costs_and_classes): Likewise.

Index: gcc/ira-costs.c
===================================================================
--- gcc/ira-costs.c	2014-09-30 10:56:20.352946321 +0100
+++ gcc/ira-costs.c	2014-09-30 11:05:02.678826946 +0100
@@ -378,12 +378,18 @@ setup_regno_cost_classes_by_aclass (int
       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).  */
-    classes_ptr = restrict_cost_classes (classes_ptr,
-					 PSEUDO_REGNO_MODE (regno),
-					 reg_class_contents[ALL_REGS]);
+    {
+      /* 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;
 }
 
@@ -396,11 +402,17 @@ setup_regno_cost_classes_by_aclass (int
 static void
 setup_regno_cost_classes_by_mode (int regno, enum machine_mode mode)
 {
-  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];
+  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];
+    }
 }
 
 /* Finilize info about the cost classes for each pseudo.  */
@@ -1526,14 +1538,11 @@ print_allocno_costs (FILE *f)
       for (k = 0; k < cost_classes_ptr->num; k++)
 	{
 	  rclass = cost_classes[k];
-	  if (! invalid_mode_change_p (regno, (enum reg_class) rclass))
-	    {
-	      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, " %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
@@ -1564,9 +1573,8 @@ print_pseudo_costs (FILE *f)
       for (k = 0; k < cost_classes_ptr->num; k++)
 	{
 	  rclass = cost_classes[k];
-	  if (! invalid_mode_change_p (regno, (enum reg_class) rclass))
-	    fprintf (f, " %s:%d", reg_class_names[rclass],
-		     COSTS (costs, regno)->cost[k]);
+	  fprintf (f, " %s:%d", reg_class_names[rclass],
+		   COSTS (costs, regno)->cost[k]);
 	}
       fprintf (f, " MEM:%i\n", COSTS (costs, regno)->mem_cost);
     }
@@ -1803,10 +1811,6 @@ find_costs_and_classes (FILE *dump_file)
 	  for (k = 0; k < cost_classes_ptr->num; k++)
 	    {
 	      rclass = cost_classes[k];
-	      /* Ignore classes that are too small or invalid for this
-		 operand.  */
-	      if (invalid_mode_change_p (i, (enum reg_class) rclass))
-		continue;
 	      if (i_costs[k] < best_cost)
 		{
 		  best_cost = i_costs[k];
@@ -1896,11 +1900,7 @@ find_costs_and_classes (FILE *dump_file)
 		      rclass = cost_classes[k];
 		      if (! ira_class_subset_p[rclass][aclass])
 			continue;
-		      /* Ignore classes that are too small or invalid
-			 for this operand.  */
-		      if (invalid_mode_change_p (i, (enum reg_class) rclass))
-			;
-		      else if (total_a_costs[k] < best_cost)
+		      if (total_a_costs[k] < best_cost)
 			{
 			  best_cost = total_a_costs[k];
 			  allocno_cost = a_costs[k];
Index: gcc/reginfo.c
===================================================================
--- gcc/reginfo.c	2014-09-30 10:56:20.352946321 +0100
+++ gcc/reginfo.c	2014-09-30 11:06:30.085805954 +0100
@@ -1326,14 +1326,10 @@ init_subregs_of_mode (void)
         find_subregs_of_mode (PATTERN (insn));
 }
 
-/* Return 1 if REGNO has had an invalid mode change in CLASS from FROM
-   mode.  */
-bool
-invalid_mode_change_p (unsigned int regno, enum reg_class rclass)
+const HARD_REG_SET *
+valid_mode_changes_for_regno (unsigned int regno)
 {
-  return (valid_mode_changes[regno]
-	  && !hard_reg_set_intersect_p (reg_class_contents[rclass],
-					*valid_mode_changes[regno]));
+  return valid_mode_changes[regno];
 }
 
 void
Index: gcc/rtl.h
===================================================================
--- gcc/rtl.h	2014-09-30 10:56:20.352946321 +0100
+++ gcc/rtl.h	2014-09-30 10:56:20.348946368 +0100
@@ -3496,7 +3496,9 @@ extern void init_reg_sets (void);
 extern void regclass (rtx, int);
 extern void reg_scan (rtx_insn *, unsigned int);
 extern void fix_register (const char *, int, int);
-extern bool invalid_mode_change_p (unsigned int, enum reg_class);
+#ifdef HARD_CONST
+extern const HARD_REG_SET *valid_mode_changes_for_regno (unsigned int);
+#endif
 
 /* In reload1.c */
 extern int function_invariant_p (const_rtx);



More information about the Gcc-patches mailing list