SSA - Single Static Assignment
Problem and Motivation:
For constant propagation analysis, we have to store the mapping for every program point . Thus the space requirement is .
To reduce this storage space we can do flow-insensitive constant propagation where instead of storing the analysis for each program point we do it for the entire CFG.
So we solve the single equation that combines the program analysis for each program point into one
The above equation joins the analysis information for each program point into a single combined analysis information.
This leads to the loss of precision.
SSA - Single Static Assignment provides a hack to work around the imprecision.
SSA - Single Static Assignment:
In flow insensitive analysis. Each variable has a single static assignment.
So every occurence of an assignment to the same variable () is changed to an assignment to a numbered variable. ()
In expression where the variable is used is replaced with a that selects the appropriate version of the variable for the expression
Unconditional Constant Propagation in SSA:
Domain:
Transfer Functions:
Solve Single Inequality by fixpoint iteration:
Conditional Constant Propagation on SSA:
Considers control flow as well. Perform two analysis in parallel.
Cooperation between two domains:
Two transfer functions per program point:
Solve system of equations:
This analysis is also known as SCCP - Sparse Conditional Constant Propagation.
function semantics:
-functions are:
- evaluated simultaneously \ in parallel,
- always placed at the beginning of the block
- are non-strict, meaning that it does not require all the inputs to be defined.
If some of the inputs are unavailable to the function then it simply does not consider it for the evaluation
Consider the following code example (left) that can be transformed into code blocks in SSA form (right)
x = ...
y = ...
while(some_condition):
t = x;
x = y;
y = t;
...
x1 = valx1
y1 = valy1
while(condition)
x3 = phi(x1, x2)
y3 = phi(y1, y2)
t = x3
x2 = y3
y2 = t
...
After using copy propagation analysis we can reduce the SSA form to following
x1 = valx1
y1 = valy1
while (condition)
x3 = phi(x1, y3)
y3 = phi(y1, x3)
...
The value that the function evaluates to depends on the edge that the control takes to enter the block.
The above code can be understood as following
g() {
x = val;
y = val;
f(x, y)
}
f(x, y) {
t = x;
x = y;
y = t;
if (condition)
f(x, y)
}
So here depending which function calls the method the input for th x and y arguments is decided. This in essence describes the working of the function.
Where to place functions?
- SSA program has the same semantics as the original program
- Every variable has a single program point where it is defined
- Every use of an SSA variable is dominated by its definition
Join Points:
Definition:
To paths and converge at a program point if
- The path is disjoint at all other points
The above points mean: Starting from two distinct points if i reach at a common point with no other intersection occuring before than this common point is the join point.
A program point needs a function for a variable if it is the convergence point of two program points and each having a definition for variable
Formally,
is the set of program points where functions have to be placed for non SSA variable
Now we know where to place the functions. but how to efficiently find such program points?
Dominance Frontiers:
Definition:
the dominance frontier for a program point is defined as the set of all program points such that is not dominated by but all the predecessors of are.
Theorem:
Note: is the iterative dominance frontier. We start with a program point that has a dominance frontier. We take one node from the frontier and find its dominance frontier, eventually we will
There is a proof for the above stated theorem which can be referred here: https://www.youtube.com/watch?v=UjXTrWjikBQ&list=PLSTUeTS8gQK6eExwf5AMvkxYD6pIWto0w&index=12
Computing Dominance Frontier:
Efficiently computed by a bottom up traversal over the dominance tree:
- Each control flow successor of is either dominated by or not
- If not dominated then it belongs to the
- If yes then we look at the dominance frontier of , for nodes that belong to and are not dominated by are also in
SSA Construction Algorithm:
- Compute Dominance Tree
- Compute Dominance frontiers for each block.
- Compute iterated dominance frontiers for all definitions of each variable. We place functions for variable at their respective join points.
- Rename variables:For every use of a variable we find the lowest definition in the dominance tree and use that definition for the variable.
