ZelluX
ZelluX

Reputation: 72655

How can I prevent GCC optimizing some statements in C?

In order to make a page dirty (switching on the dirty bit in the page table entry), I touch the first bytes of the page like this:

pageptr[0] = pageptr[0];

But in practice, GCC will ignore the statement by dead store elimination. In order to prevent GCC optimizing it, I rewrite the statement as follows:

volatile int tmp;
tmp = pageptr[0];
pageptr[0] = tmp;

It seems the trick works, but somewhat ugly. I would like to know is there any directives or syntax which has the same effect? And I don't want to use a -O0 flag, since it will bring great performance penalty as well.

Upvotes: 159

Views: 237834

Answers (3)

Dietrich Epp
Dietrich Epp

Reputation: 213338

Turning off optimization fixes the problem, but it is unnecessary. A safer alternative is to make it illegal for the compiler to optimize out the store by using the volatile type qualifier.

// Assuming pageptr is unsigned char * already...
unsigned char *pageptr = ...;
((unsigned char volatile *)pageptr)[0] = pageptr[0];

The volatile type qualifier instructs the compiler to be strict about memory stores and loads. One purpose of volatile is to let the compiler know that the memory access has side effects, and therefore must be preserved. In this case, the store has the side effect of causing a page fault, and you want the compiler to preserve the page fault.

This way, the surrounding code can still be optimized, and your code is portable to other compilers which don't understand GCC's #pragma or __attribute__ syntax.

Upvotes: 120

FRob
FRob

Reputation: 4041

Instead of using the new pragmas, you can also use __attribute__((optimize("O0"))) for your needs. This has the advantage of just applying to a single function and not all functions defined in the same file.

Usage example:

void __attribute__((optimize("O0"))) foo(unsigned char data) {
    // unmodifiable compiler code
}

Upvotes: 185

Plow
Plow

Reputation: 4227

You can use

#pragma GCC push_options
#pragma GCC optimize ("O0")

your code

#pragma GCC pop_options

to disable optimizations since GCC 4.4.

See the GCC documentation if you need more details.

Upvotes: 247

Related Questions