Bug 7963 – dmd doesn't inline std.algorithm.swap on a 'alias this' struct
Status
RESOLVED
Resolution
FIXED
Severity
enhancement
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2012-04-21T16:49:12Z
Last change time
2020-03-21T03:56:34Z
Keywords
performance
Assigned to
No Owner
Creator
bearophile_hugs
Comments
Comment #0 by bearophile_hugs — 2012-04-21T16:49:12Z
I have seen that dmd doesn't inline swap() when it's used on a simple struct that contains a fixed size array with alias this:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
This is a version that uses std.algorithm.swap, inlining of swap doesn't happen:
import std.algorithm: swap;
struct Foo {
int[2] xy;
alias xy this;
}
int main() {
auto f1 = Foo([1, 2]);
auto f2 = Foo([1, 2]);
swap(f1, f2);
return f1[0];
}
__Dmain comdat
L0: sub ESP,014h
mov ECX,1
mov EDX,offset FLAT:_D12TypeInfo_G2i6__initZ
push EBX
push ESI
push ECX
sub ESP,4
push 2
push EDX
call near ptr __d_arrayliteralTX
add ESP,0Ch
mov EBX,EAX
pop ECX
mov [EBX],ECX
mov ECX,2
mov EAX,[EBX]
mov 4[EBX],ECX
mov EDX,4[EBX]
mov 0Ch[ESP],EAX
mov 010h[ESP],EDX
mov EDX,offset FLAT:_D12TypeInfo_G2i6__initZ
push ECX
push EDX
call near ptr __d_arrayliteralTX
mov ESI,EAX
lea ECX,014h[ESP]
mov dword ptr [EAX],1
mov EAX,[ESI]
mov dword ptr 4[ESI],2
mov EDX,4[ESI]
mov 01Ch[ESP],EAX
mov 020h[ESP],EDX
push ECX
lea EAX,020h[ESP]
call near ptr _D3std9algorithm21__T4swapTS5test33FooZ4swapFNaNbNeKS5test33FooKS5test33FooZv
add ESP,8
mov EAX,0Ch[ESP]
pop ESI
pop EBX
add ESP,014h
ret
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
This is a version that uses a shorter (and less correct) swapping function, here inlining happens:
void swap2(T)(ref T lhs, ref T rhs) pure nothrow {
auto tmp = lhs;
lhs = rhs;
rhs = tmp;
}
struct Foo {
int[2] xy;
alias xy this;
}
int main() {
auto f1 = Foo([1, 2]);
auto f2 = Foo([1, 2]);
swap2(f1, f2);
return f1[0];
}
__Dmain comdat
L0: push EAX
mov ECX,offset FLAT:_D12TypeInfo_G2i6__initZ
push EAX
mov EAX,1
push EBX
push ESI
push EDI
push EAX
sub ESP,4
push 2
push ECX
call near ptr __d_arrayliteralTX
add ESP,0Ch
mov EDX,EAX
pop EAX
mov ESI,2
mov EDI,offset FLAT:_D12TypeInfo_G2i6__initZ
push ESI
mov [EDX],EAX
mov 4[EDX],ESI
push EDI
call near ptr __d_arrayliteralTX
mov EBX,EAX
mov dword ptr [EAX],1
mov EAX,[EBX]
mov 4[EBX],ESI
mov EDX,4[EBX]
mov 014h[ESP],EAX
mov 018h[ESP],EDX
add ESP,8
mov EAX,0Ch[ESP]
pop EDI
pop ESI
pop EBX
add ESP,8
ret
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
swap() is a very basic function, it's used all the time in sorts. I have found this performance problem because the missed inlining slows down the sort routine I was using.
Test done with dmd 2.060alpha, with -O -release -inline.
Note: this problem doesn't happen if alias this is not used:
struct Foo2 {
int[2] xy;
}