Strange inlining behaviour
John Colvin
john.loughran.colvin at gmail.com
Tue Feb 2 20:42:38 UTC 2021
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:
More information about the D.gnu
mailing list