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