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

Reply via email to