avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[avr-gcc-list] Tip: handling volatile operands


From: andrewhutchinson
Subject: [avr-gcc-list] Tip: handling volatile operands
Date: Thu, 10 Jan 2008 14:24:46 -0500

I have come across a few instances where very inefficient c code is created by 
volatile operands - often accidentally and thru no fault of the compiler(s)

volatile is typically applied to hardware registers and interrupt variable that 
can change outside of the scope of the use in the use function.

So unless we use volatile, the compiler thinks they dont change and use can get 
optimised away!!!

For example:

 while (ioport != 0)
{

}


With volatile, each and every explicit reference will be created an maintained 
in the function. And will not be optimised away..

Ok that's easy! 

Now there is a downside that is over looked, particulary since voltatile is 
often applied non-selectively to io locations.

Accessing a volatile variable can produce very poor code - that might not be 
needed. Consider this:

if ((ioport  & 1) ||  (ioport & 2) || (ioport & 0x0c))
{
}


If ioport is a volatile, this will create 3 separate reads from io/memory and 3 
separate tests and quite likely the use of a temporary register to hold the 1/0 
result!

It might also be problematic that ioport might change halfway thru the tests 
and cause an unexpected result.

If ioport were a "normal" variable, there would be one read and one test!

So, if you don't want the absolute latest value of a volatile,  use a temporary!

unsigned char a = ioport;

if ((a& 1) ||  (a& 2) || (a& 0x0c))
{
}

Will produce much better code!






reply via email to

[Prev in Thread] Current Thread [Next in Thread]