Patchwork profitable_hard_regs vs. PR 48435

login
register
mail settings
Submitter Richard Sandiford
Date Sept. 30, 2012, 6:42 p.m.
Message ID <87wqzbqrnk.fsf@talisman.home>
Download mbox | patch
Permalink /patch/188188/
State New
Headers show

Comments

Richard Sandiford - Sept. 30, 2012, 6:42 p.m.
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  <vmakarov@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
Vladimir Makarov - Oct. 1, 2012, 11:52 p.m.
On 12-09-30 2:42 PM, Richard Sandiford wrote:
> 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  <vmakarov@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?
>
>
>
> 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.
Ok. thanks, Richard.

Patch

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);
+	  }
 	}
 }