September 21, 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!