www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Missed optimisation case - internal use of STCin

reply "Iain Buclaw" <ibuclaw gdcproject.org> writes:
Hi,

I'm currently testing out a GCC optimisation that allows you to 
set call argument flags.  The current assumptions being:

in parameters  =>  Assume no escape, no clobber (read-only).
ref parameters, classes and pointers  =>  Assume worst case.
default  =>  Assume no escape.


See here for implementation details:
http://gcc.gnu.org/ml/fortran/2010-05/msg00032.html


The idea for the 'in' parameters being that if we have the 
following:
--
bool somefunc (in char[] a);


The compiler can assume that whatever parameters are passed, they 
do not changes.  So the compiler can more aggressively optimise 
the following case, for instance.

eg:
--
char[] foo = "bar";
assert(foo == "bar");
somefunc(foo);
assert(foo == "bar");


One problem I've found with this though, is that the front-end 
tends to set all library function parameters as STCin, so the 
optimisation is fundamentally broken:

eg:
--
int[3] arr = [2,3,1];
arr.sort;  // Defined internally as _adSort(in void[], in 
TypeInfo);
assert(arr[0] == 1);  // Compiler infers as false, throws assert.


I think it would be more than reasonable to fix the frontend here 
so that the internal representation better matches that found in 
the internal runtime library.  Just wanted to pass this by you 
guys first.


Regards
Iain.
Apr 19 2014
next sibling parent "Iain Buclaw" <ibuclaw gdcproject.org> writes:
On Saturday, 19 April 2014 at 10:49:22 UTC, Iain Buclaw wrote:
 Hi,

 I'm currently testing out a GCC optimisation that allows you to 
 set call argument flags.  The current assumptions being:

 in parameters  =>  Assume no escape, no clobber (read-only).
 ref parameters, classes and pointers  =>  Assume worst case.
 default  =>  Assume no escape.

That should read: ref parameters, inout parameters, classes and pointers. The default of assuming no escape is an experiment - I may limit this to only scalar types, and parameters marked as 'scope' (So long as no one plans on deprecating it soon :)
Apr 19 2014
prev sibling next sibling parent Artur Skawina via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 04/19/14 13:03, Iain Buclaw via Digitalmars-d wrote:
 On Saturday, 19 April 2014 at 10:49:22 UTC, Iain Buclaw wrote:
 Hi,

 I'm currently testing out a GCC optimisation that allows you to set call
argument flags.  The current assumptions being:

 in parameters  =>  Assume no escape, no clobber (read-only).
 ref parameters, classes and pointers  =>  Assume worst case.
 default  =>  Assume no escape.

That should read: ref parameters, inout parameters, classes and pointers. The default of assuming no escape is an experiment - I may limit this to only scalar types, and parameters marked as 'scope' (So long as no one plans on deprecating it soon :)

What does "assume no escape" actually mean? [The above list doesn't really make sense. W/o context, it's hard to even tell why, hence the question.] Also, 'inout' is about constness -- doesn't affect lifetime and reachability, but does imply no clobbering. artur
Apr 19 2014
prev sibling next sibling parent Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 19 April 2014 13:02, Artur Skawina via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 On 04/19/14 13:03, Iain Buclaw via Digitalmars-d wrote:
 On Saturday, 19 April 2014 at 10:49:22 UTC, Iain Buclaw wrote:
 Hi,

 I'm currently testing out a GCC optimisation that allows you to set call
argument flags.  The current assumptions being:

 in parameters  =>  Assume no escape, no clobber (read-only).
 ref parameters, classes and pointers  =>  Assume worst case.
 default  =>  Assume no escape.

That should read: ref parameters, inout parameters, classes and pointers. The default of assuming no escape is an experiment - I may limit this to only scalar types, and parameters marked as 'scope' (So long as no one plans on deprecating it soon :)

What does "assume no escape" actually mean? [The above list doesn't really make sense. W/o context, it's hard to even tell why, hence the question.] Also, 'inout' is about constness -- doesn't affect lifetime and reachability, but does imply no clobbering.

'out' parameters - I sometimes confuse the two when I have a head cold. :o)
Apr 19 2014
prev sibling next sibling parent Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 19 April 2014 13:02, Artur Skawina via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 On 04/19/14 13:03, Iain Buclaw via Digitalmars-d wrote:
 On Saturday, 19 April 2014 at 10:49:22 UTC, Iain Buclaw wrote:
 Hi,

 I'm currently testing out a GCC optimisation that allows you to set call
argument flags.  The current assumptions being:

 in parameters  =>  Assume no escape, no clobber (read-only).
 ref parameters, classes and pointers  =>  Assume worst case.
 default  =>  Assume no escape.

That should read: ref parameters, inout parameters, classes and pointers. The default of assuming no escape is an experiment - I may limit this to only scalar types, and parameters marked as 'scope' (So long as no one plans on deprecating it soon :)

What does "assume no escape" actually mean? [The above list doesn't really make sense. W/o context, it's hard to even tell why, hence the question.]

