glsl: Fix handling of function calls inside nested loops.

Previously, when visiting an ir_call, loop analysis would only mark
the innermost enclosing loop as containing a call.  As a result, when
encountering a loop like this:

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

it would incorrectly conclude that the outer loop ran three times.
(This is not certain; if foo() modifies i, then the outer loop might
run more or fewer times).

Fixes piglit test "vs-call-in-nested-loop.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 11:06:43 -08:00
parent 877db5a792
commit cb38a0dc0a

View file

@ -223,14 +223,14 @@ loop_analysis::visit(ir_loop_jump *ir)
ir_visitor_status
loop_analysis::visit_enter(ir_call *ir)
{
/* If we're not somewhere inside a loop, there's nothing to do. */
if (this->state.is_empty())
return visit_continue;
/* Mark every loop that we're currently analyzing as containing an ir_call
* (even those at outer nesting levels).
*/
foreach_list(node, &this->state) {
loop_variable_state *const ls = (loop_variable_state *) node;
ls->contains_calls = true;
}
loop_variable_state *const ls =
(loop_variable_state *) this->state.get_head();
ls->contains_calls = true;
return visit_continue_with_parent;
}