This is another patch needed for the MIPS MD_REGS change described here:

    http://gcc.gnu.org/ml/gcc-patches/2012-09/msg01992.html

The profitable_hard_regs set used during IRA colouring used to be restricted
to registers that are valid for the allocno's mode.  That caused problems
for multi-register modes that can only start with an even register (say),
because profitable_hard_regs would only include the even start registers,
not the pairing odd registers.  Vlad fixed it with:

2011-04-08  Vladimir Makarov  <vmaka...@redhat.com>

        PR inline-asm/48435
        * ira-color.c (setup_profitable_hard_regs): Add comments.
        Don't take prohibited hard regs into account.
        (setup_conflict_profitable_regs): Rename to
        get_conflict_profitable_regs.
        (check_hard_reg_p): Check prohibited hard regs.

However, one effect of that change is that if register R belongs to class CL
but can never be used anywhere in a register of mode M, it will still be
included in profitable_hard_regs.  That's the case with MD_REGS and
register HI on MIPS.

The patch below is a half-way house between the original behaviour
and the post-48435 one.  It restricts profitable_hard_regs to registers
that can be used for the allocno's mode, but doesn't restrict it to
starting registers.

Most of the ira.c change is reindentation, so I've included a -b
diff as well.

As with the patch linked above, I checked that this produced no
difference in assembly output for a set of x86_64 gcc .ii files
(tested with -O2 -march=native on gcc20).  Also tested on
x86_64-linux-gnu (including -m32) and mipsisa64-elf.  OK to install?

Richard


gcc/
        * ira-int.h (target_ira_int): Add x_ira_useful_class_mode_regs.
        (ira_useful_class_mode_regs): New macro.
        * ira.c (clarify_prohibited_class_mode_regs): Set up
        ira_useful_class_mode_regs.
        * ira-color.c (setup_profitable_hard_regs): Use it to initialise
        profitable_hard_regs.

