[10/11] Fix LRA to handle multi-word eliminable registers

Message ID 20180613185805.7833-11-dimitar@dinux.eu
State New
Headers show
Series
  • New backend for the TI PRU processor
Related show

Commit Message

Dimitar Dimitrov June 13, 2018, 6:58 p.m.
From: Dimitar Dimitrov <dddimitrov@mm-sol.com>


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.

gcc/ChangeLog:

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

	* lra-eliminations.c (set_ptr_hard_reg_bits): New function.
	(update_reg_eliminate): Mark all spanning hw registers.

gcc/testsuite/ChangeLog:

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

	* gcc.target/pru/lra-framepointer-fragmentation-1.c: New test.
	* gcc.target/pru/lra-framepointer-fragmentation-2.c: New test.

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>
Signed-off-by: Dimitar Dimitrov <dddimitrov@mm-sol.com>

---
 gcc/lra-eliminations.c                             | 14 ++++-
 .../pru/lra-framepointer-fragmentation-1.c         | 33 ++++++++++++
 .../pru/lra-framepointer-fragmentation-2.c         | 61 ++++++++++++++++++++++
 3 files changed, 106 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/pru/lra-framepointer-fragmentation-1.c
 create mode 100644 gcc/testsuite/gcc.target/pru/lra-framepointer-fragmentation-2.c

-- 
2.11.0

Comments

Vladimir Makarov June 21, 2018, 5:44 p.m. | #1
On 06/13/2018 02:58 PM, Dimitar Dimitrov wrote:
> From: Dimitar Dimitrov <dddimitrov@mm-sol.com>

>

> 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.

>

> gcc/ChangeLog:

>

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

>

> 	* lra-eliminations.c (set_ptr_hard_reg_bits): New function.

> 	(update_reg_eliminate): Mark all spanning hw registers.

>

> gcc/testsuite/ChangeLog:

>

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

>

> 	* gcc.target/pru/lra-framepointer-fragmentation-1.c: New test.

> 	* gcc.target/pru/lra-framepointer-fragmentation-2.c: New test.

>

> 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>

> Signed-off-by: Dimitar Dimitrov <dddimitrov@mm-sol.com>

> ---

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

>   .../pru/lra-framepointer-fragmentation-1.c         | 33 ++++++++++++

>   .../pru/lra-framepointer-fragmentation-2.c         | 61 ++++++++++++++++++++++

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

>   create mode 100644 gcc/testsuite/gcc.target/pru/lra-framepointer-fragmentation-1.c

>   create mode 100644 gcc/testsuite/gcc.target/pru/lra-framepointer-fragmentation-2.c

>

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

> index 21d8d5f8018..566cc2c8248 100644

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

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

> @@ -1180,6 +1180,16 @@ spill_pseudos (HARD_REG_SET set)

>     bitmap_clear (&to_process);

>   }

>   

> +static void set_ptr_hard_reg_bits (HARD_REG_SET *hard_reg_set, int r)

> +{

> +  int w;

> +

> +  for (w = 0; w < GET_MODE_SIZE (Pmode); w += UNITS_PER_WORD, r++)

> +    {

> +	  SET_HARD_REG_BIT (*hard_reg_set, r);

> +    }

> +}

> +

The patch itself is ok but for uniformity I'd use

     for (int i = hard_regno_nregs (r, Pmode) - 1; i >= 0; i--)
       SET_HARD_REG_BIT (*hard_reg_set, r + i);


Approved with the above change.
Jeff Law June 21, 2018, 11:03 p.m. | #2
On 06/21/2018 11:44 AM, Vladimir Makarov wrote:
> 

> 

> On 06/13/2018 02:58 PM, Dimitar Dimitrov wrote:

>> From: Dimitar Dimitrov <dddimitrov@mm-sol.com>

>>

>> 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.

>>

>> gcc/ChangeLog:

>>

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

>>

>>     * lra-eliminations.c (set_ptr_hard_reg_bits): New function.

>>     (update_reg_eliminate): Mark all spanning hw registers.

>>

>> gcc/testsuite/ChangeLog:

>>

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

>>

>>     * gcc.target/pru/lra-framepointer-fragmentation-1.c: New test.

>>     * gcc.target/pru/lra-framepointer-fragmentation-2.c: New test.

>>

>> 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>

>> Signed-off-by: Dimitar Dimitrov <dddimitrov@mm-sol.com>

>> ---

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

