ARM Technical Support Knowledge Articles

My code behaves strangely at higher optimization levels

Applies to: ARM Developer Suite (ADS), DS-5, RealView Development Suite (RVDS)

Answer

If you experience problems with your code:

  • when reading and writing to memory mapped hardware 
  • getting stuck in loop, when polling hardware
  • exhibiting strange behaviour in threaded programs

If these are particularly apparent at higher optimization levels (-O2 and -O3) but not at lower optimization levels it is likely that you may need to declare some of your variables as volatile.

If a variable is declared as volatile the compiler can assume that the object may be changed out of its visibility. This means the compiler can not perform a number optimizations, including caching variables in local registers, to avoid memory accesses. If a variable is not declared as volatile the compiler can assume that the value has not changed and perform a number of optimizations on it.

There are a number of different situations where you might wish to declare variables as volatile. These include:

  • Accessing memory mapped peripherals
  • Variables shared between multiple threads
  • Global variables accessed in interrupt routines

The following simple example demonstrates the effect on code generation when declaring a global variable as volatile.

C code:

/* volatile */ int buffer_full;

void read_stream(void)
{
  int count;

  while (!buffer_full) {
     count++;
  }
}

Code generation when buffer_full is not declared as volatile

     LDR      r0,[pc,#12]   ; Load address of "buffer_full"
     LDR      r0,[r0,#0]    ; Load "buffer_full"
loop CMP      r0,#0         ; Check "buffer_full"
     BEQ      loop          ; If not "buffer_full" branch to loop --> code stuck in loop!

Code generation when buffer_full is declared as volatile

     LDR      r1,[pc,#12]   ; Load address of "buffer_full"
loop LDR      r0,[r1,#0]    ; Load "buffer_full"
     CMP      r0,#0         ; Check "buffer_full"
     BEQ      loop          ; If not "buffer_full" branch to loop

Note that the count++ has been optimized away as it has no effect on the program.

Article last edited on: 2011-08-30 15:24:32

Rate this article

[Bad]
|
|
[Good]
Disagree? Move your mouse over the bar and click

Did you find this article helpful? Yes No

How can we improve this article?

Link to this article
Copyright © 2011 ARM Limited. All rights reserved. External (Open), Non-Confidential