www.digitalmars.com         C & C++   DMDScript  

D.gnu - Strange inlining behaviour

reply John Colvin <john.loughran.colvin gmail.com> writes:
https://d.godbolt.org/z/r8Gj1b

Very odd results, or at least they seem odd to me. Lambdas being 
treated differently to nested functions, behaviour being 
different depending on whether there is a `pragma(inline, false)` 
function to forward to? Also, different behaviour depending on 
whether the `pragma(inline, false)` is inside or outside the 
function!

I ran in to this in a more significant chunk of code where a 
lambda wasn't being inlined as expected, what's here is a simple 
example case.

pragma(inline, false)
int foo1() {
     alias bar = (int s) => s;
     return bar(3);
}

version (TryThisToo) {} else
int foo5() {
     pragma(inline, false);
     alias bar = (int s) => s;
     return bar(3);
}

int foo2() {
     alias bar = (int s) => s;
     return bar(3);
}

pragma(inline, false)
int foo3() {
     int bar(int s) { return s; }
     return bar(3);
}

int foo4() {
     int bar(int s) { return s; }
     return bar(3);
}

All asm done with gdc 10.2 -O3

If we define TryThisToo we get

pure nothrow  nogc  safe int example.foo3().bar(int).constprop.0:
.LFB18:
.LVL0:
         mov     eax, 3
         ret
.LFE18:
pure nothrow  nogc  safe int example.foo1().__lambda1(int):
.LVL1:
.LFB1:
         mov     eax, edi
         ret
.LFE1:
int example.foo1():
.LFB0:
         mov     edi, 3
         call    pure nothrow  nogc  safe int 
example.foo1().__lambda1(int)
.LVL2:
         ret
.LFE0:
int example.foo2():
.LFB2:
         mov     eax, 3
         ret
.LFE2:
pure nothrow  nogc  safe int example.foo2().__lambda1(int):
.LFB15:
         jmp     pure nothrow  nogc  safe int 
example.foo1().__lambda1(int)
.LFE15:
int example.foo3():
.LFB4:
         call    pure nothrow  nogc  safe int 
example.foo3().bar(int).constprop.0
.LVL3:
         ret
.LFE4:
int example.foo4():
.LFB17:
         mov     eax, 3
         ret
.LFE17:


I we don't define it, we instead get:


pure nothrow  nogc  safe int example.foo3().bar(int).constprop.0:
.LFB24:
.LVL0:
         mov     eax, 3
         ret
.LFE24:
pure nothrow  nogc  safe int example.foo1().__lambda1(int):
.LVL1:
.LFB1:
         mov     eax, edi
         ret
.LFE1:
int example.foo1():
.LFB0:
         mov     edi, 3
         call    pure nothrow  nogc  safe int 
example.foo1().__lambda1(int)
.LVL2:
         ret
.LFE0:
int example.foo5():
.LFB2:
         mov     eax, 3
         ret
.LFE2:
pure nothrow  nogc  safe int example.foo5().__lambda1(int):
.LFB17:
         jmp     pure nothrow  nogc  safe int 
example.foo1().__lambda1(int)
.LFE17:
int example.foo2():
.LFB21:
         jmp     int example.foo5()
.LFE21:
pure nothrow  nogc  safe int example.foo2().__lambda1(int):
.LFB19:
         jmp     pure nothrow  nogc  safe int 
example.foo1().__lambda1(int)
.LFE19:
int example.foo3():
.LFB6:
         call    pure nothrow  nogc  safe int 
example.foo3().bar(int).constprop.0
.LVL3:
         ret
.LFE6:
int example.foo4():
.LFB23:
         jmp     int example.foo5()
.LFE23:
Feb 02 2021
parent John Colvin <john.loughran.colvin gmail.com> writes:
On Tuesday, 2 February 2021 at 20:42:38 UTC, John Colvin wrote:
 https://d.godbolt.org/z/r8Gj1b

 Very odd results, or at least they seem odd to me. Lambdas 
 being treated differently to nested functions, behaviour being 
 different depending on whether there is a `pragma(inline, 
 false)` function to forward to? Also, different behaviour 
 depending on whether the `pragma(inline, false)` is inside or 
 outside the function!

 [...]
see also https://github.com/ldc-developers/ldc/issues/3652
Feb 02 2021