GCC LTO esegue l'eliminazione del codice morto del file incrociato?
Domanda
Dì che ho una funzione
void do_something() {
//....
#ifdef FEATURE_X
feature_x();
#endif
//....
}
.
Posso compilare ed eseguire questo senza problemi;Se voglio la funzione che posso passare -D FEATURE_X
e funziona.
Tuttavia, cosa succede se vorrei mettere do_something
in un altro file (e non è necessario ricompilare anche quel file ogni volta che decido di cambiare l'opzione).Se fosse nello stesso file, presumo che
const int FEATURE_X=0;
void do_something() {
//....
if(FEATURE_X) {
feature_x();
}
//....
}
.
utilizzerà correttamente l'eliminazione del codice morto, eliminando la chiamata.Se lo metto in un altro file, senza lto,
extern const int FEATURE_X;
void do_something() {
//....
if(FEATURE_X) {
feature_x();
}
//....
}
.
Non rimuoverà il codice (non ha modo di conoscere).Quindi, con l'ottimizzazione del tempo di collegamento abilitato, il compilatore può rilevare il valore del FEATURE_X
al momento del collegamento, determinare se il codice viene utilizzato o meno e rimuoverlo se appropriato?
Soluzione
GCC esegue la rimozione della funzione irraggiungibile del modulo croce, ma non sarà in grado di determinare il codice è morto nell'ultima volta che il valore costante di feature_x sarà determinato troppo tardi.
Se usi -d way o metti il tuo const int FEATURE_X=0;
in ogni modulo allora sì, il codice verrà eliminato.
Altri suggerimenti
Se invece del codice di riferimento:
extern const int FEATURE_X;
void do_something() {
//....
if(FEATURE_X) {
feature_x();
}
//....
}
.
Cosa succede se è stato fatto con una variabile di tempo di collegamento come:
extern const int FEATURE_X;
void do_something() {
//....
if(NULL != &FEATURE_X) {
feature_x();
}
//....
}
.
Quindi nel file di istruzioni del linker, definisci
define exported symbol FEATURE_X = 0x0
.
Ci sarebbe comunque comunque per ottimizzarlo al momento del collegamento?