2013-07-13 56 views
2

我有代碼工作與列表。我使用tail calls。不幸的是,GCC沒有優化通話。爲什麼海灣合作委員會沒有優化這個尾巴呼叫?

這裏是一個遞歸計算鏈表的長度的函數的C代碼:

size_t ll_length(const ll_t* list) { 
    return ll_length_rec(list, 0); 
} 

size_t ll_length_rec(const ll_t* list, size_t size_so_far) 
{ 
    if (list) { 
     return ll_length_rec(list->next, size_so_far + 1); 
    } else { 
     return size_so_far; 
    } 
} 

這裏是彙編代碼:

.globl _ll_length_rec 
_ll_length_rec: 
LFB8: 
    .loc 1 47 0 
    pushq %rbp 
LCFI6: 
    movq %rsp, %rbp 
LCFI7: 
    subq $32, %rsp 
LCFI8: 
    movq %rdi, -8(%rbp) 
    movq %rsi, -16(%rbp) 
    .loc 1 48 0 
    cmpq $0, -8(%rbp) 
    je L8 
    .loc 1 49 0 
    movq -16(%rbp), %rsi 
    incq %rsi 
    movq -8(%rbp), %rax 
    movq 8(%rax), %rdi 
    call _ll_length_rec # < THIS SHOUD BE OPTIMIZED 
    movq %rax, -24(%rbp) 
    jmp L10 

如果GCC將優化它,就不會有沒有call在asm中。

gcc -S -fnested-functions -foptimize-sibling-calls \ 
    -03 -g -Wall -o llist llist.c 

和GCC的版本是::

i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5666) (dot 3) 

回答

9

如果我將-O3添加到編輯行中,它似乎不會生成違規呼叫,而如果沒有它,我會得到未優化的呼叫。我不知道在我的腦海所有海灣合作委員會的選擇,但對於-03-O3故意筆誤?

Ltmp2: 
     pushq %rbp 
Ltmp0: 
     movq %rsp, %rbp 
Ltmp1: 
     jmp  LBB1_1 
     .align 4, 0x90 
LBB1_3: 
     addq $2, %rsi 
Ltmp3: 
     movq (%rax), %rdi 
Ltmp4: 
LBB1_1: 
Ltmp5: 
     testq %rdi, %rdi 
     je  LBB1_5 
Ltmp6: 
     movq (%rdi), %rax 
     testq %rax, %rax 
     jne  LBB1_3 
     incq %rsi 
LBB1_5: 
     movq %rsi, %rax 
Ltmp7: 
Ltmp8: 
     popq %rbp 
     ret 
+2

+1的眼睛是雪亮的。 –

+1

** TYPO !!!!!!!!!! ** –

+5

TYP0 !!!!!!!!!!! –

2

最有可能的,因爲無論你的函數聲明爲static,這意味着符號必須是可見的鏈接器的情況下,任何我編譯其他編譯單元在鏈接時需要它們。嘗試使用-fwhole-program標誌進行編譯,看看會發生什麼。

+0

或者宣佈'static',如果任何這些從另一個編譯單元需要,添加一個非靜態包裝。 – rodrigo

+0

用'-fwhole-program'並與'static'並在這兩種情況下嘗試過沒有優化 –

1

可能取決於GCC和特定版本的版本。這是我從GCC 3.4.4獲得Windows無法啓動-O2和高達

.globl _ll_length_rec 
    .def _ll_length_rec; .scl 2; .type 32; .endef 
_ll_length_rec: 
    pushl %ebp 
    movl %esp, %ebp 
    movl 8(%ebp), %edx 
    movl 12(%ebp), %eax 
    jmp L3 
    .p2align 4,,7 
L6: 
    movl (%edx), %edx 
    incl %eax 
L3: 
    testl %edx, %edx 
    jne L6 
    popl %ebp 
    ret 
相關問題