Jump to page: 1 2
Thread overview
Re: CTFE pow()
Jan 01, 2015
H. S. Teoh
Jan 01, 2015
Xinok
Jan 02, 2015
Daniel Murphy
Jan 02, 2015
Don
Jan 02, 2015
Iain Buclaw
Jan 02, 2015
Daniel Murphy
Jan 02, 2015
Iain Buclaw
Jan 12, 2015
Iain Buclaw
Jan 12, 2015
Manu
Jan 13, 2015
Iain Buclaw
January 01, 2015
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
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
"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
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
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
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
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
"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
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
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.
« First   ‹ Prev
1 2