----------------------------- a5ss Static Single Assignment ----------------------------- 1 : |: 2 i = 0; | i_4 = 0; 3 goto ; | goto ; 4 | 5 : |: 6 if (a > b) | if (a_2 > b_7(D)) 7 goto ; | goto ; 8 else | else 9 goto ; | goto ; 10 | 11 : |: 12 a = b + n; | a_8 = b_7(D) + n_6(D); 13 goto ; | goto ; 14 | 15 : |: 16 a = b * n; | a_9 = b_7(D) * n_6(D); 17 | 18 : |: 19 i = i + 1; | # a_1 = PHI 20 | i_10 = i_3 + 1; 21 | 22 : |: 23 if (i < n) | # a_2 = PHI 24 goto ; | # i_3 = PHI 25 else | if (i_3 < n_6(D)) 26 goto ; | goto ; 27 | else 28 | goto ; 29 | 30 : |: 31 return; | return; 32 | 33 } |} 1 Local variables are suffixed with a unique number which represents the assignment. For example, `a_2' refers to the usage of variable `a' and the only assignment which reaches this point is the assignment `a_2'. Variables that are likely to be used before any assignment are suffixed with `(D)' to indicate that the assignment was implicit in the declaration. This happens to both uninitialized local variables and formal parameters. 2 A PHI node merges assignments from different paths and creates a new assignment. For example: # a_1 = PHI indicates that if the control reaches here from basic block 4 then use the value of a_8; otherwise if the control reaches here from basic block 5 then use the value of a_9. 3 A switch statement can result in a merge of more than two paths (and hence possibly more than two assignments). Consider: int main() { int a, b; switch (a) { case 1: b = 2; break; case 2: b = 3; break; case 3: b = 4; case 4: b = 5; break; case 5: case 6: b = 6; break; default: b = 7; } return b; } In this case the PHI node at the end of the switch statement will merge multiple assignments such as: # b_1 = PHI