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.



Reply via email to