Edge Rewrite
// HTMLRewriter · presentation

This page was redesigned at the edge.

Cloudflare fetched the original article and streamed it through HTMLRewriter to apply an entirely new visual system without rebuilding the source page.

Jump to content

Reaching definition

From Wikipedia, the free encyclopedia

In compiler theory, a reaching definition is a definition of a variable that may reach a particular point in a program without another definition of the same variable occurring along the intervening control-flow path.[1] For example, in the following code:

d1 : y := 3
d2 : x := y

d1 is a reaching definition for d2. In the following, example, however:

d1 : y := 3
d2 : y := 4
d3 : x := y

d1 is no longer a reaching definition for d3, because d2 kills its reach: the value defined in d1 is no longer available and cannot reach d3.

As analysis

[edit]

The similarly named reaching definitions analysis is a data-flow analysis that statically determines which definitions may reach a given point in the code. Because of its simplicity, it is often used as a canonical example of data-flow analysis in compiler textbooks.[2] The data-flow confluence operator used is set union, and the analysis is a forward data-flow analysis. Reaching definitions can be used to compute use-def chains.[3]

The data-flow equations used for a given basic block in reaching definitions are:

In other words, the set of reaching definitions going into consists of all reaching definitions coming from 's predecessors, . consists of the basic blocks with control flow edges leading into . The reaching definitions coming out of are the reaching definitions entering , minus those whose variables are redefined in , together with any new definitions generated within .[4]

For a generic instruction, we define the and sets as follows:

  • , a set containing the definition generated by the instruction
  • , the set of other definitions of killed by the instruction

where is the set of all definitions that assign to the variable . Here is a unique label attached to the assigning instruction; thus, the domain of values in reaching definitions consists of these instruction labels.

Worklist algorithm

[edit]

Reaching definitions are usually calculated using an iterative worklist algorithm.[5]

Input: control-flow graph CFG = (Nodes, Edges, Entry, Exit)

// Initialize
for all CFG nodes n in N,
    OUT[n] = emptyset; // can optimize by OUT[n] = GEN[n];

// put all nodes into the changed set
// N is all nodes in graph,
Changed = N;

// Iterate 
while (Changed != emptyset)
{
    choose a node n in Changed;
    // remove it from the changed set
    Changed = Changed -{ n };

    // init IN[n] to be empty
    IN[n] = emptyset;

    // calculate IN[n] from predecessors' OUT[p]
    for all nodes p in predecessors(n)
         IN[n] = IN[n] Union OUT[p];

    oldout = OUT[n]; // save old OUT[n]
    
    // update OUT[n] using transfer function f_n ()
    OUT[n] = GEN[n] Union (IN[n] -KILL[n]);

    // any change to OUT[n] compared to previous value?
    if (OUT[n] changed) // compare oldout vs. OUT[n]
    {    
        // if yes, put all successors of n into the changed set
        for all nodes s in successors(n)
             Changed = Changed U { s };
    }
}

See also

[edit]

References

[edit]
  1. ↑ Aho, Alfred V.; Sethi, Ravi & Ullman, Jeffrey D. (1986). Compilers: Principles, Techniques, and Tools. Addison Wesley. ISBN 0-201-10088-6.
  2. ↑ Cooper, Keith D. & Torczon, Linda (2005). Engineering a Compiler. Morgan Kaufmann. ISBN 1-55860-698-X.
  3. ↑ Muchnick, Steven S. (1997). Advanced Compiler Design and Implementation. Morgan Kaufmann. ISBN 1-55860-320-4.
  4. ↑ Nielson, Flemming; Nielson, Hanne Riis; Hankin, Chris (2005). Principles of Program Analysis. Springer. ISBN 3-540-65410-0.
  5. ↑ Cooper, Keith D. & Torczon, Linda (2005). Engineering a Compiler. Morgan Kaufmann. ISBN 1-55860-698-X.

Further reading

[edit]