Actually, I might change the default to assume worst case. I've just tried this out, which is still valid. class C { int * p; this(int x) { p = &x; // escapes the address of the parameter. } } Worse, scope doesn't error on the general case either. class D { int * p; this(scope int x) { p = &x; // escapes the address of the scope parameter. } } Do these examples give you a good example?
Apr 19 2014
prev sibling next sibling parent Artur Skawina via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 04/19/14 14:37, Iain Buclaw via Digitalmars-d wrote:
 On 19 April 2014 13:02, Artur Skawina via Digitalmars-d
 <digitalmars-d puremagic.com> wrote:
 On 04/19/14 13:03, Iain Buclaw via Digitalmars-d wrote:
 On Saturday, 19 April 2014 at 10:49:22 UTC, Iain Buclaw wrote:
 Hi,

 I'm currently testing out a GCC optimisation that allows you to set call
argument flags.  The current assumptions being:

 in parameters  =>  Assume no escape, no clobber (read-only).
 ref parameters, classes and pointers  =>  Assume worst case.
 default  =>  Assume no escape.

That should read: ref parameters, inout parameters, classes and pointers. The default of assuming no escape is an experiment - I may limit this to only scalar types, and parameters marked as 'scope' (So long as no one plans on deprecating it soon :)

What does "assume no escape" actually mean? [The above list doesn't really make sense. W/o context, it's hard to even tell why, hence the question.]

Actually, I might change the default to assume worst case. I've just tried this out, which is still valid. class C { int * p; this(int x) { p = &x; // escapes the address of the parameter. } }

This might be currently accepted, but it is clearly invalid (escapes local; the only way to make it work safely would be to silently copy 'x' to the GC-managed heap, which would be way too costly). A f(A a) { g(&a); return a; } // likewise with ref instead of pointer. This is OK (even if ideally 'g' should be forbidden from escaping 'a'). Similarly: A f(A a) { auto o = register(&a); // can modify 'a' o.blah(); // ditto doneWith(o); // ditto return a; } What I was wondering was things like whether that "assume no escape" property was transitive; if /locally/ escaping was disallowed, and to what extent. What does "assume no escape" mean at all? In your examples you're mentioning refs together with pointers, that would only make sense if no-escape were transitive -- but then treating all args as no-escape would be very wrong.
 Worse, scope doesn't error on the general case either.
 
 class D {
    int * p;
    this(scope int x) {
      p = &x; // escapes the address of the scope parameter.
    }
 }

D's "scope" isn't enforced in any way right now, which means that code could exist that is invalid, but currently works. It would break silently(!) when compiled with a decent compiler, which still doesn't enforce scope.
 Do these examples give you a good example?

I'm worried about a) invalid assumptions making it into GDC; b) certain valid assumptions making into GDC. The latter because it could mean that code that's incorrect, but still accepted by the other compilers could silently break when compiled with GDC. artur
Apr 19 2014
prev sibling next sibling parent Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 19 April 2014 14:33, Artur Skawina via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 On 04/19/14 14:37, Iain Buclaw via Digitalmars-d wrote:
 On 19 April 2014 13:02, Artur Skawina via Digitalmars-d
 <digitalmars-d puremagic.com> wrote:
 On 04/19/14 13:03, Iain Buclaw via Digitalmars-d wrote:
 On Saturday, 19 April 2014 at 10:49:22 UTC, Iain Buclaw wrote:
 Hi,

 I'm currently testing out a GCC optimisation that allows you to set call
argument flags.  The current assumptions being:

 in parameters  =>  Assume no escape, no clobber (read-only).
 ref parameters, classes and pointers  =>  Assume worst case.
 default  =>  Assume no escape.

That should read: ref parameters, inout parameters, classes and pointers. The default of assuming no escape is an experiment - I may limit this to only scalar types, and parameters marked as 'scope' (So long as no one plans on deprecating it soon :)

What does "assume no escape" actually mean? [The above list doesn't really make sense. W/o context, it's hard to even tell why, hence the question.]

Actually, I might change the default to assume worst case. I've just tried this out, which is still valid. class C { int * p; this(int x) { p = &x; // escapes the address of the parameter. } }

This might be currently accepted, but it is clearly invalid (escapes local; the only way to make it work safely would be to silently copy 'x' to the GC-managed heap, which would be way too costly). A f(A a) { g(&a); return a; } // likewise with ref instead of pointer. This is OK (even if ideally 'g' should be forbidden from escaping 'a'). Similarly: A f(A a) { auto o = register(&a); // can modify 'a' o.blah(); // ditto doneWith(o); // ditto return a; } What I was wondering was things like whether that "assume no escape" property was transitive; if /locally/ escaping was disallowed, and to what extent. What does "assume no escape" mean at all? In your examples you're mentioning refs together with pointers, that would only make sense if no-escape were transitive -- but then treating all args as no-escape would be very wrong.
 Worse, scope doesn't error on the general case either.

 class D {
    int * p;
    this(scope int x) {
      p = &x; // escapes the address of the scope parameter.
    }
 }

D's "scope" isn't enforced in any way right now, which means that code could exist that is invalid, but currently works. It would break silently(!) when compiled with a decent compiler, which still doesn't enforce scope.

People should get bug fixing soon then. =)
 Do these examples give you a good example?

I'm worried about a) invalid assumptions making it into GDC; b) certain valid assumptions making into GDC. The latter because it could mean that code that's incorrect, but still accepted by the other compilers could silently break when compiled with GDC.

Invalid assumptions rarely make it into GDC. The testsuite is a good bench for this, as well as several projects (now I've got dub set-up) to test it in the wild. Saying that, we have had to revert some optimisation cases as D's schizophrenic nature of enforcing attributes and behaviours is becoming increasingly dismal. eg: - nothrow has *no* guarantee, period, because it still allows unrecoverable errors being thrown, and allows people to catch said unrecoverable errors. - pure is a tough nut to crack also. The theory should allow you to be able to cache return values, but in practise... - The nature of debug statements breaks guarantees of both nothrow and pure, possibly many more. - Defining reliable strict aliasing rules, it turns out, is not that simple (this is something that Walter has mentioned about D should have good guarantees for, ie: D arrays). I'm just in investigating all avenues, as I usually do. There is no reason why 'in' shouldn't have more powerful guarantees IMO, and what I've found is not a problem with user code, it's a problem with the compiler implementation. For reference, this is the declaration of _adSort in rt.qsort: extern (C) void[] _adSort(void[], TypeInfo); This is how the compiler frontend defines the function internally for its own use: extern (C) T[] _adSort(in void[], in TypeInfo);
Apr 19 2014
prev sibling next sibling parent "Dicebot" <public dicebot.lv> writes:
On Saturday, 19 April 2014 at 14:21:23 UTC, Iain Buclaw via 
Digitalmars-d wrote:
 eg:
 - nothrow has *no* guarantee, period, because it still allows
 unrecoverable errors being thrown, and allows people to catch 
 said
 unrecoverable errors.

Hm, it is hard to find clear answer in spec but I _think_ that replacing error throwing with program halting in release mode for nothrow function should be valid behavior.
Apr 19 2014
prev sibling next sibling parent Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 19 April 2014 15:36, Dicebot via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 On Saturday, 19 April 2014 at 14:21:23 UTC, Iain Buclaw via Digitalmars-d
 wrote:
 eg:
 - nothrow has *no* guarantee, period, because it still allows
 unrecoverable errors being thrown, and allows people to catch said
 unrecoverable errors.

Hm, it is hard to find clear answer in spec but I _think_ that replacing error throwing with program halting in release mode for nothrow function should be valid behavior.

Nope. I can't recall the exact code, but an example is in the testsuite. It was discovered when porting to ARM, which was found to omit unwind directives for D nothrow functions, causing runtime hangs when said 'nothrow' functions infact threw an Error.
Apr 19 2014
prev sibling next sibling parent "Dicebot" <public dicebot.lv> writes:
On Saturday, 19 April 2014 at 15:00:26 UTC, Iain Buclaw via 
Digitalmars-d wrote:
 Nope.  I can't recall the exact code, but an example is in the
 testsuite.  It was discovered when porting to ARM, which was 
 found to
 omit unwind directives for D nothrow functions, causing runtime 
 hangs
 when said 'nothrow' functions infact threw an Error.

Now I am pretty sure _this_ is a druntime bug. I don't know about being able to catch actual exception but the fact that unwinding is not guaranteed for Errors is mentioned either on dlang.org or in TDPL.
Apr 19 2014
prev sibling next sibling parent Artur Skawina via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 04/19/14 16:21, Iain Buclaw via Digitalmars-d wrote:
 On 19 April 2014 14:33, Artur Skawina via Digitalmars-d
 <digitalmars-d puremagic.com> wrote:
 On 04/19/14 14:37, Iain Buclaw via Digitalmars-d wrote:
 On 19 April 2014 13:02, Artur Skawina via Digitalmars-d
 <digitalmars-d puremagic.com> wrote:
 On 04/19/14 13:03, Iain Buclaw via Digitalmars-d wrote:
 On Saturday, 19 April 2014 at 10:49:22 UTC, Iain Buclaw wrote:
 I'm currently testing out a GCC optimisation that allows you to set call
argument flags.  The current assumptions being:

 in parameters  =>  Assume no escape, no clobber (read-only).
 ref parameters, classes and pointers  =>  Assume worst case.
 default  =>  Assume no escape.

That should read: ref parameters, inout parameters, classes and pointers. The default of assuming no escape is an experiment - I may limit this to only scalar types, and parameters marked as 'scope' (So long as no one plans on deprecating it soon :)

What does "assume no escape" actually mean? [The above list doesn't really make sense. W/o context, it's hard to even tell why, hence the question.]

Actually, I might change the default to assume worst case. I've just tried this out, which is still valid. class C { int * p; this(int x) { p = &x; // escapes the address of the parameter. } }

This might be currently accepted, but it is clearly invalid (escapes local; the only way to make it work safely would be to silently copy 'x' to the GC-managed heap, which would be way too costly). A f(A a) { g(&a); return a; } // likewise with ref instead of pointer. This is OK (even if ideally 'g' should be forbidden from escaping 'a'). Similarly: A f(A a) { auto o = register(&a); // can modify 'a' o.blah(); // ditto doneWith(o); // ditto return a; } What I was wondering was things like whether that "assume no escape" property was transitive; if /locally/ escaping was disallowed, and to what extent. What does "assume no escape" mean at all? In your examples you're mentioning refs together with pointers, that would only make sense if no-escape were transitive -- but then treating all args as no-escape would be very wrong.
 Worse, scope doesn't error on the general case either.

 class D {
    int * p;
    this(scope int x) {
      p = &x; // escapes the address of the scope parameter.
    }
 }

D's "scope" isn't enforced in any way right now, which means that code could exist that is invalid, but currently works. It would break silently(!) when compiled with a decent compiler, which still doesn't enforce scope.

People should get bug fixing soon then. =)

Until some kind of diagnostics appear, most of those bugs won't even be found. It's too easy to write "auto f (in A a)" and then forget about the implicit 'scope' when modifying the function body.
 Do these examples give you a good example?

I'm worried about a) invalid assumptions making it into GDC; b) certain valid assumptions making into GDC. The latter because it could mean that code that's incorrect, but still accepted by the other compilers could silently break when compiled with GDC.

Invalid assumptions rarely make it into GDC. The testsuite is a good

AFAICT what you're proposing *is* invalid. I can't be sure because it's not clear what that "no-escape" property means; that's why I asked about it twice already... Clearly, escaping objects reachable indirectly via function arguments is perfectly fine (eg string slicing), yet you wanted to treat args as no-escape by default. Also, treating /some/ types specially wouldn't be ideal; struct A { int a; /* no pointers or classes */ } struct B { int* b; /*...*/ } f(A); // should be treated similarly to 'f(int)' f(B); // should be treated similarly to 'f(int*)' Yes, not doing it is "just" a missed optimization, but in practice it means that wrapping types becomes even more expensive in D (it's already almost prohibitively so - eg returning small one-element structs from functions needlessly happens by ref).
 bench for this, as well as several projects (now I've got dub set-up)
 to test it in the wild.

These problems will result in invalid optimizations, so can be hard to trigger and may come and go away randomly.
 Saying that, we have had to revert some optimisation cases as D's
 schizophrenic nature of enforcing attributes and behaviours is
 becoming increasingly dismal.
 
 eg:
 - nothrow has *no* guarantee, period, because it still allows
 unrecoverable errors being thrown, and allows people to catch said
 unrecoverable errors.
 - pure is a tough nut to crack also.  The theory should allow you to
 be able to cache return values, but in practise...

D's "pure" doesn't have much in common with the "normal" pure concept; exposing gcc's pure via an attribute and completely ignoring D's version is probably the only practical solution, anything else would be too costly, result in too small gains, and be too hard to get right.
 - The nature of debug statements breaks guarantees of both nothrow and
 pure, possibly many more.
 - Defining reliable strict aliasing rules, it turns out, is not that
 simple (this is something that Walter has mentioned about D should
 have good guarantees for, ie: D arrays).

Short term, disabling strict aliasing is the only option. I was scared of the impact it had before you even started to add support for it a few years ago (the codegen was already different w/ -fno-strict-aliasing before, which meant that I immediately had to disable it everywhere...) There probably does not exist a single D program that respects strict aliasing rules, other than by chance. The perf gains are minimal globally, but the potential for silent data corruption is huge.
 I'm just in investigating all avenues, as I usually do.  There is no
 reason why 'in' shouldn't have more powerful guarantees IMO, and what

Of course "scope" (which is part of "in) should be taken advantage of. I'm concerned about args not marked as "scope" being treated wrongly. [The scope-related bugs in D programs is a /language/ or frontend problem, not a reason to avoid doing the right thing in GDC. It's just that in practice what can happen is that GDC will be seen as miscompiling "working" D programs...] artur
Apr 19 2014
prev sibling next sibling parent Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 19 April 2014 17:10, Artur Skawina via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 On 04/19/14 16:21, Iain Buclaw via Digitalmars-d wrote:
 On 19 April 2014 14:33, Artur Skawina via Digitalmars-d
 <digitalmars-d puremagic.com> wrote:
 On 04/19/14 14:37, Iain Buclaw via Digitalmars-d wrote:
 On 19 April 2014 13:02, Artur Skawina via Digitalmars-d
 <digitalmars-d puremagic.com> wrote:
 On 04/19/14 13:03, Iain Buclaw via Digitalmars-d wrote:
 On Saturday, 19 April 2014 at 10:49:22 UTC, Iain Buclaw wrote:
 I'm currently testing out a GCC optimisation that allows you to set call
argument flags.  The current assumptions being:

 in parameters  =>  Assume no escape, no clobber (read-only).
 ref parameters, classes and pointers  =>  Assume worst case.
 default  =>  Assume no escape.

That should read: ref parameters, inout parameters, classes and pointers. The default of assuming no escape is an experiment - I may limit this to only scalar types, and parameters marked as 'scope' (So long as no one plans on deprecating it soon :)

What does "assume no escape" actually mean? [The above list doesn't really make sense. W/o context, it's hard to even tell why, hence the question.]

Actually, I might change the default to assume worst case. I've just tried this out, which is still valid. class C { int * p; this(int x) { p = &x; // escapes the address of the parameter. } }

This might be currently accepted, but it is clearly invalid (escapes local; the only way to make it work safely would be to silently copy 'x' to the GC-managed heap, which would be way too costly). A f(A a) { g(&a); return a; } // likewise with ref instead of pointer. This is OK (even if ideally 'g' should be forbidden from escaping 'a'). Similarly: A f(A a) { auto o = register(&a); // can modify 'a' o.blah(); // ditto doneWith(o); // ditto return a; } What I was wondering was things like whether that "assume no escape" property was transitive; if /locally/ escaping was disallowed, and to what extent. What does "assume no escape" mean at all? In your examples you're mentioning refs together with pointers, that would only make sense if no-escape were transitive -- but then treating all args as no-escape would be very wrong.
 Worse, scope doesn't error on the general case either.

 class D {
    int * p;
    this(scope int x) {
      p = &x; // escapes the address of the scope parameter.
    }
 }

D's "scope" isn't enforced in any way right now, which means that code could exist that is invalid, but currently works. It would break silently(!) when compiled with a decent compiler, which still doesn't enforce scope.

People should get bug fixing soon then. =)

Until some kind of diagnostics appear, most of those bugs won't even be found. It's too easy to write "auto f (in A a)" and then forget about the implicit 'scope' when modifying the function body.
 Do these examples give you a good example?

I'm worried about a) invalid assumptions making it into GDC; b) certain valid assumptions making into GDC. The latter because it could mean that code that's incorrect, but still accepted by the other compilers could silently break when compiled with GDC.

Invalid assumptions rarely make it into GDC. The testsuite is a good

AFAICT what you're proposing *is* invalid. I can't be sure because it's not clear what that "no-escape" property means; that's why I asked about it twice already... Clearly, escaping objects reachable indirectly via function arguments is perfectly fine (eg string slicing), yet you wanted to treat args as no-escape by default.

Not wanted - experimented. I could not think at the time a use case where a parameter could escape. And *I* have shown a very valid use case to *disprove myself*. I'm not sure of your continual persistence of bringing this up as this is no longer relevant to me. Other than possibly the silent breaking of 'scope' or 'in' parameters that are misused (accepts invalid bugs).
 bench for this, as well as several projects (now I've got dub set-up)
 to test it in the wild.

These problems will result in invalid optimizations, so can be hard to trigger and may come and go away randomly.
 Saying that, we have had to revert some optimisation cases as D's
 schizophrenic nature of enforcing attributes and behaviours is
 becoming increasingly dismal.

 eg:
 - nothrow has *no* guarantee, period, because it still allows
 unrecoverable errors being thrown, and allows people to catch said
 unrecoverable errors.
 - pure is a tough nut to crack also.  The theory should allow you to
 be able to cache return values, but in practise...

D's "pure" doesn't have much in common with the "normal" pure concept; exposing gcc's pure via an attribute and completely ignoring D's version is probably the only practical solution, anything else would be too costly, result in too small gains, and be too hard to get right.

Is what we do. I think the current conditions for a pure in the C sense function in D is more or less impossible to achieve. The only guarantee that we can cling onto is that the transitive nature of pure means that functions can be const folded as deep as the pure rabbit hole goes.
 - The nature of debug statements breaks guarantees of both nothrow and
 pure, possibly many more.
 - Defining reliable strict aliasing rules, it turns out, is not that
 simple (this is something that Walter has mentioned about D should
 have good guarantees for, ie: D arrays).

Short term, disabling strict aliasing is the only option. I was scared of the impact it had before you even started to add support for it a few years ago (the codegen was already different w/ -fno-strict-aliasing before, which meant that I immediately had to disable it everywhere...) There probably does not exist a single D program that respects strict aliasing rules, other than by chance. The perf gains are minimal globally, but the potential for silent data corruption is huge.

I think the performance gains are worthy of note, most benchmarks tend to suggest that code is at least 5% slower with strict aliasing optimisations turned off.
 I'm just in investigating all avenues, as I usually do.  There is no
 reason why 'in' shouldn't have more powerful guarantees IMO, and what

Of course "scope" (which is part of "in) should be taken advantage of. I'm concerned about args not marked as "scope" being treated wrongly. [The scope-related bugs in D programs is a /language/ or frontend problem, not a reason to avoid doing the right thing in GDC. It's just that in practice what can happen is that GDC will be seen as miscompiling "working" D programs...]

Indeed. However my approach may be the reverse here as my attention span is short lived when it comes to working/moving around the various areas of gdc (Implement the optimisation, then fix the accepts invalid upstream), otherwise it may not be for another 2 years till I look at this again.
Apr 19 2014
prev sibling next sibling parent Artur Skawina via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 04/20/14 03:00, Iain Buclaw via Digitalmars-d wrote:
 On 19 April 2014 17:10, Artur Skawina via Digitalmars-d
 <digitalmars-d puremagic.com> wrote:
 On 04/19/14 16:21, Iain Buclaw via Digitalmars-d wrote:
 On 19 April 2014 14:33, Artur Skawina via Digitalmars-d
 <digitalmars-d puremagic.com> wrote:
 On 04/19/14 14:37, Iain Buclaw via Digitalmars-d wrote:
 On 19 April 2014 13:02, Artur Skawina via Digitalmars-d
 <digitalmars-d puremagic.com> wrote:
 On 04/19/14 13:03, Iain Buclaw via Digitalmars-d wrote:
 On Saturday, 19 April 2014 at 10:49:22 UTC, Iain Buclaw wrote:
 I'm currently testing out a GCC optimisation that allows you to set call
argument flags.  The current assumptions being:

 in parameters  =>  Assume no escape, no clobber (read-only).
 ref parameters, classes and pointers  =>  Assume worst case.
 default  =>  Assume no escape.

That should read: ref parameters, inout parameters, classes and pointers. The default of assuming no escape is an experiment - I may limit this to only scalar types, and parameters marked as 'scope' (So long as no one plans on deprecating it soon :)

What does "assume no escape" actually mean? [The above list doesn't really make sense. W/o context, it's hard to even tell why, hence the question.]






 What I was wondering was things like whether that "assume no escape"
 property was transitive; if /locally/ escaping was disallowed, and
 to what extent. What does "assume no escape" mean at all? In your
 examples you're mentioning refs together with pointers, that would
 only make sense if no-escape were transitive -- but then treating all
 args as no-escape would be very wrong.




 I'm worried about a) invalid assumptions making it into GDC;
 b) certain valid assumptions making into GDC. The latter because
 it could mean that code that's incorrect, but still accepted by
 the other compilers could silently break when compiled with GDC.

Invalid assumptions rarely make it into GDC. The testsuite is a good

AFAICT what you're proposing *is* invalid. I can't be sure because it's not clear what that "no-escape" property means; that's why I asked about it twice already... Clearly, escaping objects reachable indirectly via function arguments is perfectly fine (eg string slicing), yet you wanted to treat args as no-escape by default.

Not wanted - experimented. I could not think at the time a use case where a parameter could escape. And *I* have shown a very valid use case to *disprove myself*. I'm not sure of your continual persistence of bringing this up as this is no longer relevant to me. Other than

Several reasons. First, I did not realize that you had changed your mind. Second, I'm just trying to figure out what that 'assume-no-escape' property implies. From a C based compiler I would have expected a feature that disallowed address-of on objects, but did not affect any other object referenced from that one (for handling C's 'register' storage class). Third, I'm paranoid when it comes to GDC regressions. Once upon the time I had a working D compiler, one that was able to deliver maybe ~75% of GCC functionality, and where the main issues were with the language and frontend, not with the tool. This was a few years ago, after you'd fixed the many small problems I had run into. The type of those issues made it very clear that I was the only one that was trying to really use GDC. Unfortunately what happened then was that things started to get worse, and by worse I mean "unusable"; GDC ceased to be able to deliver functionality and performance that was in the same league as GCC C/C++. LTO stopped working (which is not only crucial for a language w/o macros and low-level control, but was useful as a work-around for tool issues, like the lack of cross module inlining). The accepted language changed in a way that was completely backward incompatible and would have required an extra preprocessing step (pragma-attributes were removed and became hard errors). GCC attributes became inaccessible; things like pure, malloc, ifunc, align, cold, regparm all used to work, but now didn't. inline, noinline and flatten were added back as /true/ D-style attributes later, and seem to work great. Thanks for exposing those, but my concern is that dealing with them one-by-one does not scale - that's why I haven't filed any bug reports wrt the other ones. Your work on getting D support merged into GCC is critically important for the survival of the language; things that are merely optimizations can happen later, or will be mostly irrelevant (if the merge never happens). But the situation right now is that the latest GDC version that works is the gcc4.6 one (IIRC 2.057 based) - I have tried to migrate to a newer one maybe 5 or 6 times over the last 1.5 year, and always run into some kind of problem immediately after trying a new build. Like the last time, with the failure of inlining of certain trivial functions. So when I then read about a proposed new optimization, which sounds dubious to me, I ask about more details, as I'm horrified that I could encounter yet another new GDC specific problem during the next round of the let's-upgrade-gdc experience...
 - Defining reliable strict aliasing rules, it turns out, is not that
 simple (this is something that Walter has mentioned about D should
 have good guarantees for, ie: D arrays).

Short term, disabling strict aliasing is the only option. I was scared of the impact it had before you even started to add support for it a few years ago (the codegen was already different w/ -fno-strict-aliasing before, which meant that I immediately had to disable it everywhere...) There probably does not exist a single D program that respects strict aliasing rules, other than by chance. The perf gains are minimal globally, but the potential for silent data corruption is huge.

I think the performance gains are worthy of note, most benchmarks tend to suggest that code is at least 5% slower with strict aliasing optimisations turned off.

I'd like to avoid something like the GCC C strict-aliasing disaster. String-aliasing helps some code, but breaks some other (legacy) code. Turning on strict-aliasing by default and recompiling the whole userspace (hundreds of packages, thousands of sources) is not going to make any noticeable difference for a desktop user, yet it is likely to trigger data-corrupting bugs /somewhere/. So the result is practically no perf gain, but a non-zero chance of corrupting user data, often by programs that are not perf sensitive at all - that's not a good trade-off. D doesn't have the MLOCs of legacy code, but I doubt that the D code that exists was written with strict aliasing in mind. Especially since the rules are not exactly well defined. artur
Apr 20 2014
prev sibling next sibling parent Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
--001a11347e9c9bbb7e04f77efb76
Content-Type: text/plain; charset=UTF-8

On 20 April 2014 13:19, Artur Skawina via Digitalmars-d <
digitalmars-d puremagic.com> wrote:
 On 04/20/14 03:00, Iain Buclaw via Digitalmars-d wrote:
 On 19 April 2014 17:10, Artur Skawina via Digitalmars-d
 <digitalmars-d puremagic.com> wrote:
 On 04/19/14 16:21, Iain Buclaw via Digitalmars-d wrote:
 On 19 April 2014 14:33, Artur Skawina via Digitalmars-d
 <digitalmars-d puremagic.com> wrote:
 On 04/19/14 14:37, Iain Buclaw via Digitalmars-d wrote:
 On 19 April 2014 13:02, Artur Skawina via Digitalmars-d
 <digitalmars-d puremagic.com> wrote:
 On 04/19/14 13:03, Iain Buclaw via Digitalmars-d wrote:
 On Saturday, 19 April 2014 at 10:49:22 UTC, Iain Buclaw wrote:
 I'm currently testing out a GCC optimisation that allows you to









 in parameters => Assume no escape, no clobber (read-only).
 ref parameters, classes and pointers => Assume worst case.
 default => Assume no escape.

That should read: ref parameters, inout parameters, classes and pointers. The default of assuming no escape is an experiment - I may limit








one plans on deprecating it soon :)
 What does "assume no escape" actually mean?
 [The above list doesn't really make sense. W/o context, it's
 hard to even tell why, hence the question.]






 What I was wondering was things like whether that "assume no escape"
 property was transitive; if /locally/ escaping was disallowed, and
 to what extent. What does "assume no escape" mean at all? In your
 examples you're mentioning refs together with pointers, that would
 only make sense if no-escape were transitive -- but then treating all
 args as no-escape would be very wrong.




 I'm worried about a) invalid assumptions making it into GDC;
 b) certain valid assumptions making into GDC. The latter because
 it could mean that code that's incorrect, but still accepted by
 the other compilers could silently break when compiled with GDC.

