[Mesa-dev] [PATCH 2/3] glsl: check if induction var incremented before use in terminator
Timothy Arceri
tarceri at itsqueeze.com
Thu Sep 14 04:47:49 UTC 2017
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,
+ 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
More information about the mesa-dev
mailing list