[Mesa-dev] [PATCH v2 2/3] glsl: check if induction var incremented before use in terminator
Michael Schellenberger Costa
mschellenbergercosta at googlemail.com
Thu Sep 21 15:51:50 UTC 2017
Out of curriosity what about decrement and other shenanigans?
--Michael
Am 21.09.2017 um 12:55 schrieb Timothy Arceri:
> 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 <nicolai.haehnle at amd.com>
> Reviewed-by: Elie Tournier <elie.tournier at collabora.com>
> ---
> 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 81a07f78f8..78279844dc 100644
> --- a/src/compiler/glsl/loop_analysis.cpp
> +++ b/src/compiler/glsl/loop_analysis.cpp
> @@ -164,20 +164,54 @@ calculate_iterations(ir_rvalue *from, ir_rvalue *to, ir_rvalue *increment,
> iter_value += bias[i];
> valid_loop = true;
> break;
> }
> }
>
> ralloc_free(mem_ctx);
> 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.
> *
> * \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
> @@ -575,20 +609,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_terminator(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:
More information about the mesa-dev
mailing list