我发现this nice tool可以让您比较不同编译器生成的代码。现在,看看这段代码:
001 int testFunction(int* input, int length) {
002 int sum = 0;
003 for (int i = 0; i < length; ++i) {
004 sum += input[i];
005 }
006 return sum;
007 }
这24行是gcc的输出,没有优化标志:
001 testFunction(int*, int):
002 pushq %rbp
003 movq %rsp, %rbp
004 movq %rdi, -24(%rbp)
005 movl %esi, -28(%rbp)
006 movl $0, -8(%rbp)
007 movl $0, -4(%rbp)
008 jmp .L2
009 .L3:
010 movl -4(%rbp), %eax
011 cltq
012 leaq 0(,%rax,4), %rdx
013 movq -24(%rbp), %rax
014 addq %rdx, %rax
015 movl (%rax), %eax
016 addl %eax, -8(%rbp)
017 addl $1, -4(%rbp)
018 .L2:
019 movl -4(%rbp), %eax
020 cmpl -28(%rbp), %eax
021 jl .L3
022 movl -8(%rbp), %eax
023 popq %rbp
024 ret
这些漂亮的14行是gcc的输出-O2
标志:
001 testFunction(int*, int):
002 testl %esi, %esi
003 jle .L4
004 xorl %edx, %edx
005 xorl %eax, %eax
006 .L3:
007 addl (%rdi,%rdx,4), %eax
008 addq $1, %rdx
009 cmpl %edx, %esi
010 jg .L3
011 rep; ret
012 .L4:
013 xorl %eax, %eax
014 ret
这122行是-O3
标志的输出:
001 testFunction(int*, int):
002 testl %esi, %esi
003 jle .L14
004 movq %rdi, %rax
005 movl %esi, %edx
006 andl $15, %eax
007 shrq $2, %rax
008 negq %rax
009 andl $3, %eax
010 cmpl %esi, %eax
011 cmova %esi, %eax
012 cmpl $8, %esi
013 ja .L29
014 .L3:
015 cmpl $1, %edx
016 movl (%rdi), %eax
017 jbe .L17
018 addl 4(%rdi), %eax
019 cmpl $2, %edx
020 jbe .L18
021 addl 8(%rdi), %eax
022 cmpl $3, %edx
023 jbe .L19
024 addl 12(%rdi), %eax
025 cmpl $4, %edx
026 jbe .L20
027 addl 16(%rdi), %eax
028 cmpl $5, %edx
029 jbe .L21
030 addl 20(%rdi), %eax
031 cmpl $6, %edx
032 jbe .L22
033 addl 24(%rdi), %eax
034 cmpl $7, %edx
035 jbe .L23
036 addl 28(%rdi), %eax
037 movl $8, %ecx
038 .L5:
039 cmpl %edx, %esi
040 je .L30
041 .L4:
042 movl %esi, %r11d
043 movl %edx, %r8d
044 subl %edx, %r11d
045 movl %r11d, %r9d
046 shrl $2, %r9d
047 leal 0(,%r9,4), %r10d
048 testl %r10d, %r10d
049 je .L7
050 pxor %xmm0, %xmm0
051 leaq (%rdi,%r8,4), %r8
052 xorl %edx, %edx
053 .L13:
054 addl $1, %edx
055 paddd (%r8), %xmm0
056 addq $16, %r8
057 cmpl %edx, %r9d
058 ja .L13
059 movdqa %xmm0, %xmm2
060 addl %r10d, %ecx
061 psrldq $8, %xmm2
062 paddd %xmm2, %xmm0
063 movdqa %xmm0, %xmm3
064 psrldq $4, %xmm3
065 paddd %xmm3, %xmm0
066 movd %xmm0, -12(%rsp)
067 addl -12(%rsp), %eax
068 cmpl %r10d, %r11d
069 je .L2
070 .L7:
071 movslq %ecx, %rdx
072 addl (%rdi,%rdx,4), %eax
073 leal 1(%rcx), %edx
074 cmpl %edx, %esi
075 jle .L2
076 movslq %edx, %rdx
077 addl $2, %ecx
078 addl (%rdi,%rdx,4), %eax
079 cmpl %ecx, %esi
080 jle .L31
081 movslq %ecx, %rcx
082 addl (%rdi,%rcx,4), %eax
083 ret
084 .L14:
085 xorl %eax, %eax
086 .L2:
087 rep; ret
088 .L30:
089 rep; ret
090 .L29:
091 testl %eax, %eax
092 jne .L32
093 xorl %edx, %edx
094 xorl %ecx, %ecx
095 xorl %eax, %eax
096 jmp .L4
097 .L31:
098 rep; ret
099 .L18:
100 movl $2, %ecx
101 jmp .L5
102 .L23:
103 movl $7, %ecx
104 jmp .L5
105 .L17:
106 movl $1, %ecx
107 jmp .L5
108 .L19:
109 movl $3, %ecx
110 jmp .L5
111 .L20:
112 movl $4, %ecx
113 jmp .L5
114 .L21:
115 movl $5, %ecx
116 jmp .L5
117 .L22:
118 movl $6, %ecx
119 jmp .L5
120 .L32:
121 movl %eax, %edx
122 jmp .L3
Clang也表现得同样如此。
我错过了什么吗?我以为-O3是更高级别的优化?这是优化的吗?