| Thread overview | |||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
January 01, 2015 Re: CTFE pow() | ||||
|---|---|---|---|---|
| ||||
On Fri, Jan 02, 2015 at 02:56:16AM +1000, Manu via Digitalmars-d wrote: > Does anyone know how to fix this? Can we please do so? It's been a > problem for like 5 years it seems. > It's a bit insane that we can't resolve any non-linear functions at > compile time. I've been waiting for this since like, forever. We even have a D code implementation of pow() already (thanks to Iain), which *should* have been CTFE-able, if it weren't for CTFE limitations that prohibit reinterpreting float values in binary, which is required for certain basic operations like isInfinite, isNaN, etc.. So it seems that the blocker right now is CTFE, which, unfortunately, is not a pretty piece of code, and requires quite a bit of care to get it done right. T -- I am Ohm of Borg. Resistance is voltage over current. | ||||
January 01, 2015 Re: CTFE pow() | ||||
|---|---|---|---|---|
| ||||
Posted in reply to H. S. Teoh | On Thursday, 1 January 2015 at 18:43:12 UTC, H. S. Teoh via Digitalmars-d wrote:
> On Fri, Jan 02, 2015 at 02:56:16AM +1000, Manu via Digitalmars-d wrote:
>> Does anyone know how to fix this? Can we please do so? It's been a
>> problem for like 5 years it seems.
>> It's a bit insane that we can't resolve any non-linear functions at
>> compile time.
>
> I've been waiting for this since like, forever. We even have a D code
> implementation of pow() already (thanks to Iain), which *should* have
> been CTFE-able, if it weren't for CTFE limitations that prohibit
> reinterpreting float values in binary, which is required for certain
> basic operations like isInfinite, isNaN, etc..
>
> So it seems that the blocker right now is CTFE, which, unfortunately, is
> not a pretty piece of code, and requires quite a bit of care to get it
> done right.
>
>
> T
I'm wondering if there's any added benefit to implementing these as intrinsic functions instead? In this way, implementing them in CTFE should be trivial and the extra knowledge given to the compiler could enable extra optimizations that wouldn't be possible otherwise. For example, the compiler understands multiplication and division so, in certain cases, it can replace these operations with bit-shifting which is faster.
| |||
January 02, 2015 Re: CTFE pow() | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Xinok | "Xinok" wrote in message news:pbjttgrpwhsffoovpida@forum.dlang.org... > I'm wondering if there's any added benefit to implementing these as intrinsic functions instead? In this way, implementing them in CTFE should be trivial and the extra knowledge given to the compiler could enable extra optimizations that wouldn't be possible otherwise. For example, the compiler understands multiplication and division so, in certain cases, it can replace these operations with bit-shifting which is faster. I was just about to suggest this. Another easy way might be to just add get/set mantissa/exponent intrinsics and use those in the ctfe versions. | |||
January 02, 2015 Re: CTFE pow() | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Daniel Murphy | On Friday, 2 January 2015 at 08:52:47 UTC, Daniel Murphy wrote:
> "Xinok" wrote in message news:pbjttgrpwhsffoovpida@forum.dlang.org...
>
>> I'm wondering if there's any added benefit to implementing these as intrinsic functions instead? In this way, implementing them in CTFE should be trivial and the extra knowledge given to the compiler could enable extra optimizations that wouldn't be possible otherwise. For example, the compiler understands multiplication and division so, in certain cases, it can replace these operations with bit-shifting which is faster.
>
> I was just about to suggest this. Another easy way might be to just add get/set mantissa/exponent intrinsics and use those in the ctfe versions.
Right. The problem with allowing casts between integers and floating point, is that then someone can create a pointer to some of the bits of the float. And that's a can of worms. It enables behaviour that is both complicated, and useless.
BTW in the existing CTFE you can cast int <-> float and long <-> double.
So you can implement pow for 64 bit floats already. It's only 80-bit reals that are a problem, because there is no integer type that is large enough. So it's really an X86-specific problem.
I did suggest allowing the specific casts for getting and setting the exponent and significand, eg:
ushort exponent = (cast(ushort *)cast(void*)&f)[4];
ulong significand = *(cast(ulong *)cast(void *)&f);
which would give you everything you need. It's really an intrinsic with very very ugly syntax.
But Iain was pretty unhappy with that idea, IIRC. I think treatment of real is very difficult for GDC already.
| |||
January 02, 2015 Re: CTFE pow() | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Don | On 2 January 2015 at 13:33, Don via Digitalmars-d <digitalmars-d@puremagic.com> wrote: > On Friday, 2 January 2015 at 08:52:47 UTC, Daniel Murphy wrote: >> >> "Xinok" wrote in message news:pbjttgrpwhsffoovpida@forum.dlang.org... >> >>> I'm wondering if there's any added benefit to implementing these as intrinsic functions instead? In this way, implementing them in CTFE should be trivial and the extra knowledge given to the compiler could enable extra optimizations that wouldn't be possible otherwise. For example, the compiler understands multiplication and division so, in certain cases, it can replace these operations with bit-shifting which is faster. >> >> >> I was just about to suggest this. Another easy way might be to just add get/set mantissa/exponent intrinsics and use those in the ctfe versions. > > > Right. The problem with allowing casts between integers and floating point, is that then someone can create a pointer to some of the bits of the float. And that's a can of worms. It enables behaviour that is both complicated, and useless. > > BTW in the existing CTFE you can cast int <-> float and long <-> double. > > So you can implement pow for 64 bit floats already. It's only 80-bit reals that are a problem, because there is no integer type that is large enough. So it's really an X86-specific problem. > > I did suggest allowing the specific casts for getting and setting the exponent and significand, eg: > > ushort exponent = (cast(ushort *)cast(void*)&f)[4]; > ulong significand = *(cast(ulong *)cast(void *)&f); > > which would give you everything you need. It's really an intrinsic with very > very ugly syntax. > But Iain was pretty unhappy with that idea, IIRC. I think treatment of real > is very difficult for GDC already. Getting is fine, setting is the bigger problem, especially when optimisations come into play. There was a more complex equivalent of: double x = 2.0; ushort *i = cast(ushort *)&x; i[3] = 0; That led to this [1] being done instead, before I switched over to using unions to satisfy @nogc and aliasing under optimisations. [1]: https://github.com/D-Programming-Language/phobos/commit/df5dab4a7af7aa441e92538876df13c0bb45cda3#diff-8b9f1870415268a4c40b628d596dc405R3100 Iain. | |||
January 02, 2015 Re: CTFE pow() | ||||
|---|---|---|---|---|
| ||||
On 1 January 2015 at 18:40, H. S. Teoh via Digitalmars-d <digitalmars-d@puremagic.com> wrote: > On Fri, Jan 02, 2015 at 02:56:16AM +1000, Manu via Digitalmars-d wrote: >> Does anyone know how to fix this? Can we please do so? It's been a >> problem for like 5 years it seems. >> It's a bit insane that we can't resolve any non-linear functions at >> compile time. > > I've been waiting for this since like, forever. We even have a D code implementation of pow() already (thanks to Iain), which *should* have been CTFE-able, if it weren't for CTFE limitations that prohibit reinterpreting float values in binary, which is required for certain basic operations like isInfinite, isNaN, etc.. > > So it seems that the blocker right now is CTFE, which, unfortunately, is not a pretty piece of code, and requires quite a bit of care to get it done right. > The fundamental structure is in place in Target. where the paintAsType implementation encodes/decodes from a char buffer (and supports up to 512 bytes). You can add support for painting a double as a ushort[4] by adding a loop, decodeInteger(e, buffer), decodeInteger(e, buffer+2), etc... The second part (and more crucial) is adding the capability into CTFE. Shouldn't be much work, but I've yet to get round to it. See: https://github.com/D-Programming-Language/dmd/blob/master/src/target.c#L287 What I'd put higher up on my list of things to address are CTFE-able unions though. Iain. | ||||
January 02, 2015 Re: CTFE pow() | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Don | On Friday, 2 January 2015 at 13:33:40 UTC, Don wrote:
> BTW in the existing CTFE you can cast int <-> float and long <-> double.
>
> So you can implement pow for 64 bit floats already. It's only 80-bit reals that are a problem, because there is no integer type that is large enough.
Why?
long has 64 bit, which is enough to represent the mantissa of 80bit reals. So you need only an additional short to hold the exponent.
| |||
January 02, 2015 Re: CTFE pow() | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Dominikus Dittes Scherkl | "Dominikus Dittes Scherkl" wrote in message news:edmacskcgtkzovhyejop@forum.dlang.org... > Why? > long has 64 bit, which is enough to represent the mantissa of 80bit reals. So you need only an additional short to hold the exponent. Because only casts from float <-> integer where sizeof(src) == sizeof(dest) are currently supported, and there is no 80-bit integral type. | |||
January 12, 2015 Re: CTFE pow() | ||||
|---|---|---|---|---|
| ||||
On 2 January 2015 at 14:19, Iain Buclaw <ibuclaw@gdcproject.org> wrote:
> On 1 January 2015 at 18:40, H. S. Teoh via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>> On Fri, Jan 02, 2015 at 02:56:16AM +1000, Manu via Digitalmars-d wrote:
>>> Does anyone know how to fix this? Can we please do so? It's been a
>>> problem for like 5 years it seems.
>>> It's a bit insane that we can't resolve any non-linear functions at
>>> compile time.
>>
>> I've been waiting for this since like, forever. We even have a D code implementation of pow() already (thanks to Iain), which *should* have been CTFE-able, if it weren't for CTFE limitations that prohibit reinterpreting float values in binary, which is required for certain basic operations like isInfinite, isNaN, etc..
>>
>> So it seems that the blocker right now is CTFE, which, unfortunately, is not a pretty piece of code, and requires quite a bit of care to get it done right.
>>
>
> The fundamental structure is in place in Target. where the paintAsType
> implementation encodes/decodes from a char buffer (and supports up to
> 512 bytes). You can add support for painting a double as a ushort[4]
> by adding a loop, decodeInteger(e, buffer), decodeInteger(e,
> buffer+2), etc...
>
> The second part (and more crucial) is adding the capability into CTFE. Shouldn't be much work, but I've yet to get round to it.
>
> See: https://github.com/D-Programming-Language/dmd/blob/master/src/target.c#L287
>
>
I've started a branch which works on this. I expect it will take me a week to finish with unittests.
Iain.
| ||||
January 12, 2015 Re: CTFE pow() | ||||
|---|---|---|---|---|
| ||||
Awesome. Really looking forward to this! :)
On 13 January 2015 at 03:12, Iain Buclaw via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
> On 2 January 2015 at 14:19, Iain Buclaw <ibuclaw@gdcproject.org> wrote:
>> On 1 January 2015 at 18:40, H. S. Teoh via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>>> On Fri, Jan 02, 2015 at 02:56:16AM +1000, Manu via Digitalmars-d wrote:
>>>> Does anyone know how to fix this? Can we please do so? It's been a
>>>> problem for like 5 years it seems.
>>>> It's a bit insane that we can't resolve any non-linear functions at
>>>> compile time.
>>>
>>> I've been waiting for this since like, forever. We even have a D code implementation of pow() already (thanks to Iain), which *should* have been CTFE-able, if it weren't for CTFE limitations that prohibit reinterpreting float values in binary, which is required for certain basic operations like isInfinite, isNaN, etc..
>>>
>>> So it seems that the blocker right now is CTFE, which, unfortunately, is not a pretty piece of code, and requires quite a bit of care to get it done right.
>>>
>>
>> The fundamental structure is in place in Target. where the paintAsType
>> implementation encodes/decodes from a char buffer (and supports up to
>> 512 bytes). You can add support for painting a double as a ushort[4]
>> by adding a loop, decodeInteger(e, buffer), decodeInteger(e,
>> buffer+2), etc...
>>
>> The second part (and more crucial) is adding the capability into CTFE. Shouldn't be much work, but I've yet to get round to it.
>>
>> See: https://github.com/D-Programming-Language/dmd/blob/master/src/target.c#L287
>>
>>
>
> I've started a branch which works on this. I expect it will take me a week to finish with unittests.
>
> Iain.
| ||||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply