PR 34998: Tracking of subreg liveness in global.c and ra-conflict.c

Kenneth Zadeck zadeck@naturalbridge.com
Wed Jan 30 02:50:00 GMT 2008


Richard Sandiford wrote:
> Ian Lance Taylor <iant@google.com> writes:
>   
>> Richard Sandiford <rsandifo@nildram.co.uk> writes:
>>
>>     
>>> gcc/
>>> 	PR rtl-optimization/34998
>>> 	* ra-conflict.c (clear_reg_in_live): Treat SUBREGs of pseudos
>>> 	as clobbering all the words covered by the SUBREG, not just all
>>> 	the bytes.
>>> 	* global.c (build_insn_chain): Likewise.
>>>       
>> This looks OK to me but I'd like to hear from one of the RA
>> maintainers.
>>     
>
> OK, thanks.  I've added them to cc:.  For reference, the original
> message was:
>
>     http://gcc.gnu.org/ml/gcc-patches/2008-01/msg01383.html
>
>   
>> This ignores strict_low_part, but it seems that that
>> should not matter for purposes of register allocation.
>>     
>
> Argh!  Good point.  I think the new code should indeed be
> conditional on the subreg not being a strict lowpart.
>
>   
>> And it doesn't handle registers of sizes other than UNITS_PER_WORD,
>> but I suspect we will have other problems in that area.
>>     
>
> Well, the patched code is only handling subregs of pseudo registers,
> and my understanding is that the semantics of assignments are always
> word-based for pseudo-register subregs, regardless of whether the pseudo
> gets allocated to a group of subword, word, or superword hard registers.
>
>  [<greps>.  Some supporting evidence from validate_subreg:
>
>     /* For pseudo registers, we want most of the same checks.  Namely:
>        If the register no larger than a word, the subreg must be lowpart.
>        If the register is larger than a word, the subreg must be the lowpart
>        of a subword.  A subreg does *not* perform arbitrary bit extraction.
>        Given that we've already checked mode/offset alignment, we only have
>        to check subword subregs here.  */
>     if (osize < UNITS_PER_WORD)
>       {
>         enum machine_mode wmode = isize > UNITS_PER_WORD ? word_mode : imode;
>         unsigned int low_off = subreg_lowpart_offset (omode, wmode);
>         if (offset % UNITS_PER_WORD != low_off)
>           return false;
>       }
>
>   rtl.texi spells out the behaviour explicitly:
>
>     Storing in a non-paradoxical @code{subreg} has undefined results for
>     bits belonging to the same word as the @code{subreg}.  This laxity
>     makes it easier to generate efficient code for such instructions.
>     To represent an instruction that preserves all the bits outside of
>     those in the @code{subreg}, use @code{strict_low_part} around the
>     @code{subreg}.
>
>   but I'm not sure how reliable that is.  The description isn't
>   conditional on the registers being pseudos or word-sized hard
>   registers, and it might not have been fully updated after the
>   move to SUBREG_BYTE. ]
>
> So let's take the case of pseudo registers allocated to a group of
> subword hard registers.  The target-independent code would not have
> known when generating the pseudo-register subregs that the pseudo
> register was destined for this type of hard register.  It couldn't
> have relied upon the other bytes in a clobbered word being preserved.
>
> So I think the patch really does model the intended behaviour of the
> pseudo-register access in this case.  E.g. if we allocate an SImode
> pseudo FOO to two HImode registers on a 32-bit target, a set of
> (subreg:HI (reg:SI FOO) ...) really should clobber both of the HImode
> registers.  ("..." is either 0 or 2, depending on endianness.  The other
> value isn't valid.)
>
> The same applies to registers wider than a word.  However, my understanding
> is that CLASS_CANNOT_CHANGE_MODE must forbid cases where you might take
> word or subword subregs of supwerword hard registers, because the
> target-independent code would have expected each word of the original
> pseudo register to be independently modifiable.  E.g. if we have a
> DImode pseudo register FOO on a 32-bit target, and we have accesses
> of the form (subreg:SI (reg:DI FOO) 0) or (subreg:SI (reg:DI FOO) 4),
> we cannot allocate FOO to a 64-bit register.  Substituting a 64-bit
> register into these subregs would make one of them invalid and would
> turn the other from a half-register clobber to a full-register clobber.
> (Which subreg is which depends on endianness.)
>
> So I'd argue that this behaviour for pseudos really is the right thing,
> rather than a more murky "good enough for cases that are likely to
> work" fix.
>
> (Er, was that vaguely convincing? ;))
>
> Richard
>   
Having been the one who wrote this code, (with a lot of help from others
listed in this mail) it was my intent to try to move things towards a
world where only the fewest number interferences are ever generated with
the intent that this might allow the current or future register
allocators to allocate some other object to occupy those other parts. 

If this does not work, and richard seems to have found chases where it
does not, then we need to back down to the more conservative marking the
entire register. 

Kenny



More information about the Gcc-patches mailing list