Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Optimizer removing pointer de-reference lines

I have a problem where the optimizer seems to be removing lines of code that are quite necessary. Some background: I have a program that interfaces a PCIe driver. I have an integer pointer UINT32 *bar_reg; that points to the user space address of the BAR register I am communicating to. To write to the register I just de-reference the pointer. *(bar_reg + OFFSET) = value;

With no optimizations, this works fine. However as soon as I turn on any level of optimization, all the lines that de-reference the pointer get removed. The way I finally discovered this was by stepping through in Visual Studio. However it happens independent of platform. I've been able to get by up to now with the optimizer off, but someone using my library code in Linux wants to turn on optimization now. So I'm curious as to why this problem occurs and what the most reasonable fix/workaround is.

like image 711
Alex Crook Avatar asked Nov 21 '14 22:11

Alex Crook


2 Answers

Use volatile keyword in order to prevent the optimization of that variable.

For example:

volatile UINT32 *bar_reg;

The issue here is that the compiler assumes that since the memory is not accessed by the program, then it means that the memory will remain unchanged and hence it might try to optimize some of the writes to that memory.

like image 57
bialpio Avatar answered Oct 19 '22 22:10

bialpio


The issue you are running into involves the as-if rule which allows the optimizer to transform your code in any way as long as it does not effect the observable behavior of the program.

So if you only write to the variable but never actually use in your program the optimizer believes there no observable behavior and assumes it can validly optimize away the writes.

In your case the data is being observed outside of your program and the way to indicate this to the compiler and optimizer is through the volatile qualifier, cppreference tells us (emphasis mine going forwrd):

an object whose type is volatile-qualified, or a subobject of a volatile object, or a mutable subobject of a const-volatile object. Every access (read or write operation, member function call, etc.) on the volatile object is treated as a visible side-effect for the purposes of optimization [...]

For reference the as-if rule is covered in the draft C++ standard in section 1.9 which says:

[...]Rather, conforming implementations are required to emulate (only) the observable behavior of the abstract machine as explained below.

and with respect to the as-if rule volatile is also covered in section 1.9 and it says:

Access to volatile objects are evaluated strictly according to the rules of the abstract machine.

like image 22
Shafik Yaghmour Avatar answered Oct 20 '22 00:10

Shafik Yaghmour