----------------------------- A-5 Static Single Assignment ----------------------------- | int main() |main () { |{ int a, b, c, d, n; | int n; | int d; | int c; | int b; | int a; | |: d = 10; | d_3 = 10; if (c > d) { | if (c_4(D) > d_3) a = 2; | goto ; b = 2; | else } else { | goto ; a = 2; | b = 3; |: } | a_5 = 2; | b_6 = 2; | goto ; | |: | a_7 = 2; | b_8 = 3; | |: | # a_1 = PHI | # b_2 = PHI c = a + b; | c_9 = a_1 + b_2; | return; | } |} Solutions --------- 1 Local variables are suffixed with a unique number which represents the assignment. For example, `d_3' refers to the usage of variable `d' and the only assignment which reaches this point is the assignment `d_3'. 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. For example, variable `c' is used as `c_4(D)' in the `if' condition. 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 3 then use the value of a_5; otherwise if the control reaches here from basic block 4 then use the value of a_7. 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