Могут ли GCC быть проинструктированы не устранять мертвый код?
Предположим, что я использую современную версию GCC
для компиляции программы на языке C. Кроме того, учтите, что моя программа содержит устаревшие ветки, но мне очень хотелось бы, чтобы мертвый код в этих устаревших ветвях компилировался и присутствовал в финальной программе. Рассмотрим следующую программу:
int main(int argc, char** argv) {
int a = 0;
goto skip;
a = -1;
skip: ;
return a;
}
Ясно, что если я использую GCC
с настройками оптимизации по умолчанию, второе назначение никогда не попадет в финальную программу, так как компилятор может легко сказать, что он никогда не будет выполнен. Предположим, что я не хочу, чтобы это произошло.
В GCC
существует несколько флагов, которые мешают мертвому коду (в первую очередь -fdce
), и я могу явно отключить их при вызове GCC соответственно:
-fno-dce
-fno-dse
-fno-tree-dce
-fno-tree-dse
Насколько я могу судить, это должно дать указание GCC
не связываться со вторым назначением. Тем не менее, соответствующий код никогда не попадает в мою программу.
Почему GCC
настаивает на удалении мертвого кода, и есть ли способ дать указание GCC не избавиться от второго назначения?
Ответы
Ответ 1
Параметры -fno-*
не работают для меня либо с gcc-4.9.2.
Тем не менее, я думаю, что следующее должно быть переносимым для всех целей gcc (4.5+):
__asm__ goto (""::::no_skip);
goto skip;
no_skip:
a = -1;
skip:;
Из руководства: "оператор asm goto всегда неявно считается изменчивым".
Кроме того, с помощью gcc-4.8 и выше вы можете рассмотреть возможность добавления атрибута, чтобы компилятор знал, что это "маловероятный" путь. Это помогает предотвратить ветвящиеся штрафы и т.д., Которые могли бы возникнуть при выборе "ожидаемого" пути:
no_skip: __attribute__ ((cold));
Разумеется, вы также можете использовать:
skip: __attribute__ ((hot));