Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can GCC be instructed not to eliminate dead code?

Tags:

c

gcc

Suppose that I'm using a modern version of GCC to compile a C program. Furthermore, consider that my program contain stale branches, but that I'd very much like the dead code in those stale branches to be compiled and present in the final program. Consider the following program:

int main(int argc, char** argv) {
    int a = 0;
    goto skip;
        a = -1;
    skip: ;
    return a;
}

Clearly, if I use GCC with default optimization settings, the second assignment will never make it to the final program, as the compiler can easily tell that it'll never be executed. Suppose that I don't want this to happen.

In GCC, there are a number of flags that dabble with dead code (most notably -fdce), and I can chose to explicitly deactivate these when invoking GCC accordingly:

-fno-dce
-fno-dse
-fno-tree-dce
-fno-tree-dse

As far as I can tell, this should instruct GCC not to mess with the second assignment. Yet, the concerned code never seems to make it into my program.

Why does GCC insist on removing the dead code, and is there a way of instructing GCC not to get rid of the second assignment?

like image 641
Caterpillar Avatar asked Feb 17 '15 16:02

Caterpillar


People also ask

Is useful to eliminate dead code in code optimization?

Removing such code has several benefits: it shrinks program size and it allows the running program to avoid executing irrelevant operations, which reduces its running time. It can also enable further optimizations by simplifying program structure. This dead code optimizer also removes code after next or break calls.

How do we do dead code elimination?

Historically, dead-code elimination was performed using information derived from data-flow analysis. An algorithm based on static single-assignment form (SSA) appears in the original journal article on SSA form by Ron Cytron et al.


1 Answers

The -fno-* options don't work for me either with gcc-4.9.2. That said, I think the following should be portable for all gcc (4.5+) targets:

__asm__ goto (""::::no_skip);
goto skip;

no_skip:
    a = -1;

skip:;

From the manual: "an asm goto statement is always implicitly considered volatile."

Furthermore, with gcc-4.8 and above, you might consider adding an attribute to let the compiler know that this is an 'unlikely' path. This helps prevent branching penalties, etc., that might otherwise occur when taking the 'expected' path:

no_skip: __attribute__ ((cold));

It stands to reason that you could also use:

skip: __attribute__ ((hot));
like image 136
Brett Hale Avatar answered Nov 12 '22 15:11

Brett Hale