Invalid assumptions rarely make it into GDC. The testsuite is a good

AFAICT what you're proposing *is* invalid. I can't be sure because it's not clear what that "no-escape" property means; that's why I asked about it twice already... Clearly, escaping objects reachable indirectly via function arguments is perfectly fine (eg string slicing), yet you wanted to treat args as no-escape by default.

Not wanted - experimented. I could not think at the time a use case where a parameter could escape. And *I* have shown a very valid use case to *disprove myself*. I'm not sure of your continual persistence of bringing this up as this is no longer relevant to me. Other than

Several reasons. First, I did not realize that you had changed your mind. Second, I'm just trying to figure out what that 'assume-no-escape' property implies. From a C based compiler I would have expected a feature that disallowed address-of on objects, but did not affect any other object referenced from that one (for handling C's 'register' storage

 Third, I'm paranoid when it comes to GDC regressions. Once upon the time
 I had a working D compiler, one that was able to deliver maybe ~75% of
 GCC functionality, and where the main issues were with the language and
 frontend, not with the tool. This was a few years ago, after you'd fixed
 the many small problems I had run into. The type of those issues made it
 very clear that I was the only one that was trying to really use GDC.
 Unfortunately what happened then was that things started to get worse, and
 by worse I mean "unusable"; GDC ceased to be able to deliver functionality
 and performance that was in the same league as GCC C/C++. LTO stopped
 working (which is not only crucial for a language w/o macros and low-level
 control, but was useful as a work-around for tool issues, like the lack
 of cross module inlining).

