November 12, 2015
On Thursday, 12 November 2015 at 14:44:49 UTC, John Colvin wrote:
>
> To test the speed of fmttable itself I split fmttable and main in to different modules, made fmttable extern(C) so I could just prototype it in the main module (no import), then compiled them separately before linking. This should prevent any possible inlining/purity cleverness. ~1s for ldmd2, ~2s for dmd, which is business as normal.
>
> dmd is being clever and spotting that fmttable is pure, it would be good if ldc/gdc could spot this to.

If so, should explicitly marking fmttable as pure close the gap for initial code?
November 12, 2015
On Thursday, 12 November 2015 at 19:11:25 UTC, tired_eyes wrote:
> On Thursday, 12 November 2015 at 14:44:49 UTC, John Colvin wrote:
>>
>> To test the speed of fmttable itself I split fmttable and main in to different modules, made fmttable extern(C) so I could just prototype it in the main module (no import), then compiled them separately before linking. This should prevent any possible inlining/purity cleverness. ~1s for ldmd2, ~2s for dmd, which is business as normal.
>>
>> dmd is being clever and spotting that fmttable is pure, it would be good if ldc/gdc could spot this to.
>
> If so, should explicitly marking fmttable as pure close the gap for initial code?

Well it won't do any harm, but it really depends on what the compiler chooses to do with the information.
November 12, 2015
I would love to be convinced. :) Can someone come up with a reduced example please?

On 11/12/2015 03:59 AM, Daniel Kozak wrote:

>      for (i=0; i < 1000000; ++i) {
>          fmttable(table);
>      }

I think what we are seeing here is more due to the unused side-effect in the loop, where compiling with -w fails compilation:

Warning: calling deneme.fmttable without side effects discards return value of type string, prepend a cast(void) if intentional

Ali

November 12, 2015
On 11/12/2015 6:44 AM, John Colvin wrote:
> dmd is being clever and spotting that fmttable is pure, it would be good if
> ldc/gdc could spot this to.

It's more than that - dmd's optimizer is designed to make use of the guarantees of a pure function. Since C/C++ do not have pure functions, ldc/gdc's optimizer may not have that capability.
November 12, 2015
On Thursday, 12 November 2015 at 21:16:25 UTC, Walter Bright wrote:
> It's more than that - dmd's optimizer is designed to make use of the guarantees of a pure function. Since C/C++ do not have pure functions, ldc/gdc's optimizer may not have that capability.

Oh, GCC has had similar notions as a non-standard attribute for ages, and LLVM since its inception.

At least for LDC, the reason why we do not currently lower many of the qualifiers like pure, nothrow, immutable, etc. is that LLVM will ruthlessly consider your code to exhibit undefined behavior if you try to be clever and violate them, subsequently optimizing based on that. In other words, if you cast away const/immutable and modify a variable, for instance, you might find that the entire function body magically disappears under your feet.

Maybe it is time to revisit this, though, but last time I tried it broke druntime/Phobos in a couple of places.

 — David
November 12, 2015
On 12 Nov 2015 10:25 pm, "David Nadlinger via Digitalmars-d" < digitalmars-d@puremagic.com> wrote:
>
> On Thursday, 12 November 2015 at 21:16:25 UTC, Walter Bright wrote:
>>
>> It's more than that - dmd's optimizer is designed to make use of the
guarantees of a pure function. Since C/C++ do not have pure functions, ldc/gdc's optimizer may not have that capability.
>
>
> Oh, GCC has had similar notions as a non-standard attribute for ages, and
LLVM since its inception.
>
> At least for LDC, the reason why we do not currently lower many of the
qualifiers like pure, nothrow, immutable, etc. is that LLVM will ruthlessly consider your code to exhibit undefined behavior if you try to be clever and violate them, subsequently optimizing based on that. In other words, if you cast away const/immutable and modify a variable, for instance, you might find that the entire function body magically disappears under your feet.
>
> Maybe it is time to revisit this, though, but last time I tried it broke
druntime/Phobos in a couple of places.
>

Same here, and for some very surprising reasons from what I recall.


