15.3. Dataflow Analysis

Dataflow analysis examines how information flows through a flowgraph from one block to another.


Liveness analysis (Dragon Book, section 9.2.5)

A variable is live at a particular point in a basic block if its value might be used later, on some path in the flowgraph.

A variable might be stored in a register while a basic block is being computed, to be stored back into memory at the end of the block. But a variable that is not live does not need to be stored.

Performing a liveness analysis is fairly simple using the following concepts.

  1. in[B] is the set of all variables that are live at entry to basic block B.

  2. out[B] is the set of all variables that are live at the end of basic block B.

  3. def[B] is the set of all variables that are assigned new values in basic block B before they are used in B.

  4. use[B] is the set of all variables that are used in B before they are assigned any value.

Because of the straight-line nature of a basic block, computing def[B] and use[B] is straightforward. Start with both sets empty and sweep through B. At instruction x = y + z:

  1. If y is not in def[B] then add y to use[B]. Do similarly for z.

  2. If x is not in use[B] then add x to def[B].

A successor of basic block B is any basic block A where there is an edge pointing from B to A. Define succ[B] to be the set of all successors of B.

in[B] and out[B] satisfy the following equations.

in[exit] =
in[B] = use[B] ∪ (out[B] − def[B])
out[B] = S ∈ succ[B] in[S])

To compute in[B] and out[B], begin with in[B] = out[B] = ∅ for all blocks B.

The final in[B] and out[B] sets are computed using fixed-point iteration. Using the above equations, compute new values for in[B] and out[B] based on the old values. Keep doing that until no change occurs.


Reaching definitions

Dataflow analysis is what allows a compiler to detect use of a variable before it is defined.

The Dragon Book shows how to do that in Section 9.2.4.