Lab 4: Lattice


Overview

In this lab, you will design several lattices and implement two program analysis algorithms based on lattice theory.

This lab consists of three parts: First, in part A, you will implement three classical lattices (diamond lattice, flat lattice, and powerset lattice). Second, in part B, you will implement a zero-value analysis algorithm based on the diamond lattice. Finally, in part C, you will restructure the liveness analysis algorithm based on the powerset lattice and implement a monotonic framework (if you are interested in it).

Getting Started

First check out the source we offered you for lab 4:

    $ git commit -am 'my solution to lab3'
    $ git fetch
    $ git checkout -b lab4 origin/lab4

these commands will first commit your changes to the lab3 branch of your local Git repository, and then create a local lab4 branch and check out the remote lab4 branch into the new local lab4 branch.

Again, you will need to merge your code from lab3 into the new lab4 branch:

    $ git merge lab3

Do not forget to resolve any conflicts before commiting to the local lab4 branch:

    $ git commit -am 'lab4 init'

You should first import the new lab4 code into your favorite IDE. There are a bunch of new files that you should browse through:

    cfg/lab4/LivenessLattice.java  liveness analysis framework
    cfg/lab4/ZeroAnalysis.java     zero analysis framework
    util/lattice/*                 lattice class definitions

Hand-in Procedure

When you finished this lab, zip you code and submit to the online teaching system.


Part A: Lattice

In compiler, lattice theory provides the mathematical foundation for data flow analysis. In this part, you'll learn and implement three types of lattices, and implement the operations to compute their least upper bounds.

Diamond Lattice

A diamond lattice is a common lattice structure in lattice theory that is shaped like a diamond and consists of four elements, as shown in the following figure. The intermediate layer of diamond lattice contains two elements, which are usually used to represent two different states in dataflow analysis. For example, in zero analysis, it can represent zero or non-zero.
         ⊤
       /    \
      M0     M1
       \    /
         ⊥
    
Exercise 1. Finish the code in the file util/lattice/DiamondLattice.java to compute the least upper bound of two diamond lattice.

Flat Lattice

A flat lattice is a type of complete lattice of height 2, in which the intermediate elements are some elements in a set that do not have a partial order relation with each other.
          ⊤
     /  /    \   \
    a1 a2   ...  an
     \  \    /   /
          ⊥
    
Exercise 2. Finish the code in the file util/lattice/FlatLattice.java to compute the least upper bound of two flat lattices.

Powerset Lattice

A powerset lattice is a complete lattice formed by all subsets of a finite set. In the dataflow analysis algorithms implemented in our previous labs, such as liveness analysis and reaching definitions analysis, their dataflow states can all be represented using powerset lattices.
        {a,b,c}
       /    |   \
     /      |     \
    {a,b} {a,c} {b,c}
    | \   /   \   / |
    |  \ /     \ /  |
    |  / \     / \  |
    {a}    {b}    {c}
      \     |     /
        \   |   /
            ∅
    
Exercise 3. Finish the code in the file util/lattice/PowerSetLattice.java to compute the least upper bound of two powerset lattices.

Part B: Zero Analysis

In this part of the lab, you will implement a zero analysis algorithm to determine whether variables (and expressions) in a program can evaluate to zero. This analysis uses a diamond lattice to represent the possible states of a variable’s value:

         ⊤
       /    \
      0     Z-0
       \    /
         ⊥
    
The analysis propagates abstract values forward along the control-flow graph using transfer functions and joins information at control-flow merges, terminating when the fixpoint is reached.

Exercise 4. Finish the code in the file cfg/lab4/ZeroAnalysis.java to implement the zero analysis algorithm.

Part C: Liveness Lattice

In this part of the lab, You will use the powerset lattice introduced in Exercise 3 to restructure the liveness analysis from Lab 2.

Exercise 5. Fill in the code in the file cfg/lab4/LivenessLattice.java to implement the liveness analysis based on lattice.

The monotonic framework is an abstract program analysis framework based on lattice theory. It ensures the termination and correctness of the analysis process by defining monotonic operations over partially ordered sets to represent program semantics. A monotonic framework generally consists of three components: a lattice, transfer functions, and a fixed-point iteration algorithm.

The Rustc compiler incorporates an exquisitely designed monotonic framework called Analysis trait. This framework primarily includes:

By defining the analysis domain, direction, and transfer function for the analysis process (the fixed-point algorithm is officially provided, requiring no user implementation), various program analysis algorithms can be implemented efficiently.

Challenge. Reference the design of the Analysis trait in Rustc and propose a monotonic framework for the dargon compiler to accommodate all data flow analysis algorithms in Lab 2.

Hand-in

This completes the lab. Remember to hand in your solution to the online teaching system.