cgcc

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.


Solution

  • 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.