This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [Patch, RTL] Eliminate redundant vec_select moves.
- From: Richard Sandiford <rdsandiford at googlemail dot com>
- To: Tejas Belagod <tbelagod at arm dot com>
- Cc: "gcc-patches\ at gcc dot gnu dot org" <gcc-patches at gcc dot gnu dot org>
- Date: Sun, 10 Nov 2013 20:03:55 +0000
- Subject: Re: [Patch, RTL] Eliminate redundant vec_select moves.
- Authentication-results: sourceware.org; auth=none
- References: <527A4309 dot 70209 at arm dot com> <8738n9sj8o dot fsf at talisman dot default> <527A5EF4 dot 5090505 at arm dot com> <87y551r01p dot fsf at talisman dot default> <527A7612 dot 2080406 at arm dot com> <877gcll9ht dot fsf at talisman dot default> <527BA073 dot 30900 at arm dot com> <87zjpg1d5p dot fsf at sandifor-thinkpad dot stglab dot manchester dot uk dot ibm dot com> <527BD411 dot 6060300 at arm dot com>
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