>>   .../pru/lra-framepointer-fragmentation-1.c         | 33 ++++++++++++

>>   .../pru/lra-framepointer-fragmentation-2.c         | 61

>> ++++++++++++++++++++++

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

>>   create mode 100644

>> gcc/testsuite/gcc.target/pru/lra-framepointer-fragmentation-1.c

>>   create mode 100644

>> gcc/testsuite/gcc.target/pru/lra-framepointer-fragmentation-2.c

>>

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

>> index 21d8d5f8018..566cc2c8248 100644

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

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

>> @@ -1180,6 +1180,16 @@ spill_pseudos (HARD_REG_SET set)

>>     bitmap_clear (&to_process);

>>   }

>>   +static void set_ptr_hard_reg_bits (HARD_REG_SET *hard_reg_set, int r)

>> +{

>> +  int w;

>> +

>> +  for (w = 0; w < GET_MODE_SIZE (Pmode); w += UNITS_PER_WORD, r++)

>> +    {

>> +      SET_HARD_REG_BIT (*hard_reg_set, r);

>> +    }

>> +}

>> +

> The patch itself is ok but for uniformity I'd use

> 

>     for (int i = hard_regno_nregs (r, Pmode) - 1; i >= 0; i--)

>       SET_HARD_REG_BIT (*hard_reg_set, r + i);

I'm a bit surprised we don't already have a utility function to do this.
Hmmm

add_to_hard_reg_set (hard_reg_set, Pmode, r)

So instead LRA ought to be using that function in the places where calls
to set_ptr_hard_reg_bits were introduced.

Dimitar, can you verify that change works?


Jeff
Dimitar Dimitrov June 22, 2018, 4:01 a.m. | #3
On четвъртък, 21 юни 2018 г. 17:03:55 EEST Jeff Law wrote:
> On 06/21/2018 11:44 AM, Vladimir Makarov wrote:

> > On 06/13/2018 02:58 PM, Dimitar Dimitrov wrote:

> >> From: Dimitar Dimitrov <dddimitrov@mm-sol.com>

> >> 

> >> 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.

> >> 

> >> gcc/ChangeLog:

> >> 

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

> >> 

> >>     * lra-eliminations.c (set_ptr_hard_reg_bits): New function.

> >>     (update_reg_eliminate): Mark all spanning hw registers.

> >> 

> >> gcc/testsuite/ChangeLog:

> >> 

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

> >> 

> >>     * gcc.target/pru/lra-framepointer-fragmentation-1.c: New test.

> >>     * gcc.target/pru/lra-framepointer-fragmentation-2.c: New test.

> >> 

> >> 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>

> >> Signed-off-by: Dimitar Dimitrov <dddimitrov@mm-sol.com>

> >> ---

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

> >>   .../pru/lra-framepointer-fragmentation-1.c         | 33 ++++++++++++

> >>   .../pru/lra-framepointer-fragmentation-2.c         | 61

> >> ++++++++++++++++++++++

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

> >>   create mode 100644

> >> gcc/testsuite/gcc.target/pru/lra-framepointer-fragmentation-1.c

> >>   create mode 100644

> >> gcc/testsuite/gcc.target/pru/lra-framepointer-fragmentation-2.c

> >> 

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

> >> index 21d8d5f8018..566cc2c8248 100644

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

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

> >> @@ -1180,6 +1180,16 @@ spill_pseudos (HARD_REG_SET set)

> >>     bitmap_clear (&to_process);

> >>   }

> >>   +static void set_ptr_hard_reg_bits (HARD_REG_SET *hard_reg_set, int r)

> >> +{

> >> +  int w;

> >> +

> >> +  for (w = 0; w < GET_MODE_SIZE (Pmode); w += UNITS_PER_WORD, r++)

> >> +    {

> >> +      SET_HARD_REG_BIT (*hard_reg_set, r);

> >> +    }

> >> +}

> >> +

> > 

> > The patch itself is ok but for uniformity I'd use

> > 

> >     for (int i = hard_regno_nregs (r, Pmode) - 1; i >= 0; i--)

> >       SET_HARD_REG_BIT (*hard_reg_set, r + i);

> 

> I'm a bit surprised we don't already have a utility function to do this.

> Hmmm

> 

> add_to_hard_reg_set (hard_reg_set, Pmode, r)

> 

> So instead LRA ought to be using that function in the places where calls

> to set_ptr_hard_reg_bits were introduced.

