Thread overview
Optimization of proposed lambda expression for upcoming DIP
Nov 10, 2017
David Nadlinger
Nov 11, 2017
Johannes Pfau
November 10, 2017
I'm currently testing the optimization for the proposed lowering in this upcoming DIP: https://github.com/dlang/DIPs/pull/97

Tested at https://explore.dgnu.org/ (love this tool, by the way) 64-bit (PC) gdc 7 with -O3 -frelease

/********** Lowering expression to lambda *************/
import core.bitop;

struct S
{
    uint field;

    uint prop() @property
    {
        return field;
    }

    uint prop(uint value) @property
    {
        return field = value;
    }
}

void main()
{
    S s;
    ((auto ref _e1) => _e1.prop(_e1.prop() + 1))(s);

    // prevent compiler from optimizing the whole thing away
    volatileStore(cast(uint*)32, s.field);
}

// OUTPUT
main:
        movq    _Dmain@GOTPCREL(%rip), %rdx
        jmp     _d_run_main@PLT
        movl    (%rdi), %eax
        ret
        movl    %esi, %eax
        movl    %esi, (%rdi)
        ret
_Dmain:
        movl    $1, 32
        xorl    %eax, %eax
        ret
uint example.main().__lambda1!(example.S).__lambda1(ref example.S):
        movl    (%rdi), %eax
        addl    $1, %eax
        movl    %eax, (%rdi)
        ret

/****** Functionally equivalent code without lowering ***********/
import core.bitop;

struct S
{
    uint field;
}

void main()
{
    S s;
    s.field += 1;

    // prevent compiler from optimizing the whole thing away
    volatileStore(cast(uint*)32, s.field);
}

// OUTPUT
main:
        movq    _Dmain@GOTPCREL(%rip), %rdx
        jmp     _d_run_main@PLT
_Dmain:
        movl    $1, 32
        xorl    %eax, %eax
        ret

-- Analysis --
`_Dmain` is equivalent, as I expected, but what's going on with `main`?  Anything to be concerned about?

Mike
November 10, 2017
On Friday, 10 November 2017 at 02:26:46 UTC, Michael V. Franklin wrote:
> `_Dmain` is equivalent, as I expected, but what's going on with `main`?  Anything to be concerned about?

I think these are just the getter and setter implementation bodies. (Note that main ends with an unconditional jmp to _d_run_main.) No idea why the symbol labels aren't shown.

 — David
November 11, 2017
Am Fri, 10 Nov 2017 02:33:41 +0000
schrieb David Nadlinger <code@klickverbot.at>:

> On Friday, 10 November 2017 at 02:26:46 UTC, Michael V. Franklin wrote:
> > `_Dmain` is equivalent, as I expected, but what's going on with `main`?  Anything to be concerned about?
> 
> I think these are just the getter and setter implementation bodies. (Note that main ends with an unconditional jmp to _d_run_main.) No idea why the symbol labels aren't shown.

This is indeed just a bug in the compiler explorer. Disable the 'Remove all lines which are only comments' option and you'll get this:

main:
        mov     rdx, QWORD PTR _Dmain@GOTPCREL[rip]
        jmp     _d_run_main@PLT
@property uint example.S.prop():
        mov     eax, DWORD PTR [rdi]
        ret
@property uint example.S.prop(uint):
        mov     eax, esi
        mov     DWORD PTR [rdi], esi
        ret
_Dmain:
...

One thing we could improve though is to not emit the lambda as a separate function, as it can never be called anyway (the only possible call is inlined).

-- Johannes