I implemented a generic data flow analysis framework that supports multiple analyses by designing a reusable structure for different types of data flow problems. The code includes:
This code implements a liveness analysis tool for Bril programs. It builds a control flow graph (CFG) from the program’s instructions, computes the in and out sets for each basic block based on variable usage (using the gen and kill sets), and then prints the liveness information for each block. The analysis helps track which variables are live at various points in the program.
Explanation: In the entry block, a, b, and d are live after the block because they are used later in the program. The variable x is defined but not used, so it is not live after entry.
Block: b2
Expected:
In: [‘a’, ‘b’]
Out: [‘b’, ‘c’, ‘d’]
Explanation: In block b2, a and b are used to compute c. d is redefined within this block, but the new value of d is used later in the done block, so d is live after b2. Additionally, b is live after b2 because it is used in the done block. c is defined in b2 and used later, so it is also live after this block.
Block: b3
Expected:
In: [‘b’, ‘d’]
Out: [‘b’, ‘c’, ‘d’]
Explanation: In block b3, b and d are live because they are used in the done block. c is redefined in b3 and is used in the done block, so it is live after b3.
Block: done
Expected:
In: [‘b’, ‘c’, ‘d’]
Out: []
Explanation: In the done block, the variables b, c, and d are used in the computation of result. After this block, there are no live variables because the function returns, so the Out set is empty.
Conclusion:
The results generated by the liveness analysis are correct based on the Bril code provided. Each block correctly identifies the variables that are live before and after it, based on the definitions and uses of those variables within the block and across the program.
Hardest Part of the Task and How We Addressed It
The hardest part was ensuring that the liveness analysis results were correctly generalized without hardcoding specific variables. The challenge was to accurately compute the gen and kill sets for each block and propagate liveness across blocks.
How We Addressed It:
Generalized Propagation: We avoided manual exclusions and relied on computing gen and kill sets to ensure only the necessary variables appeared in the In and Out sets.
Fixed-Point Iteration: Liveness information was iteratively propagated until no changes occurred, ensuring accurate results.
Validation: We compared the results for each block with expected outcomes to ensure correctness.
This approach ensured a generalized and correct liveness analysis.