> 

> Dimitar, can you verify that change works?


Thank you. I'll test it and will update the patch.


The SET_HARD_REG_BIT call in check_pseudos_live_through_calls also seems 
suspicous to me. I'll try to come up with a regression test case to justify 
its upgrade to add_to_hard_reg_set().

Regards,
Dimitar
Jeff Law June 22, 2018, 5 a.m. | #4
On 06/21/2018 10:01 PM, Dimitar Dimitrov wrote:
> On четвъртък, 21 юни 2018 г. 17:03:55 EEST Jeff Law wrote:

>> On 06/21/2018 11:44 AM, Vladimir Makarov wrote:

>>> On 06/13/2018 02:58 PM, Dimitar Dimitrov wrote:

>>>> From: Dimitar Dimitrov <dddimitrov@mm-sol.com>

>>>>

>>>> 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.

>>>>

>>>> gcc/ChangeLog:

>>>>

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

>>>>

>>>>     * lra-eliminations.c (set_ptr_hard_reg_bits): New function.

>>>>     (update_reg_eliminate): Mark all spanning hw registers.

>>>>

>>>> gcc/testsuite/ChangeLog:

>>>>

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

>>>>

>>>>     * gcc.target/pru/lra-framepointer-fragmentation-1.c: New test.

>>>>     * gcc.target/pru/lra-framepointer-fragmentation-2.c: New test.

>>>>

>>>> 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>

>>>> Signed-off-by: Dimitar Dimitrov <dddimitrov@mm-sol.com>

>>>> ---

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

>>>>   .../pru/lra-framepointer-fragmentation-1.c         | 33 ++++++++++++

>>>>   .../pru/lra-framepointer-fragmentation-2.c         | 61

>>>> ++++++++++++++++++++++

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

>>>>   create mode 100644

>>>> gcc/testsuite/gcc.target/pru/lra-framepointer-fragmentation-1.c

>>>>   create mode 100644

>>>> gcc/testsuite/gcc.target/pru/lra-framepointer-fragmentation-2.c

>>>>

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

>>>> index 21d8d5f8018..566cc2c8248 100644

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

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

>>>> @@ -1180,6 +1180,16 @@ spill_pseudos (HARD_REG_SET set)

>>>>     bitmap_clear (&to_process);

>>>>   }

>>>>   +static void set_ptr_hard_reg_bits (HARD_REG_SET *hard_reg_set, int r)

>>>> +{

>>>> +  int w;

>>>> +

>>>> +  for (w = 0; w < GET_MODE_SIZE (Pmode); w += UNITS_PER_WORD, r++)

>>>> +    {

>>>> +      SET_HARD_REG_BIT (*hard_reg_set, r);

>>>> +    }

>>>> +}

>>>> +

>>>

>>> The patch itself is ok but for uniformity I'd use

>>>

>>>     for (int i = hard_regno_nregs (r, Pmode) - 1; i >= 0; i--)

>>>       SET_HARD_REG_BIT (*hard_reg_set, r + i);

>>

>> I'm a bit surprised we don't already have a utility function to do this.

>> Hmmm

>>

>> add_to_hard_reg_set (hard_reg_set, Pmode, r)

>>

>> So instead LRA ought to be using that function in the places where calls

>> to set_ptr_hard_reg_bits were introduced.

>>

>> Dimitar, can you verify that change works?

> 

> Thank you. I'll test it and will update the patch.

> 

> 

> The SET_HARD_REG_BIT call in check_pseudos_live_through_calls also seems 

> suspicous to me. I'll try to come up with a regression test case to justify 

> its upgrade to add_to_hard_reg_set().

I wouldn't be surprised if there's others, particularly WRT Pmode.
Targets where Pmode != word_mode are relatively rare and those that
exist aren't extensively tested.

Jeff
> 

> Regards,

> Dimitar

>
Jeff Law June 22, 2018, 4:37 p.m. | #5
On 06/21/2018 10:01 PM, Dimitar Dimitrov wrote:
> On четвъртък, 21 юни 2018 г. 17:03:55 EEST Jeff Law wrote:

>> On 06/21/2018 11:44 AM, Vladimir Makarov wrote:

>>> On 06/13/2018 02:58 PM, Dimitar Dimitrov wrote:

>>>> From: Dimitar Dimitrov <dddimitrov@mm-sol.com>

>>>>

>>>> 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.

>>>>

