Lecture notes 20210609 SSA 3

Review

Consider the following CFG:
        1 --> 2
        2 --> 3, 11
        3 --> 4, 8
        4 --> 5
        5 --> 6
        6 --> 5, 7
        7 --> 2
        8 --> 9
        9 --> 6, 10
        10 --> 8
Please draw its dominance tree.
Suppose S = [1; 3; 4; 7], compute the iterated dominance frontier of S.

Desctructing SSA form

When freshly constructed, an SSA code is conventional (we will explain that later) and its destruction is straightforward: one simply has to rename all PHI-related variables (source and destination operands of the same Phi-function) into a unique representative variable. Then, each PHI-function should have syntactically identical names for all its operands, and thus can be removed to coalesce the related live-ranges.
Here, we say that x and y are PHI-related to one another if they are referenced by the same PHI-command, i.e., if x and y are either parameters or defined by the PHI-command. We refer to a set of PHI-related variables as a PHI-web, i.e. a PHI-web is an equivalence class of the reflexive transitive closure of the PHI-related relation. The PHI-webs discovery algorithm is straightforward and efficient based on the union-find pattern:
  • (1) For each variable v
  • (1.1) Let phiweb(v) be the singleton set containing v
  • (2) For each PHI-command a0 = PHI(a1, a2, ..., an)
  • (2.1) For i in 1, 2, 3, ..., n
  • (2.1.1) Union phiweb(a0) and phiweb(ai)
We call an SSA code conventional, if all variables of a PHI-web have non-overlapping live-ranges.

Making nonconventional SSA form conventional

Consider the following program.
      CFG:
      1 --> 2, 3
      2 --> 4
      3 --> 4

      Original Instructions:
      1:
         a <-- ...
         tmp <-- a
      2:
         a <- a
      3:
         a <- a + 1
      4:
         ... <- a
         ... <- tmp
    
      Conventional SSA:
      1:
         a1 <-- ...
         tmp <-- a1
      2:
         a2 <- a1
      3:
         a3 <- a1 + 1
      4:
         a4 <- PHI (a2a3)
         ... <- a4
         ... <- tmp

      Transformed SSA:
      1:
         a1 <-- ...
      2:
      3:
         a3 <- a1 + 1
      4:
         a4 <- PHI (a1a3)
         ... <- a4
         ... <- a1
It shows that an SSA form may be non-conventional after some transformation. In order to destruct such kind of SSA, we need to add new variables so that any two variables in a PHI-web will not interfere with each other. This is not hard for the sample program above.
      After adding new variables:
      1:
         a1 <-- ...
      2:
         a1' <- a1
      3:
         a3 <- a1 + 1
         a3' <- a3
      4:
         a4 <- PHI (a1'a3')
         ... <- a4
         ... <- a1

Partial redundancy elimination

The following examples shows typical situations of partial redundancy elimination.
      CFG:
        1 --> 2, 3
        2 --> 4
        3 --> 4
      Instructions (before optimization):
        2: ... <-- a + b
        4: ... <-- a + b
      Instructions (after optimization):
        2: ... <-- a + b
        3: ... <-- a + b
      CFG:
        1 --> 2
        2 --> 2, 3
      Instructions (before optimization):
        2: ... <-- a + b
      Instructions (after optimization):
        1: ... <-- a + b
This can be done by insertion-and-deletion.
      Example 1:
      Annotating the expression:
        2: ... <-- a + b [h]
        4: h <-- PHI (hh)
           ... <-- a + b [h]
      Inserting expressions:
        2: ... <-- a + b [h]
        3: ... <-- a + b [h]
        4: h <-- PHI (hh)
           ... <-- a + b [h]
      deleting expressions:
        2: ... <-- a + b [h]
        3: ... <-- a + b [h]
        4: h <-- PHI (hh)
      Example 2:
      Annotating the expression:
        2: h <-- PHI (hh)
           ... <-- a + b [h]
      Inserting expressions:
        1: ... <-- a + b [h]
        2: h <-- PHI (hh)
           ... <-- a + b [h]
      deleting expressions:
        1: ... <-- a + b [h]
        2: h <-- PHI (hh)

(* 2021-06-09 07:55 *)