2

Есть ли способ получить информацию во время или после компиляции о том, какие части кода были оптимизированы, но не глядя на сборку или выполнение кода.Как узнать, какой код был оптимизирован?

Было бы хорошо сразу узнать, если большой кусок кода будет оптимизирован.

+0

Почему это было бы хорошо знать? Это работа оптимизатора *, чтобы оптимизировать большие куски кода. Он удаляет сложные абстракции, вспомогательные методы, всевозможные вещи, которые люди пишут, чтобы сделать код более понятным и понятным. Почему вы чувствуете, что вам нужно угадать оптимизатор? У вас есть настоящая проблема? –

+0

@Cody Grey он может выявить ошибки в коде, который я компилирую (или даже в компиляторе), и это удовлетворит мое любопытство :) – user2373145

ответ

1
gcc -S 

выводит код сборки, который был бы передан ассемблеру (и в конечном итоге был связан с исполняемым файлом). Если вы правильно прищурились (и терпеливы), вы можете работать в обратном направлении от этого, чтобы подтвердить, действительно ли данный бит кода был включен в исполняемый файл или был оптимизирован.

Очевидно, что не то, что вы могли бы сделать, если у вас есть подозрение, что что-то происходит, учитывая время и усилия, необходимые ...

+0

Я знаю о -S, но я надеюсь, что есть более простое решение. – user2373145

1

Извините, но ваши ожидания не соответствуют тому, что компиляторы на самом деле. Независимо от того, пытаетесь ли вы найти мертвый код или найти ошибки, которые вызывают запуск кода для пропуска, это не информация, которую компилятор может предоставить в удобной для чтения форме.

С компилятором, который переводит каждую строку исходного кода в последовательность машинных инструкций, компилятор может легко сказать вам, что он не содержит ничего, соответствующего конкретной строке. Конечно, он не мог сказать вам, была ли строка переведена на машинные инструкции, но эти машинные инструкции на самом деле никогда не будут выполняться - достижимость кода - undecidable - но я не думаю, что это то, что вам нужно.

Проблема в том, что современные оптимизирующие компиляторы намного сложнее, чем это. Кусок кода часто копируется и компилируется несколько раз при разных предположениях (специализация, частичная оценка, разворот цикла, ...). Или, наоборот, фрагменты кода могут быть объединены вместе (функция inlining, ...). Между исходным кодом и машинным кодом нет простого соответствия. (Вот почему отладчикам иногда приходится сообщать точное расположение исходного кода двоичной команды.)

Если большой фрагмент кода оптимизирован, это может быть просто потому, что это одна из многих специализированных копий, и эта специальность никогда не бывает (например, есть отдельный код для x==0 и x!=0, а отдельный код для y==0 и y!=0 и x и y никогда не являются 0 вместе, поэтому ветвь x==0 && y==0 в конечном итоге отбрасывается). Это может быть что-то, генерируемое условной командой времени компиляции, например макросом C, который оптимизирует компилятор; это происходит так часто в C-коде, что если компиляторы сообщили обо всех таких случаях, это создало бы множество ложных срабатываний.

Получение полезных отчетов о потенциально неиспользуемом коде или подозрительном программном коде, который может указывать на ошибку, требует довольно иного рода статического анализа, чем то, что делают компиляторы. Есть инструменты, которые могут это сделать, но они, как правило, не являются теми же инструментами, которые преобразуют исходный код в оптимизированный машинный код. Создание инструментов статического анализа, которые одновременно обнаруживают потенциальные проблемы, достаточно часто для того, чтобы быть полезными, и не дают так много ложных срабатываний, что они практически непригодны для использования, непросто.

Смежные вопросы