>>>> gcc/ChangeLog:

>>>>

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

>>>>

>>>>     * lra-eliminations.c (set_ptr_hard_reg_bits): New function.

>>>>     (update_reg_eliminate): Mark all spanning hw registers.

>>>>

>>>> gcc/testsuite/ChangeLog:

>>>>

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

>>>>

>>>>     * gcc.target/pru/lra-framepointer-fragmentation-1.c: New test.

>>>>     * gcc.target/pru/lra-framepointer-fragmentation-2.c: New test.

>>>>

>>>> 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>

>>>> Signed-off-by: Dimitar Dimitrov <dddimitrov@mm-sol.com>

>>>> ---

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

>>>>   .../pru/lra-framepointer-fragmentation-1.c         | 33 ++++++++++++

>>>>   .../pru/lra-framepointer-fragmentation-2.c         | 61

>>>> ++++++++++++++++++++++

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

>>>>   create mode 100644

>>>> gcc/testsuite/gcc.target/pru/lra-framepointer-fragmentation-1.c

>>>>   create mode 100644

>>>> gcc/testsuite/gcc.target/pru/lra-framepointer-fragmentation-2.c

>>>>

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

>>>> index 21d8d5f8018..566cc2c8248 100644

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

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

>>>> @@ -1180,6 +1180,16 @@ spill_pseudos (HARD_REG_SET set)

>>>>     bitmap_clear (&to_process);

>>>>   }

>>>>   +static void set_ptr_hard_reg_bits (HARD_REG_SET *hard_reg_set, int r)

>>>> +{

>>>> +  int w;

>>>> +

>>>> +  for (w = 0; w < GET_MODE_SIZE (Pmode); w += UNITS_PER_WORD, r++)

>>>> +    {

>>>> +      SET_HARD_REG_BIT (*hard_reg_set, r);

>>>> +    }

>>>> +}

>>>> +

>>>

>>> The patch itself is ok but for uniformity I'd use

>>>

>>>     for (int i = hard_regno_nregs (r, Pmode) - 1; i >= 0; i--)

>>>       SET_HARD_REG_BIT (*hard_reg_set, r + i);

>>

>> I'm a bit surprised we don't already have a utility function to do this.

>> Hmmm

>>

>> add_to_hard_reg_set (hard_reg_set, Pmode, r)

>>

>> So instead LRA ought to be using that function in the places where calls

>> to set_ptr_hard_reg_bits were introduced.

>>

>> Dimitar, can you verify that change works?

> 

> Thank you. I'll test it and will update the patch.

And go ahead and either break out the two new tests.  I suspect we'll
want to install the LRA patch immediately since it's an independent bugfix.


> 

> 

> The SET_HARD_REG_BIT call in check_pseudos_live_through_calls also seems 

> suspicous to me. I'll try to come up with a regression test case to justify 

> its upgrade to add_to_hard_reg_set().

If you can construct a test, great, but from my reading it's clearly
wrong as well and we ought to fix it too.

Jeff

ps.  Do you have a copyright assignment on file with the FSF for GCC work?
Dimitar Dimitrov June 23, 2018, 12:13 p.m. | #6
On петък, 22 юни 2018 г. 10:37:10 EEST Jeff Law wrote:
> On 06/21/2018 10:01 PM, Dimitar Dimitrov wrote:

> > On четвъртък, 21 юни 2018 г. 17:03:55 EEST Jeff Law wrote:

> >> On 06/21/2018 11:44 AM, Vladimir Makarov wrote:

> >>> On 06/13/2018 02:58 PM, Dimitar Dimitrov wrote:

> >>>> From: Dimitar Dimitrov <dddimitrov@mm-sol.com>

> >>>> 

> >>>> 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.

> >>>> 

> >>>> gcc/ChangeLog:

> >>>> 

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

> >>>> 

> >>>>     * lra-eliminations.c (set_ptr_hard_reg_bits): New function.

> >>>>     (update_reg_eliminate): Mark all spanning hw registers.

> >>>> 

> >>>> gcc/testsuite/ChangeLog:

> >>>> 

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

> >>>> 

> >>>>     * gcc.target/pru/lra-framepointer-fragmentation-1.c: New test.

> >>>>     * gcc.target/pru/lra-framepointer-fragmentation-2.c: New test.

> >>>> 

> >>>> 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>

> >>>> Signed-off-by: Dimitar Dimitrov <dddimitrov@mm-sol.com>

