Compiler analysis of single-use types? Escape analysis of types?
Ali Çehreli via Digitalmars-d
digitalmars-d at puremagic.com
Wed Aug 17 23:29:07 PDT 2016
On 08/17/2016 05:59 PM, Dicebot wrote:
> On 08/18/2016 12:25 AM, Ali Çehreli wrote:
>> I'm wondering whether there is such a thing as single-use of a type in
>> compiler technology. I think if the compiler could determine that a type
>> is used only once, it could apply optimizations.
>>
>> A colleague of mine raised the issue of D's use of the GC even for
>> seemingly local delegates. For example, even though everything remains
>> local for the following lambda, countAbove() cannot be @nogc:
>>
>> auto countAbove(int[] a, int limit) {
>> return a.filter!(x => x >= limit).count();
>> }
>>
>> The reason is due to the fact that filter() returns a struct object that
>> takes the delegate as an alias template parameter. Here is a reduction
>> of the issue with my understanding in comments:
>
> I believe actual reason is that aliased lambda has to allocate a closure
> because it refers to stack local variable (limit).
Right.
> This compiles just fine:
>
> auto countAbove(int[] a, int limit) @nogc {
> return a.filter!(x => x >= 1).count();
> }
However, as my test code demonstrates, even when the lambda refers to
stack local variable, closure is NOT allocated in the case of the
function call. As far as I can tell, the actual reason for the
allocation is the struct object that filter() returns.
I am trying to understand why the struct object requires the closure
allocation. I made myself believe that this is the reason: Being an
alias template parameter, the lambda is a part of the type (the
instantiation of the struct template). Even though the compiler could
determine that the single object does not escape, its type can be used
again.
I'm wondering whether that's the reason. If so, the compiler could prove
that the type is used only once and not allocate the closure.
Note that although they look the same to us, S!(() => i) and S!(() => i)
are different types to the compiler because the two lambdas are
different anonymous objects, effectively making the struct template
instances different.
Ali
More information about the Digitalmars-d
mailing list