Почему LLVM добавляет две дополнительные инструкции для одной и той же программы? - PullRequest
8 голосов
/ 05 февраля 2011

Я собираю эту программу на C и сравниваю сгенерированный код сборки:

int main(){ return 0; }

GCC дает эту основную функцию (cc hello.c -S):

_main:
LFB2:
    pushq   %rbp
LCFI0:
    movq    %rsp, %rbp
LCFI1:
    movl    $0, %eax
    leave
    ret

LLVM дает эту основную функцию (clang hello.c -S):

_main:
Leh_func_begin0:
    pushq   %rbp
Ltmp0:
    movq    %rsp, %rbp
Ltmp1:
    movl    $0, %eax
    movl    $0, -4(%rbp)
    popq    %rbp
    ret
Leh_func_end0:

Для чего нужны movl $0, -4(%rbp) и popq %rbp?Перемещать что-либо в стеке и высовывать его сразу после этого мне кажется бесполезным.

Ответы [ 3 ]

9 голосов
/ 05 февраля 2011

На самом деле они сопоставимы. Leave - инструкция высокого уровня:

Из руководства Intel:

16-bit: C9 LEAVE A Valid Valid Set SP to BP, then pop BP.
32-bit: C9 LEAVE A N.E. Valid Set ESP to EBP, then pop EBP.
64-bit: C9 LEAVE A Valid N.E. Set RSP to RBP, then pop RBP.

в основном, отпуск эквивалентен

movq %rbp, %rsp
popq %rbp
9 голосов
/ 05 февраля 2011

Инструкция movl $0, -4(%rbp) мертва, потому что это неоптимизированный код. Попробуйте передать -O обоим компиляторам, чтобы посмотреть, что изменится.

2 голосов
/ 05 февраля 2011

Похоже, что LLVM использует традиционную функцию пролог / эпилог, тогда как GCC использует тот факт, что точке входа не нужно очищать

...