Re: Missed optimisation case - internal use of STCin

2014-04-21 Thread Iain Buclaw via Digitalmars-d
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
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.

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
class).

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


Re: Missed optimisation case - internal use of STCin

2014-04-21 Thread Iain Buclaw via Digitalmars-d
On 21 Apr 2014 09:56, Iain Buclaw ibuc...@gdcproject.org wrote:

 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 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.

 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
class).

 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.


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.


Re: Missed optimisation case - internal use of STCin

2014-04-21 Thread Artur Skawina via Digitalmars-d
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@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


Re: Missed optimisation case - internal use of STCin

2014-04-20 Thread 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 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 

Re: Missed optimisation case - internal use of STCin

2014-04-20 Thread Iain Buclaw via Digitalmars-d
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
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).

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 

Missed optimisation case - internal use of STCin

2014-04-19 Thread Iain Buclaw via Digitalmars-d

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.


Re: Missed optimisation case - internal use of STCin

2014-04-19 Thread Iain Buclaw via Digitalmars-d

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 :)


Re: Missed optimisation case - internal use of STCin

2014-04-19 Thread Artur Skawina via Digitalmars-d
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


Re: Missed optimisation case - internal use of STCin

2014-04-19 Thread Iain Buclaw via Digitalmars-d
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)


Re: Missed optimisation case - internal use of STCin

2014-04-19 Thread Iain Buclaw via Digitalmars-d
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?


Re: Missed optimisation case - internal use of STCin

2014-04-19 Thread Artur Skawina via Digitalmars-d
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


Re: Missed optimisation case - internal use of STCin

2014-04-19 Thread Iain Buclaw via Digitalmars-d
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);


Re: Missed optimisation case - internal use of STCin

2014-04-19 Thread Dicebot via Digitalmars-d
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.


Re: Missed optimisation case - internal use of STCin

2014-04-19 Thread Iain Buclaw via Digitalmars-d
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.


Re: Missed optimisation case - internal use of STCin

2014-04-19 Thread Dicebot via Digitalmars-d
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.


Re: Missed optimisation case - internal use of STCin

2014-04-19 Thread Artur Skawina via Digitalmars-d
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 

Re: Missed optimisation case - internal use of STCin

2014-04-19 Thread Iain Buclaw via Digitalmars-d
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