November 12, 2015
On Thursday, 12 November 2015 at 21:16:25 UTC, Walter Bright wrote:
> On 11/12/2015 6:44 AM, John Colvin wrote:
>> dmd is being clever and spotting that fmttable is pure, it would be good if
>> ldc/gdc could spot this to.
>
> It's more than that - dmd's optimizer is designed to make use of the guarantees of a pure function. Since C/C++ do not have pure functions, ldc/gdc's optimizer may not have that capability.

gcc has had the pure function attribute since version 2.96 in 2000.
November 13, 2015
On 11/12/2015 11:50 AM, Ali Çehreli wrote:
> I would love to be convinced. :) Can someone come up with a reduced
> example please?
>
> On 11/12/2015 03:59 AM, Daniel Kozak wrote:
>
>  >      for (i=0; i < 1000000; ++i) {
>  >          fmttable(table);
>  >      }
>
> I think what we are seeing here is more due to the unused side-effect in
> the loop, where compiling with -w fails compilation:
>
> Warning: calling deneme.fmttable without side effects discards return
> value of type string, prepend a cast(void) if intentional
>
> Ali
>

Can someone please tell me if I am mistaken not.

Once again, I don't think this example is fast because the compiler reuses the return value of fmttable() in the loop. Rather, it simply removes the whole expression because its only side-effect is not used in the program.

Perhaps that's what everybody else is saying anyway. :)

(Why don't I look at the assembly myself? Going to a meeting... :p)

Ali

November 13, 2015
On Thursday, 12 November 2015 at 21:24:30 UTC, David Nadlinger wrote:
> On Thursday, 12 November 2015 at 21:16:25 UTC, Walter Bright wrote:
>> [...]
>
> Oh, GCC has had similar notions as a non-standard attribute for ages, and LLVM since its inception.
>
> At least for LDC, the reason why we do not currently lower many of the qualifiers like pure, nothrow, immutable, etc. is that LLVM will ruthlessly consider your code to exhibit undefined behavior if you try to be clever and violate them, subsequently optimizing based on that. In other words, if you cast away const/immutable and modify a variable, for instance, you might find that the entire function body magically disappears under your feet.
>
> Maybe it is time to revisit this, though, but last time I tried it broke druntime/Phobos in a couple of places.

That sounds awesome.

Maybe only enable it for @safe code?
November 14, 2015
On 13 November 2015 at 08:38, Iain Buclaw via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
> On 12 Nov 2015 10:25 pm, "David Nadlinger via Digitalmars-d" <digitalmars-d@puremagic.com> wrote:
>>
>> On Thursday, 12 November 2015 at 21:16:25 UTC, Walter Bright wrote:
>>>
>>> It's more than that - dmd's optimizer is designed to make use of the guarantees of a pure function. Since C/C++ do not have pure functions, ldc/gdc's optimizer may not have that capability.
>>
>>
>> Oh, GCC has had similar notions as a non-standard attribute for ages, and LLVM since its inception.
>>
>> At least for LDC, the reason why we do not currently lower many of the qualifiers like pure, nothrow, immutable, etc. is that LLVM will ruthlessly consider your code to exhibit undefined behavior if you try to be clever and violate them, subsequently optimizing based on that. In other words, if you cast away const/immutable and modify a variable, for instance, you might find that the entire function body magically disappears under your feet.
>>
>> Maybe it is time to revisit this, though, but last time I tried it broke druntime/Phobos in a couple of places.
>>
>
> Same here, and for some very surprising reasons from what I recall.

These language mechanisms offer D a huge potential advantage, it would
be really good to understand why we can't make use of them, and work
towards fixing this.
I don't think people should be surprised if the optimiser takes
advantage of their code attribution. It may break existing code
because violating these attributes never caused any problem before,
but surely violating those attributes was never actually valid code,
and it's reasonable that they expect their code to break in the future
as compilers improve their ability to take advantage of these
attributes?

In the meantime, there probably needs to be strong warnings about violating attributes, and if patterns have emerged that rely on violating such attributes, we should publish a recommended alternative.