Compiler analysis of single-use types? Escape analysis of types?

Meta via Digitalmars-d digitalmars-d at puremagic.com
Wed Aug 17 19:45:05 PDT 2016


On Wednesday, 17 August 2016 at 21:25:00 UTC, 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:
>
> void foo(alias dg)() {
>     dg();
> }
>
> struct S(alias dg) {
>     void bar() {
>         dg();
>     }
> }
>
> void main() {
>     int i;
>
>     /* The following call can be marked as @nogc because foo() 
> does
>      * not escape the delegate. (It can indeed appear in @nogc
>      * code today.) */
>     foo!(() => i)();
>
>     /* The following expression does not escape the delegate
>      * either. (Note that object 's' is not escaped.) So, one 
> would
>      * expect the following code be @nogc as well. However, 
> 2.071 does
>      * allocate from the GC. */
>     S!(() => i) s;
>
>     /* Although one would expect that last line above to be 
> @nogc as
>      * well, I can see one potential issue there that warrants 
> the GC
>      * use: Although no reference to the local 'i' is escaped, 
> the
>      * *type* of 's' can be obtained perhaps by typeof() to make
>      * another object of the same type, which may be escaped. */
>     typeof(s) s2;
>
>     /* s2 carries another alias to local 'i' through its 
> *type*! */
> }
>
> If the compiler could see that 's' is not escaped *and* it's 
> type is used only once, then the expression with the second 
> lambda could be @nogc as well. Does that make sense? Is there 
> such a thing?
>
> Thank you,
> Ali

If I understand correctly, this is exactly what linear types are 
(i.e., what Rust uses... or maybe that was affine types, which 
are similar). D actually does have fairly primitive support for 
affine types with `@disable this()`, opAssign and `this (this)`.


More information about the Digitalmars-d mailing list