2012-10-03 70 views
2

說我有一個功能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的值,確定代碼是否被使用,並在適當的情況下將其刪除?

回答

7

GCC確實會跨模塊無法訪問的函數刪除,但它不能確定代碼在您最後一個測試用例中死了,因爲FEATURE_X的常量值將被確定爲太晚。

如果您將使用-D方式或將您的const int FEATURE_X=0;放入每個模塊中,那麼代碼將被刪除。

+0

太棒了,謝謝。請注意,使用反引號而不是普通引號會導致包圍文本爲「代碼」排版(等寬字體等)。 – zebediah49

+1

看來最近版本的gcc確實可以及時地確定這個常量值來消除死代碼。 –

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 

無論如何要在鏈接時優化它嗎?