digitalmars.D.bugs - [Issue 4440] New: inlined delegates produces different asm than straight lined code
- d-bugmail puremagic.com (48/48) Jul 08 2010 http://d.puremagic.com/issues/show_bug.cgi?id=4440
- d-bugmail puremagic.com (85/85) Jul 09 2010 http://d.puremagic.com/issues/show_bug.cgi?id=4440
- d-bugmail puremagic.com (37/37) Jul 11 2010 http://d.puremagic.com/issues/show_bug.cgi?id=4440
- d-bugmail puremagic.com (16/16) Jul 11 2010 http://d.puremagic.com/issues/show_bug.cgi?id=4440
- d-bugmail puremagic.com (14/47) Jul 11 2010 http://d.puremagic.com/issues/show_bug.cgi?id=4440
- d-bugmail puremagic.com (8/8) Jul 11 2010 http://d.puremagic.com/issues/show_bug.cgi?id=4440
- d-bugmail puremagic.com (7/10) Jul 11 2010 http://d.puremagic.com/issues/show_bug.cgi?id=4440
- d-bugmail puremagic.com (21/21) Jul 11 2010 http://d.puremagic.com/issues/show_bug.cgi?id=4440
- d-bugmail puremagic.com (14/14) Aug 29 2010 http://d.puremagic.com/issues/show_bug.cgi?id=4440
- d-bugmail puremagic.com (34/34) Aug 29 2010 http://d.puremagic.com/issues/show_bug.cgi?id=4440
- d-bugmail puremagic.com (12/12) Aug 29 2010 http://d.puremagic.com/issues/show_bug.cgi?id=4440
http://d.puremagic.com/issues/show_bug.cgi?id=4440
Summary: inlined delegates produces different asm than straight
lined code
Product: D
Version: D1 & D2
Platform: Other
OS/Version: All
Status: NEW
Severity: normal
Priority: P2
Component: DMD
AssignedTo: nobody puremagic.com
ReportedBy: braddr puremagic.com
---
split from bug 859:
Leandro Lucarella 2010-06-27 18:49:49 PDT
I'm having some performance problems moving some stuff from a lower-level
C-style to a higher-lever D-style. Here is an example:
---
int find_if(bool delegate(ref int) predicate)
{
for (int i = 0; i < 100; i++)
if (predicate(i))
return i;
return -1;
}
int main()
{
// for (int i = 0; i < 100; i++)
// if (i == 99)
// return i;
// return -1;
return find_if((ref int i) { return i == 99; });
}
---
The program produced by this source executes 4 times more instructions than the
more direct (lower-level) version commented out. I would expect DMD to inline
all functions/delegates and produce the same asm for both, but that's not the
case.
This is a reduced test-case, but I'm working on improving the GC and I'm really
hitting this problem. If I use this higher-level style in the GC, a Dil run for
generating the Tango docs is 3.33 times slower than the C-ish style used by the
current GC.
So I think this is a real problem for D, it's really important to be able to
encourage people to use the higher-level D constructs.
--
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jul 08 2010
http://d.puremagic.com/issues/show_bug.cgi?id=4440
Leandro Lucarella <llucax gmail.com> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |llucax gmail.com
PDT ---
I'm not very keen at reading asm, but I'm seeing a couple of 'call's in the
generated code:
---
$ dmd -release -O -gc -inline -c test.d
$ objdump -d test.o
test.o: file format elf32-i386
Disassembly of section .text:
00000000 <.text>:
0: c3 ret
1: 60 pusha
2: b8 38 00 00 00 mov $0x38,%eax
7: b9 00 00 00 00 mov $0x0,%ecx
c: 8b 11 mov (%ecx),%edx
e: 89 10 mov %edx,(%eax)
10: 89 01 mov %eax,(%ecx)
12: 61 popa
13: c3 ret
Disassembly of section .text._D4test7find_ifFDFKiZbZi:
00000000 <_D4test7find_ifFDFKiZbZi>:
0: 55 push %ebp
1: 8b ec mov %esp,%ebp
3: 83 ec 0c sub $0xc,%esp
6: 53 push %ebx
7: 8b 55 0c mov 0xc(%ebp),%edx
a: 8b 45 08 mov 0x8(%ebp),%eax
d: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp)
14: 89 d3 mov %edx,%ebx
16: 8d 4d fc lea -0x4(%ebp),%ecx
19: 8b 45 08 mov 0x8(%ebp),%eax
1c: 51 push %ecx
1d: ff d3 call *%ebx
1f: 84 c0 test %al,%al
21: 74 0a je 2d <_D4test7find_ifFDFKiZbZi+0x2d>
23: 8b 45 fc mov -0x4(%ebp),%eax
26: 5b pop %ebx
27: 8b e5 mov %ebp,%esp
29: 5d pop %ebp
2a: c2 08 00 ret $0x8
2d: ff 45 fc incl -0x4(%ebp)
30: 83 7d fc 64 cmpl $0x64,-0x4(%ebp)
34: 7c e0 jl 16 <_D4test7find_ifFDFKiZbZi+0x16>
36: 5b pop %ebx
37: 8b e5 mov %ebp,%esp
39: b8 ff ff ff ff mov $0xffffffff,%eax
3e: 5d pop %ebp
3f: c2 08 00 ret $0x8
42: 90 nop
43: 90 nop
Disassembly of section .text._Dmain:
00000000 <_Dmain>:
0: 55 push %ebp
1: 8b ec mov %esp,%ebp
3: b9 00 00 00 00 mov $0x0,%ecx
8: 51 push %ecx
9: 31 c0 xor %eax,%eax
b: 50 push %eax
c: e8 fc ff ff ff call d <_Dmain+0xd>
11: 5d pop %ebp
12: c3 ret
13: 90 nop
Disassembly of section .text._D4test4mainFZi12__dgliteral1MFKiZb:
00000000 <_D4test4mainFZi12__dgliteral1MFKiZb>:
0: 55 push %ebp
1: 8b ec mov %esp,%ebp
3: 50 push %eax
4: 8b 4d 08 mov 0x8(%ebp),%ecx
7: b8 01 00 00 00 mov $0x1,%eax
c: 83 39 63 cmpl $0x63,(%ecx)
f: 74 02 je 13
<_D4test4mainFZi12__dgliteral1MFKiZb+0x13>
11: 31 c0 xor %eax,%eax
13: 8b e5 mov %ebp,%esp
15: 5d pop %ebp
16: c2 04 00 ret $0x4
---
Am I understanding it all wrong?
--
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jul 09 2010
http://d.puremagic.com/issues/show_bug.cgi?id=4440
Brad Roberts <braddr puremagic.com> changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|NEW |ASSIGNED
AssignedTo|nobody puremagic.com |braddr puremagic.com
---
Reducing the test case further:
extern(C) int printf(const char*, ...);
bool if_delegate(int i, bool delegate(ref int) predicate)
{
return predicate(i);
}
bool if_nodelegate(int i)
{
return i == 99;
}
void main()
{
foreach(i; 1 .. 100)
if (if_delegate(i, (ref int j) { return j == 99; }))
printf("i = %d\n", i);
foreach(i; 1 .. 100)
if (if_nodelegate(i))
printf("i = %d\n", i);
}
In the previous version of the code, the use of the for loops makes the cost of
the functions too high for the inliner to bother inlining find_if into main.
Also,in the non-inlined version of the function, there's no way for it to
inline the delegate since it's a variable, not a constant thing.
This changed version reduces the problem to: will it inline the delegate? The
answer is still no, but allows that specific problem to be explored.
Leandro, does this stray too far away from the underlying code that led you to
file this bug?
--
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jul 11 2010
http://d.puremagic.com/issues/show_bug.cgi?id=4440
---
Ok.. still doesn't inline the delegate in this version:
extern(C) int printf(const char*, ...);
void main()
{
auto d = (ref int j) { return j == 99; };
foreach(i; 1 .. 100)
if (d(i))
printf("i = %d\n", i);
}
There's nothing in the dmd frontend inliner that even tries to deal with this
sort of inlining right now.
--
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jul 11 2010
http://d.puremagic.com/issues/show_bug.cgi?id=4440
PDT ---
Reducing the test case further:
extern(C) int printf(const char*, ...);
bool if_delegate(int i, bool delegate(ref int) predicate)
{
return predicate(i);
}
bool if_nodelegate(int i)
{
return i == 99;
}
void main()
{
foreach(i; 1 .. 100)
if (if_delegate(i, (ref int j) { return j == 99; }))
printf("i = %d\n", i);
foreach(i; 1 .. 100)
if (if_nodelegate(i))
printf("i = %d\n", i);
}
In the previous version of the code, the use of the for loops makes the cost of
the functions too high for the inliner to bother inlining find_if into main.
Also,in the non-inlined version of the function, there's no way for it to
inline the delegate since it's a variable, not a constant thing.
This changed version reduces the problem to: will it inline the delegate? The
answer is still no, but allows that specific problem to be explored.
Leandro, does this stray too far away from the underlying code that led you to
file this bug?
Yes, the loop is important, because this happens a lot with opApply(), which
almost always includes a loop, and when I use (x having an opApply() method):
foreach (a; x) {
// some code
}
I almost always want // some code to be inlined, since it's not even a function
(from the POV of the programmer), but maybe that should be another bug report,
I really don't know.
--
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jul 11 2010
http://d.puremagic.com/issues/show_bug.cgi?id=4440 --- Ok. I'll keep that in mind. One step at a time for now though; need to get _any_ delegate inlining to happen before worrying about popping up the layers up to an opApply function. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jul 11 2010
http://d.puremagic.com/issues/show_bug.cgi?id=4440 PDT ---Ok. I'll keep that in mind. One step at a time for now though; need to get _any_ delegate inlining to happen before worrying about popping up the layers up to an opApply function.Agreed, thanks for giving it some time to this :) -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jul 11 2010
http://d.puremagic.com/issues/show_bug.cgi?id=4440
---
Created an attachment (id=690)
add support for inlining function literals
This patch adds support for inlining function literals. This won't cover many
cases as most hide behind a variable, but it's a building block in the right
direction:
The test case for this patch.. very contrived:
extern(C) int printf(const char*, ...);
void main()
{
int i = 99;
if ((delegate(ref int j) { return j == 99; })(i))
printf("i = %d\n", i);
}
same result if the keyword 'delegate' is omitted.
It passes an abbreviated (only used ARGS="-O -inline -release") run of the test
suite.
--
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jul 11 2010
http://d.puremagic.com/issues/show_bug.cgi?id=4440
David Simcha <dsimcha yahoo.com> changed:
What |Removed |Added
----------------------------------------------------------------------------
Blocks| |4264
Summary|[patch] inlined delegates |[patch] Inlining delegate
|produces different asm than |literals
|straight lined code |
Blocks 4264 because I need delegate literal inlining to get decent performance
out of opApply-based map, filter, etc.
--
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Aug 29 2010
http://d.puremagic.com/issues/show_bug.cgi?id=4440
I just tried this patch out and on second thought I'm not sure it's worth
integrating as-is because it's so limited. It won't even handle the case where
a function that calls a delegate gets inlined and the delegate passed from the
call site is a literal. Even the following doesn't get inlined:
bool evaluateDelegate(bool delegate() dg) {
return dg();
}
void main() {
evaluateDelegate({return false;});
}
Here's the disassembly of main():
__Dmain PROC NEAR
; COMDEF __Dmain
sub esp, 24 ; 0000 _ 83. EC, 18
xor eax, eax ; 0003 _ 31. C0
mov ecx, offset _D5test94mainFZv12__dgliteral1MFZb; 0005 _ B9,
00000000(segrel)
push ebx ; 000A _ 53
mov edx, ecx ; 000B _ 8B. D1
mov dword ptr [esp+4H], eax ; 000D _ 89. 44 24, 04
mov eax, dword ptr [esp+4H] ; 0011 _ 8B. 44 24, 04
mov ebx, dword ptr [esp+4H] ; 0015 _ 8B. 5C 24, 04
mov dword ptr [esp+8H], ecx ; 0019 _ 89. 4C 24, 08
call edx ; 001D _ FF. D2
xor eax, eax ; 001F _ 31. C0
pop ebx ; 0021 _ 5B
add esp, 24 ; 0022 _ 83. C4, 18
ret ; 0025 _ C3
__Dmain ENDP
--
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Aug 29 2010
http://d.puremagic.com/issues/show_bug.cgi?id=4440 PDT --- Agreed. Getting delegate inlining in dmd is going to take serious work. The problem is that the inliner is no where near a const propagation pass. It needs to know that the variables in play have a single, unchangeable, value. At the point of inlining, there's just a variable with an unknown -- to the compiler -- value. So, while this change does help that one narrow use case, it's of almost no practical value. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Aug 29 2010









d-bugmail puremagic.com 