отключить все очевидные исключения при компиляции с помощью gcc (без изменения исходного кода!)
Я хочу сохранить весь мертвый код (или все, что очевидно может быть оптимизировано) при компиляции с помощью gcc, но даже с
-O0
, часть мертвого кода все еще оптимизирована. Как я могу сохранить весь код, не меняя исходный код ? Пример кода выглядит следующим образом, и при компиляции с
g++ -S -O0 main.cc
, то
if-statement
будет оптимизирован в ассемблерном коде (не будет
cmpl
а также
jmp
код).
int main() {
constexpr int a = 123; // or const int a = 0; I do not want to remove `const` or `constexpr` qualifier.
if (a) // or just if (123)
return 1;
return 0;
}
Связанный вопрос здесь: Отключить исключение "if (0)" в gcc . Но ответы там требуют, чтобы вы изменили исходный код (удалите квалификатор const / constexpr), чего я не хочу делать.
Может быть, я не изменяю свой исходный код, а использую только некоторые флаги компилятора для этого?
1 ответ
В этом случае в GCC невозможно сохранить условие, поскольку оно удаляется на очень ранней стадии компиляции.
Прежде всего, вот шаги компиляции GCC:
- Синтаксический анализ кода (синтаксис и семантика), создающий AST в GENERIC представлении (HL-IR)
- Генерация GIMPLE высокого уровня (ML-IR)
- Генерация GIMPLE низкого уровня (ML-IR)
- Оптимизация дерева SSA (ML-IR)
- Генерация RTL (LL-IR)
- Оптимизация кода
- Генерация сборки
Условие уже удалено после генерации (теоретически неоптимизированного) высокоуровневого представления GIMPLE. Таким образом, перед любым шагом оптимизации. В этом можно убедиться, используя флаг GCC.
-fdump-tree-all
и посмотрите на первый сгенерированный код GIMPLE. Вот результат:
;; Function int main() (null)
;; enabled by -tree-original
{
const int a = 123;
<<cleanup_point const int a = 123;>>;
return <retval> = 1;
return <retval> = 0;
}
return <retval> = 0;
Можно заметить, что результирующий код совпадает с обоими и. Фактически,
constexpr
рассматривается как простой
const
переменная в коде HL GIMPLE.
Трудно узнать, когда условие точно удаляется на шаге 1, поскольку GENERIC является внутренним представлением GCC, зависящим от реализации. Он не очень гибкий / настраиваемый. AFAIK, пока еще невозможно сгенерировать представление AST / GENERIC. Вы можете извлечь его самостоятельно с помощью некоторых плагинов GCC, но это довольно сложная задача.