отключить все очевидные исключения при компиляции с помощью 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:

  1. Синтаксический анализ кода (синтаксис и семантика), создающий AST в GENERIC представлении (HL-IR)
  2. Генерация GIMPLE высокого уровня (ML-IR)
  3. Генерация GIMPLE низкого уровня (ML-IR)
  4. Оптимизация дерева SSA (ML-IR)
  5. Генерация RTL (LL-IR)
  6. Оптимизация кода
  7. Генерация сборки

Условие уже удалено после генерации (теоретически неоптимизированного) высокоуровневого представления 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, но это довольно сложная задача.

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