Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the standard way to constrain a optimizing compiler to keep duplicate assignments?

I have some embedded code that writes commands to a memory address to control a peripherial like so:

void intelStartEraseBlock(uint16_t *wordAddress) {
  *wordAddress =  0x20;  //block erase
  *wordAddress =  0xD0;  //block erase confirm
}

I suspect that the optimizer is skipping the first assignment. Is this a job for volatile? or is there a better solution...

Note: this is legacy api code, so I don't plan of refactoring much. I am looking for a 'local' fix here.

like image 805
CodePoet Avatar asked Dec 02 '22 22:12

CodePoet


2 Answers

That's exactly why the volatile keyword was created. This is the classical example of its usage.

like image 150
Spidey Avatar answered Dec 04 '22 12:12

Spidey


Yes, just declare wordAddress as a pointer to volatile data:

void intelStartEraseBlock(volatile uint16_t *wordAddress) {
   ...
}

The volatile keyword tells the compiler that the semantics have to match up with the abstract virtual machine specified by the C language -- in other words, every time you write to a volatile variable, the code has to actually write to memory, and every time you read from a volatile variable, the code has to actually read from memory.

The compiler is not allowed to optimize away these reads and writes, even if it thinks they are redundant.

Note that it must be the pointed-to data which is declared volatile, not the pointer itself. Like the const keyword, it makes a big difference. Since wordAddress is itself a variable on the stack, we don't care of reads/writes of it actually go out to the stack memory, but we do care that the memory it points to (presumably some type of memory-mapped I/O) is actually read/written.

like image 28
Adam Rosenfield Avatar answered Dec 04 '22 12:12

Adam Rosenfield