glsl: make loop unrolling more like the nir unrolling path
authorTimothy Arceri <tarceri@itsqueeze.com>
Mon, 4 Sep 2017 03:11:49 +0000 (13:11 +1000)
committerTimothy Arceri <tarceri@itsqueeze.com>
Mon, 9 Oct 2017 23:05:37 +0000 (10:05 +1100)
commit646621c66da946aa06482e70d8cbc149756c477c
tree7d1251ce36d11af5d955d9fc187152284b54089c
parentd24e16fe1f63d8f666dd57cfddf8340d439b391a
glsl: make loop unrolling more like the nir unrolling path

The old code assumed that loop terminators will always be at
the start of the loop, resulting in otherwise unrollable
loops not being unrolled at all. For example the current
code would unroll:

  int j = 0;
  do {
     if (j > 5)
        break;

     ... do stuff ...

     j++;
  } while (j < 4);

But would fail to unroll the following as no iteration limit was
calculated because it failed to find the terminator:

  int j = 0;
  do {
     ... do stuff ...

     j++;
  } while (j < 4);

Also we would fail to unroll the following as we ended up
calculating the iteration limit as 6 rather than 4. The unroll
code then assumed we had 3 terminators rather the 2 as it
wasn't able to determine that "if (j > 5)" was redundant.

  int j = 0;
  do {
     if (j > 5)
        break;

     ... do stuff ...

     if (bool(i))
        break;

     j++;
  } while (j < 4);

This patch changes this pass to be more like the NIR unrolling pass.
With this change we handle loop terminators correctly and also
handle cases where the terminators have instructions in their
branches other than a break.

V2:
- fixed regression where loops with a break in else were never
  unrolled in v1.
- fixed confusing/wrong naming of bools in complex unrolling.

Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
Tested-by: Dieter Nützel <Dieter@nuetzel-hh.de>
src/compiler/glsl/loop_analysis.cpp
src/compiler/glsl/loop_analysis.h
src/compiler/glsl/loop_unroll.cpp