On Thursday, 2017-09-14 14:47:49 +1000, Timothy Arceri wrote: > 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. > --- > src/compiler/glsl/loop_analysis.cpp | 38 > +++++++++++++++++++++++++++++++++++++ > 1 file changed, 38 insertions(+) > > diff --git a/src/compiler/glsl/loop_analysis.cpp > b/src/compiler/glsl/loop_analysis.cpp > index b9bae43536..8a0425d185 100644 > --- a/src/compiler/glsl/loop_analysis.cpp > +++ b/src/compiler/glsl/loop_analysis.cpp > @@ -25,20 +25,54 @@ > #include "loop_analysis.h" > #include "ir_hierarchical_visitor.h" > > static bool is_loop_terminator(ir_if *ir); > > static bool all_expression_operands_are_loop_constant(ir_rvalue *, > hash_table *); > > static ir_rvalue *get_basic_induction_increment(ir_assignment *, hash_table > *); > > +static bool > +incremented_before_termionator(ir_loop *loop, ir_variable *var,
s/termionator/terminator/ :) (don't know enough to really review though, sorry) > + 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. > * > * \arg in_assignee is true if the reference was on the LHS of an assignment. > * > * \arg in_conditional_code_or_nested_loop is true if the reference occurred > * inside an if statement or a nested loop. > * > * \arg current_assignment is the ir_assignment node that the loop variable > is > @@ -436,20 +470,24 @@ loop_analysis::visit_leave(ir_loop *ir) > > ir_variable *var = counter->variable_referenced(); > > ir_rvalue *init = find_initial_value(ir, var); > > loop_variable *lv = ls->get(var); > if (lv != NULL && lv->is_induction_var()) { > t->iterations = calculate_iterations(init, limit, lv->increment, > cmp); > > + if (incremented_before_termionator(ir, var, t->ir)) { > + t->iterations--; > + } > + > if (t->iterations >= 0 && > (ls->limiting_terminator == NULL || > t->iterations < ls->limiting_terminator->iterations)) { > ls->limiting_terminator = t; > } > } > break; > } > > default: > -- > 2.13.5 > _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev