glsl: Ignore loop-too-large heuristic if there's bad variable indexing

Graphics / Mesa 3D Graphics Library / Mesa - Kenneth Graunke [whitecape.org] - 11 April 2014 19:41 UTC

Many shaders use a pattern such as:

for (int i = 0; i < NUM_LIGHTS; i++) { ...access a uniform array, or shader input/output array... }

where NUM_LIGHTS is a small constant (such as 2, 4, or 8).

The expectation is that the compiler will unroll those loops, turning the array access into constant indexing, which is more efficient, and which may enable array splitting and other optimizations.

In many cases, our heuristic fails - either there's another tiny nested loop inside, or the estimated number of instructions is just barely beyond the threshold. So, we fail to unroll the loop, leaving the
variable indexing in place.

Drivers which don't support the particular flavor of variable indexing will call lower_variable_index_to_cond_assign(), which generates piles and piles of immensely inefficient code. We'd like to avoid generating that.

This patch detects unsupported forms of variable-indexing in loops, where the array index is a loop induction variable. In that case, it bypasses the loop-too-large heuristic and forces unrolling.

Improves performance in various microbenchmarks: Gl32PSBump8 by 47%, Gl32ShMapVsm by 80%, and Gl32ShMapPcf by 27%. No changes in shader-db.

v2: Check ir->array for being an array or matrix, rather than the ir_dereference_array itself.
v3: Fix and expand statistics in commit message.

857f3a6 glsl: Ignore loop-too-large heuristic if there's bad variable indexing.
src/glsl/loop_unroll.cpp | 61 +++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 58 insertions(+), 3 deletions(-)

Upstream: cgit.freedesktop.org


  • Share