I have not seen this, infact the opposite. As for speed of runtime. Many of the optimisations that were removed in the last year have been found when porting to architectures that are less forgiving than x86. I still don't what's up with LTO. It's not easy to debug, and fails in a way that doesn't seem to suggest a front-end problem (it chokes when reading LTO information written by itself).
 The accepted language changed in a way that
 was completely backward incompatible and would have required an extra
 preprocessing step (pragma-attributes were removed and became hard
 errors). GCC attributes became inaccessible; things like  pure,  malloc,
  ifunc,  align,  cold,  regparm all used to work, but now didn't.  inline,
  noinline and  flatten were added back as /true/ D-style attributes later,
 and seem to work great.

Many of these attributes to which need a good reason to be hashed out. Originally my intention was to only expose those that are impossible to infer otherwise in D through existing language features.
 Thanks for exposing those, but my concern is that
 dealing with them one-by-one does not scale - that's why I haven't filed
 any bug reports wrt the other ones.

They were exposed one-by-one before too. The entire source of routines was pretty much a copy-paste job from c-common.c. It has been suggested by the gcc maintainers to put those attributes into a more common area that can be shared between C/C++/ObjC and D - but there were too many subtle differences to make that work at all. So instead I lopped of the head of the problem. The same as D iasm support, which was similarly dropped completely.
 Your work on getting D support merged
 into GCC is critically important for the survival of the language; things
 that are merely optimizations can happen later, or will be mostly

 (if the merge never happens).
 But the situation right now is that the latest GDC version that works is
 the gcc4.6 one (IIRC 2.057 based) - I have tried to migrate to a newer one
 maybe 5 or 6 times over the last 1.5 year, and always run into some kind

 problem immediately after trying a new build.

What projects are you having problems with. My experience says that there are more frontend implementation problems than gdc glue when moving across several major versions.
 Like the last time, with the
 failure of inlining of certain trivial functions. So when I then read

 a proposed new optimization, which sounds dubious to me, I ask about
 more details, as I'm horrified that I could encounter yet another new GDC
 specific problem during the next round of the let's-upgrade-gdc


