Re: Base subreg rules on REGMODE_NATURAL_SIZE rather than UNITS_PER_WORD

2017-11-08 Thread Jeff Law
On 11/06/2017 07:53 AM, Richard Sandiford wrote:
>>> 2017-09-18  Richard Sandiford  
>>> Alan Hayward  
>>> David Sherwood  
>>>
>>> gcc/
>>> * doc/rtl.texi: Rewrite the subreg rules so that they partition
>>> the inner register into REGMODE_NATURAL_SIZE bytes rather than
>>> UNITS_PER_WORD bytes.
>>> * emit-rtl.c (validate_subreg): Divide subregs into blocks
>>> based on REGMODE_NATURAL_SIZE of the inner mode.
>>> (gen_lowpart_common): Split the SCALAR_FLOAT_MODE_P and
>>> !SCALAR_FLOAT_MODE_P cases.  Use REGMODE_NATURAL_SIZE for the latter.
>>> * expr.c (store_constructor): Use REGMODE_NATURAL_SIZE to test
>>> whether something is likely to occupy more than one register.
>> OK.  Though I must admit, I expected a larger change after reading the
>> intro.
> 
> Heh.  As it turned out I did find one more place that needed to change
> (lowpart_bit_field_p).  Maybe there'll be more -- e.g. it'd probably
> make sense to make lower-subreg.c split based on this instead of
> UNITS_PER_WORD.
> 
> How about this?  Tested as before.
> 
> Thanks,
> Richard
> 
> 
> 2017-11-06  Richard Sandiford  
>   Alan Hayward  
>   David Sherwood  
> 
> gcc/
>   * doc/rtl.texi: Rewrite the subreg rules so that they partition
>   the inner register into REGMODE_NATURAL_SIZE bytes rather than
>   UNITS_PER_WORD bytes.
>   * emit-rtl.c (validate_subreg): Divide subregs into blocks
>   based on REGMODE_NATURAL_SIZE of the inner mode.
>   (gen_lowpart_common): Split the SCALAR_FLOAT_MODE_P and
>   !SCALAR_FLOAT_MODE_P cases.  Use REGMODE_NATURAL_SIZE for the latter.
>   * expmed.c (lowpart_bit_field_p): Divide the value up into
>   chunks of REGMODE_NATURAL_SIZE rather than UNITS_PER_WORD.
>   * expr.c (store_constructor): Use REGMODE_NATURAL_SIZE to test
>   whether something is likely to occupy more than one register.
OK.  I still expect more fallout though :-)

Jeff


Re: Base subreg rules on REGMODE_NATURAL_SIZE rather than UNITS_PER_WORD

2017-11-06 Thread Richard Sandiford
Jeff Law  writes:
> On 09/18/2017 05:26 AM, Richard Sandiford wrote:
>> Originally subregs operated at the word level and subreg offsets
>> were measured in words.  The offset units were later changed from
>> words to bytes (SUBREG_WORD became SUBREG_BYTE), but the fundamental
>> assumption that subregs should operate at the word level remained.
>> Whether (subreg:M1 (reg:M2 R2) N) is well-formed depended on the
>> way that M1 and M2 partitioned into words and whether the subword
>> part of N represented a lowpart.  However, some questions depended
>> instead on the macro REGMODE_NATURAL_SIZE, which was introduced
>> as part of the patch that moved from SUBREG_WORD to SUBREG_BYTE.
>> It is used to decide whether setting (subreg:M1 (reg:M2 R2) N)
>> clobbers all of R2 or just part of it (df_read_modify_subreg).
>> 
>> Using words doesn't really make sense for modern vector
>> architectures.  Vector registers are usually bigger than
>> a word and:
>> 
>> (a) setting the scalar lowpart of them usually clobbers the
>> rest of the register (contrary to the subreg rules,
>> where only the containing words should be clobbered).
>> 
>> (b) high words of vector registers are often not independently
>> addressable, even though that's what the subreg rules expect.
>> 
>> This patch therefore uses REGMODE_NATURAL_SIZE instead of
>> UNITS_PER_WORD to determine the size of the independently
>> addressable blocks in an inner register.
>> 
>> This is needed for SVE because the number of words in a vector
>> mode isn't known at compile time, so isn't a sensible basis
>> for calculating the number of registers.
>> 
>> The only existing port to define REGMODE_NATURAL_SIZE is
>> 64-bit SPARC, where FP registers are 32 bits.  (This is the
>> opposite of the use case for SVE, since the natural division
>> is smaller than a word.)  I compiled the testsuite before and
>> after the patch for sparc64-linux-gnu and the only test whose
>> assembly changed was g++.dg/debug/pr65678.C, where the order
>> of two independent stores was reversed and where a different
>> register was picked for one pseudo.  The new code was
>> otherwise equivalent to the old code.
>> 
>> Tested on aarch64-linux-gnu, x86_64-linux-gnu and powerpc64le-linux-gnu.
>> Also tested by comparing the testsuite assembly output on at least one
>> target per CPU directory, with only the SPARC differences just mentioned.
>> OK to install?
>> 
>> Richard
>> 
>> 
>> 2017-09-18  Richard Sandiford  
>>  Alan Hayward  
>>  David Sherwood  
>> 
>> gcc/
>>  * doc/rtl.texi: Rewrite the subreg rules so that they partition
>>  the inner register into REGMODE_NATURAL_SIZE bytes rather than
>>  UNITS_PER_WORD bytes.
>>  * emit-rtl.c (validate_subreg): Divide subregs into blocks
>>  based on REGMODE_NATURAL_SIZE of the inner mode.
>>  (gen_lowpart_common): Split the SCALAR_FLOAT_MODE_P and
>>  !SCALAR_FLOAT_MODE_P cases.  Use REGMODE_NATURAL_SIZE for the latter.
>>  * expr.c (store_constructor): Use REGMODE_NATURAL_SIZE to test
>>  whether something is likely to occupy more than one register.
> OK.  Though I must admit, I expected a larger change after reading the
> intro.

