On Mon Jan 29 14:33:20 2024 +0000, Giovanni Mascellani wrote:
Mmmh, what you are describing seems more what is happening in `materialize_ssa_to_temps()`: there SSA registers are converted to TEMP registers, and PHI nodes must be converted to MOV/MOVC because they're not allowed with TEMPs. So in practice that transformation does something like this:
label l10 ... add sr20, sr18, sr19 branch l11 label l11 phi sr21, l9, sr20, ... ...
is converted to
label l10 ... add r20, r18, r19 mov r21, r20 branch l11 label l11 [phi is removed] ...
In other words, not only we're converting PHI to MOV/MOVC, but we're also moving it before than BRANCH (otherwise the predecessor information is lost). The structurizer is dispatched after this has already happened, so there are no PHIs nor SSAs in sight. It converts this:
label l10 ... branch l11
to something like this:
# Introduce a fresh TEMP to represent the currently executing block r100 = 1 loop switch r100 ... case l(10) # Do whatever block l10 is supposed to do mov r100, l(11) break ... endswitch endloop
Of course the MOV becomes a MOVC if the BRANCH was conditional. So now the program is structured in the sense of TPF programs, and it can be passed to the CF flattener pass and then to the SPIR-V backend.
When I tested materialisation of SSA to TEMP a while ago I didn't use MOVC, so I'm wondering if it's needed only because of the structuriser. For example, this:
``` label l1 ... branch sr1, l2, l3 label l2 mov sr2, v0.x branch l4 label l3 mov sr3, v1.x branch l4 label l4 phi sr5, sr2, l2, sr3, l3 ```
Becomes:
``` label l1 ... branch r0.x, l2, l3 label l2 mov r1.x, v0.x branch l4 label l3 mov r1.x, v1.x branch l4 label l4 ```