GCC LTO 是不是执行跨文件死代码消除?

Posted

技术标签:

【中文标题】GCC LTO 是不是执行跨文件死代码消除?【英文标题】:Does GCC LTO perform cross-file dead code elimination?GCC LTO 是否执行跨文件死代码消除? 【发布时间】:2012-10-03 19:16:13 【问题描述】:

说我有一个函数

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 的值,判断代码是否被使用,并在适当的时候将其移除?

【问题讨论】:

【参考方案1】:

GCC 确实移除了跨模块无法访问的功能,但它无法确定您最后一个测试用例中的代码已死,因为 FEATURE_X 的常量值确定得太晚了。

如果你将使用 -D 方式或将const int FEATURE_X=0; 放入每个模块中,那么是的,代码将被消除。

【讨论】:

太棒了,谢谢。请注意,使用反引号而不是常规引号会导致被包围的文本是“代码”排版(等宽等)。 现在看来gcc的最新版本确实及时确定了常量值来消除死代码。【参考方案2】:

如果不是引用的代码:

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

有没有办法在链接时优化它?

【讨论】:

以上是关于GCC LTO 是不是执行跨文件死代码消除?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 GCC LTO 与不同优化的目标文件一起使用?

使用函数指针消除 gcc 死代码

在gcc编译器中禁用特定优化(死代码消除)

防止 GCC LTO 删除函数

v8 是不是能够根据 `const` 的值消除死代码?

如何编写启用 LTO 的代码?