Re: Base subreg rules on REGMODE_NATURAL_SIZE rather than UNITS_PER_WORD
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
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
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