我一直被告知,编译器足够智能,可以消除死代码。我编写的许多代码在编译时都包含大量已知信息,但代码必须以... 的形式编写。
我一直被告知编译器足够智能,可以消除死代码。我编写的大部分代码在编译时都有很多已知信息,但代码必须以最通用的形式编写。我不懂任何汇编语言,所以我无法检查生成的汇编语言。什么样的代码可以在最终的可执行文件中有效地消除?
举几个例子,但不限于
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>();
///////////////////////////
如果 的定义 f
在其他目标代码中,而 被调用的 f(true)
在主代码中,会怎么样?链接时间优化能否有效消除死代码?有什么编码风格/编译器选项/技巧可以促进死代码的消除?
通常,如果您使用 the -O
flag ,则会打开以下标志:
-fauto-inc-dec
-fcompare-elim
-fcprop-registers
-fdce
[...]
-fdce
代表“死代码消除”。我建议您在编译二进制文件时,先启用或禁用此选项(即明确关闭此选项),以确保二进制文件是否按您希望的方式进行了优化。
了解 编译器的 不同过程
- SSA 积极死代码消除。由“-fssa-dce”选项启用。此过程执行消除被认为不必要的代码的操作,因为这些代码对程序没有外部可见的影响。它以线性时间运行。
至于如何帮助链接器消除死代码,请阅读 本演示文稿 。两个主要要点是:
使用 -ffunction-sections -fdata-sections 编译您的模块 – 它没有任何缺点!
- 这包括静态库,而不仅仅是二进制文件——使您的库的用户能够受益于更有效的死代码删除。
- 将您的二进制文件与--gc-sections链接,除非您必须链接到使用魔术部分的令人讨厌的第三方静态库。
您可能还想看看 这个 GCC 错误 (看看可能会错过哪些优化机会以及原因)。