Skip to content

Draft: RFC: Move terminating if-statement to the bottom of the loop

Ian Romanick requested to merge idr/mesa:wip/loop-backward-branch into main

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.

  1. 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++) {
        ...
    }
  1. 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.

Merge request reports