You are on page 1of 4

Compiler Optimizations - Part 2

March 25, 2012

1 Introduction
In a previous lesson, we studied the eect of compiler optimizations without
actually checking out the assembly code which the compiler generates with
optimizations enabled. In this lesson, we will compile small C programs with
optimization enabled and check out the resulting assembly language code .
1
[Note: it is good that you review the rst part of this series before continuing]

2 Example 1
Remember, when you enable optimization, the compiler acts super-smart and
tries to map C statements to assembly language fragments which run faster
(compared with the case where you do not enable optimizations).
Let us nd out what the compiler does with the following C program (a.c):

#include <msp430.h>
main()
{
int i;
i = 10;
}

Compile this in the following manner:

msp430-gcc -S -O3 -mmcu=msp430g2231 -mdisable-watchdog a.c

Here is the assembler output I got:

.file "a.c"
.arch msp430g2231
.cpu 430
.mpy none
1 Check out http://en.wikipedia.org/wiki/Compiler_optimization for a general discussion
on compiler optimizations

1
.section .init9,"ax",@progbits
.p2align 1,0
.global main
.type main,@function
/***********************
* Function `main'
***********************/
main:
.Lfe1:
.size main,.Lfe1-main
;; End of function

Notice something interesting?


Yes, there is no trace of the local variable i in our main program! You
don't see space being allocated on the stack; you don't see a mov instruction
which stores 10 to a location on the stack.
In fact, your main is empty! There are absolutely no assembly language
statements in the body of main!
This makes sense because the two statements have no computational eect
on the program and eliminating them does not change the logic of the program
in any way - the optimizing process does not change the overall logic of the
program.

3 Example 2
Optimization is tricky business. Take the case of the following program:

#include <msp430.h>
main()
{
int i;
for(i = 0; i < 20000; i++);
}

The for loop has a denite eect; you can use it to introduce a small delay in
your code when you are writing say an LED blinking program. Compile the code
with optimizations enabled (like we did in the previous example) and look at the
assembly language output. You will see that the once again the body of main
has been completely eliminated! This will create trouble if you are writing a
program where you need to have time delay in between some statements.
The problem is that the compiler is incapable of detecting side-eects 2 (like
time delays) generated by your code. As far as the compiler is concerned, from

2 Most often, the side eect is a write/read to/from a memory mapped peripheral device.
Simply writing a value to an integer variable like i has no computational eect if the variable
is not used anywhere in the code. But what if you are writing to a variable which represents
say an I/O port - eliminating such statements can create trouble.

2
a pure computational point of view, a for loop which iterates twenty thousand
times and increments the value of a variable every iteration can be replaced by
a simple statement like this:

i = 20000

and if the variable i is not used anywhere in the code, even that statement
can be eliminated without changing the computational logic of the program.
Unfortunately, your program will many a time depend on physical side-eects
(like time delays) generated by the code - in such cases, you have to explicitly
instruct the compiler not to apply optimizations on certain statements in your
program.
As an experiment, change the declaration of i to:

volatile int i;

compile the code with optimizations enabled and once again look at the assembly
output produced .
3

4 Exercise 1
Compile the following program with optimizations enabled:

#include <msp430.h>
extern void fun(int*);
main()
{
int i;
i = 10;
fun(&i);
}

Does space get allocated for variable i? How do you explain this behaviour?
Do you have some other observations regarding the generated assembly language
code?

5 Exercise 2
Compile the following program with optimizations enabled.

#include <msp430.h>
extern void fun(int *);
int sqr(int x)
{
return x*x;
3 Ref: http://en.wikipedia.org/wiki/Volatile_variable

3
}
main()
{
int i;
i = sqr(3);
fun(&i);
}

Is the function sqr getting called? What is the magic that the compiler has
performed in this case?
Try the same experiment with a function more complex than sqrt - say for
example a recursive factorial:

int fact(int n)
{
if(n == 0) return 1;
else return n * fact(n-1);
}

The following discussions may be useful:

http://blog.32leaves.net/?p=674
http://stackoverow.com/questions/190232/can-a-recursive-function-
be-inline

6 Exercise 3
Compile the following program with and without optimzations enabled:

#include <msp430.h>
main()
{
int i = 1;
while(i == 1);
}

What do you observe?

7 Test
There is no test associated with this lesson.

You might also like