O GCC LTO executa a eliminação de código morto entre arquivos?
Pergunta
Digamos que eu tenha uma função
void do_something() {
//....
#ifdef FEATURE_X
feature_x();
#endif
//....
}
Posso compilar e executar isso sem problemas;se eu quiser o recurso posso passar -D FEATURE_X
e funciona.
No entanto, e se eu quiser colocar do_something
em outro arquivo (e não preciso recompilar esse arquivo toda vez que eu decidir alterar a opção).Se estivesse no mesmo arquivo, presumo que
const int FEATURE_X=0;
void do_something() {
//....
if(FEATURE_X) {
feature_x();
}
//....
}
usará a eliminação de código morto corretamente, eliminando a chamada.Se eu colocar isso em outro arquivo, sem LTO,
extern const int FEATURE_X;
void do_something() {
//....
if(FEATURE_X) {
feature_x();
}
//....
}
Não removerá o código (não tem como saber).Assim, com a otimização do tempo de link habilitada, o compilador pode detectar o valor de FEATURE_X
no momento do link, determine se o código é usado ou não e remova-o, se apropriado?
Solução
O GCC remove funções inacessíveis entre módulos, mas não será capaz de determinar se o código está morto em seu último caso de teste, porque o valor constante de FEATURE_X será determinado tarde demais.
Se você usar o modo -D ou colocar seu const int FEATURE_X=0;
em cada módulo então sim, o código será eliminado.
Outras dicas
Se em vez do código referenciado:
extern const int FEATURE_X;
void do_something() {
//....
if(FEATURE_X) {
feature_x();
}
//....
}
e se isso fosse feito com uma variável de tempo de link assim:
extern const int FEATURE_X;
void do_something() {
//....
if(NULL != &FEATURE_X) {
feature_x();
}
//....
}
Em seguida, no arquivo de instruções do vinculador, defina
define exported symbol FEATURE_X = 0x0
Haveria alguma maneira de otimizá-lo no momento do link?