The failure of inlining is not a blocker IMO - relying on 'hidden' features, NRVO being another example, in user code is a bug. Regardless of the validity. This particular problem has been noted and it is being dealt with by improving the relationship between differing variants of const and mutable types. --001a11347e9c9bbb7e04f77efb76 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable <p dir=3D"ltr">On 20 April 2014 13:19, Artur Skawina via Digitalmars-d &lt;= <a href=3D"mailto:digitalmars-d puremagic.com">digitalmars-d puremagic.com<= /a>&gt; wrote:<br> &gt; On 04/20/14 03:00, Iain Buclaw via Digitalmars-d wrote:<br> &gt;&gt; On 19 April 2014 17:10, Artur Skawina via Digitalmars-d<br> &gt;&gt; &lt;<a href=3D"mailto:digitalmars-d puremagic.com">digitalmars-d p= uremagic.com</a>&gt; wrote:<br> &gt;&gt;&gt; On 04/19/14 16:21, Iain Buclaw via Digitalmars-d wrote:<br> &gt;&gt;&gt;&gt; On 19 April 2014 14:33, Artur Skawina via Digitalmars-d<br=

mars-d puremagic.com</a>&gt; wrote:<br> &gt;&gt;&gt;&gt;&gt; On 04/19/14 14:37, Iain Buclaw via Digitalmars-d wrote= :<br> &gt;&gt;&gt;&gt;&gt;&gt; On 19 April 2014 13:02, Artur Skawina via Digitalm= ars-d<br> &gt;&gt;&gt;&gt;&gt;&gt; &lt;<a href=3D"mailto:digitalmars-d puremagic.com"=
digitalmars-d puremagic.com</a>&gt; wrote:<br>

-d wrote:<br> &gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; On Saturday, 19 April 2014 at 10:49:22 UTC= , Iain Buclaw wrote:<br> &gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; I&#39;m currently testing out a GCC op= timisation that allows you to set call argument flags. The current assumpti= ons being:<br> &gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;<br> &gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; in parameters =3D&gt; Assume no escape= , no clobber (read-only).<br> &gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; ref parameters, classes and pointers = =3D&gt; Assume worst case.<br> &gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; default =3D&gt; Assume no escape.<br> &gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;<br> &gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; That should read:<br> &gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;<br> &gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; ref parameters, inout parameters, classes = and pointers.<br> &gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;<br> &gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; The default of assuming no escape is an ex= periment - I may limit this to only scalar types, and parameters marked as = &#39;scope&#39; (So long as no one plans on deprecating it soon :)<br> &gt;&gt;&gt;&gt;&gt;&gt;&gt;<br> &gt;&gt;&gt;&gt;&gt;&gt;&gt; What does &quot;assume no escape&quot; actuall= y mean?<br> &gt;&gt;&gt;&gt;&gt;&gt;&gt; [The above list doesn&#39;t really make sense.= W/o context, it&#39;s<br> &gt;&gt;&gt;&gt;&gt;&gt;&gt; hard to even tell why, hence the question.]<br=

&gt;&gt;&gt;&gt;&gt; What I was wondering was things like whether that &quo= t;assume no escape&quot;<br> &gt;&gt;&gt;&gt;&gt; property was transitive; if /locally/ escaping was dis= allowed, and<br> &gt;&gt;&gt;&gt;&gt; to what extent. What does &quot;assume no escape&quot;= mean at all? In your<br> &gt;&gt;&gt;&gt;&gt; examples you&#39;re mentioning refs together with poin= ters, that would<br> &gt;&gt;&gt;&gt;&gt; only make sense if no-escape were transitive -- but th= en treating all<br> &gt;&gt;&gt;&gt;&gt; args as no-escape would be very wrong.<br> &gt;<br> &gt;&gt;&gt;&gt;&gt; I&#39;m worried about a) invalid assumptions making it= into GDC;<br> &gt;&gt;&gt;&gt;&gt; b) certain valid assumptions making into GDC. The latt= er because<br> &gt;&gt;&gt;&gt;&gt; it could mean that code that&#39;s incorrect, but stil= l accepted by<br> &gt;&gt;&gt;&gt;&gt; the other compilers could silently break when compiled= with GDC.<br> &gt;&gt;&gt;&gt;<br> &gt;&gt;&gt;&gt; Invalid assumptions rarely make it into GDC. The testsuite= is a good<br> &gt;&gt;&gt;<br> &gt;&gt;&gt; AFAICT what you&#39;re proposing *is* invalid. I can&#39;t be = sure because<br> &gt;&gt;&gt; it&#39;s not clear what that &quot;no-escape&quot; property me= ans; that&#39;s why I<br> &gt;&gt;&gt; asked about it twice already...<br> &gt;&gt;&gt; Clearly, escaping objects reachable indirectly via function ar= guments<br> &gt;&gt;&gt; is perfectly fine (eg string slicing), yet you wanted to treat= args as<br> &gt;&gt;&gt; no-escape by default.<br> &gt;&gt;<br> &gt;&gt; Not wanted - experimented. I could not think at the time a use cas= e<br> &gt;&gt; where a parameter could escape. And *I* have shown a very valid us= e<br> &gt;&gt; case to *disprove myself*. I&#39;m not sure of your continual pers= istence<br> &gt;&gt; of bringing this up as this is no longer relevant to me. Other tha= n<br> &gt;<br> &gt; Several reasons. First, I did not realize that you had changed your mi= nd.<br> &gt; Second, I&#39;m just trying to figure out what that &#39;assume-no-esc= ape&#39;<br> &gt; property implies. From a C based compiler I would have expected a feat= ure<br> &gt; that disallowed address-of on objects, but did not affect any other<br=

9; storage class).<br> &gt; Third, I&#39;m paranoid when it comes to GDC regressions. Once upon th= e time<br> &gt; I had a working D compiler, one that was able to deliver maybe ~75% of= <br> &gt; GCC functionality, and where the main issues were with the language an= d<br> &gt; frontend, not with the tool. This was a few years ago, after you&#39;d= fixed<br> &gt; the many small problems I had run into. The type of those issues made = it<br> &gt; very clear that I was the only one that was trying to really use GDC.<= br> &gt; Unfortunately what happened then was that things started to get worse,= and<br> &gt; by worse I mean &quot;unusable&quot;; GDC ceased to be able to deliver= functionality<br> &gt; and performance that was in the same league as GCC C/C++. LTO stopped<= br> &gt; working (which is not only crucial for a language w/o macros and low-l= evel<br> &gt; control, but was useful as a work-around for tool issues, like the lac= k<br> &gt; of cross module inlining).</p> <p dir=3D"ltr">I have not seen this, infact the opposite.</p> <p dir=3D"ltr">As for speed of runtime.=C2=A0 Many of the optimisations tha= t were removed in the last year have been found when porting to architectur= es that are less forgiving than x86.</p> <p dir=3D"ltr">I still don&#39;t what&#39;s up with LTO. It&#39;s not easy = to debug, and fails in a way that doesn&#39;t seem to suggest a front-end p= roblem (it chokes when reading LTO information written by itself).</p> <p dir=3D"ltr">&gt; The accepted language changed in a way that<br> &gt; was completely backward incompatible and would have required an extra<= br> &gt; preprocessing step (pragma-attributes were removed and became hard<br> &gt; errors). GCC attributes became inaccessible; things like pure, mallo= c,<br> &gt; ifunc, align, cold, regparm all used to work, but now didn&#39;t. = inline,<br> &gt; noinline and flatten were added back as /true/ D-style attributes la= ter,<br> &gt; and seem to work great.</p> <p dir=3D"ltr">Many of these attributes to which need a good reason to be h= ashed out.=C2=A0 Originally my intention was to only expose those that are = impossible to infer otherwise in D through existing language features.</p> <p dir=3D"ltr">&gt; Thanks for exposing those, but my concern is that<br> &gt; dealing with them one-by-one does not scale - that&#39;s why I haven&#= 39;t filed<br> &gt; any bug reports wrt the other ones.</p> <p dir=3D"ltr">They were exposed one-by-one before too. The entire source o= f routines was pretty much a copy-paste job from c-common.c. It has been su= ggested by the gcc maintainers to put those attributes into a more common a= rea that can be shared between C/C++/ObjC and D - but there were too many s= ubtle differences to make that work at all.=C2=A0 So instead I lopped of th= e head of the problem. The same as D iasm support, which was similarly drop= ped completely.</p> <p dir=3D"ltr">&gt; Your work on getting D support merged<br> &gt; into GCC is critically important for the survival of the language; thi= ngs<br> &gt; that are merely optimizations can happen later, or will be mostly irre= levant<br> &gt; (if the merge never happens).<br> &gt; But the situation right now is that the latest GDC version that works = is<br> &gt; the gcc4.6 one (IIRC 2.057 based) - I have tried to migrate to a newer= one<br> &gt; maybe 5 or 6 times over the last 1.5 year, and always run into some ki= nd of<br> &gt; problem immediately after trying a new build.</p> <p dir=3D"ltr">What projects are you having problems with. My experience sa= ys that there are more frontend implementation problems than gdc glue when = moving across several major versions. </p> <p dir=3D"ltr">&gt; Like the last time, with the<br> &gt; failure of inlining of certain trivial functions. So when I then read = about<br> &gt; a proposed new optimization, which sounds dubious to me, I ask about<b= r> &gt; more details, as I&#39;m horrified that I could encounter yet another = new GDC<br> &gt; specific problem during the next round of the let&#39;s-upgrade-gdc ex= perience...<br> &gt;</p> <p dir=3D"ltr">The failure of inlining is not a blocker IMO - relying on &#= 39;hidden&#39; features, NRVO being another example, in user code is a bug.= Regardless of the validity.=C2=A0 This particular problem has been noted a= nd it is being dealt with by improving the relationship between differing v= ariants of const and mutable types.</p> --001a11347e9c9bbb7e04f77efb76--
Apr 20 2014
prev sibling next sibling parent Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
--001a11c3ce54209ed504f789ae9a
Content-Type: text/plain; charset=UTF-8

