Draft: RFC: Move terminating if-statement to the bottom of the loop
This is more of an early "RFC" MR than anything else. I haven't done much with loop transformations in NIR, so I'm especially looking for feedback from @tarceri and others about my approach there.
Right now, this only processes the most basic kind of loop. Simple loops with a single break, no continues, and a known loop trip count. These loops are very easy to move the single terminator to the bottom. Even that requires a small pile of code.
Because the scope is so limited, very few shaders are affected. I was honestly hoping for a few more Vulkan shaders. I haven't done any analysis on the loops that are rejected by the pass.
There are (at least) two directions to go from here.
- Try to apply to a broader class of loops. It shouldn't be to hard to apply this transform to any loop terminator that is guaranteed to execute at least once and doesn't contain a
continue
. The loop might not necessarily execute once, but the transformation can be applied if the limiting termintor must be true at least once. Something like:
for (i = 0; i < 10 && some_condition; i++) {
...
}
- Convert "count up" loops where the loop counter is only used for loop control (it should have exactly three uses: the phi, the compare, and the increment) into "count down" loops. On some platforms this can make it possible to eliminate the comparison instruction. I guess this transformation is orthogonal and could be applied even without moving the terminator. In some cases the comparison can be a bit more expensive because it might have to stall waiting for the increment. A related optimization would convert the loop counter to a
uint16_t
when possible.