Достаточно ли безумный уровень оптимизации gcc (-O3)?

Как часть ответа на другой вопрос, я хотел показать, что безумный уровень оптимизации gcc (-O3) в основном удалит все переменные, которые не использовались в main. Код был:

#include <stdio.h>
int main (void) {
   char bing[71];
   int x = 7;
   bing[0] = 11;
   return 0;
}

и gcc -O3 вывод был:

    .file "qq.c"
    .text
    .p2align 4,,15
.globl main
    .type main, @function
main:
    pushl %ebp
    xorl %eax, %eax
    movl %esp, %ebp
    popl %ebp
    ret
    .size main, .-main
    .ident "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3"
    .section .note.GNU-stack,"",@progbits

Теперь я вижу, что он удалил локальные переменные, но там все еще есть немало потерь. Мне кажется, что весь

    pushl %ebp
    xorl %eax, %eax
    movl %esp, %ebp
    popl %ebp
    ret

раздел можно заменить на более простой:

    xorl %eax, %eax
    ret

Кто-нибудь знает, почему gcc не выполняет эту оптимизацию? Я знаю, что сэкономит очень мало для main Само по себе, но, если бы это было сделано и с обычными функциями, эффект ненужной настройки указателя стека в массивном цикле был бы значительным.

Команда, использованная для генерации сборки:

gcc -O3 -std=c99 -S qq.c

2 ответа

Решение

Вы можете включить эту конкретную оптимизацию с помощью -fomit-frame-pointer флаг компилятора. Это делает невозможной отладку на некоторых машинах и существенно более трудной для всего остального, поэтому обычно она отключена.

Хотя ваша документация GCC может сказать, что -fomit-frame-pointer включен на разных уровнях оптимизации, вы, вероятно, обнаружите, что это не так - вам почти наверняка придется явно включить его самостоятельно.

Включение -fomit-frame-pointer ( источник) должен избавиться от лишних манипуляций со стеком.

GCC, очевидно, оставил их, потому что они облегчают отладку (получая трассировку стека при необходимости), хотя в документах отмечается, что -fomit-frame-pointer по умолчанию, начиная с GCC 4.6.

Другие вопросы по тегам