Skip to content

Compiler-Intermediate Code Generation & Code Optimization

  • Three Address Code
  • Control Sequence
  • Variable Declaration

Intermediate Code

Intermediate code separates the front end and the back end. It is an intermediate level between

  • a high level parse tree and
  • low level microprocessor instructions.

It is internal to compilers. Different compilers may have different intermediate codes.

Possible types of intermediate code:

  • Syntax trees
  • Static single assignment
  • Three address code

Three Address Code

Each 3AC instruction consists of at most

  • one operator (binary or unary) and three address (variable number)

For example,

  • x=y op z (binary operator)
  • x=opy (unary operator)
  • x=y (copy/ assignment)
  • goto L (unconditional goto, L is the label of the destination)
  • if x relationalop ythen goto L (conditional goto)

To convert a parse tree to 3AC, we need two synthesized attributes for each node in the parse tree.

Suppose we have a grammar production E

  • E.name stores the name of the variable containing the value of E.
  • E.code stores the sequence of 3AC that computes the value if E.

The function newtemp() is used when the temporary variable names for intermediate results are generated.

Example

Define the attributes for the following grammar

  • Sid=E
  • E1E2+E3|E2E3|E2|(E2)|id

Sid=E

s.code:=E.code||id.name=E.name
  • "||" means "followed by"
  • No S.name because id=E is an assignment, not computing a value.

E1E2+E3

  • E1.name:=newtemp()
  • E1.code:=E2.code||E3.code||E1.name=E2.name+E3.name

E1E2E3

  • E1.name:=newtemp()
  • E1.code:=E2.code||E3.code||E1.name=E2.nameE3.name

E1E2

  • E1.name:=E2.name
  • E1.code:=E2.code||E1.name=E2.name

E1(E2.name)

  • E1.name:=E2.name
  • E1.code:=E2.code

E1id

  • E1.name:=id.name (intrinsic)
  • E1.code:="" (nothing to compute)

Control Sequence

Variable Declaration

Loop

If Statement