Bug 6767 – Range case statements generate horrific code
Status
RESOLVED
Resolution
WORKSFORME
Severity
major
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
x86
OS
Mac OS X
Creation time
2011-10-04T10:43:00Z
Last change time
2015-08-24T05:01:45Z
Assigned to
nobody
Creator
peter.alexander.au
Comments
Comment #0 by peter.alexander.au — 2011-10-04T10:43:04Z
int foo(int n)
{
switch (n)
{
case 0: .. case 255:
return 0;
default:
return 1;
}
}
Compiled with all optimisation (-O -inline -release) in DMD 2.055, I get the following code generated (it's the same without optimisation, too):
_D4test3fooFiZi:
00001bb4 pushl %ebp
00001bb5 movl %esp,%ebp
00001bb7 pushl %eax
00001bb8 testl %eax,%eax
00001bba je 0x00002571
00001bc0 cmpl $0x01,%eax
00001bc3 je 0x00002571
00001bc9 cmpl $0x02,%eax
00001bcc je 0x00002571
00001bd2 cmpl $0x03,%eax
00001bd5 je 0x00002571
00001bdb cmpl $0x04,%eax
00001bde je 0x00002571
00001be4 cmpl $0x05,%eax
00001be7 je 0x00002571
... for all 256 values ...
0000255a cmpl $0x000000fd,%eax
0000255f je 0x00002571
00002561 cmpl $0x000000fe,%eax
00002566 je 0x00002571
00002568 cmpl $0x000000ff,%eax
0000256d je 0x00002571
0000256f jmp 0x00002577
00002571 movl %ebp,%esp
00002573 xorl %eax,%eax
00002575 popl %ebp
00002576 ret
00002577 movl %ebp,%esp
00002579 movl $0x00000001,%eax
0000257e popl %ebp
0000257f ret
Essentially, it has generated a massive O(n) function for what should be a couple of compares if not better.
Comment #1 by hsteoh — 2015-08-24T05:01:45Z
This seems to have been fixed in git HEAD. Tested on Linux/64-bit, compile with dmd -O. The function compiles to:
------
0000000000000000 <_D4test3fooFiZi>:
0: 55 push %rbp
1: 48 8b ec mov %rsp,%rbp
4: 48 83 ec 10 sub $0x10,%rsp
8: 48 81 ff ff 00 00 00 cmp $0xff,%rdi
f: 77 0e ja 1f <_D4test3fooFiZi+0x1f>
11: ff 24 fd 00 00 00 00 jmpq *0x0(,%rdi,8)
18: 31 c0 xor %eax,%eax
1a: 48 8b e5 mov %rbp,%rsp
1d: 5d pop %rbp
1e: c3 retq
1f: b8 01 00 00 00 mov $0x1,%eax
24: 48 8b e5 mov %rbp,%rsp
27: 5d pop %rbp
28: c3 retq
29: 0f 1f 80 00 00 00 00 nopl 0x0(%rax)
------
Which is probably close to optimal. At least, it no longer produces the O(n) nastiness. :-)