Index: gcc/ira-int.h
===================================================================
--- gcc/ira-int.h       2012-09-30 18:59:09.463447170 +0100
+++ gcc/ira-int.h       2012-09-30 19:21:59.395407339 +0100
@@ -816,6 +816,20 @@ struct target_ira_int {
      values for given mode are zero.  */
   HARD_REG_SET 
x_ira_prohibited_class_mode_regs[N_REG_CLASSES][NUM_MACHINE_MODES];
 
+  /* Index [CL][M] contains R if R appears somewhere in a register of the form:
+
+         (reg:M R'), R' not in x_ira_prohibited_class_mode_regs[CL][M]
+
+     For example, if:
+
+     - (reg:M 2) is valid and occupies two registers;
+     - register 2 belongs to CL; and
+     - register 3 belongs to the same pressure class as CL
+
+     then (reg:M 2) contributes to [CL][M] and registers 2 and 3 will be
+     in the set.  */
+  HARD_REG_SET x_ira_useful_class_mode_regs[N_REG_CLASSES][NUM_MACHINE_MODES];
+
   /* The value is number of elements in the subsequent array.  */
   int x_ira_important_classes_num;
 
@@ -902,6 +916,8 @@ #define ira_class_hard_reg_index \
   (this_target_ira_int->x_ira_class_hard_reg_index)
 #define ira_prohibited_class_mode_regs \
   (this_target_ira_int->x_ira_prohibited_class_mode_regs)
+#define ira_useful_class_mode_regs \
+  (this_target_ira_int->x_ira_useful_class_mode_regs)
 #define ira_important_classes_num \
   (this_target_ira_int->x_ira_important_classes_num)
 #define ira_important_classes \
Index: gcc/ira.c
===================================================================
--- gcc/ira.c   2012-09-30 19:20:32.555409864 +0100
+++ gcc/ira.c   2012-09-30 19:21:59.396407339 +0100
@@ -1495,29 +1495,36 @@ clarify_prohibited_class_mode_regs (void
 
   for (cl = (int) N_REG_CLASSES - 1; cl >= 0; cl--)
     for (j = 0; j < NUM_MACHINE_MODES; j++)
-      for (k = ira_class_hard_regs_num[cl] - 1; k >= 0; k--)
-       {
-         hard_regno = ira_class_hard_regs[cl][k];
-         if (TEST_HARD_REG_BIT (ira_prohibited_class_mode_regs[cl][j], 
hard_regno))
-           continue;
-         nregs = hard_regno_nregs[hard_regno][j];
-          if (hard_regno + nregs > FIRST_PSEUDO_REGISTER)
-            {
-              SET_HARD_REG_BIT (ira_prohibited_class_mode_regs[cl][j],
-                                hard_regno);
-               continue;
-            }
-         pclass = ira_pressure_class_translate[REGNO_REG_CLASS (hard_regno)];
-         for (nregs-- ;nregs >= 0; nregs--)
-           if (((enum reg_class) pclass
-                != ira_pressure_class_translate[REGNO_REG_CLASS
-                                                (hard_regno + nregs)]))
+      {
+       CLEAR_HARD_REG_SET (ira_useful_class_mode_regs[cl][j]);
+       for (k = ira_class_hard_regs_num[cl] - 1; k >= 0; k--)
+         {
+           hard_regno = ira_class_hard_regs[cl][k];
+           if (TEST_HARD_REG_BIT (ira_prohibited_class_mode_regs[cl][j], 
hard_regno))
+             continue;
+           nregs = hard_regno_nregs[hard_regno][j];
+           if (hard_regno + nregs > FIRST_PSEUDO_REGISTER)
              {
                SET_HARD_REG_BIT (ira_prohibited_class_mode_regs[cl][j],
                                  hard_regno);
-               break;
+                continue;
              }
-       }
+           pclass = ira_pressure_class_translate[REGNO_REG_CLASS (hard_regno)];
+           for (nregs-- ;nregs >= 0; nregs--)
+             if (((enum reg_class) pclass
+                  != ira_pressure_class_translate[REGNO_REG_CLASS
+                                                  (hard_regno + nregs)]))
+               {
+                 SET_HARD_REG_BIT (ira_prohibited_class_mode_regs[cl][j],
+                                   hard_regno);
+                 break;
+               }
+           if (!TEST_HARD_REG_BIT (ira_prohibited_class_mode_regs[cl][j],
+                                   hard_regno))
+             add_to_hard_reg_set (&ira_useful_class_mode_regs[cl][j],
+                                  (enum machine_mode) j, hard_regno);
+         }
+      }
 }
 
 /* Allocate and initialize IRA_REGISTER_MOVE_COST, IRA_MAY_MOVE_IN_COST
Index: gcc/ira-color.c
===================================================================
--- gcc/ira-color.c     2012-09-30 18:59:09.463447170 +0100
+++ gcc/ira-color.c     2012-09-30 19:21:59.394407339 +0100
@@ -1023,10 +1023,9 @@ setup_profitable_hard_regs (void)
        CLEAR_HARD_REG_SET (data->profitable_hard_regs);
       else
        {
+         mode = ALLOCNO_MODE (a);
          COPY_HARD_REG_SET (data->profitable_hard_regs,
-                            reg_class_contents[aclass]);
-         AND_COMPL_HARD_REG_SET (data->profitable_hard_regs,
-                                 ira_no_alloc_regs);
+                            ira_useful_class_mode_regs[aclass][mode]);
          nobj = ALLOCNO_NUM_OBJECTS (a);
          for (k = 0; k < nobj; k++)
            {

Index: gcc/ira-color.c
===================================================================
--- gcc/ira-color.c	2012-09-30 18:59:09.463447170 +0100
+++ gcc/ira-color.c	2012-09-30 19:21:59.394407339 +0100
@@ -1023,10 +1023,9 @@ setup_profitable_hard_regs (void)
 	CLEAR_HARD_REG_SET (data->profitable_hard_regs);
       else
 	{
+	  mode = ALLOCNO_MODE (a);
 	  COPY_HARD_REG_SET (data->profitable_hard_regs,
-			     reg_class_contents[aclass]);
-	  AND_COMPL_HARD_REG_SET (data->profitable_hard_regs,
-				  ira_no_alloc_regs);
+			     ira_useful_class_mode_regs[aclass][mode]);
 	  nobj = ALLOCNO_NUM_OBJECTS (a);
 	  for (k = 0; k < nobj; k++)
 	    {
Index: gcc/ira-int.h
===================================================================
--- gcc/ira-int.h	2012-09-30 18:59:09.463447170 +0100
+++ gcc/ira-int.h	2012-09-30 19:21:59.395407339 +0100
@@ -816,6 +816,20 @@ struct target_ira_int {
      values for given mode are zero.  */
   HARD_REG_SET x_ira_prohibited_class_mode_regs[N_REG_CLASSES][NUM_MACHINE_MODES];
 
+  /* Index [CL][M] contains R if R appears somewhere in a register of the form:
+
+         (reg:M R'), R' not in x_ira_prohibited_class_mode_regs[CL][M]
+
+     For example, if:
+
+     - (reg:M 2) is valid and occupies two registers;
+     - register 2 belongs to CL; and
+     - register 3 belongs to the same pressure class as CL
+
+     then (reg:M 2) contributes to [CL][M] and registers 2 and 3 will be
+     in the set.  */
+  HARD_REG_SET x_ira_useful_class_mode_regs[N_REG_CLASSES][NUM_MACHINE_MODES];
+
   /* The value is number of elements in the subsequent array.  */
   int x_ira_important_classes_num;
 
@@ -902,6 +916,8 @@ #define ira_class_hard_reg_index \
   (this_target_ira_int->x_ira_class_hard_reg_index)
 #define ira_prohibited_class_mode_regs \
   (this_target_ira_int->x_ira_prohibited_class_mode_regs)
+#define ira_useful_class_mode_regs \
+  (this_target_ira_int->x_ira_useful_class_mode_regs)
 #define ira_important_classes_num \
   (this_target_ira_int->x_ira_important_classes_num)
 #define ira_important_classes \
Index: gcc/ira.c
===================================================================
--- gcc/ira.c	2012-09-30 19:20:32.555409864 +0100
+++ gcc/ira.c	2012-09-30 19:21:59.396407339 +0100
@@ -1495,6 +1495,8 @@ clarify_prohibited_class_mode_regs (void
 
   for (cl = (int) N_REG_CLASSES - 1; cl >= 0; cl--)
     for (j = 0; j < NUM_MACHINE_MODES; j++)
+      {
+	CLEAR_HARD_REG_SET (ira_useful_class_mode_regs[cl][j]);
       for (k = ira_class_hard_regs_num[cl] - 1; k >= 0; k--)
 	{
 	  hard_regno = ira_class_hard_regs[cl][k];
@@ -1517,6 +1519,11 @@ clarify_prohibited_class_mode_regs (void
 				  hard_regno);
 		break;
 	      }
+	    if (!TEST_HARD_REG_BIT (ira_prohibited_class_mode_regs[cl][j],
+				    hard_regno))
+	      add_to_hard_reg_set (&ira_useful_class_mode_regs[cl][j],
+				   (enum machine_mode) j, hard_regno);
+	  }
 	}
 }
 

Reply via email to