Three address code in Compiler
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
Three Address Codes are Used in Compiler Applications
Optimization: Three-address code is often used as an intermediate
representation of code during the optimization phases of the compilation
process. The three-address code allows the compiler to analyze the code and
perform optimizations that can improve the performance of the generated
code.
Code generation: Three address codes can also be used as an intermediate
representation of code during the code generation phase of the compilation
process. The three-address code allows the compiler to generate code that is
specific to the target platform, while also ensuring that the generated code is
correct and efficient.
Debugging: Three address codes can be helpful in debugging the code
generated by the compiler. Since the address code is a low-level language, it is
often easier to read and understand than the final generated code. Developers
can use the three address codes to trace the execution of the program and
identify errors or issues that may be present.
Language translation: Three address codes can also be used to translate code
from one programming language to another. By translating code to a common
intermediate representation, it becomes easier to translate the code to
multiple target languages.
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.
Three Address Code
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.
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.
Example - Consider expression a = b * - c + b * - c
• 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
X=(a+b)-(a+b-c)