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

【问题讨论】:

    标签: gcc dead-code lto


    【解决方案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
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-04-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-18
      • 2012-02-17
      相关资源
      最近更新 更多