Discussion:
Last Postblit Optimization and r-value ref
IgorStepanov via Digitalmars-d
2014-09-21 15:59:10 UTC
Permalink
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!

Loading...