On 20 Apr 2014 13:19, "Artur Skawina via Digitalmars-d" <
digitalmars-d puremagic.com> wrote:
 On 04/20/14 03:00, Iain Buclaw via Digitalmars-d wrote:
 On 19 April 2014 17:10, Artur Skawina via Digitalmars-d
 <digitalmars-d puremagic.com> wrote:
 On 04/19/14 16:21, Iain Buclaw via Digitalmars-d wrote:
 On 19 April 2014 14:33, Artur Skawina via Digitalmars-d
 <digitalmars-d puremagic.com> wrote:
 On 04/19/14 14:37, Iain Buclaw via Digitalmars-d wrote:
 On 19 April 2014 13:02, Artur Skawina via Digitalmars-d
 <digitalmars-d puremagic.com> wrote:
 On 04/19/14 13:03, Iain Buclaw via Digitalmars-d wrote:
 On Saturday, 19 April 2014 at 10:49:22 UTC, Iain Buclaw wrote:
 I'm currently testing out a GCC optimisation that allows you to









 in parameters  =>  Assume no escape, no clobber (read-only).
 ref parameters, classes and pointers  =>  Assume worst case.
 default  =>  Assume no escape.

That should read: ref parameters, inout parameters, classes and pointers. The default of assuming no escape is an experiment - I may limit








one plans on deprecating it soon :)
 What does "assume no escape" actually mean?
 [The above list doesn't really make sense. W/o context, it's
 hard to even tell why, hence the question.]






 What I was wondering was things like whether that "assume no escape"
 property was transitive; if /locally/ escaping was disallowed, and
 to what extent. What does "assume no escape" mean at all? In your
 examples you're mentioning refs together with pointers, that would
 only make sense if no-escape were transitive -- but then treating all
 args as no-escape would be very wrong.




 I'm worried about a) invalid assumptions making it into GDC;
 b) certain valid assumptions making into GDC. The latter because
 it could mean that code that's incorrect, but still accepted by
 the other compilers could silently break when compiled with GDC.

Invalid assumptions rarely make it into GDC. The testsuite is a good

AFAICT what you're proposing *is* invalid. I can't be sure because it's not clear what that "no-escape" property means; that's why I asked about it twice already... Clearly, escaping objects reachable indirectly via function arguments is perfectly fine (eg string slicing), yet you wanted to treat args as no-escape by default.

Not wanted - experimented. I could not think at the time a use case where a parameter could escape. And *I* have shown a very valid use case to *disprove myself*. I'm not sure of your continual persistence of bringing this up as this is no longer relevant to me. Other than

Several reasons. First, I did not realize that you had changed your mind.

It wouldn't be an experiment if I didn't change my mind 30 times. :)
 Second, I'm just trying to figure out what that 'assume-no-escape'
 property implies. From a C based compiler I would have expected a feature
 that disallowed address-of on objects, but did not affect any other
 object referenced from that one (for handling C's 'register' storage

This is an optimisation not built with a C compiler in mind, nor is it leveraged by C/C++, so I don't think you should think of it in this way. I was actually made aware of this particular attribute when someone spoke to a GNU/Fortran maintainer and thought that INTENT(IN) - or at least the no clobber aspect - could be used to improve optimisations around 'immutable' parameters. Something that gives us the one up that C-family const could never guarantee (currently there is no difference between const and immutable). That is still on the table to do using this attribute pending investigation. The no escape aspect leverages on what 'scope' and 'in' should be enforcing.
 Third, I'm paranoid when it comes to GDC regressions. Once upon the time
 I had a working D compiler, one that was able to deliver maybe ~75% of
 GCC functionality, and where the main issues were with the language and
 frontend, not with the tool.

GCC functionality is not to be confused with C/C++ functionality. And most of the attributes exposed to C-family languages were nothing more an excess baggage, ie: artificial makes no sense when there is no inline keyword. Anything that needs raising would ideally be in a bug report, as I can't keep track of issues raised in threads. Regards Iain --001a11c3ce54209ed504f789ae9a Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable <p dir=3D"ltr">On 20 Apr 2014 13:19, &quot;Artur Skawina via Digitalmars-d&= quot; &lt;<a href=3D"mailto:digitalmars-d puremagic.com">digitalmars-d pure= magic.com</a>&gt; wrote:<br> &gt;<br> &gt; On 04/20/14 03:00, Iain Buclaw via Digitalmars-d wrote:<br> &gt; &gt; On 19 April 2014 17:10, Artur Skawina via Digitalmars-d<br> &gt; &gt; &lt;<a href=3D"mailto:digitalmars-d puremagic.com">digitalmars-d = puremagic.com</a>&gt; wrote:<br> &gt; &gt;&gt; On 04/19/14 16:21, Iain Buclaw via Digitalmars-d wrote:<br> &gt; &gt;&gt;&gt; On 19 April 2014 14:33, Artur Skawina via Digitalmars-d<b= r> &gt; &gt;&gt;&gt; &lt;<a href=3D"mailto:digitalmars-d puremagic.com">digita= lmars-d puremagic.com</a>&gt; wrote:<br> &gt; &gt;&gt;&gt;&gt; On 04/19/14 14:37, Iain Buclaw via Digitalmars-d wrot= e:<br> &gt; &gt;&gt;&gt;&gt;&gt; On 19 April 2014 13:02, Artur Skawina via Digital= mars-d<br> &gt; &gt;&gt;&gt;&gt;&gt; &lt;<a href=3D"mailto:digitalmars-d puremagic.com= ">digitalmars-d puremagic.com</a>&gt; wrote:<br> &gt; &gt;&gt;&gt;&gt;&gt;&gt; On 04/19/14 13:03, Iain Buclaw via Digitalmar= s-d wrote:<br> &gt; &gt;&gt;&gt;&gt;&gt;&gt;&gt; On Saturday, 19 April 2014 at 10:49:22 UT= C, Iain Buclaw wrote:<br> &gt; &gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; I&#39;m currently testing out a GCC o= ptimisation that allows you to set call argument flags. =C2=A0The current a= ssumptions being:<br> &gt; &gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;<br> &gt; &gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; in parameters =C2=A0=3D&gt; =C2=A0Ass= ume no escape, no clobber (read-only).<br> &gt; &gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; ref parameters, classes and pointers = =C2=A0=3D&gt; =C2=A0Assume worst case.<br> &gt; &gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; default =C2=A0=3D&gt; =C2=A0Assume no= escape.<br> &gt; &gt;&gt;&gt;&gt;&gt;&gt;&gt;<br> &gt; &gt;&gt;&gt;&gt;&gt;&gt;&gt; That should read:<br> &gt; &gt;&gt;&gt;&gt;&gt;&gt;&gt;<br> &gt; &gt;&gt;&gt;&gt;&gt;&gt;&gt; ref parameters, inout parameters, classes= and pointers.<br> &gt; &gt;&gt;&gt;&gt;&gt;&gt;&gt;<br> &gt; &gt;&gt;&gt;&gt;&gt;&gt;&gt; The default of assuming no escape is an e= xperiment - I may limit this to only scalar types, and parameters marked as= &#39;scope&#39; =C2=A0(So long as no one plans on deprecating it soon :)<b= r> &gt; &gt;&gt;&gt;&gt;&gt;&gt;<br> &gt; &gt;&gt;&gt;&gt;&gt;&gt; What does &quot;assume no escape&quot; actual= ly mean?<br> &gt; &gt;&gt;&gt;&gt;&gt;&gt; [The above list doesn&#39;t really make sense= . W/o context, it&#39;s<br> &gt; &gt;&gt;&gt;&gt;&gt;&gt; hard to even tell why, hence the question.]<b= r> &gt;<br> &gt; &gt;&gt;&gt;&gt; What I was wondering was things like whether that &qu= ot;assume no escape&quot;<br> &gt; &gt;&gt;&gt;&gt; property was transitive; if /locally/ escaping was di= sallowed, and<br> &gt; &gt;&gt;&gt;&gt; to what extent. What does &quot;assume no escape&quot= ; mean at all? In your<br> &gt; &gt;&gt;&gt;&gt; examples you&#39;re mentioning refs together with poi= nters, that would<br> &gt; &gt;&gt;&gt;&gt; only make sense if no-escape were transitive -- but t= hen treating all<br> &gt; &gt;&gt;&gt;&gt; args as no-escape would be very wrong.<br> &gt;<br> &gt; &gt;&gt;&gt;&gt; I&#39;m worried about a) invalid assumptions making i= t into GDC;<br> &gt; &gt;&gt;&gt;&gt; b) certain valid assumptions making into GDC. The lat= ter because<br> &gt; &gt;&gt;&gt;&gt; it could mean that code that&#39;s incorrect, but sti= ll accepted by<br> &gt; &gt;&gt;&gt;&gt; the other compilers could silently break when compile= d with GDC.<br> &gt; &gt;&gt;&gt;<br> &gt; &gt;&gt;&gt; Invalid assumptions rarely make it into GDC. =C2=A0The te= stsuite is a good<br> &gt; &gt;&gt;<br> &gt; &gt;&gt; AFAICT what you&#39;re proposing *is* invalid. I can&#39;t be= sure because<br> &gt; &gt;&gt; it&#39;s not clear what that &quot;no-escape&quot; property m= eans; that&#39;s why I<br> &gt; &gt;&gt; asked about it twice already...<br> &gt; &gt;&gt; Clearly, escaping objects reachable indirectly via function a= rguments<br> &gt; &gt;&gt; is perfectly fine (eg string slicing), yet you wanted to trea= t args as<br> &gt; &gt;&gt; no-escape by default.<br> &gt; &gt;<br> &gt; &gt; Not wanted - experimented. =C2=A0I could not think at the time a = use case<br> &gt; &gt; where a parameter could escape. =C2=A0And *I* have shown a very v= alid use<br> &gt; &gt; case to *disprove myself*. =C2=A0I&#39;m not sure of your continu= al persistence<br> &gt; &gt; of bringing this up as this is no longer relevant to me. =C2=A0Ot= her than<br> &gt;<br> &gt; Several reasons. First, I did not realize that you had changed your mi= nd.</p> <p dir=3D"ltr">It wouldn&#39;t be an experiment if I didn&#39;t change my m= ind 30 times. :)</p> <p dir=3D"ltr">&gt; Second, I&#39;m just trying to figure out what that &#3= 9;assume-no-escape&#39;<br> &gt; property implies. From a C based compiler I would have expected a feat= ure<br> &gt; that disallowed address-of on objects, but did not affect any other<br=

9; storage class).</p> <p dir=3D"ltr">This is an optimisation not built with a C compiler in mind,= nor is it leveraged by C/C++, so I don&#39;t think you should think of it = in this way.</p> <p dir=3D"ltr">I was actually made aware of this particular attribute when = someone spoke to a GNU/Fortran maintainer and thought that INTENT(IN) - or = at least the no clobber aspect - could be used to improve optimisations aro= und &#39;immutable&#39; parameters. Something that gives us the one up that= C-family const could never guarantee (currently there is no difference bet= ween const and immutable).=C2=A0 That is still on the table to do using thi= s attribute pending investigation.</p> <p dir=3D"ltr">The no escape aspect leverages on what &#39;scope&#39; and &= #39;in&#39; should be enforcing.</p> <p dir=3D"ltr">&gt; Third, I&#39;m paranoid when it comes to GDC regression= s. Once upon the time<br> &gt; I had a working D compiler, one that was able to deliver maybe ~75% of= <br> &gt; GCC functionality, and where the main issues were with the language an= d<br> &gt; frontend, not with the tool.</p> <p dir=3D"ltr">GCC functionality is not to be confused with C/C++ functiona= lity.=C2=A0 And most of the attributes exposed to C-family languages were n= othing more an excess baggage, ie: artificial makes no sense when there is= no inline keyword.</p> <p dir=3D"ltr">Anything that needs raising would ideally be in a bug report= , as I can&#39;t keep track of issues raised in threads.</p> <p dir=3D"ltr">Regards<br> Iain</p> --001a11c3ce54209ed504f789ae9a--
Apr 21 2014
prev sibling next sibling parent Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
--001a11347e9c5b5cea04f789c4f5
Content-Type: text/plain; charset=UTF-8

