What kind of dead code can GCC eliminate from the

2020-02-08 16:05发布

问题:

I have always been told that compiler is sufficient smart to eliminate dead code. Much of the code that I am writing has a lot of information known at compile time but the code has to be written in most generic form. I don't know any assembly so I cannot examine the generated assembly. What kind of code that can be effectively eliminated in the final executable?

Few examples but not limited to

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>();
///////////////////////////

What if definition of f is in other objective code and the the called f(true) is in main. Will link time optimisation effectively eliminate the dead code? What is the coding style/compiler option/trick to facilitate dead code elimination?

回答1:

Typically, if you're compiling with the -O flag on the following flags are turned on:

      -fauto-inc-dec 
      -fcompare-elim 
      -fcprop-registers 
      -fdce  
      [...]

-fdce stands for Dead Code Elimination. I'd suggest you compile your binaries with and without (i.e. by turning off explicitly) this option to make sure if your binaries are as optimized as you'd like them to be.

Read about the different passes of the compiler:

  • SSA Aggressive Dead Code Elimination. Turned on by the `-fssa-dce' option. This pass performs elimination of code considered unnecessary because it has no externally visible effects on the program. It operates in linear time.

As for helping the linker with dead code elimination go through this presentation. Two major takeaways being:

Compile your modules with -ffunction-sections -fdata-sections – there are no downsides to it!

  • This includes static libraries, not just binaries – make it possible for users of your library to benefit from more efficient dead code removal.
  • Link your binaries with --gc-sections, unless you have to link against nasty third-party static library which uses magic sections.

You may also want to take a look at this GCC bug (to see what chances of optimization may be missed and why).



回答2:

Your example focuses on dead code elimination inside functions.

Another type of dead code elimination, is removal of entire unused symbols (functions or variables) which can be achieved with:

-fdata-sections -ffunction-sections -Wl,--gc-sections

as mentioned at: How to remove unused C/C++ symbols with GCC and ld?

These flags are not enabled in the various GCC -O levels (-O1, -O2, etc) by default.



回答3:

When I used template parameter constant in such if expression then dce (Dead Code Elimination) compiler (GCC 4.8.1 on Linux) flags did not helped and O2, O3 optimization also did not helped. I had to use template specialization wrapper:

template<bool b>
f();

template<>
f<true>(){
  //some code on true condition
}

template<>
f<false>(){
  //some code on false condition
}

Also macros can be used to avoid compilation of the unused code branch, but it depends on the compiler (whether it processed macros as they occur in the code or on precompiling stage):

template<bool b>
f(){
 #if b
  //some code
 #elif
  //some code
 #endif  // b
}