Issue 6767 - Range case statements generate horrific code
Summary: Range case statements generate horrific code
Status: RESOLVED WORKSFORME
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: x86 Mac OS X
: P2 major
Assignee: No Owner
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-10-04 10:43 UTC by Peter Alexander
Modified: 2015-08-24 05:01 UTC (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Peter Alexander 2011-10-04 10:43:04 UTC
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 hsteoh 2015-08-24 05:01:45 UTC
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. :-)