In DXIL handling there will be many more cases analogous to those which shader_normaliser_new_instructions() serves. I think it's less hazardous to eliminate the need to repeat the `count + 1` formula every time.
We could perhaps also rename shader_normaliser_new_instructions() to something that makes the difference more obvious.
Either way, I think the more fundamental discussion is about what we want the interface for IR manipulation to look like. We can talk about the implementation later, but I'd like to be able to argue about transformation passes on the level of "replace these instructions with these other instructions", "insert these instructions after this one", "delete these instructions", and so on, rather than on the level of carefully manipulating entries in an array.
I'm sure the people working on the HLSL parts of vkd3d-shader could provide some suggestions about what works and what doesn't, but for a comparison, look at e.g. lower_abs() for a trivial example, or lower_return() and lower_calls() for more complicated examples that are perhaps conceptually closer to what we're doing here. HLSL IR is a bit higher level than what we have here, and of course stored in a different way, but I imagine that in terms of API it's in the general direction of where we'd like to go.
The special MOV handler tracks the fork/join instance id. Theoretically fxc could use a FORKINSTID register directly as a register address, but instead it emits `mov r0, vForkInstanceId` and then uses r0 as the address.
Sure, but why is that a problem? Wouldn't "mov r0, vForkInstanceId" be replaced with "mov r0, <constant>", after which using "r0" for addressing should do the right thing?