0% found this document useful (0 votes)
45 views8 pages

Wa0001

Intermediate Code Generation is a crucial stage in compiler design where source code is translated into machine-independent intermediate code, enhancing portability and optimization. Common representations of this intermediate code include Postfix Notation and Three-Address Code, which can be implemented using Quadruples, Triples, and Indirect Triples. Each representation has its advantages and disadvantages, impacting code optimization and rearrangement during the compilation process.

Uploaded by

dss745147
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
45 views8 pages

Wa0001

Intermediate Code Generation is a crucial stage in compiler design where source code is translated into machine-independent intermediate code, enhancing portability and optimization. Common representations of this intermediate code include Postfix Notation and Three-Address Code, which can be implemented using Quadruples, Triples, and Indirect Triples. Each representation has its advantages and disadvantages, impacting code optimization and rearrangement during the compilation process.

Uploaded by

dss745147
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 8

Intermediate Code Generation in Compiler Design

The front end of a compiler translates a source program into an independent intermediate
code, then the back end of the compiler uses this intermediate code to generate the target
code (which can be understood by the machine). The benefits of using machine-
independent intermediate code are:

• Because of the machine-independent intermediate code, portability will be


enhanced. For example, suppose, if a compiler translates the source language to its
target machine language without having the option for generating intermediate
code, then for each new machine, a full native compiler is required. Because,
obviously, there were some modifications in the compiler itself according to the
machine specifications.

• Retargeting is facilitated.

• It is easier to apply source code modification to improve the performance of source


code by optimizing the intermediate code.

Intermediate Code Generation is a stage in the process of compiling a program, where the
compiler translates the source code into an intermediate representation. This representation
is not machine code but is simpler than the original high-level code. Here’s how it works:

• Translation: The compiler takes the high-level code (like C or Java) and converts it
into an intermediate form, which can be easier to analyze and manipulate.

• Portability: This intermediate code can often run on different types of machines
without needing major changes, making it more versatile.

• Optimization: Before turning it into machine code, the compiler can optimize this
intermediate code to make the final program run faster or use less memory.

he following are commonly used intermediate code representations:

Postfix Notation

• Also known as reverse Polish notation or suffix notation.

• In the infix notation, the operator is placed between operands, e.g., a + b. Postfix
notation positions the operator at the right end, as in ab +.

• For any postfix expressions e1 and e2 with a binary operator (+) , applying the
operator yields e1e2+.

• Postfix notation eliminates the need for parentheses, as the operator’s position and
arity allow unambiguous expression decoding.

• In postfix notation, the operator consistently follows the operand.


Example 1: The postfix representation of the expression (a + b) * c is : ab + c *
Example 2: The postfix representation of the expression (a – b) * (c + d) + (a – b) is : ab – cd
+ *ab -+

Three-Address Code

• A three address statement involves a maximum of three references, consisting of two


for operands and one for the result.

• A sequence of three address statements collectively forms a three address code.

• The typical form of a three address statement is expressed as x = y op z, where x, y,


and z represent memory addresses.

• Each variable (x, y, z) in a three address statement is associated with a specific


memory location.

While a standard three address statement includes three references, there are instances
where a statement may contain fewer than three references, yet it is still categorized as a
three address statement.
Example: The three address code for the expression a + b * c + d : T1 = b * c T2 = a + T1 T3 =
T2 + d; T 1 , T2 , T3 are temporary variables.

There are 3 ways to represent a Three-Address Code in compiler design:


i) Quadruples
ii) Triples
iii) Indirect Triples

TAC is an intermediate representation of three-address code utilized by compilers to ease


the process of code generation. Complex expressions are, therefore, decomposed into
simple steps comprising, at most, three addresses: two operands and one result using this
code. The results from TAC are always stored in the temporary variables that a compiler
generates. This design ensures explicit ordering of the operations that come into play. Since
it is simple, TAC lends itself nicely to optimization and translation to machine code.

General Representation

a=b
a = op b
a = b op c

Where a, b, or c represents operands like names, constants or compiler-generated


temporaries and op represents the operator

Example-1: Convert the expression a * – (b + c) into three address codes.


*Uminus= Unary Minus

Implementation of Three Address Code


There are 3 representations of three address code namely

• Quadruple

• Triples

• Indirect Triples

1. Quadruple: It is a structure which consists of 4 fields namely op, arg1, arg2 and result. op
denotes the operator and arg1 and arg2 denotes the two operands and result is used to
store the result of the expression.

Advantage

• Easy to rearrange code for global optimization.

• One can quickly access value of temporary variables using symbol table.

Disadvantage

• Contain lot of temporaries.

• Temporary variable creation increases time and space complexity.

Example – Consider expression a = b * – c + b * – c. The three address code is:

t1 = uminus c (Unary minus operation on c)


t2 = b * t1
t3 = uminus c (Another unary minus operation on c)
t4 = b * t3
t5 = t2 + t4
a = t5 (Assignment of t5 to a)
2. Triples: This representation doesn’t make use of extra temporary variable to represent a
single operation instead when a reference to another triple’s value is needed, a pointer to
that triple is used. So, it consist of only three fields namely op, arg1 and arg2.

Disadvantage

• Temporaries are implicit and difficult to rearrange code.

• It is difficult to optimize because optimization involves moving intermediate code.


When a triple is moved, any other triple referring to it must be updated also. With
help of pointer one can directly access symbol table entry.

Example – Consider expression a = b * – c + b * – c


3. Indirect Triples This representation makes use of pointer to the listing of all references to
computations which is made separately and stored. Its similar in utility as compared to
quadruple representation but requires less space than it. Temporaries are implicit and easier
to rearrange code.

Example – Consider expression a = b * – c + b * – c

Question – Write quadruple, triples and indirect triples for following expression : (x + y) * (y
+ z) + (x + y + z)
Explanation – The three address code is:

(1) t1 = x + y
(2) t2 = y + z
(3) t3 = t1 * t2
(4) t4 = t1 + z
(5) t5 = t3 + t4

You might also like