Intermediate Code Generation

Intermediate representations include syntax trees, DAGs, postfix notation and three-address code (TAC), where each instruction has at most three addresses: x = y op z.

Three-Address Code Example

Text
Source: a = b * -c + b * -c

t1 = minus c
t2 = b * t1
t3 = minus c
t4 = b * t3
t5 = t2 + t4
a  = t5

Quadruples, Triples and Indirect Triples

#oparg1arg2result
0minusct1
1*bt1t2
2minusct3
3*bt3t4
4+t2t4t5
5=t5a

Triples omit the result field and refer to earlier instructions by position, e.g. (1) * b (0). Indirect triples keep a separate list of pointers to triples, so instructions can be reordered easily during optimization.

Control Flow

Text
Source:  while (i < 10) { sum = sum + i; i = i + 1; }

L1: if i < 10 goto L2
    goto L3
L2: t1 = sum + i
    sum = t1
    t2 = i + 1
    i = t2
    goto L1
L3: ...

Backpatching fills in jump targets later, allowing one-pass generation of code for boolean expressions and control flow.

Track your progress through the Compiler Design course