"H.J. Lu" <hjl.to...@gmail.com> writes:
> On Wed, Dec 11, 2013 at 1:13 AM, Richard Sandiford
> <rdsandif...@googlemail.com> wrote:
>> Richard Henderson <r...@redhat.com> writes:
>>> On 12/10/2013 10:44 AM, Richard Sandiford wrote:
>>>> Sorry, I don't understand.  I never said it was invalid.  I said
>>>> (subreg:SF (reg:V4SF X) 1) was invalid if (reg:V4SF X) represents
>>>> a single register.  On a little-endian target, the offset cannot be
>>>> anything other than 0 in that case.
>>>>
>>>> So the CANNOT_CHANGE_MODE_CLASS code above seems to be checking for
>>>> something that is always invalid, regardless of the target.  That kind
>>>> of situation should be rejected by target-independent code instead.
>>>
>>> But, we want to disable the subreg before we know whether or not (reg:V4SF 
>>> X)
>>> will be allocated to a single hard register.  That is something that we 
>>> can't
>>> know in target-independent code before register allocation.
>>
>> I was thinking that if we've got a class, we've also got things like
>> CLASS_MAX_NREGS.  Maybe that doesn't cope with padding properly though.
>> But even in the padding cases an offset-based check in C_C_M_C could
>> be derived from other information.
>>
>> subreg_get_info handles padding with:
>>
>>       nregs_xmode = HARD_REGNO_NREGS_WITH_PADDING (xregno, xmode);
>>       if (GET_MODE_INNER (xmode) == VOIDmode)
>>         xmode_unit = xmode;
>>       else
>>         xmode_unit = GET_MODE_INNER (xmode);
>>       gcc_assert (HARD_REGNO_NREGS_HAS_PADDING (xregno, xmode_unit));
>>       gcc_assert (nregs_xmode
>>                   == (GET_MODE_NUNITS (xmode)
>>                       * HARD_REGNO_NREGS_WITH_PADDING (xregno, xmode_unit)));
>>       gcc_assert (hard_regno_nregs[xregno][xmode]
>>                   == (hard_regno_nregs[xregno][xmode_unit]
>>                       * GET_MODE_NUNITS (xmode)));
>>
>>       /* You can only ask for a SUBREG of a value with holes in the middle
>>          if you don't cross the holes.  (Such a SUBREG should be done by
>>          picking a different register class, or doing it in memory if
>>          necessary.)  An example of a value with holes is XCmode on 32-bit
>>          x86 with -m128bit-long-double; it's represented in 6 32-bit 
>> registers,
>>          3 for each part, but in memory it's two 128-bit parts.
>>          Padding is assumed to be at the end (not necessarily the 'high 
>> part')
>>          of each unit.  */
>>       if ((offset / GET_MODE_SIZE (xmode_unit) + 1
>>            < GET_MODE_NUNITS (xmode))
>>           && (offset / GET_MODE_SIZE (xmode_unit)
>>               != ((offset + GET_MODE_SIZE (ymode) - 1)
>>                   / GET_MODE_SIZE (xmode_unit))))
>>         {
>>           info->representable_p = false;
>>           rknown = true;
>>         }
>>
>> and I wouldn't really want to force targets to individually reproduce
>> that kind of logic at the class level.  If the worst comes to the worst
>> we could cache the difficult cases.
>>
>
> My case is x86 CANNOT_CHANGE_MODE_CLASS only needs
> to know if the subreg byte is zero or not.  It doesn't care about mode
> padding.  You are concerned about information passed to
> CANNOT_CHANGE_MODE_CLASS is too expensive for target
> to process.  It isn't the case for x86.

No, I'm concerned that by going this route, we're forcing every target
(or at least every target with wider-than-word registers, which is most
of the common ones) to implement the same target-independent restriction.
This is not an x86-specific issue.

Thanks,
Richard

Reply via email to