Подтвердить что ты не робот

Какая разница между флагами -O3 и (-O2 +, которые man gcc говорит -O3, добавляет -O2)?

Недавно я получил сообщение об ошибке о программе, которая не скомпилируется с помощью переключателя -O3 (см. https://github.com/cschwan/sage-on-gentoo/issues/66). В частности, проблема заключается в том, что компиляция зависает в определенный момент. Проблема решается путем компиляции с -O2 (мне хорошо известно, что программы, скомпилированные с -O3, могут быть повреждены, но я не знал, что -O3 может повесить компилятор). Если вы хотите воспроизвести запуск проблемы

wget http://perso.ens-lyon.fr/xavier.pujol/fplll/libfplll-3.0.12.tar.gz
tar -xf libfplll-3.0.12.tar.gz
cd libfplll-3.0.12
./configure CXXFLAGS="-O3"
make

Я задавался вопросом, почему -O3 подвешивает компилятор, и поэтому я попытался отследить проблему. Во-первых, я попытался выяснить разницу между -O2 между -O3. На странице Gcc man указано, что -O3 включает переключатели -O2 и следующие (позволяет называть их x):

-finline-functions -funswitch-loops -fpredictive-commoning -fgcse-after-reload
-ftree-vectorize -fipa-cp-clone

Я проверил, что сравнивая вывод gcc при вызове с -Q -O2 --help=optimizers и -Q -O3 --help=optimizers. Затем я решил выборочно удалить коммутаторы, чтобы найти тот, который вызывает проблему. Однако компиляция отлично работает с -O2 и дополнительными переключателями выше, поэтому я заключаю

-O3 != -O2 x

Теперь мой вопрос: Кто-нибудь знает, есть ли другая разница между -O2 и -O3 (недокументированная?), кто-нибудь испытал подобное поведение? Возможно, это ошибка компилятора?

4b9b3361

Ответ 1

Персональные страницы могут устаревать, но вы можете найти фактические списки для O2 и O3.

Чтобы получить полный список (почти, проверьте "обновление" ) опций оптимизации -f, которые я использую, я предлагаю вам использовать -fverbose-asm -save-temps (или -fverbose-asm -S) - есть полный список в верхней части asm файла (*.с).

Для gcc-4.6.0 я получил x (разница между O2 и O3):

 -fgcse-after-reload
 -finline-functions
 -fipa-cp-clone
 -fpredictive-commoning
 -ftree-loop-distribute-patterns
 -ftree-vectorize
 -funswitch-loops

Другим источником информации для вашего вопроса являются источники GCC (файл gcc/opts.c и, возможно, gcc/common.opt) как gcc-4.6.0:

/* -O3 optimizations.  */
{ OPT_LEVELS_3_PLUS, OPT_ftree_loop_distribute_patterns, NULL, 1 },
{ OPT_LEVELS_3_PLUS, OPT_fpredictive_commoning, NULL, 1 },
/* Inlining of functions reducing size is a good idea with -Os
   regardless of them being declared inline.  */
{ OPT_LEVELS_3_PLUS_AND_SIZE, OPT_finline_functions, NULL, 1 },
{ OPT_LEVELS_3_PLUS, OPT_funswitch_loops, NULL, 1 },
{ OPT_LEVELS_3_PLUS, OPT_fgcse_after_reload, NULL, 1 },
{ OPT_LEVELS_3_PLUS, OPT_ftree_vectorize, NULL, 1 },
{ OPT_LEVELS_3_PLUS, OPT_fipa_cp_clone, NULL, 1 },

Я также проверил, делает gcc проверять -On в других файлах (поиск символа cscope для x_optimize).

Единственное дополнительное использование n из опции -On - сохранение значения в макросе __OPTIMIZE__. Поэтому некоторые заголовки могут вести себя по-разному для значения этого макроса равным 2 или 3.

UPDATE: В GCC WIKI есть вопросы об этом:

  • "Is -O1 (-O2, -O3 или -Os) эквивалентно индивидуальным опциям -оптимизации?"

Нет. Во-первых, отдельные параметры оптимизации (-f *) не включают оптимизацию, требуется опция -Os или -Ox с x > 0. Во-вторых, флаги -Ox обеспечивают множество оптимизаций, которые не контролируются ни одной отдельной опцией -f *. Не планируется добавлять отдельные параметры для управления всеми этими оптимизациями.

  • "Какие конкретные флаги включены -O1 (-O2, -O3 или -Os)?"

Зависит от платформы и версии GCC. Вы можете заставить GCC рассказать вам, какие флаги он дает, делая это:

touch empty.c
gcc -O1 -S -fverbose-asm empty.c
cat empty.s

Ответ 2

Если ваш компилятор зависает, тогда да - я бы рассматривал это как ошибку компилятора. У компиляторов тоже есть ошибки.

(даже если компилятор, используемый для компиляции вашего компилятора, имеет ошибки, в новом компиляторе может быть введена ошибка - gcc предпринимает некоторые шаги, чтобы избежать этого путем его начальной загрузки).

Это могут быть и другие вещи, например. для выполнения оптимизации требуется гораздо больше времени, чтобы выполнить, или увеличенный уровень оптимизации заставляет использовать больше памяти, и ваша система начинает сбой.