[Mesa-dev] [PATCH v2 2/3] glsl: check if induction var incremented before use in terminator

Timothy Arceri tarceri at itsqueeze.com
Thu Sep 21 22:55:19 UTC 2017


On 22/09/17 01:51, Michael Schellenberger Costa wrote:
> Out of curriosity what about decrement and other shenanigans?

My commit message is a little misleading. The method in which the 
induction var changes doesn't matter, we just check if something was 
assigned to it (we trust the rest of the analysis code to do its job and 
make sure its a valid induction var). If there was an assignment before 
the terminator is checked we reduce the iteration count of the loop, 
again the way in which the induction variable is changed is irrelevant 
we simple reduce the number of passes over the loop by 1.

Hope this makes sense.

Tim

> 
> --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