D.gnu - Strange inlining behaviour
- John Colvin (129/129) Feb 02 2021 https://d.godbolt.org/z/r8Gj1b
- John Colvin (2/10) Feb 02 2021 see also https://github.com/ldc-developers/ldc/issues/3652
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
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