disable all obvious elimination when compiling with gcc (without changing my source code!)

267 Views Asked by At

I want to keep all dead code (or anything that is even obviously can be optimized) when compiling with gcc, but even with -O0, some dead code are still optimized. How can I keep all code without changing my source code? The sample code is as follows, and when compiling with g++ -S -O0 main.cc, the if-statement will be optimized in assembly code (there will be no cmpl and jmp code).

int main() {
  constexpr int a = 123; // or const int a = 0; I do not want to remove `const` or `constexpr` qualifier.
  if (a) // or just if (123)
    return 1;
  return 0;
}

A related question is here: Disable "if(0)" elimination in gcc. But the answers there need you to change your source code (remove const/constexpr qualifier) which I do not want to do.

Could it be that I do not change my source code but only use some compiler flags to achieve this?

1

There are 1 best solutions below

0
On BEST ANSWER

This is not possible with GCC to keep the conditional in this case since it is removed during a very early stage of the compilation.

First of all, here is the compilation steps of GCC:

  1. Code parsing (syntax & semantics) producing an AST in GENERIC representation (HL-IR)
  2. High-level GIMPLE generation (ML-IR)
  3. Low-level GIMPLE generation (ML-IR)
  4. Tree SSA optimization (ML-IR)
  5. RTL generation (LL-IR)
  6. Code optimization
  7. Assembly generation

The conditional is already removed after the generation of the (theoretically unoptimized) high-level GIMPLE representation. Thus, before any optimization step. One can check this by using the GCC flag -fdump-tree-all and look at the first generated GIMPLE code. Here is the result:

;; Function int main() (null)
;; enabled by -tree-original
{
  const int a = 123;

  <<cleanup_point   const int a = 123;>>;
  return <retval> = 1;
  return <retval> = 0;
}
return <retval> = 0;

One can note that the resulting code is the same with both constexpr and const. Actually, constexpr is treated as a simple const variable in the HL GIMPLE code.

It is hard to know when the conditional is exactly removed in Step 1 as GENERIC is an implementation-dependent internal representation of GCC. It is not very flexible/customizable. AFAIK, it is not even yet possible to generate the AST/GENERIC representation. You can extract it yourself with some GCC plugins, but this is a quite tricky task.