> >>>> ---

> >>>> 

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

> >>>>   .../pru/lra-framepointer-fragmentation-1.c         | 33 ++++++++++++

> >>>>   .../pru/lra-framepointer-fragmentation-2.c         | 61

> >>>> 

> >>>> ++++++++++++++++++++++

> >>>> 

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

> >>>>   create mode 100644

> >>>> 

> >>>> gcc/testsuite/gcc.target/pru/lra-framepointer-fragmentation-1.c

> >>>> 

> >>>>   create mode 100644

> >>>> 

> >>>> gcc/testsuite/gcc.target/pru/lra-framepointer-fragmentation-2.c

> >>>> 

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

> >>>> index 21d8d5f8018..566cc2c8248 100644

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

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

> >>>> @@ -1180,6 +1180,16 @@ spill_pseudos (HARD_REG_SET set)

> >>>> 

> >>>>     bitmap_clear (&to_process);

> >>>>   

> >>>>   }

> >>>>   +static void set_ptr_hard_reg_bits (HARD_REG_SET *hard_reg_set, int

> >>>>   r)

> >>>> 

> >>>> +{

> >>>> +  int w;

> >>>> +

> >>>> +  for (w = 0; w < GET_MODE_SIZE (Pmode); w += UNITS_PER_WORD, r++)

> >>>> +    {

> >>>> +      SET_HARD_REG_BIT (*hard_reg_set, r);

> >>>> +    }

> >>>> +}

> >>>> +

> >>> 

> >>> The patch itself is ok but for uniformity I'd use

> >>> 

> >>>     for (int i = hard_regno_nregs (r, Pmode) - 1; i >= 0; i--)

> >>>     

> >>>       SET_HARD_REG_BIT (*hard_reg_set, r + i);

> >> 

> >> I'm a bit surprised we don't already have a utility function to do this.

> >> Hmmm

> >> 

> >> add_to_hard_reg_set (hard_reg_set, Pmode, r)

> >> 

> >> So instead LRA ought to be using that function in the places where calls

> >> to set_ptr_hard_reg_bits were introduced.

> >> 

> >> Dimitar, can you verify that change works?

> > 

> > Thank you. I'll test it and will update the patch.

> 

> And go ahead and either break out the two new tests.  I suspect we'll

> want to install the LRA patch immediately since it's an independent bugfix.

I verified that add_to_hard_reg_set() fixes the failing tests for PRU.

> 

> > The SET_HARD_REG_BIT call in check_pseudos_live_through_calls also seems

> > suspicous to me. I'll try to come up with a regression test case to

> > justify

> > its upgrade to add_to_hard_reg_set().

> 

> If you can construct a test, great, but from my reading it's clearly

> wrong as well and we ought to fix it too.

I'll send a standalone LRA fix, without PRU tests.

> 

> Jeff

> 

> ps.  Do you have a copyright assignment on file with the FSF for GCC work?

Yes. FSF has my copyright assignment since November 2016 for GCC, Binutils and 
GDB.

Regards,
Dimitar

Patch

diff --git a/gcc/lra-eliminations.c b/gcc/lra-eliminations.c
index 21d8d5f8018..566cc2c8248 100644
--- a/gcc/lra-eliminations.c
+++ b/gcc/lra-eliminations.c
@@ -1180,6 +1180,16 @@  spill_pseudos (HARD_REG_SET set)
   bitmap_clear (&to_process);
 }
 
