Open In App

Directed Acyclic Graph in Compiler Design (with examples)

Last Updated : 26 May, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

In compiler design, a Directed Acyclic Graph (DAG) plays a crucial role in representing expressions and optimizing code. A DAG is a graph containing directed edges but no cycles, ensuring no path leads back to the starting node. DAGs are particularly useful in eliminating redundant computations and detecting common sub-expressions, making program execution more efficient. This graphical representation helps optimize the Intermediate Code Generation phase of a compiler.

What is a Directed Acyclic Graph?

The Directed Acyclic Graph (DAG) is used to represent the structure of basic blocks, visualize the flow of values between basic blocks, and provide optimization techniques in basic blocks. To apply an optimization technique to a basic block, a DAG is a three-address code generated as the result of intermediate code generation.

  • Directed acyclic graphs are a type of data structure and they are used to apply transformations to basic blocks.
  • The Directed Acyclic Graph (DAG) facilitates the transformation of basic blocks.
  • DAG is an efficient method for identifying common sub-expressions.
  • It demonstrates how the statement's computed value is used in subsequent statements.

Examples of Directed Acyclic Graph

Direct Acyclic Graph

Directed Acyclic Graph Characteristics

A Directed Acyclic Graph for Basic Block is a directed acyclic graph with the following labels on nodes.

  • The graph's leaves each have a unique identifier, which can be variable names or constants.
  • The interior nodes of the graph are labelled with an operator symbol.
  • In addition, nodes are given a string of identifiers to use as labels for storing the computed value.
  • Directed Acyclic Graphs have their own definitions for transitive closure and transitive reduction.
  • Directed Acyclic Graphs have topological orderings defined.

Algorithm for Construction of Directed Acyclic Graph

There are three possible scenarios for building a DAG on three address codes:

Case 1 : x = y op z
Case 2 : x = op y
Case 3  : x = y

Directed Acyclic Graph for the above cases can be built as follows :

Step 1:

  • If the y operand is not defined, then create a node (y).
  • If the z operand is not defined, create a node for case(1) as node(z).

Step 2:

  • Create node(OP) for case(1), with node(z) as its right child and node(OP) as its left child (y).
  • For the case (2), see if there is a node operator (OP) with one child node (y).
  • Node n will be node(y)  in case (3).

Step 3:
Remove x from the list of node identifiers. Step 2: Add x to the list of attached identifiers for node n.

Example 1:

T0 = a + b        â†’Expression 1
T1 = T0 + c   →Expression 2
d = T0 + T1         →Expression 3

Expression 1 :                   T0 = a + b

Direct Acyclic Graph

Expression 2:                    T1 = T0 + c

Direct Acyclic Graph

 Expression 3 :                          d = T0 + T1    

DIrect Acyclic Graph
Final Directed acyclic graph

Example 2:

T1 = a + b      
T2 = T1 + c     
T3 = T1 x T2    

Direct Acyclic Graph

Example 3:

T1 = a + b
T2 = a - b
T3 = T2 * T1
T4 = T1 - T3
T5 = T4 + T3

Direct Acyclic Graph
Final Directed acyclic graph

Example 4:

a = b x c
d = b
e = d x c
b = e
f = b + c
g = f + d

Directed-Acyclic-Graph-
Example 4 - Directed Acyclic Graph

Example 5:

  •  T1 : = 4*I0
  • T2 : = a[T1]
  • T3 : = 4*I0
  • T4 : = b[T3]
  • T5 : = T2 * T4
  • T6 : = prod + T5
  • prod : = T6
  • T7 : = I0 + 1
  • I0 : = T7
  • if I0 <= 20 goto 1
FInal Direct Acyclic Graph
Final Directed acyclic graph

Application of Directed Acyclic Graph

  • Identification of Common Subexpressions : A DAG helps detect repeated subexpressions in code. This enables efficient common subexpression elimination.
  • Tracking Variable Usage : It identifies variables used within the block and those computed externally. This aids in understanding data dependencies.
  • Statement Value Tracking : DAGs show which statements produce values used outside the block. This supports code optimization and preservation.
  • Code Representation : Code can be modeled as a DAG showing inputs and outputs of operations. This helps visualize and optimize computations.
  • Reactive Value Systems : In some languages, values are linked via a DAG. Changing one value triggers updates in all dependent values.

Next Article
Article Tags :

Similar Reads