Richard Biener <richard.guent...@gmail.com> writes:
> On Wed, Oct 31, 2012 at 1:05 PM, Richard Sandiford
> <rdsandif...@googlemail.com> wrote:
>> Richard Biener <richard.guent...@gmail.com> writes:
>>> On Wed, Oct 31, 2012 at 11:43 AM, Richard Sandiford
>>> <rdsandif...@googlemail.com> wrote:
>>>> Richard Biener <richard.guent...@gmail.com> writes:
>>>>> On Thu, Oct 25, 2012 at 12:55 PM, Kenneth Zadeck
>>>>> <zad...@naturalbridge.com> wrote:
>>>>>>
>>>>>> On 10/25/2012 06:42 AM, Richard Biener wrote:
>>>>>>>
>>>>>>> On Wed, Oct 24, 2012 at 7:23 PM, Mike Stump
>>>>>>> <mikest...@comcast.net> wrote:
>>>>>>>>
>>>>>>>> On Oct 24, 2012, at 2:43 AM, Richard Biener 
>>>>>>>> <richard.guent...@gmail.com>
>>>>>>>> wrote:
>>>>>>>>>
>>>>>>>>> On Tue, Oct 23, 2012 at 6:12 PM, Kenneth Zadeck
>>>>>>>>> <zad...@naturalbridge.com> wrote:
>>>>>>>>>>
>>>>>>>>>> On 10/23/2012 10:12 AM, Richard Biener wrote:
>>>>>>>>>>>
>>>>>>>>>>> +  HOST_WIDE_INT val[2 * MAX_BITSIZE_MODE_ANY_INT /
>>>>>>>>>>> HOST_BITS_PER_WIDE_INT];
>>>>>>>>>>>
>>>>>>>>>>> are we sure this rounds properly?  Consider a port with max byte 
>>>>>>>>>>> mode
>>>>>>>>>>> size 4 on a 64bit host.
>>>>>>>>>>
>>>>>>>>>> I do not believe that this can happen.  The core compiler
>>>>>>>>>> includes all
>>>>>>>>>> modes up to TI mode, so by default we already up to 128 bits.
>>>>>>>>>
>>>>>>>>> And mode bitsizes are always power-of-two?  I suppose so.
>>>>>>>>
>>>>>>>> Actually, no, they are not.  Partial int modes can have bit sizes that
>>>>>>>> are not power of two, and, if there isn't an int mode that is
>>>>>>>> bigger, we'd
>>>>>>>> want to round up the partial int bit size.  Something like ((2 *
>>>>>>>> MAX_BITSIZE_MODE_ANY_INT + HOST_BITS_PER_WIDE_INT - 1) /
>>>>>>>> HOST_BITS_PER_WIDE_INT should do it.
>>>>>>>>
>>>>>>>>>>> I still would like to have the ability to provide specializations of
>>>>>>>>>>> wide_int
>>>>>>>>>>> for "small" sizes, thus ideally wide_int would be a template
>>>>>>>>>>> templated
>>>>>>>>>>> on the number of HWIs in val.  Interface-wise wide_int<2> should be
>>>>>>>>>>> identical to double_int, thus we should be able to do
>>>>>>>>>>>
>>>>>>>>>>> typedef wide_int<2> double_int;
>>>>>>>>>>
>>>>>>>>>> If you want to go down this path after the patches get in, go for it.
>>>>>>>>>> I
>>>>>>>>>> see no use at all for this.
>>>>>>>>>> This was not meant to be a plug in replacement for double int. This
>>>>>>>>>> goal of
>>>>>>>>>> this patch is to get the compiler to do the constant math the way 
>>>>>>>>>> that
>>>>>>>>>> the
>>>>>>>>>> target does it.   Any such instantiation is by definition placing 
>>>>>>>>>> some
>>>>>>>>>> predefined limit that some target may not want.
>>>>>>>>>
>>>>>>>>> Well, what I don't really like is that we now have two implementations
>>>>>>>>> of functions that perform integer math on two-HWI sized integers.  
>>>>>>>>> What
>>>>>>>>> I also don't like too much is that we have two different interfaces to
>>>>>>>>> operate
>>>>>>>>> on them!  Can't you see how I come to not liking this?  Especially the
>>>>>>>>> latter …
>>>>>>>>
>>>>>>>> double_int is logically dead.  Reactoring wide-int and double-int is a
>>>>>>>> waste of time, as the time is better spent removing double-int from the
>>>>>>>> compiler.  All the necessary semantics and code of double-int _has_ 
>>>>>>>> been
>>>>>>>> refactored into wide-int already.  Changing wide-int in any way to vend
>>>>>>>> anything to double-int is wrong, as once double-int is removed,
>>>>>>>> then all the
>>>>>>>> api changes to make double-int share from wide-int is wasted and
>>>>>>>> must then
>>>>>>>> be removed.  The path forward is the complete removal of
>>>>>>>> double-int; it is
>>>>>>>> wrong, has been wrong and always will be wrong, nothing can change 
>>>>>>>> that.
>>>>>>>
>>>>>>> double_int, compared to wide_int, is fast and lean.  I doubt we will
>>>>>>> get rid of it - you
>>>>>>> will make compile-time math a _lot_ slower.  Just profile when you for
>>>>>>> example
>>>>>>> change get_inner_reference to use wide_ints.
>>>>>>>
>>>>>>> To be able to remove double_int in favor of wide_int requires _at least_
>>>>>>> templating wide_int on 'len' and providing specializations for 1 and 2.
>>>>>>>
>>>>>>> It might be a non-issue for math that operates on trees or RTXen due to
>>>>>>> the allocation overhead we pay, but in recent years we transitioned
>>>>>>> important
>>>>>>> paths away from using tree math to using double_ints _for speed 
>>>>>>> reasons_.
>>>>>>>
>>>>>>> Richard.
>>>>>>
>>>>>> i do not know why you believe this about the speed.     double int always
>>>>>> does synthetic math since you do everything at 128 bit precision.
>>>>>>
>>>>>> the thing about wide int, is that since it does math to the precision's
>>>>>> size, it almost never does uses synthetic operations since the sizes for
>>>>>> almost every instance can be done using the native math on the machine.
>>>>>> almost every call has a check to see if the operation can be done
>>>>>> natively.
>>>>>> I seriously doubt that you are going to do TI mode math much faster than 
>>>>>> i
>>>>>> do it and if you do who cares.
>>>>>>
>>>>>> the number of calls does not effect the performance in any
>>>>>> negative way and
>>>>>> it fact is more efficient since common things that require more than one
>>>>>> operation in double in are typically done in a single operation.
>>>>>
>>>>> Simple double-int operations like
>>>>>
>>>>> inline double_int
>>>>> double_int::and_not (double_int b) const
>>>>> {
>>>>>   double_int result;
>>>>>   result.low = low & ~b.low;
>>>>>   result.high = high & ~b.high;
>>>>>   return result;
>>>>> }
>>>>>
>>>>> are always going to be faster than conditionally executing only one
>>>>> operation
>>>>> (but inside an offline function).
>>>>
>>>> OK, this is really in reply to the 4.8 thing, but it felt more
>>>> appropriate here.
>>>>
>>>> It's interesting that you gave this example, since before you were
>>>> complaining about too many fused ops.  Clearly this one could be
>>>> removed in favour of separate and() and not() operations, but why
>>>> not provide a fused one if there are clients who'll make use of it?
>>>
>>> I was more concerned about fused operations that use precision
>>> or bitsize as input.  That is for example
>>>
>>>>> +  bool only_sign_bit_p (unsigned int prec) const;
>>>>> +  bool only_sign_bit_p () const;
>>>
>>> The first is construct a wide-int with precision prec (and sign- or
>>> zero-extend it) and then call only_sign_bit_p on it.  Such function
>>> should not be necessary and existing callers should be questioned
>>> instead of introducing it.
>>>
>>> In fact wide-int seems to have so many "fused" operations that
>>> we run out of sensible recognizable names for them.  Which results
>>> in a lot of confusion on what the functions actually do (at least for me).
>>
>> Well, I suppose I can't really say anything useful either way on
>> that one, since I'm not writing the patch and I'm not reviewing it :-)
>>
>>>> I think Kenny's API is just taking that to its logical conclusion.
>>>> There doesn't seem to be anything sacrosanct about the current choice
>>>> of what's fused and what isn't.
>>>
>>> Maybe.  I'd rather have seen an initial small wide-int API and fused
>>> operations introduced separately together with the places they are
>>> used.  In the current way it's way too tedious to go over all of them
>>> and match them with callers, lookup enough context and then
>>> make up my mind on whether the caller should do sth different or not.
>>>
>>> Thus, consider the big initial API a reason that all this review takes
>>> so long ...
>>>
>>>> The speed problem we had using trees for internal arithmetic isn't
>>>> IMO a good argument for keeping double_int in preference to wide_int.
>>>> Allocating and constructing tree objects to hold temporary values,
>>>> storing an integer representation in it, then calling tree arithmetic
>>>> routines that pull out the integer representation again and create a
>>>> tree to hold the result, is going to be much slower than using either
>>>> double_int or wide_int.  I'd be very surprised if we notice any
>>>> measurable difference between double_int and wide_int here.
>>>>
>>>> I still see no reason to keep double_int around.  The width of a host
>>>> wide integer really shouldn't have any significance.
>>>>
>>>> Your main complaint seems to be that the wide_int API is different
>>>> from the double_int one, but we can't literally use the same API, since
>>>> double_int has an implicit precision and bitsize, and wide_int doesn't.
>>>> Having a precision that is separate from the underlying representation
>>>> is IMO the most important feature of wide_int, so:
>>>>
>>>>    template wide_int<2> double_int;
>>>>
>>>> is never going to be a drop-in, API-compatible replacement for double_int.
>>>
>>> My reasoning was that if you strip wide-int of precision and bitsize
>>> you have a double_int<N> class.
>>
>> But you don't!  Because...
>>
>>> Thus wide-int should have a base
>>> of that kind and just add precision / bitsize ontop of that.  It wouldn't
>>> be a step forward if we end up replacing double_int uses with
>>> wide_int uses with precision of 2 * HOST_BITS_PER_WIDE_INT,
>>> would it?
>>
>> ...the precision and bitsize isn't an optional extra, either conceptually
>> or in implementation.  wide_int happens to use N HOST_WIDE_INTS under
>> the hood, but the value of N is an internal implementation detail.
>> No operations are done to N HWIs, they're done to the number of bits
>> in the operands.  Whereas a double_int<N> class does everything to N HWIs.
>
> If that's the only effect then either bitsize or precision is redundant (and
> we also have len ...).  Note I did not mention len above, thus the base
> class would retain 'len' and double-int would simply use 2 for it
> (if you don't template it but make it variable).

But that means that wide_int has to model a P-bit operation as a
"normal" len*HOST_WIDE_INT operation and then fix up the result
after the fact, which seems unnecessarily convoluted.  I still don't
see why a full-precision 2*HOST_WIDE_INT operation (or a full-precision
X*HOST_WIDE_INT operation for any X) has any special meaning.

Richard

Reply via email to