In D there's no "inline" (even if it sometimes useful, see the 
pragma(allow_inline) of LDC, that's useful to force the inlining of functions 
that contain asm) because compilers are today regarded as smart enough to 
inline functions automatically when they see it's an advantage (sometimes they 
are wrong, it's an heuristics).

But D contains "scope" to suggest the compiler to stack allocate a class 
instance. Recently LDC is (sometimes) able to find by itself when an object 
behaves well enough to perform its automatic and invisible scoping (in such 
situation LDC adds an invisible stack-allocated variable that's the reference 
to the stack-allocated object, such reference is also used if you reassign the 
reference). So eventually D2 may choose to deprecate this usage of "scope" 
leaving such decision fully to the compiler, as in the inline case, reducing 
the work of the programmer a bit. Java compilers too perform such automatic 
stack allocation (and HotSpot is a bit better than LDC still in such regard, 
but I have a simple idea that may put LDC almost on par on this, 
http://www.dsource.org/projects/ldc/ticket/339 ).

About this topic, time ago some people have asked for a way to add "scope" to 
object class members, like this:

class Foo {
    int x;
    this(int xx) { this.x = xx; }
}

class Bar {
    scope Foo f; // ***
    int y;
    this(int xx, int yy) {
        this.f = new Foo(xx);
        this.y = yy;
    }
}

void main() {
    auto b = new Bar(10, 20);
    printf("%d %d\n", b.f.x, b.y);
}


This kind of optimization can be useful, this is shown in an example of small 
raytracing benchmark (I can offer all the code if you need it):

Timings, seconds, best of 3, on a 32 bit Ubuntu-like Linux:
  ray1_scoped_cpp  7.99
  ray1_d           8.51 (LDC Aug 3 2009)
  ray1_cpp         8.66

In "ray1_scoped_cpp" an object that's a class attribute is scoped, in ray1_cpp 
it is not as in the D code (Walter once said that D is slower than C++: it's 
often no longer true if you use LDC and if the code is the "same" (same = after 
compiler optimizations)).


Instead of adding "scope" to Foo f; inside Bar, a different possibility is to 
add LDC (and other future _D1_ compilers) a way to perform such optimization by 
themselves, in a transparent way (such "transparency" is sometimes dangerous, 
also because abstractions sometimes leak, but I assume it may be worth it 
anyway). This is not an easy thing to implement, but I think it can be done. 
The size of the class changes, the position of its fields changes, etc. There 
are some things that have to be special-cased to allow this optimization to 
produce programs that work correctly. An alternative solution that probably 
requires less special-casing is to add an invisible field to the class that has 
such scoped object member, this invisible field is the reference, that can be 
reassigned, etc. (Even with this extra field I think it can result as an 
optimization still, because there's more cache coherence, less total memory 
allocated, LDC is probably able to optimize away some deferences !
 of this class reference, etc).

Bye,
bearophile

Reply via email to