[Patch, RTL] Eliminate redundant vec_select moves.

Richard Sandiford rdsandiford@googlemail.com
Sun Nov 10 20:59:00 GMT 2013


Tejas Belagod <tbelagod@arm.com> writes:
>> The problem is that one reg rtx can span several hard registers.
>> E.g. (reg:V4SI 32) might represent one 64-bit register (no. 32),
>> but it might instead represent two 32-bit registers (nos. 32 and 33).
>> Obviously the latter's not very likely for vectors this small,
>> but more likely for larger ones (including on NEON IIRC).
>> 
>> So if we had 2 32-bit registers being treated as a V4HI, it would be:
>> 
>>    <--32--><--33-->
>>    msb          lsb
>>    0000111122223333
>>    VVVVVVVV
>>    00001111
>>    msb  lsb
>>    <--32-->
>> 
>> for big endian and:
>> 
>>    <--33--><--32-->
>>    msb          lsb
>>    3333222211110000
>>            VVVVVVVV
>>            11110000
>>            msb  lsb
>>            <--32-->
>> 
>> for little endian.
>
> Ah, ok, that makes things clearer. Thanks for that.
>
> I can't find any helper function that figures out if we're writing partial or 
> full result regs. Would something like
>
>      REGNO (src) == REGNO (dst) &&
>      HARD_REGNO_NREGS (src) == HARD_REGNO_NREGS (dst) == 1
>
> be a sane check for partial result regs?

Yeah, that should work.  I think a more general alternative would be:

  simplify_subreg_regno (REGNO (src), GET_MODE (src),
                         offset, GET_MODE (dst)) == (int) REGNO (dst)

where:

  offset = GET_MODE_UNIT_SIZE (GET_MODE (src)) * INTVAL (XVECEXP (sel, 0))

That offset is the byte offset of the first selected element from the
start of a vector in memory, which is also the way that SUBREG_BYTEs
are counted.  For little-endian it gives the offset of the lsb of the
slice, while for big-endian it gives the offset of the msb (which is
also how SUBREG_BYTEs work).

The simplify_subreg_regno should cope with both single-register vectors
and multi-register vectors.

Thanks,
Richard



More information about the Gcc-patches mailing list