If a resource is live on entry to an extended basic block and if the resource’s value can come from multiple sources, the extended basic block has a “phi node” that collects together these multiple sources. The phi node conceptually has one input for each incoming edge of the extended basic block, with the input specifying the value of the resource on that edge. For example, suppose a function contains the following RTL:
;; Basic block bb3 … (set (reg:SI R1) (const_int 0)) ;; A (set (pc) (label_ref bb5)) ;; Basic block bb4 … (set (reg:SI R1) (const_int 1)) ;; B ;; Fall through ;; Basic block bb5 ;; preds: bb3, bb4 ;; live in: R1 … (code_label bb5) … (set (reg:SI R2) (plus:SI (reg:SI R1) …)) ;; C
The value of R1 on entry to block 5 can come from either A or B. The extended basic block that contains block 5 would therefore have a phi node with two inputs: the first input would have the value of R1 defined by A and the second input would have the value of R1 defined by B. This phi node would then provide the value of R1 for C (assuming that R1 does not change again between the start of block 5 and C).
Since RTL is not a “native” SSA representation, these phi nodes simply collect together definitions that already exist. Each input to a phi node for a resource R is itself a definition of resource R (or is null if the resource is completely undefined for a particular incoming edge). This is in contrast to a native SSA representation like GIMPLE, where the phi inputs can be arbitrary expressions. As a result, RTL SSA phi nodes never involve “hidden” moves: all moves are instead explicit.
Phi nodes are represented as a
Each input to a phi node is represented as an