+static void set_ptr_hard_reg_bits (HARD_REG_SET *hard_reg_set, int r)
+{
+  int w;
+
+  for (w = 0; w < GET_MODE_SIZE (Pmode); w += UNITS_PER_WORD, r++)
+    {
+	  SET_HARD_REG_BIT (*hard_reg_set, r);
+    }
+}
+
 /* Update all offsets and possibility for elimination on eliminable
    registers.  Spill pseudos assigned to registers which are
    uneliminable, update LRA_NO_ALLOC_REGS and ELIMINABLE_REG_SET.  Add
@@ -1264,13 +1274,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);
+      set_ptr_hard_reg_bits (&temp_hard_reg_set, 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);
+	  set_ptr_hard_reg_bits (&temp_hard_reg_set, ep->to);
 	if (maybe_ne (ep->previous_offset, ep->offset))
 	  {
 	    bitmap_ior_into (insns_with_changed_offsets,
diff --git a/gcc/testsuite/gcc.target/pru/lra-framepointer-fragmentation-1.c b/gcc/testsuite/gcc.target/pru/lra-framepointer-fragmentation-1.c
new file mode 100644
index 00000000000..ee1288fc2ae
--- /dev/null
+++ b/gcc/testsuite/gcc.target/pru/lra-framepointer-fragmentation-1.c
@@ -0,0 +1,33 @@ 
+/* { dg-do assemble } */
+/* { dg-options "-O1 -fno-omit-frame-pointer" } */
+#include <stdint.h>
+
+extern uint64_t global;
+
+uint64_t __attribute__((noinline)) test(uint64_t a, uint64_t b,
+                                         uint64_t c, uint64_t d,
+                                         uint64_t e, uint64_t f,
+                                         uint64_t g, uint64_t h)
+{
+  uint64_t l1 = 0x12345678, l2 = 0x87654321, l3 = 1001, l4 = 1002;
+  uint64_t l5 = 1004;
+  uint32_t l6 = 2005;
+  uint8_t c1 = 101, c2 = 102;
+
+  /* The numerous dummy asm input operands create just
+   * enough register pressure to resort to using
+   * FP.b1 (r4.b1).
+   */
+
+  asm ("nop" /* { dg-error "'asm' operand has impossible constraints" } */
+       : "=r" (l1)
+       : "0" (l1), "r" (a), "r"(b),
+       "r"(c), "r"(d), "r"(e), "r"(f),
+       "r"(g), "r"(h), "r"(l2),
+       "r"(c1), "r"(c2),
+       "r"(l3), "r"(l4), "r"(l5), "r"(l6));
+
+  global = a+b+c+d+e+f+g+h + c1+c2 + l2;
+
+  return l1;
+}
diff --git a/gcc/testsuite/gcc.target/pru/lra-framepointer-fragmentation-2.c b/gcc/testsuite/gcc.target/pru/lra-framepointer-fragmentation-2.c
new file mode 100644
index 00000000000..6c98e9bf13b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/pru/lra-framepointer-fragmentation-2.c
@@ -0,0 +1,61 @@ 
+/* { dg-do run } */
+/* { dg-options "-O1 -fomit-frame-pointer" } */
+#include <stdint.h>
+
+extern void abort (void);
+
+uint64_t global = 5;
+
+uint64_t __attribute__((noinline)) test(uint64_t a, uint64_t b,
+                                         uint64_t c, uint64_t d,
+                                         uint64_t e, uint64_t f,
+                                         uint64_t g, uint64_t h)
+{
+  uint64_t l1 = 0x12345678, l2 = 0x87654321, l3 = 1001, l4 = 1002;
+  uint64_t l5 = 1004;
+  uint32_t l6 = 2005;
+  uint8_t c1 = 101, c2 = 102;
+
+  /* The numerous dummy asm input operands create just
+   * enough register pressure to resort to using FP (r4).
+   */
+
+  asm ("ldi32 %0, 0x11223344\n\t"
+       "add %0, %0, %2\n\t"
+       "add %0, %0, %3\n\t"
+       "add %0, %0, %4\n\t"
+       "add %0, %0, %5\n\t"
+       "add %0, %0, %6\n\t"
+       "add %0, %0, %7\n\t"
+       "add %0, %0, %8\n\t"
+       "add %0, %0, %9\n\t"
+       "add %0, %0, %10\n\t"
+       "add %0, %0, %11\n\t"
+       "add %0, %0, %12\n\t"
+       "add %0, %0, %13\n\t"
+       "add %0, %0, %14\n\t"
+       "add %0, %0, %15\n\t"
+       "add %0, %0, %16\n\t"
+       : "=r" (l1)
+       : "0" (l1), "r" (a), "r"(b),
+       "r"(c), "r"(d), "r"(e), "r"(f),
+       "r"(g), "r"(h), "r"(c1), "r"(c2),
+       "r"(l2), "r"(l3), "r"(l4), "r"(l5), "r"(l6));
+
+  global = a+b+c+d+e+f+g+h + c1+c2 + l2+l3+l4+l5+l6;
+
+  return l1;
+}
+
+int main()
+{
+  uint64_t a = test(1, 2, 3, 4, 5, 6, 7, 8);
+
+  if (a != 0x98878ae8) {
+    abort();
+  }
+  if (global != 0x876557a4) {
+    abort();
+  }
+  return 0;
+}