On 21 Apr 2014 09:56, "Iain Buclaw" <ibuclaw gdcproject.org> wrote:
 On 20 Apr 2014 13:19, "Artur Skawina via Digitalmars-d" <

 On 04/20/14 03:00, Iain Buclaw via Digitalmars-d wrote:
 On 19 April 2014 17:10, Artur Skawina via Digitalmars-d
 <digitalmars-d puremagic.com> wrote:
 On 04/19/14 16:21, Iain Buclaw via Digitalmars-d wrote:
 On 19 April 2014 14:33, Artur Skawina via Digitalmars-d
 <digitalmars-d puremagic.com> wrote:
 On 04/19/14 14:37, Iain Buclaw via Digitalmars-d wrote:
 On 19 April 2014 13:02, Artur Skawina via Digitalmars-d
 <digitalmars-d puremagic.com> wrote:
 On 04/19/14 13:03, Iain Buclaw via Digitalmars-d wrote:
 On Saturday, 19 April 2014 at 10:49:22 UTC, Iain Buclaw wrote:
 I'm currently testing out a GCC optimisation that allows you










 in parameters  =>  Assume no escape, no clobber (read-only).
 ref parameters, classes and pointers  =>  Assume worst case.
 default  =>  Assume no escape.

That should read: ref parameters, inout parameters, classes and pointers. The default of assuming no escape is an experiment - I may









as no one plans on deprecating it soon :)
 What does "assume no escape" actually mean?
 [The above list doesn't really make sense. W/o context, it's
 hard to even tell why, hence the question.]






 What I was wondering was things like whether that "assume no






 property was transitive; if /locally/ escaping was disallowed, and
 to what extent. What does "assume no escape" mean at all? In your
 examples you're mentioning refs together with pointers, that would
 only make sense if no-escape were transitive -- but then treating






 args as no-escape would be very wrong.




 I'm worried about a) invalid assumptions making it into GDC;
 b) certain valid assumptions making into GDC. The latter because
 it could mean that code that's incorrect, but still accepted by
 the other compilers could silently break when compiled with GDC.

Invalid assumptions rarely make it into GDC. The testsuite is a





 AFAICT what you're proposing *is* invalid. I can't be sure because
 it's not clear what that "no-escape" property means; that's why I
 asked about it twice already...
 Clearly, escaping objects reachable indirectly via function arguments
 is perfectly fine (eg string slicing), yet you wanted to treat args




 no-escape by default.

Not wanted - experimented. I could not think at the time a use case where a parameter could escape. And *I* have shown a very valid use case to *disprove myself*. I'm not sure of your continual persistence of bringing this up as this is no longer relevant to me. Other than

