Skip to content

nir/nir_opt_move: allow to move uniforms and run in non-SSA form

Iago Toral requested to merge itoral/mesa:nir_move_uniform into main

On V3D the quality of the code we generate is significantly affected by how we decide to assign accumulators during register allocation, which is determined by liveness, favoring short-lived temps.

There are many shaders that end up doing a whole lot of uniform loads in bulk with their uses coming later, which is very inconvenient for our register allocation process because this increases uniform liveness and causes us to use accumulators less efficiently, leading to significant churn.

To fix this, we want to move uniforms right before their first use in the same block using the nir_opt_move pass, however, we want to do this after our NIR scheduler pass. This is a problem because nir_opt_move currently expects the shader to be in SSA form, but our NIR scheduler expects to run after the our-of-SSA pass.

This series makes a trivial change to nir_opt_move so it works in non-SSA form by skipping instructions that don't produce SSA defs, which allows us to run it after the NIR scheduling pass and the shader-db gains from this (and adding the capacity to move uniforms) are quite significant for us (see shader-db results in last patch).

I understand that NIR optimization passes are expected to run in SSA form though, so I wonder if this change is acceptable. If it is not, then I guess we will have to replicate this in the driver in some form since the gains for us are too important to miss and modifying the scheduler to not undo nir_opt_move doesn't look like a good path either, since the scheduler works in terms of instruction dependencies, execution delays and register pressure estimations, which are all concepts that are orthogonal to what we want to control here so it would be a bit of a kludge and probably we won't even get the same results.

Edited by Iago Toral

Merge request reports