[v2] Fix LRA to handle multi-word eliminable registers

Message ID 20180623123859.30728-1-dimitar@dinux.eu
State New
Headers show
Series
  • [v2] Fix LRA to handle multi-word eliminable registers
Related show

Commit Message

Dimitar Dimitrov June 23, 2018, 12:38 p.m.
For some targets, Pmode != UNITS_PER_WORD. Take this into account
when marking hard registers as being used.

I tested C and C++ testsuits for x86_64 with and without this
patch. There was no regression, i.e. gcc.sum and g++.sum matched
exactly.

Changes since patch series v1:
  - Cleanup to use add_to_hard_reg_set.
  - Also fix check_pseudos_live_through_calls.
  - Decouple PRU tests so that LRA patch is now standalone.

gcc/ChangeLog:

2018-06-23  Dimitar Dimitrov  <dimitar@dinux.eu>

	* lra-eliminations.c (update_reg_eliminate): Mark all spanning hard
	registers for Pmode..
	* lra-lives.c (check_pseudos_live_through_calls): Mark all spanning
	hard registers for the clobbered pseudo.

Cc: Vladimir Makarov <vmakarov@redhat.com>
Cc: Peter Bergner <bergner@vnet.ibm.com>
Cc: Kenneth Zadeck <zadeck@naturalbridge.com>
Cc: Seongbae Park <seongbae.park@gmail.com>
Cc: Jeff Law <law@redhat.com>
Signed-off-by: Dimitar Dimitrov <dimitar@dinux.eu>

---
 gcc/lra-eliminations.c | 4 ++--
 gcc/lra-lives.c        | 3 ++-
 2 files changed, 4 insertions(+), 3 deletions(-)

-- 
2.11.0

Comments

Vladimir Makarov June 26, 2018, 9:54 p.m. | #1
On 06/23/2018 08:38 AM, Dimitar Dimitrov wrote:
> For some targets, Pmode != UNITS_PER_WORD. Take this into account

> when marking hard registers as being used.

>

> I tested C and C++ testsuits for x86_64 with and without this

> patch. There was no regression, i.e. gcc.sum and g++.sum matched

> exactly.

>

> Changes since patch series v1:

>    - Cleanup to use add_to_hard_reg_set.

>    - Also fix check_pseudos_live_through_calls.

>    - Decouple PRU tests so that LRA patch is now standalone.

>

> gcc/ChangeLog:

>

> 2018-06-23  Dimitar Dimitrov  <dimitar@dinux.eu>

>

> 	* lra-eliminations.c (update_reg_eliminate): Mark all spanning hard

> 	registers for Pmode..

> 	* lra-lives.c (check_pseudos_live_through_calls): Mark all spanning

> 	hard registers for the clobbered pseudo.

I am not sure about necessity of a change in 
check_pseudos_live_through_calls.  But I guess reload treats partially 
clobbered regs in analogous way as the change.  Plus the change makes 
LRA code safer anyway.

So please go ahead and commit the patch into the trunk.

Thank you.
> Cc: Vladimir Makarov <vmakarov@redhat.com>

> Cc: Peter Bergner <bergner@vnet.ibm.com>

> Cc: Kenneth Zadeck <zadeck@naturalbridge.com>

> Cc: Seongbae Park <seongbae.park@gmail.com>

> Cc: Jeff Law <law@redhat.com>

> Signed-off-by: Dimitar Dimitrov <dimitar@dinux.eu>

> ---

>   gcc/lra-eliminations.c | 4 ++--

>   gcc/lra-lives.c        | 3 ++-

>   2 files changed, 4 insertions(+), 3 deletions(-)

>

> diff --git a/gcc/lra-eliminations.c b/gcc/lra-eliminations.c

> index 21d8d5f8018..f5f104020b3 100644

> --- a/gcc/lra-eliminations.c

> +++ b/gcc/lra-eliminations.c

> @@ -1264,13 +1264,13 @@ update_reg_eliminate (bitmap insns_with_changed_offsets)

>     CLEAR_HARD_REG_SET (temp_hard_reg_set);

>     for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)

>       if (elimination_map[ep->from] == NULL)

> -      SET_HARD_REG_BIT (temp_hard_reg_set, ep->from);

