1

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?

Daniel
  • 1,783
  • 2
  • 15
  • 25
  • What you're trying to achieve with this? – HolyBlackCat Jul 05 '21 at 06:14
  • C and C++ compilers are explicitely allowed to use the *as if* rule: they are free to rearrange the source code the way they want **provided the observables results are the same of what a naive strictly conformant implementation could produce**. And gcc is known to aggressively optimize out dead code or code that would have lead to UB... Maybe you could try a different compiler? – Serge Ballesta Jul 05 '21 at 06:32
  • @HolyBlackCat For now it's just for some simple tests. – Daniel Jul 05 '21 at 07:01
  • Then the answer is "probably not possible". If you explain what this is for, then we might be able to suggest alternative solutions. – HolyBlackCat Jul 05 '21 at 07:03
  • @SergeBallesta Yes, and I suppose the extent of this as-if rule is determined by `-O` and some other flags, but it seems not possible to achieve `0-extent` effect of this rule. I also check clang and the result is the same. – Daniel Jul 05 '21 at 07:10
  • @HolyBlackCat I am just curious with the [`constexpr if-statement`](https://en.cppreference.com/w/cpp/language/if), because if `const` in a `if-statement` has the same effect of a `constexpr if-statement`, then why do I need to use a `constexpr if-statement` instead of only using `const`? And this is another reason that I want to ensure whether on earth they are all the same (optimized to the same code no matter what flags you provide) for compilers. – Daniel Jul 05 '21 at 07:14
  • Well I hoped that we could easily find *toy* C++ compilers with no optimisations at all as results of student trainings. But a google search did not show any. Maybe C++ language is way to complex for that... – Serge Ballesta Jul 05 '21 at 07:19
  • 1
    @Daniel The difference can only be seen in templates, when the condition of `if constexpr` depends on a template parameter. Then, the branch that's not taken is validated less strictly (compared to regular `if`), allowing you to have things in it (depending on template parameters) that wouldn't compile otherwise. – HolyBlackCat Jul 05 '21 at 07:20

1 Answers1

1

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.

Jérôme Richard
  • 41,678
  • 6
  • 29
  • 59