glsl: Fix loop analysis of nested loops.

Previously, when visiting a variable dereference, loop analysis would
only consider its effect on the innermost enclosing loop.  As a
result, when encountering a loop like this:

    for (int i = 0; i < 3; i++) {
      for (int j = 0; j < 3; j++) {
        ...
        i = 2;
      }
    }

it would incorrectly conclude that the outer loop ran three times.

Fixes piglit test "vs-inner-loop-modifies-outer-loop-var.shader_test".

Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
This commit is contained in:
Paul Berry
2013-11-28 10:48:37 -08:00
parent 2e060551bd
commit 877db5a792
2 changed files with 29 additions and 17 deletions

View File

@@ -167,8 +167,11 @@ public:
/** Are all variables in the RHS of the assignment loop constants? */
bool rhs_clean;
/** Is there an assignment to the variable that is conditional? */
bool conditional_assignment;
/**
* Is there an assignment to the variable that is conditional, or inside a
* nested loop?
*/
bool conditional_or_nested_assignment;
/** Reference to the first assignment to the variable in the loop body. */
ir_assignment *first_assignment;
@@ -197,7 +200,7 @@ public:
{
const bool is_const = (this->num_assignments == 0)
|| ((this->num_assignments == 1)
&& !this->conditional_assignment
&& !this->conditional_or_nested_assignment
&& !this->read_before_write
&& this->rhs_clean);
@@ -214,7 +217,8 @@ public:
return is_const;
}
void record_reference(bool in_assignee, bool in_conditional_code,
void record_reference(bool in_assignee,
bool in_conditional_code_or_nested_loop,
ir_assignment *current_assignment);
};