GCC从最终输出中消除了什么样的死代码?

leo*_*on 17 c c++ gcc templates g++

我一直被告知编译器足以聪明地消除死代码.我编写的大部分代码在编译时都知道很多信息,但代码必须以最通用的形式编写.我不知道任何装配,所以我无法检查生成的装配.什么样的代码可以在最终的可执行文件中有效消除?

几个例子但不限于

f(bool b){
 if(b){
  //some code
 }else{
  //some code
 }
}
f(true);
//////////////////////////
template<bool b>
f(){
 if(b){
  //some code
 }else{
  //some code
 }
}
f<true>();
///////////////////////////
Run Code Online (Sandbox Code Playgroud)

如果f在其他目标代码中定义并且被调用f(true)是主要的,那该怎么办?链接时间优化会有效消除死代码吗?什么是编码样式/编译器选项/技巧,以促进死代码消除?

dir*_*tly 25

通常情况下,如果你用编译-O标志下列标志开启:

      -fauto-inc-dec 
      -fcompare-elim 
      -fcprop-registers 
      -fdce  
      [...]
Run Code Online (Sandbox Code Playgroud)

-fdce代表死码消除.我建议您使用和不使用(即通过明确关闭)此选项来编译您的二进制文件,以确保您的二进制文件是否像您希望的那样优化.

阅读有关编译器的不同传递:

  • SSA积极的死代码消除.由`-fssa-dce'选项打开.此过程执行消除被认为不必要的代码,因为它对程序没有外部可见的影响.它以线性时间运行.

至于帮助链接器消除死代码,请通过此演示文稿.两个主要的要点是:

使用-ffunction-sections -fdata-sections编译模块 - 没有任何缺点!

  • 这包括静态库,而不仅仅是二进制文件 - 使您的库用户可以从更有效的死代码删除中受益.
  • 将您的二进制文件链接到--gc-sections,除非您必须链接使用魔术部分的令人讨厌的第三方静态库.

您可能还想查看此GCC错误(以了解可能错过优化的可能性以及原因).

  • @*:RTL =寄存器传输语言是一种Lisp启发的低级中间语言(GCC使用的三种语言之一)(以及另一种称为GIMPLE)用于优化目的. (3认同)
  • @ *:打开-O时,如何显式完全关闭“ -fdce”? (2认同)