April 08, 2013 Re: To help LDC/GDC | ||||
---|---|---|---|---|
| ||||
Posted in reply to David Nadlinger Attachments:
| On 8 April 2013 14:32, David Nadlinger <see@klickverbot.at> wrote: > On Monday, 8 April 2013 at 12:37:48 UTC, Manu wrote: > >> On 8 April 2013 21:46, Iain Buclaw <ibuclaw@ubuntu.com> wrote: >> >>> Only builtins are pure in the sense of 'C'. Even functions considered >>> PUREstrong by the frontend may update an internal state, so the rules >>> just >>> don't apply. Except for maybe global functions... In any case, the >>> only >>> benefit you can reap from 'D pure' functions are that they are more >>> likely >>> to be const-folded / inlined. >>> >>> >> Oh my god... ..... this is the most upsetting thing I've heard all day! :( >> No really, I have been SOOOO excited for so long about this optimisation >> potential in D! >> There's gotta be something that can be done! >_< >> >> Does the front end know if the function actually DOES assign to any state? The compiler could easily work that out, and in the event it doesn't actually perform any such assignment, it could be marked pure for reals... >> > > Iain, are you sure about that? (No offense, but you have been wrong about what GCC can/can't do in the past. :P) Could you maybe elaborate a bit and present a counterexample? It might also be a question of how the »as-if« rule is really defined for pure function calls. > > In any case, if the source is available, the LLVM optimizer is usually very good at figuring out »pure for reals« (inferring the LLVM 'readnone' attribute). Obviously, this doesn't help you when you are doing separate compilation, though. > > David > Sure about what? I don't even know what you are talking about. :o) <sic> -- Iain Buclaw *(p < e ? p++ : p) = (c & 0x0f) + '0'; |
April 08, 2013 Re: To help LDC/GDC | ||||
---|---|---|---|---|
| ||||
Attachments:
| On 8 April 2013 13:37, Manu <turkeyman@gmail.com> wrote: > Oh my god... ..... this is the most upsetting thing I've heard all day! :( > No really, I have been SOOOO excited for so long about this optimisation > potential in D! > There's gotta be something that can be done! >_< > > Does the front end know if the function actually DOES assign to any state? The compiler could easily work that out, and in the event it doesn't actually perform any such assignment, it could be marked pure for reals... > > Haven't looked, but it appears to have a general idea of this. D 'weak pure' and 'const pure' may update an internal state (had the latter bite me hard once). The only case where 'strong pure' might do this is by throwing an exception or an assert being thrown - this changes program state so can't be marked pure. So having identified this, we can safely say that functions could only be 'C pure' in the following case: - Compiled function is 'strong pure' - Compiled function is 'nothrow' - We are compiling in release mode. Only then we (the frontend) can safely say that 'this function has *absolutely* no side effects, so can be marked as pure'. Pure is never inferred. -- Iain Buclaw *(p < e ? p++ : p) = (c & 0x0f) + '0'; |
April 08, 2013 Re: To help LDC/GDC | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | On 04/08/2013 05:07 PM, Jacob Carlborg wrote: > On 2013-04-08 14:52, Iain Buclaw wrote: >> On 8 April 2013 13:25, Jacob Carlborg <doob@me.com <mailto:doob@me.com>> >> wrote: >> >> On 2013-04-08 10:29, Iain Buclaw wrote: >> >> This information could possibly be helpful. Though given that >> most of >> (gdc) codegen is on par with g++, there's probably not much on >> the list >> that isn't already detected by the backend optimisation passes. >> >> >> Multiple calls to pure functions could be cached. >> >> -- >> /Jacob Carlborg >> >> >> Not always, but in some circumstances, yes. >> >> --- >> struct Foo >> { >> int a = 0; >> pure int bar (immutable int x) >> { >> ++a; >> return x * 2; >> } >> } >> >> >> void main() >> { >> Foo f; >> int i = f.bar(2) + f.bar(2); >> >> assert (i == 8); >> assert (f.a == 2); >> } > > I though that wasn't possible. What's the point of pure if that's possible? > Foo.bar can be used in a strongly pure computation. It is superficially similar to how state transformers allow mutable state in Haskell. If you want more guarantees, you could mark a member function const, inout or immutable pure. DIP30 removes some optimization potential for at least const pure. Furthermore, the exact meaning of inout will have to be determined. Unfortunately it is both useful to have a specifier that prevents mutation but allows to return a mutable part of the function input and to have a specifier that allows mutation in case the function input is in fact mutable. Unfortunately, DMD does not implement type checking for delegates in a meaningful way. The specifiers const/immutable/pure should have consistent meanings for member functions and functions nested inside functions. (http://d.puremagic.com/issues/show_bug.cgi?id=9148) |
April 08, 2013 Re: To help LDC/GDC | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | On 2013-04-08, 17:07, Jacob Carlborg wrote: > On 2013-04-08 14:52, Iain Buclaw wrote: >> On 8 April 2013 13:25, Jacob Carlborg <doob@me.com <mailto:doob@me.com>> >> wrote: >> >> On 2013-04-08 10:29, Iain Buclaw wrote: >> >> This information could possibly be helpful. Though given that >> most of >> (gdc) codegen is on par with g++, there's probably not much on >> the list >> that isn't already detected by the backend optimisation passes. >> >> >> Multiple calls to pure functions could be cached. >> >> -- >> /Jacob Carlborg >> >> >> Not always, but in some circumstances, yes. >> >> --- >> struct Foo >> { >> int a = 0; >> pure int bar (immutable int x) >> { >> ++a; >> return x * 2; >> } >> } >> >> >> void main() >> { >> Foo f; >> int i = f.bar(2) + f.bar(2); >> >> assert (i == 8); >> assert (f.a == 2); >> } > > I though that wasn't possible. What's the point of pure if that's possible? Like others have stated, it's so you can do this: struct Foo { int a = 0; pure int bar( int n ) { // Weakly pure a += n; return a; } } pure int Baz( int n ) { // Strongly pure Foo foo; return foo.bar( n ); } Foo.bar has only local mutability, so if the Foo originated in a (strongly) pure function, Foo.bar can be called inside that pure function without violating the purity requirement. The three levels (weakly pure/strongly pure/impure) are needed, but a redesign would perhaps use a different keyword for weakly pure. -- Simen |
April 08, 2013 Re: To help LDC/GDC | ||||
---|---|---|---|---|
| ||||
Posted in reply to David Nadlinger | Am Mon, 08 Apr 2013 15:32:35 +0200
schrieb "David Nadlinger" <see@klickverbot.at>:
> On Monday, 8 April 2013 at 12:37:48 UTC, Manu wrote:
> > On 8 April 2013 21:46, Iain Buclaw <ibuclaw@ubuntu.com> wrote:
> >> Only builtins are pure in the sense of 'C'. Even functions
> >> considered
> >> PUREstrong by the frontend may update an internal state, so
> >> the rules just
> >> don't apply. Except for maybe global functions... In any
> >> case, the only
> >> benefit you can reap from 'D pure' functions are that they are
> >> more likely
> >> to be const-folded / inlined.
> >>
> >
> > Oh my god... ..... this is the most upsetting thing I've heard
> > all day! :(
> > No really, I have been SOOOO excited for so long about this
> > optimisation
> > potential in D!
> > There's gotta be something that can be done! >_<
> >
> > Does the front end know if the function actually DOES assign to
> > any state?
> > The compiler could easily work that out, and in the event it
> > doesn't
> > actually perform any such assignment, it could be marked pure
> > for reals...
>
> Iain, are you sure about that? (No offense, but you have been wrong about what GCC can/can't do in the past. :P) Could you maybe elaborate a bit and present a counterexample? It might also be a question of how the »as-if« rule is really defined for pure function calls.
>
> In any case, if the source is available, the LLVM optimizer is usually very good at figuring out »pure for reals« (inferring the LLVM 'readnone' attribute). Obviously, this doesn't help you when you are doing separate compilation, though.
>
> David
I guess he only meant that the pure attribute doesn't help much, especially when compared to the GCC __pure__ C attribute. Of course the backend might still figure out that a function is really pure if the source code is known, but that probably also applies to functions not marked as pure so there's not much benefit for the backend if a function is marked pure or not.
|
April 08, 2013 Re: To help LDC/GDC | ||||
---|---|---|---|---|
| ||||
Posted in reply to Manu | Am Mon, 8 Apr 2013 22:37:33 +1000 schrieb Manu <turkeyman@gmail.com>: > > Only builtins are pure in the sense of 'C'. Even functions considered PUREstrong by the frontend may update an internal state, so the rules just don't apply. Except for maybe global functions... In any case, the only benefit you can reap from 'D pure' functions are that they are more likely to be const-folded / inlined. > > > > Oh my god... ..... this is the most upsetting thing I've heard all > day! :( No really, I have been SOOOO excited for so long about this > optimisation potential in D! > There's gotta be something that can be done! >_< And to make it even worse AFAICT D's nothrow is also meaningless for optimization. As you can still throw errors/throwables the backend gains nothing from nothrow. It still has to analyze a function to know if it is actually __NOTHROW__ in the gcc sense. I think there was at least one gdc bug related to this which only showed on ARM, but I'd have to check that again. http://bugzilla.gdcproject.org/show_bug.cgi?id=10 (Though admittedly I'm not sure if there's any optimization potential with nothrow) |
April 08, 2013 Re: To help LDC/GDC | ||||
---|---|---|---|---|
| ||||
Posted in reply to Iain Buclaw | Am Mon, 8 Apr 2013 16:40:34 +0100
schrieb Iain Buclaw <ibuclaw@ubuntu.com>:
> On 8 April 2013 13:37, Manu <turkeyman@gmail.com> wrote:
>
> > Oh my god... ..... this is the most upsetting thing I've heard all
> > day! :( No really, I have been SOOOO excited for so long about this
> > optimisation potential in D!
> > There's gotta be something that can be done! >_<
> >
> > Does the front end know if the function actually DOES assign to any state? The compiler could easily work that out, and in the event it doesn't actually perform any such assignment, it could be marked pure for reals...
> >
> >
> Haven't looked, but it appears to have a general idea of this. D 'weak pure' and 'const pure' may update an internal state (had the latter bite me hard once). The only case where 'strong pure' might do this is by throwing an exception or an assert being thrown - this changes program state so can't be marked pure.
>
> So having identified this, we can safely say that functions could
> only be 'C pure' in the following case:
> - Compiled function is 'strong pure'
> - Compiled function is 'nothrow'
> - We are compiling in release mode.
>
> Only then we (the frontend) can safely say that 'this function has *absolutely* no side effects, so can be marked as pure'. Pure is never inferred.
>
Can't a strong pure + nothrow + release mode function still throw errors? Or is this the "we don't guarantee anything regarding Errors" case and we just don't care?
|
April 08, 2013 Re: To help LDC/GDC | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen Kjaeraas | On 2013-04-08 20:14, Simen Kjaeraas wrote: > Like others have stated, it's so you can do this: > > struct Foo { > int a = 0; > pure int bar( int n ) { // Weakly pure > a += n; > return a; > } > } > > pure int Baz( int n ) { // Strongly pure > Foo foo; > return foo.bar( n ); > } > > Foo.bar has only local mutability, so if the Foo originated in a > (strongly) pure function, Foo.bar can be called inside that pure > function without violating the purity requirement. > > The three levels (weakly pure/strongly pure/impure) are needed, > but a redesign would perhaps use a different keyword for weakly > pure. I see. -- /Jacob Carlborg |
April 08, 2013 Re: To help LDC/GDC | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen Kjaeraas | On Monday, 8 April 2013 at 18:15:11 UTC, Simen Kjaeraas wrote:
> The three levels (weakly pure/strongly pure/impure) are needed,
> but a redesign would perhaps use a different keyword for weakly
> pure.
Why should it?
I mean, using another name for "pure" would arguably make sense, given the confusion it seems to have caused in the past. But if you are suggesting to differentiate between various "kinds of purity" on a keyword level, I'm not sure what benefits you are hoping to get.
David
|
April 08, 2013 Re: To help LDC/GDC | ||||
---|---|---|---|---|
| ||||
Posted in reply to David Nadlinger | On Monday, 8 April 2013 at 19:48:50 UTC, David Nadlinger wrote:
> On Monday, 8 April 2013 at 18:15:11 UTC, Simen Kjaeraas wrote:
>> The three levels (weakly pure/strongly pure/impure) are needed,
>> but a redesign would perhaps use a different keyword for weakly
>> pure.
>
> Why should it?
>
> I mean, using another name for "pure" would arguably make sense, given the confusion it seems to have caused in the past. But if you are suggesting to differentiate between various "kinds of purity" on a keyword level, I'm not sure what benefits you are hoping to get.
>
> David
What will you do if you want to make Foo.bar _strongly_ pure and compiler to verify it?
|
Copyright © 1999-2021 by the D Language Foundation