Выполняет ли GCC LTO устранение мертвого кода между файлами?
Вопрос
Скажем, у меня есть функция
void do_something() {
//....
#ifdef FEATURE_X
feature_x();
#endif
//....
}
Я могу скомпилировать и запустить это без проблем;если мне нужна эта функция, я могу отказаться -D FEATURE_X
и это работает.
Однако что, если я хочу поставить do_something
в другой файл (и мне не придется перекомпилировать этот файл каждый раз, когда я решу изменить параметр).Если бы это было в том же файле, я предполагаю, что
const int FEATURE_X=0;
void do_something() {
//....
if(FEATURE_X) {
feature_x();
}
//....
}
будет правильно использовать устранение мертвого кода, исключая вызов.Если я помещу это в другой файл без LTO,
extern const int FEATURE_X;
void do_something() {
//....
if(FEATURE_X) {
feature_x();
}
//....
}
Он не удалит код (он не знает).Итак, при включенной оптимизации времени компоновки, может ли компилятор обнаружить значение FEATURE_X
во время ссылки определить, используется ли код или нет, и удалить его, если необходимо?
Решение
GCC выполняет удаление недоступной функции межмодуля, но он не сможет определить, что код мертв в вашем последнем тестовом примере, поскольку постоянное значение FEATURE_X будет определено слишком поздно.
Если вы будете использовать путь -D или поместите свой const int FEATURE_X=0;
в каждый модуль, тогда да, код будет удален.
Другие советы
Если вместо ссылочного кода:
extern const int FEATURE_X;
void do_something() {
//....
if(FEATURE_X) {
feature_x();
}
//....
}
.
Что, если это было сделано со временем ссылки, как так:
extern const int FEATURE_X;
void do_something() {
//....
if(NULL != &FEATURE_X) {
feature_x();
}
//....
}
.
Тогда в файле инструкции линкера определите
define exported symbol FEATURE_X = 0x0
.
будет ли в любом случае, чтобы оптимизировать его по ссылке?