CHAPTER 6: CODE OPTIMIZATION & CODE GENERATION
Why? Optimizing intermediate code is easier and machine-independent. Once we generate
machine code, optimizations become machine-specific and harder.
1. What is Code Optimization?
Code optimization improves the intermediate code to make it faster and smaller without
changing what it does.
Think of it like: Editing your writing to make it clearer without changing the message.
Common Optimizations with Examples:
a) Constant Folding
// Before optimization
x=5+3
// After optimization (compiler calculates it)
x=8
b) Constant Propagation
// Before
a=5
b=a+3
// After
a=5
b=8
c) Common Subexpression Elimination (CSE)
// Before
t1 = b * c
t2 = b * c
t3 = t1 + t2
// After (calculate once, use twice)
t1 = b * c
t3 = t1 + t1
d) Dead Code Elimination
// Before
x=5
x = 10
return x
// After (first assignment wasted)
x = 10
return x
e) Loop Invariant Code Motion
// Before
for (i = 0; i < 100; i++) {
x = y + 5 // y+5 never changes!
a[i] = x
}
// After (move outside loop)
x=y+5
for (i = 0; i < 100; i++) {
a[i] = x
}
f) Strength Reduction
// Before (multiplication is expensive)
x=y*2
// After (shift is faster)
x = y << 1
2. What is Code Generation?
Code generation converts optimized intermediate code into actual machine code (assembly
language) that the CPU can execute.
Think of it like: Translating your final draft into another language.
Example – TAC to Assembly:
Input (Optimized TAC):
t1 = b * c
t2 = a + t1
x = t2
Output (x86 Assembly):
assembly
mov eax, [b] ; load b into register
imul eax, [c] ; multiply by c
mov [t1], eax ; store in t1
mov eax, [a] ; load a
add eax, [t1] ; add t1
mov [x], eax ; store result in x
3. Why Optimization
Reason Explanation
Machine Independence Optimizations work for any CPU
Easier to Optimize TAC is simpler than assembly
One Optimization, Many Targets Optimize once, generate code for x86, ARM, MIPS
More Opportunities More optimizations possible at IR level
Complete Example
Original C Code:
a = 5 + 3;
b = a * 1;
c = (x + y) + (x + y);
Step 1: Generate Intermediate Code (TAC)
t1 = 5 + 3
a = t1
t2 = a * 1
b = t2
t3 = x + y
t4 = x + y
t5 = t3 + t4
c = t5
Step 2: Apply Optimizations
// Constant folding: 5+3 = 8
a=8
// Multiplication by 1 removed
b=a
// Common subexpression elimination
t1 = x + y
c = t1 + t1
// Final optimized TAC
a=8
b=a
t1 = x + y
c = t1 + t1
Step 3: Generate Assembly (after optimization)
mov [a], 8 ;a=8
mov eax, [a] ; load a
mov [b], eax ;b=a
mov eax, [x] ; load x
add eax, [y] ; eax = x + y
add eax, eax ; multiply by 2
mov [c], eax ; c = 2*(x+y)