diff options
author | Timothy Arceri <[email protected]> | 2017-09-04 13:11:49 +1000 |
---|---|---|
committer | Timothy Arceri <[email protected]> | 2017-10-10 10:05:37 +1100 |
commit | 646621c66da946aa06482e70d8cbc149756c477c (patch) | |
tree | 7d1251ce36d11af5d955d9fc187152284b54089c /src/compiler/glsl/loop_analysis.h | |
parent | d24e16fe1f63d8f666dd57cfddf8340d439b391a (diff) |
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 <[email protected]>
Tested-by: Dieter Nützel <[email protected]>
Diffstat (limited to 'src/compiler/glsl/loop_analysis.h')
-rw-r--r-- | src/compiler/glsl/loop_analysis.h | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/src/compiler/glsl/loop_analysis.h b/src/compiler/glsl/loop_analysis.h index 99b6bf75638..4e110018461 100644 --- a/src/compiler/glsl/loop_analysis.h +++ b/src/compiler/glsl/loop_analysis.h @@ -55,7 +55,7 @@ public: class loop_variable *get(const ir_variable *); class loop_variable *insert(ir_variable *); class loop_variable *get_or_insert(ir_variable *, bool in_assignee); - class loop_terminator *insert(ir_if *); + class loop_terminator *insert(ir_if *, bool continue_from_then); /** @@ -210,6 +210,9 @@ public: * terminate the loop (if that is a fixed value). Otherwise -1. */ int iterations; + + /* Does the if continue from the then branch or the else branch */ + bool continue_from_then; }; |