On Wednesday, 17 September 2014 at 15:03:12 UTC, Andrei
Alexandrescu wrote:
On 9/17/14, 3:03 AM, IgorStepanov wrote:
BTW. About r-values:
void fun(S s)
{
fun2(s); //pass s by value.
}
Now, compiler inserts postblit call before func2 call and dtor
before
end of fun.
Is the call to dtor part of fun(), or part of fun()'s call
sequence? I've always meant to look at that. LMK if you know
for sure.
Dtor call is a part of fun().
I've written test code...
struct Foo
{
this(int i)
{
}
this(this)
{
}
~this()
{
}
}
void calledFunc(Foo probe)
{
}
void main()
{
calledFunc(Foo(42));
}
... add a trace output into Statement_toIR::visit(ExpStatement
*s) ...
printf("ExpStatement::toIR(), exp = %s in %s\n", s->exp ?
s->exp->toChars() : "", irs->symbol ? irs->symbol->toChars() :
"NULL");
... and got:
ExpStatement::toIR(), exp = probe.~this() in calledFunc
However, it is able to doesn't it, because after fun2 call,
s isn't used.
Thus, we can implement last postblit optimization:
If compiler want to insert postblit, and object is't used
after this
postblit, compiler is able to doesn't generate postblit and
last dtor
calls.
Is there limitation of this optimization?
It may 90 percent to solve a r-value ref task.
I think rvalues are already not postblitted into functions.
Indeed more postblits can be optimized away for variables are
are last used in a function call.
Andrei
Yes, rvalues aren't posblitted. However I want and I can't
deliver without postblits rvalue from first call (of constructor
or factory function) through intermediate calls to the final
place of stay.
struct AA(Key, Value)
{
this(T...)(T args)
{
buckets.length = T.length;
foreach (i; Step2Tuple!(T.length))
{
alias key = args[i];
alias value = args[i+1];
size_t key_hash = hashOf(key);
size_t idx = key_hash % T.length;
auto e = new Entry(key_hash, key, value,
impl.buckets[idx]);
buckets[idx] = e;
}
}
...
private static struct Entry
{
size_t hash;
Key key;
Value value;
Entry* next;
}
Entry*[] buckets;
}
AA!(Key, Value) aaLiteral(Key, Value, T...)(auto ref T args)
{
return AA!(Key, Value)(args);
}
....
//somewhere in user code:
auto aa = aaLiteral!(Foo, int)(Foo(1), 1, Foo(2), 2); //postblits
aren't called.
I want to place Foo(1) to buckets[nn].key without postblit call.
Compiler can't help me now, however, I think, It can do it
without language change.