On Mon, Dec 2, 2013 at 2:48 PM, Richard Sandiford
<rdsandif...@googlemail.com> wrote:
> Richard Biener <richard.guent...@gmail.com> writes:
>> On Sat, Nov 30, 2013 at 10:43 AM, Richard Sandiford
>> <rdsandif...@googlemail.com> wrote:
>>> So maybe two INTEGER_CST lengths weren't enough.  Because bitsizetype
>>> can be offset_int-sized, wi::to_offset had a TYPE_PRECISION condition
>>> to pick the array length:
>>>
>>> template <int N>
>>> inline unsigned int
>>> wi::extended_tree <N>::get_len () const
>>> {
>>>   if (N == MAX_BITSIZE_MODE_ANY_INT
>>>       || N > TYPE_PRECISION (TREE_TYPE (m_t)))
>>>     return TREE_INT_CST_EXT_NUNITS (m_t);
>>>   else
>>>     return TREE_INT_CST_NUNITS (m_t);
>>> }
>>>
>>> and this TYPE_PRECISION condition was relatively hot in
>>> get_ref_base_and_extent when compiling insn-recog.ii.
>>>
>>> Adding a third length for offset_int does seem to reduce the cost of
>>> the offset_int + to_offset addition.
>>>
>>> Tested on x86_64-linux-gnu.  OK to install?
>>
>> Hmm, that's now getting a bit excessive ...
>
> Well, we access trees in three different ways, and we want all of them
> to be cheap, so having three fields in the tree seems pretty natural.

Hmm, I guess you are right :/

>>  inline unsigned int
>>  wi::extended_tree <N>::get_len () const
>>  {
>> -  if (N == MAX_BITSIZE_MODE_ANY_INT
>> -      || N > TYPE_PRECISION (TREE_TYPE (m_t)))
>> +  if (N == ADDR_MAX_PRECISION)
>> +    return TREE_INT_CST_OFFSET_NUNITS (m_t);
>> +  else if (N == MAX_BITSIZE_MODE_ANY_INT
>> +          || N > TYPE_PRECISION (TREE_TYPE (m_t)))
>>      return TREE_INT_CST_EXT_NUNITS (m_t);
>>    else
>>      return TREE_INT_CST_NUNITS (m_t);
>>
>> Shouldn't it be N >= TYPE_PRECISION () btw?
>
> No, TREE_INT_CST_NUNITS is for accessing the tree in TYPE_PRECISION
> and TREE_INT_CST_EXT_NUNITS is for accessing it in wider precisions.
>
> N is always >= TYPE_PRECISION here, from the assert in the constructor:
>
>   gcc_checking_assert (TYPE_PRECISION (TREE_TYPE (t)) <= N);
>
> TREE_INT_CST_OFFSET_NUNITS is just a cached x ? TREE_INT_CST_NUNITS (m_t)
> : TREE_INT_CST_EXT_NUNITS (m_t) result for a particular precision.
>
>> Looking at the implementation it seems it would also work with
>>
>>    return MIN (TREE_INT_CST_EXT_NUNITS (m_t), N / HOST_BITS_PER_WIDE_INT);
>
> Yeah, the MIN in the patch was probably bogus sorry.  It only works
> if we can assume that no bitsizetype will have ADDR_MAX_PRECISION
> significant (non-sign) bits -- in particular that there's no such thing as
> an all-1s _unsigned_ bitsizetype.  That might be true in practice given
> the way we use offsets, but it isn't safe to generalise that to all N.
>
> A safer form would be:
>
>    if (ext_len > OFFSET_INT_ELTS)
>      TREE_INT_CST_OFFSET_NUNITS (t) = len;
>    else
>      TREE_INT_CST_OFFSET_NUNITS (t) = ext_len;
>
> The reason the general form doesn't work for all N is because of the
> compressed representation.  E.g. the example I gave a while ago about
> a 256-bit all-1s unsigned number being { -1 } as a 256-bit number and
> { -1, -1, -1, -1, 0 } as a 257+-bit number.
>
> But the point of the patch is to avoid any runtime checks here,
> so the TYPE_PRECISION case is never actually used now.  I just kept
> it around for completeness, since we'd been using it successfully so far.
> I can put in a gcc_unreachable if you prefer.

Yeah, I'd prefer a gcc_unreachable and a comment.

Thanks,
Richard.

> Thanks,
> Richard

Reply via email to