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; }
Comment #1 by b2.temp — 2020-02-20T09:23:52Z
It does now: void test() { auto f1 = Foo([1, 2]); auto f2 = Foo([1, 2]); swap(f1, f2); } ;------- SUB 000000000045A858h ------- 000000000045A858h push rbp 000000000045A859h mov rbp, rsp 000000000045A85Ch sub rsp, 28h 000000000045A860h mov qword ptr [rbp-28h], rbx 000000000045A864h mov eax, 00000001h 000000000045A869h mov dword ptr [rbp-18h], eax 000000000045A86Ch mov ecx, 00000002h 000000000045A871h mov dword ptr [rbp-14h], ecx 000000000045A874h lea rsi, qword ptr [rbp-18h] 000000000045A878h mov cl, 08h 000000000045A87Ah lea rdi, qword ptr [rbp-20h] 000000000045A87Eh rep movsb 000000000045A880h mov dword ptr [rbp-08h], eax 000000000045A883h mov dword ptr [rbp-04h], 00000002h 000000000045A88Ah lea rsi, qword ptr [rbp-08h] 000000000045A88Eh mov ecx, 00000008h 000000000045A893h lea rdi, qword ptr [rbp-10h] 000000000045A897h rep movsb 000000000045A899h lea rax, qword ptr [rbp-20h] 000000000045A89Dh lea rdx, qword ptr [rbp-10h] 000000000045A8A1h mov rbx, qword ptr [rax] 000000000045A8A4h mov rcx, qword ptr [rdx] 000000000045A8A7h mov qword ptr [rax], rcx 000000000045A8AAh mov qword ptr [rdx], rbx 000000000045A8ADh mov rbx, qword ptr [rbp-28h] 000000000045A8B1h leave 000000000045A8B2h ret ;-------------------------------------