Heh.  As it turned out I did find one more place that needed to change
(lowpart_bit_field_p).  Maybe there'll be more -- e.g. it'd probably
make sense to make lower-subreg.c split based on this instead of
UNITS_PER_WORD.

How about this?  Tested as before.

Thanks,
Richard


2017-11-06  Richard Sandiford  
Alan Hayward  
David Sherwood  

gcc/
* doc/rtl.texi: Rewrite the subreg rules so that they partition
the inner register into REGMODE_NATURAL_SIZE bytes rather than
UNITS_PER_WORD bytes.
* emit-rtl.c (validate_subreg): Divide subregs into blocks
based on REGMODE_NATURAL_SIZE of the inner mode.
(gen_lowpart_common): Split the SCALAR_FLOAT_MODE_P and
!SCALAR_FLOAT_MODE_P cases.  Use REGMODE_NATURAL_SIZE for the latter.
* expmed.c (lowpart_bit_field_p): Divide the value up into
chunks of REGMODE_NATURAL_SIZE rather than UNITS_PER_WORD.
* expr.c (store_constructor): Use REGMODE_NATURAL_SIZE to test
whether something is likely to occupy more than one register.

Index: gcc/doc/rtl.texi
===
--- gcc/doc/rtl.texi2017-11-06 14:44:22.098357016 +
+++ gcc/doc/rtl.texi2017-11-06 14:49:48.804883947 +
@@ -1925,19 +1925,32 @@ false.
 When @var{m1} is at least as narrow as @var{m2} the @code{subreg}
 expression is called @dfn{normal}.
 
+@findex REGMODE_NATURAL_SIZE
 Normal @code{subreg}s restrict consideration to certain bits of
-@var{reg}.  There are two cases.  If @var{m1} is smaller than a word,
-the @code{subreg} refers to the least-significant part (or
-@dfn{lowpart}) of one word of @var{reg}.  If @var{m1} is word-sized or
-greater, the @code{subreg} refers to one or more 

Re: Base subreg rules on REGMODE_NATURAL_SIZE rather than UNITS_PER_WORD

2017-10-13 Thread Jeff Law
On 09/18/2017 05:26 AM, Richard Sandiford wrote:
> Originally subregs operated at the word level and subreg offsets
> were measured in words.  The offset units were later changed from
> words to bytes (SUBREG_WORD became SUBREG_BYTE), but the fundamental
> assumption that subregs should operate at the word level remained.
> Whether (subreg:M1 (reg:M2 R2) N) is well-formed depended on the
> way that M1 and M2 partitioned into words and whether the subword
> part of N represented a lowpart.  However, some questions depended
> instead on the macro REGMODE_NATURAL_SIZE, which was introduced
> as part of the patch that moved from SUBREG_WORD to SUBREG_BYTE.
> It is used to decide whether setting (subreg:M1 (reg:M2 R2) N)
> clobbers all of R2 or just part of it (df_read_modify_subreg).
> 
> Using words doesn't really make sense for modern vector
> architectures.  Vector registers are usually bigger than
> a word and:
> 
> (a) setting the scalar lowpart of them usually clobbers the
> rest of the register (contrary to the subreg rules,
> where only the containing words should be clobbered).
> 
> (b) high words of vector registers are often not independently
> addressable, even though that's what the subreg rules expect.
> 
> This patch therefore uses REGMODE_NATURAL_SIZE instead of
> UNITS_PER_WORD to determine the size of the independently
> addressable blocks in an inner register.
> 
> This is needed for SVE because the number of words in a vector
> mode isn't known at compile time, so isn't a sensible basis
> for calculating the number of registers.
> 
> The only existing port to define REGMODE_NATURAL_SIZE is
> 64-bit SPARC, where FP registers are 32 bits.  (This is the
> opposite of the use case for SVE, since the natural division
> is smaller than a word.)  I compiled the testsuite before and
> after the patch for sparc64-linux-gnu and the only test whose
> assembly changed was g++.dg/debug/pr65678.C, where the order
> of two independent stores was reversed and where a different
> register was picked for one pseudo.  The new code was
> otherwise equivalent to the old code.
> 
> Tested on aarch64-linux-gnu, x86_64-linux-gnu and powerpc64le-linux-gnu.
> Also tested by comparing the testsuite assembly output on at least one
> target per CPU directory, with only the SPARC differences just mentioned.
> OK to install?
> 
> Richard
> 
> 
> 2017-09-18  Richard Sandiford  
>   Alan Hayward  
>   David Sherwood  
> 
> gcc/
>   * doc/rtl.texi: Rewrite the subreg rules so that they partition
>   the inner register into REGMODE_NATURAL_SIZE bytes rather than
>   UNITS_PER_WORD bytes.
>   * emit-rtl.c (validate_subreg): Divide subregs into blocks
>   based on REGMODE_NATURAL_SIZE of the inner mode.
>   (gen_lowpart_common): Split the SCALAR_FLOAT_MODE_P and
>   !SCALAR_FLOAT_MODE_P cases.  Use REGMODE_NATURAL_SIZE for the latter.
>   * expr.c (store_constructor): Use REGMODE_NATURAL_SIZE to test
>   whether something is likely to occupy more than one register.
OK.  Though I must admit, I expected a larger change after reading the
intro.

jeff