From: Timothy Arceri Date: Thu, 21 Sep 2017 03:55:56 +0000 (+1000) Subject: glsl: check if induction var incremented before use in terminator X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=d24e16fe1f63d8f666dd57cfddf8340d439b391a;p=mesa.git glsl: check if induction var incremented before use in terminator do-while loops can increment the starting value before the condition is checked. e.g. do { ndx++; } while (ndx < 3); This commit changes the code to detect this and reduces the iteration count by 1 if found. V2: fix terminator spelling Reviewed-by: Nicolai Hähnle Reviewed-by: Elie Tournier Tested-by: Dieter Nützel --- diff --git a/src/compiler/glsl/loop_analysis.cpp b/src/compiler/glsl/loop_analysis.cpp index 81a07f78f8f..78279844dc8 100644 --- a/src/compiler/glsl/loop_analysis.cpp +++ b/src/compiler/glsl/loop_analysis.cpp @@ -171,6 +171,40 @@ calculate_iterations(ir_rvalue *from, ir_rvalue *to, ir_rvalue *increment, return (valid_loop) ? iter_value : -1; } +static bool +incremented_before_terminator(ir_loop *loop, ir_variable *var, + ir_if *terminator) +{ + for (exec_node *node = loop->body_instructions.get_head(); + !node->is_tail_sentinel(); + node = node->get_next()) { + ir_instruction *ir = (ir_instruction *) node; + + switch (ir->ir_type) { + case ir_type_if: + if (ir->as_if() == terminator) + return false; + break; + + case ir_type_assignment: { + ir_assignment *assign = ir->as_assignment(); + ir_variable *assignee = assign->lhs->whole_variable_referenced(); + + if (assignee == var) { + assert(assign->condition == NULL); + return true; + } + + break; + } + + default: + break; + } + } + + unreachable("Unable to find induction variable"); +} /** * Record the fact that the given loop variable was referenced inside the loop. @@ -582,6 +616,10 @@ loop_analysis::visit_leave(ir_loop *ir) t->iterations = calculate_iterations(init, limit, lv->increment, cmp); + if (incremented_before_terminator(ir, var, t->ir)) { + t->iterations--; + } + if (t->iterations >= 0 && (ls->limiting_terminator == NULL || t->iterations < ls->limiting_terminator->iterations)) {