The process of translating a source language into machine code for a given target machine is done by intermediate-code. It lies between the high-level language and the machine language. See the below image that illustrates the position of the intermediate code generator:
- If a compiler cannot produce intermediate code while converting the source code into machine code, then a full native compiler is required for each new machine.
- With the use of intermediate code, we don’t need a new compiler for every new machine because it keeps the analysis portion same for all the compilers.
- The synthesis phase of the compiler is varying according to the target machine.
It is closer to the source code. It can be easily generated using source code. Code modification can easily improve the source code’s performance. It is less preferred for the optimization of the target machine.
It is closer to the target machine. It is suitable for a machine-independent task like register allocation and instruction selection.
Directed Acyclic Graph
A directed acyclic graph (called a DAG) for an expression identifies the expression’s subexpressions that occur more than once. A DAG can be constructed similar to a syntax tree.
Let us see how we can construct a DAG for any expression:
The atomic operands will be the leaves of a DAG, whereas operators will be the interior node.
a + a * (b – c) + (b – c) * d
As we can see that, a appears twice in the expression, so a has two parents. The two occurrences of the common subexpression b-c are represented by one node “-.” This node has two parents, representing its two uses in the subexpressions a*(b-c) and (b-c)*d. There will be only one parent for the node b and c because the common subexpression b-c use both nodes.