> +      add_to_hard_reg_set (&temp_hard_reg_set, Pmode, ep->from);

>       else if (elimination_map[ep->from] == ep)

>         {

>   	/* Prevent the hard register into which we eliminate from

>   	   the usage for pseudos.  */

>           if (ep->from != ep->to)

> -	  SET_HARD_REG_BIT (temp_hard_reg_set, ep->to);

> +	  add_to_hard_reg_set (&temp_hard_reg_set, Pmode, ep->to);

>   	if (maybe_ne (ep->previous_offset, ep->offset))

>   	  {

>   	    bitmap_ior_into (insns_with_changed_offsets,

> diff --git a/gcc/lra-lives.c b/gcc/lra-lives.c

> index 588bc09cb8e..920fd02b997 100644

> --- a/gcc/lra-lives.c

> +++ b/gcc/lra-lives.c

> @@ -581,7 +581,8 @@ check_pseudos_live_through_calls (int regno,

>     for (hr = 0; hr < FIRST_PSEUDO_REGISTER; hr++)

>       if (targetm.hard_regno_call_part_clobbered (hr,

>   						PSEUDO_REGNO_MODE (regno)))

> -      SET_HARD_REG_BIT (lra_reg_info[regno].conflict_hard_regs, hr);

> +      add_to_hard_reg_set (&lra_reg_info[regno].conflict_hard_regs,

> +			   PSEUDO_REGNO_MODE (regno), hr);

>     lra_reg_info[regno].call_p = true;

>     if (! sparseset_bit_p (pseudos_live_through_setjumps, regno))

>       return;
Jeff Law June 28, 2018, 3:44 a.m. | #2
On 06/23/2018 06:38 AM, Dimitar Dimitrov wrote:
> 2018-06-23  Dimitar Dimitrov  <dimitar@dinux.eu>

> 

> 	* lra-eliminations.c (update_reg_eliminate): Mark all spanning hard

> 	registers for Pmode..

> 	* lra-lives.c (check_pseudos_live_through_calls): Mark all spanning

> 	hard registers for the clobbered pseudo.

Thanks.  I put this through the usual bootstrap & regression tests and
installed the change onto the trunk.

jeff

Patch

diff --git a/gcc/lra-eliminations.c b/gcc/lra-eliminations.c
index 21d8d5f8018..f5f104020b3 100644
--- a/gcc/lra-eliminations.c
+++ b/gcc/lra-eliminations.c
@@ -1264,13 +1264,13 @@  update_reg_eliminate (bitmap insns_with_changed_offsets)
   CLEAR_HARD_REG_SET (temp_hard_reg_set);
   for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
     if (elimination_map[ep->from] == NULL)
-      SET_HARD_REG_BIT (temp_hard_reg_set, ep->from);
+      add_to_hard_reg_set (&temp_hard_reg_set, Pmode, ep->from);
     else if (elimination_map[ep->from] == ep)
       {
 	/* Prevent the hard register into which we eliminate from
 	   the usage for pseudos.  */
         if (ep->from != ep->to)
-	  SET_HARD_REG_BIT (temp_hard_reg_set, ep->to);
+	  add_to_hard_reg_set (&temp_hard_reg_set, Pmode, ep->to);
 	if (maybe_ne (ep->previous_offset, ep->offset))
 	  {
 	    bitmap_ior_into (insns_with_changed_offsets,
diff --git a/gcc/lra-lives.c b/gcc/lra-lives.c
index 588bc09cb8e..920fd02b997 100644
--- a/gcc/lra-lives.c
+++ b/gcc/lra-lives.c
@@ -581,7 +581,8 @@  check_pseudos_live_through_calls (int regno,
   for (hr = 0; hr < FIRST_PSEUDO_REGISTER; hr++)
     if (targetm.hard_regno_call_part_clobbered (hr,
 						PSEUDO_REGNO_MODE (regno)))
-      SET_HARD_REG_BIT (lra_reg_info[regno].conflict_hard_regs, hr);
+      add_to_hard_reg_set (&lra_reg_info[regno].conflict_hard_regs,
+			   PSEUDO_REGNO_MODE (regno), hr);
   lra_reg_info[regno].call_p = true;
   if (! sparseset_bit_p (pseudos_live_through_setjumps, regno))
     return;