2012-05-19 10 views
5

Chciałem spojrzeć w jaki sposób niektóre C/C++ funkcje zostały przetłumaczone na montaż i stworzyłem następujący plik:Dlaczego gcc tworzy redundantny kod zespołu?

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

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

I potem skompilował z gcc -S (a także próbował z g++ -S), ale kiedy spojrzał na Kod montaż, byłem rozczarowany aby znaleźć trywialny funkcji redundancji w barze, że myślałem gcc powinien być w stanie zoptymalizować dala:

_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: 

między innymi linie

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

wydają się niepotrzebnie zbędne. Czy istnieje jakikolwiek powód, dla którego gcc (i prawdopodobnie inne kompilatory) nie może/nie optymalizuje tego?

+1

Uruchom gcc za pomocą przełącznika -O, aby włączyć standardowe optymalizacje. –

+0

której wersji gcc używasz? –

Odpowiedz

11

Myślałem, że gcc powinien być w stanie zoptymalizować.

Z gcc manual:

Bez opcji optymalizacji kompilatora celem jest zmniejszenie kosztów opracowywania i do debugowania przynieść oczekiwanych rezultatów.

Innymi słowy, nie optymalizuje, chyba że o to poprosisz. Po włączeniu optymalizacji z wykorzystaniem flagi -O3, gcc 4.4.6 produkuje dużo bardziej wydajny kod:

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

uzyskać więcej informacji, zobacz Options That Control Optimization w instrukcji.

+0

Och, założyłem, że standardowe optymalizacje będą domyślnie włączone. Dlaczego oni nie są? – Matt

+7

@Matt: Aby zacytować instrukcję, "Bez opcji optymalizacji celem kompilatora jest zmniejszenie kosztów kompilacji i sprawienie, by debugowanie przyniosło oczekiwane rezultaty." – NPE

+1

@Matt A ponieważ tak wybrali realizatorzy. Jeśli nie uzyskasz odpowiedzi od jednego z nich, jest to daremne pytanie. – EJP

8

Kod generowany przez kompilator bez optymalizacji jest zwykle prostym tłumaczeniem na podstawie instrukcji, a instrukcje nie są instrukcjami programu, ale instrukcjami pośredniej reprezentacji, w której można wprowadzić nadmiarowość.

Jeśli montaż oczekiwać bez zbędnych takich instrukcji, należy gcc -O -S

rodzaju optymalizacji pan spodziewa się nazywa peephole optimization. Kompilatory zazwyczaj mają ich wiele, ponieważ w przeciwieństwie do bardziej globalnych optymalizacji, są tanie w zastosowaniu i (ogólnie) nie ryzykują pogorszenia kodu - jeśli zastosowane pod koniec kompilacji, przynajmniej.

W this blog post, podam przykład, w którym zarówno GCC, jak i Clang mogą posunąć się aż do generowania krótszych instrukcji 32-bitowych, gdy typ całkowity w kodzie źródłowym jest 64-bitowy, ale tylko najniższy 32-bitowy wynik ma znaczenie .

Powiązane problemy