2012-05-19 36 views
5

我想看看如何某些C/C++的功能被翻譯成彙編和我創建以下文件:爲什麼gcc創建冗餘彙編代碼?

struct foo { 
    int x; 
    char y[0]; 
}; 

char *bar(struct foo *f) 
{ 
    return f->y; 
} 

然後,我gcc -S編譯這一點(也試圖與g++ -S),但是當我看着彙編代碼,我很失望地發現,我認爲gcc應該能夠優化掉酒吧功能的瑣碎冗餘:

_bar: 
Leh_func_begin1: 
     pushq %rbp 
Ltmp0: 
     movq %rsp, %rbp 
Ltmp1: 
     movq %rdi, -8(%rbp) 
     movq -8(%rbp), %rax 
     movabsq $4, %rcx 
     addq %rcx, %rax 
     movq %rax, -24(%rbp) 
     movq -24(%rbp), %rax 
     movq %rax, -16(%rbp) 
     movq -16(%rbp), %rax 
     popq %rbp 
     ret 
Leh_func_end1: 

除其他事項外,該行

 movq %rax, -24(%rbp) 
     movq -24(%rbp), %rax 
     movq %rax, -16(%rbp) 
     movq -16(%rbp), %rax 

顯得毫無意義的多餘。 gcc(可能還有其他編譯器)是否有任何理由不能/不會優化它呢?

+1

請使用-O開關運行gcc以啓用標準優化。 –

+0

您使用的是哪個版本的gcc? –

回答

11

我以爲gcc應該能夠優化掉。

gcc manual

沒有任何的優化選項,編譯器的目標是降低編譯成本,使調試產生預期的效果。

換句話說,它不會優化,除非你問它。當我打開使用-O3標誌優化,GCC 4.4.6產生更有效的代碼:

bar: 
.LFB0: 
     .cfi_startproc 
     leaq 4(%rdi), %rax 
     ret 
     .cfi_endproc 

有關更多細節,參見Options That Control Optimization手動英寸

+0

哦,我認爲默認情況下標準優化將會開啓。他們爲什麼不是? – Matt

+7

@Matt:引用手冊,「沒有任何優化選項,編譯器的目標是降低編譯成本並使調試產生預期結果。」 – NPE

+1

@Matt因爲執行者如此選擇。除非你在這裏得到一個答案,否則這是一個徒勞的問題。 – EJP

8

編譯器不經過優化就生成的代碼通常是直接逐條指令翻譯,並且指令不是程序的指令,而是那些可能已經引入冗餘的中間表示。

如果你希望裝配沒有這樣的冗餘指令,使用gcc -O -S

那種你希望被稱爲peephole optimization優化。編譯器通常具有很多這樣的功能,因爲與更多的全局優化不同,它們便宜並且(通常)不會使代碼變得更糟 - 至少在編譯結束時應用。

this blog post中,我提供了一個例子,其中當源代碼中的整數類型是64位但只有結果的最低32位時,GCC和Clang可能會生成較短的32位指令。