Several reasons. First, I did not realize that you had changed your


 It wouldn't be an experiment if I didn't change my mind 30 times. :)

 Second, I'm just trying to figure out what that 'assume-no-escape'
 property implies. From a C based compiler I would have expected a


 that disallowed address-of on objects, but did not affect any other
 object referenced from that one (for handling C's 'register' storage


 This is an optimisation not built with a C compiler in mind, nor is it

 I was actually made aware of this particular attribute when someone spoke

no clobber aspect - could be used to improve optimisations around 'immutable' parameters. Something that gives us the one up that C-family const could never guarantee (currently there is no difference between const and immutable). That is still on the table to do using this attribute pending investigation.
 The no escape aspect leverages on what 'scope' and 'in' should be

 Third, I'm paranoid when it comes to GDC regressions. Once upon the time
 I had a working D compiler, one that was able to deliver maybe ~75% of
 GCC functionality, and where the main issues were with the language and
 frontend, not with the tool.

GCC functionality is not to be confused with C/C++ functionality. And

excess baggage, ie: artificial makes no sense when there is no inline keyword.
 Anything that needs raising would ideally be in a bug report, as I can't


As for the original topic. STCin is an attribute ignored by the compiler (only talking about gdc) - which is a shame because marking parameters as 'in' I see is still encouraged. And I would assume the same is true also for dmd and ldc, otherwise someone would have noticed this bug by now. --001a11347e9c5b5cea04f789c4f5 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable <p dir=3D"ltr"><br> On 21 Apr 2014 09:56, &quot;Iain Buclaw&quot; &lt;<a href=3D"mailto:ibuclaw= gdcproject.org">ibuclaw gdcproject.org</a>&gt; wrote:<br> &gt;<br> &gt; On 20 Apr 2014 13:19, &quot;Artur Skawina via Digitalmars-d&quot; &lt;= <a href=3D"mailto:digitalmars-d puremagic.com">digitalmars-d puremagic.com<= /a>&gt; wrote:<br> &gt; &gt;<br> &gt; &gt; On 04/20/14 03:00, Iain Buclaw via Digitalmars-d wrote:<br> &gt; &gt; &gt; On 19 April 2014 17:10, Artur Skawina via Digitalmars-d<br> &gt; &gt; &gt; &lt;<a href=3D"mailto:digitalmars-d puremagic.com">digitalma= rs-d puremagic.com</a>&gt; wrote:<br> &gt; &gt; &gt;&gt; On 04/19/14 16:21, Iain Buclaw via Digitalmars-d wrote:<= br> &gt; &gt; &gt;&gt;&gt; On 19 April 2014 14:33, Artur Skawina via Digitalmar= s-d<br> &gt; &gt; &gt;&gt;&gt; &lt;<a href=3D"mailto:digitalmars-d puremagic.com">d= igitalmars-d puremagic.com</a>&gt; wrote:<br> &gt; &gt; &gt;&gt;&gt;&gt; On 04/19/14 14:37, Iain Buclaw via Digitalmars-d= wrote:<br> &gt; &gt; &gt;&gt;&gt;&gt;&gt; On 19 April 2014 13:02, Artur Skawina via Di= gitalmars-d<br> &gt; &gt; &gt;&gt;&gt;&gt;&gt; &lt;<a href=3D"mailto:digitalmars-d puremagi= c.com">digitalmars-d puremagic.com</a>&gt; wrote:<br> &gt; &gt; &gt;&gt;&gt;&gt;&gt;&gt; On 04/19/14 13:03, Iain Buclaw via Digit= almars-d wrote:<br> &gt; &gt; &gt;&gt;&gt;&gt;&gt;&gt;&gt; On Saturday, 19 April 2014 at 10:49:= 22 UTC, Iain Buclaw wrote:<br> &gt; &gt; &gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; I&#39;m currently testing out a = GCC optimisation that allows you to set call argument flags. =C2=A0The curr= ent assumptions being:<br> &gt; &gt; &gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;<br> &gt; &gt; &gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; in parameters =C2=A0=3D&gt; =C2= =A0Assume no escape, no clobber (read-only).<br> &gt; &gt; &gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; ref parameters, classes and poin= ters =C2=A0=3D&gt; =C2=A0Assume worst case.<br> &gt; &gt; &gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; default =C2=A0=3D&gt; =C2=A0Assu= me no escape.<br> &gt; &gt; &gt;&gt;&gt;&gt;&gt;&gt;&gt;<br> &gt; &gt; &gt;&gt;&gt;&gt;&gt;&gt;&gt; That should read:<br> &gt; &gt; &gt;&gt;&gt;&gt;&gt;&gt;&gt;<br> &gt; &gt; &gt;&gt;&gt;&gt;&gt;&gt;&gt; ref parameters, inout parameters, cl= asses and pointers.<br> &gt; &gt; &gt;&gt;&gt;&gt;&gt;&gt;&gt;<br> &gt; &gt; &gt;&gt;&gt;&gt;&gt;&gt;&gt; The default of assuming no escape is= an experiment - I may limit this to only scalar types, and parameters mark= ed as &#39;scope&#39; =C2=A0(So long as no one plans on deprecating it soon= :)<br> &gt; &gt; &gt;&gt;&gt;&gt;&gt;&gt;<br> &gt; &gt; &gt;&gt;&gt;&gt;&gt;&gt; What does &quot;assume no escape&quot; a= ctually mean?<br> &gt; &gt; &gt;&gt;&gt;&gt;&gt;&gt; [The above list doesn&#39;t really make = sense. W/o context, it&#39;s<br> &gt; &gt; &gt;&gt;&gt;&gt;&gt;&gt; hard to even tell why, hence the questio= n.]<br> &gt; &gt;<br> &gt; &gt; &gt;&gt;&gt;&gt; What I was wondering was things like whether tha= t &quot;assume no escape&quot;<br> &gt; &gt; &gt;&gt;&gt;&gt; property was transitive; if /locally/ escaping w= as disallowed, and<br> &gt; &gt; &gt;&gt;&gt;&gt; to what extent. What does &quot;assume no escape= &quot; mean at all? In your<br> &gt; &gt; &gt;&gt;&gt;&gt; examples you&#39;re mentioning refs together wit= h pointers, that would<br> &gt; &gt; &gt;&gt;&gt;&gt; only make sense if no-escape were transitive -- = but then treating all<br> &gt; &gt; &gt;&gt;&gt;&gt; args as no-escape would be very wrong.<br> &gt; &gt;<br> &gt; &gt; &gt;&gt;&gt;&gt; I&#39;m worried about a) invalid assumptions mak= ing it into GDC;<br> &gt; &gt; &gt;&gt;&gt;&gt; b) certain valid assumptions making into GDC. Th= e latter because<br> &gt; &gt; &gt;&gt;&gt;&gt; it could mean that code that&#39;s incorrect, bu= t still accepted by<br> &gt; &gt; &gt;&gt;&gt;&gt; the other compilers could silently break when co= mpiled with GDC.<br> &gt; &gt; &gt;&gt;&gt;<br> &gt; &gt; &gt;&gt;&gt; Invalid assumptions rarely make it into GDC. =C2=A0T= he testsuite is a good<br> &gt; &gt; &gt;&gt;<br> &gt; &gt; &gt;&gt; AFAICT what you&#39;re proposing *is* invalid. I can&#39= ;t be sure because<br> &gt; &gt; &gt;&gt; it&#39;s not clear what that &quot;no-escape&quot; prope= rty means; that&#39;s why I<br> &gt; &gt; &gt;&gt; asked about it twice already...<br> &gt; &gt; &gt;&gt; Clearly, escaping objects reachable indirectly via funct= ion arguments<br> &gt; &gt; &gt;&gt; is perfectly fine (eg string slicing), yet you wanted to= treat args as<br> &gt; &gt; &gt;&gt; no-escape by default.<br> &gt; &gt; &gt;<br> &gt; &gt; &gt; Not wanted - experimented. =C2=A0I could not think at the ti= me a use case<br> &gt; &gt; &gt; where a parameter could escape. =C2=A0And *I* have shown a v= ery valid use<br> &gt; &gt; &gt; case to *disprove myself*. =C2=A0I&#39;m not sure of your co= ntinual persistence<br> &gt; &gt; &gt; of bringing this up as this is no longer relevant to me. =C2= =A0Other than<br> &gt; &gt;<br> &gt; &gt; Several reasons. First, I did not realize that you had changed yo= ur mind.<br> &gt;<br> &gt; It wouldn&#39;t be an experiment if I didn&#39;t change my mind 30 tim= es. :)<br> &gt;<br> &gt; &gt; Second, I&#39;m just trying to figure out what that &#39;assume-n= o-escape&#39;<br> &gt; &gt; property implies. From a C based compiler I would have expected a= feature<br> &gt; &gt; that disallowed address-of on objects, but did not affect any oth= er<br> &gt; &gt; object referenced from that one (for handling C&#39;s &#39;regist= er&#39; storage class).<br> &gt;<br> &gt; This is an optimisation not built with a C compiler in mind, nor is it= leveraged by C/C++, so I don&#39;t think you should think of it in this wa= y.<br> &gt;<br> &gt; I was actually made aware of this particular attribute when someone sp= oke to a GNU/Fortran maintainer and thought that INTENT(IN) - or at least t= he no clobber aspect - could be used to improve optimisations around &#39;i= mmutable&#39; parameters. Something that gives us the one up that C-family = const could never guarantee (currently there is no difference between const= and immutable).=C2=A0 That is still on the table to do using this attribut= e pending investigation.<br> &gt;<br> &gt; The no escape aspect leverages on what &#39;scope&#39; and &#39;in&#39= ; should be enforcing.<br> &gt;<br> &gt; &gt; Third, I&#39;m paranoid when it comes to GDC regressions. Once up= on the time<br> &gt; &gt; I had a working D compiler, one that was able to deliver maybe ~7= 5% of<br> &gt; &gt; GCC functionality, and where the main issues were with the langua= ge and<br> &gt; &gt; frontend, not with the tool.<br> &gt;<br> &gt; GCC functionality is not to be confused with C/C++ functionality.=C2= =A0 And most of the attributes exposed to C-family languages were nothing m= ore an excess baggage, ie: artificial makes no sense when there is no inli= ne keyword.<br> &gt;<br> &gt; Anything that needs raising would ideally be in a bug report, as I can= &#39;t keep track of issues raised in threads.<br> &gt;</p> <p dir=3D"ltr">As for the original topic.</p> <p dir=3D"ltr">STCin is an attribute ignored by the compiler (only talking = about gdc) - which is a shame because marking parameters as &#39;in&#39; I = see is still encouraged.=C2=A0 And I would assume the same is true also for= dmd and ldc, otherwise someone would have noticed this bug by now.</p> --001a11347e9c5b5cea04f789c4f5--
Apr 21 2014
prev sibling parent Artur Skawina via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 04/20/14 22:11, Iain Buclaw via Digitalmars-d wrote:
 The failure of inlining is not a blocker IMO

It is one in practice. A language with a compiler that can not even inline this trivial function: test %rdi,%rdi sete %al retq is not a viable alternative to C. Not everything can or should be an enum, and D doesn't have macros -- there is no workaround. [That's "array.empty". More context, for people not reading the GDC list: http://forum.dlang.org/thread/mailman.75.1396605155.19942.d.gnu puremagic.com ] The bug may be hard to fix, and I really appreciate your effort, but this definitely *is* a major problem.
 relying on 'hidden' features, NRVO being another example, in user code is a
bug.

Not if RVO is mandated by a spec. Yes, I had trouble with this in the past too. :) IIRC an auto-return-type related problem was fixed by Walter some time ago; but I still have to maintain the workaround, even after the bug has been fixed upstream... artur
Apr 21 2014