Last Postblit Optimization and r-value ref

IgorStepanov via Digitalmars-d digitalmars-d at puremagic.com
Sun Sep 21 08:59:10 PDT 2014


I've created issue about last postblit call optimization (LPO):
https://issues.dlang.org/show_bug.cgi?id=13492
As I wrote in issue description, this optimization can solve 90% 
r-value reference issue.
Let's talk about remaining 10%.
There are remain two issue:
1. value argument causes full copying it to stack (can be 
important for a large structs and static arrays)
2. When r-value passed to auto-ref function (or simply: to any 
function by value) then this value becomes a l-value and can be 
passed to the next call as l-value ref:
void first(Foo f)
{
    second(f);
}

void second(Foo f)
{
   writeln("by value");
   globalFoo = f; //perform LPO
}

void second(ref Foo f)
{
   writeln("by ref");
   globalFoo = f; //can't perform LPO
}

first(Foo(42)); //passed to first by value, to second by ref and 
prints "by ref"

I suggest a small ABI change which can solve this issues without 
major language changes.

1. Let's pass all structs and static arrays by ref (Keeping a 
value semantic).
2. Let's forward value args (include passed by auto ref) to a 
value args of a next call

See, how it will works with this changes and LPO:

void second(ref Foo); [1]
void second(Foo);     [2]

void first(Foo f)
{
    second(f);
    second(f);
}

Translates to:

void first(Foo f)
{
    Foo __tmp1 = f; //postblit is called
    second(&__tmp1); //[2] is called, f passed by ref

    second(f); //[2] is called, f passed by ref, postblit isn't 
called because LPO
}

If second() writes f to any storage (e. g. struct field), f will 
be saved to this storage without postblit and dtor calls and 
struct copying (for the second call of "second()")

This changes allow us simulate r-value refs without major 
language changes.

Destroy!


More information about the Digitalmars-d mailing list