[Mesa-dev] [PATCH 1/4] glsl: Extract functions from loop_analysis::visit(ir_dereference_variable *).

Paul Berry stereotype441 at gmail.com
Thu Nov 28 11:41:06 PST 2013


This function is about to get more complex.
---
 src/glsl/loop_analysis.cpp | 91 +++++++++++++++++++++++++++++++++-------------
 src/glsl/loop_analysis.h   |  4 ++
 2 files changed, 70 insertions(+), 25 deletions(-)

diff --git a/src/glsl/loop_analysis.cpp b/src/glsl/loop_analysis.cpp
index b08241a..3f2a14b 100644
--- a/src/glsl/loop_analysis.cpp
+++ b/src/glsl/loop_analysis.cpp
@@ -33,6 +33,43 @@ static bool all_expression_operands_are_loop_constant(ir_rvalue *,
 static ir_rvalue *get_basic_induction_increment(ir_assignment *, hash_table *);
 
 
+/**
+ * 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 is true if the reference occurred inside an if
+ * statement.
+ *
+ * \arg current_assignment is the ir_assignment node that the loop variable is
+ * on the LHS of, if any (ignored if \c in_assignee is false).
+ */
+void
+loop_variable::record_reference(bool in_assignee, bool in_conditional_code,
+                                ir_assignment *current_assignment)
+{
+   if (in_assignee) {
+      assert(current_assignment != NULL);
+
+      this->conditional_assignment = in_conditional_code
+         || current_assignment->condition != NULL;
+
+      if (this->first_assignment == NULL) {
+         assert(this->num_assignments == 0);
+
+         this->first_assignment = current_assignment;
+      }
+
+      this->num_assignments++;
+   } else if (this->first_assignment == current_assignment) {
+      /* This catches the case where the variable is used in the RHS of an
+       * assignment where it is also in the LHS.
+       */
+      this->read_before_write = true;
+   }
+}
+
+
 loop_state::loop_state()
 {
    this->ht = hash_table_ctor(0, hash_table_pointer_hash,
@@ -102,6 +139,32 @@ loop_variable_state::insert(ir_if *if_stmt)
    return t;
 }
 
+
+/**
+ * If the given variable already is recored in the state for this loop, return
+ * the corresponding loop_variable object that records information about it.
+ *
+ * Otherwise, create a new loop_variable object to record information about
+ * the variable, and set its \c read_before_write field appropriately based on
+ * \c in_assignee.
+ *
+ * \arg in_assignee is true if this variable was encountered on the LHS of an
+ * assignment.
+ */
+loop_variable *
+loop_variable_state::get_or_insert(ir_variable *var, bool in_assignee)
+{
+   loop_variable *lv = this->get(var);
+
+   if (lv == NULL) {
+      lv = this->insert(var);
+      lv->read_before_write = !in_assignee;
+   }
+
+   return lv;
+}
+
+
 namespace {
 
 class loop_analysis : public ir_hierarchical_visitor {
@@ -181,32 +244,10 @@ loop_analysis::visit(ir_dereference_variable *ir)
       (loop_variable_state *) this->state.get_head();
 
    ir_variable *var = ir->variable_referenced();
-   loop_variable *lv = ls->get(var);
-
-   if (lv == NULL) {
-      lv = ls->insert(var);
-      lv->read_before_write = !this->in_assignee;
-   }
-
-   if (this->in_assignee) {
-      assert(this->current_assignment != NULL);
+   loop_variable *lv = ls->get_or_insert(var, this->in_assignee);
 
-      lv->conditional_assignment = (this->if_statement_depth > 0)
-	 || (this->current_assignment->condition != NULL);
-
-      if (lv->first_assignment == NULL) {
-	 assert(lv->num_assignments == 0);
-
-	 lv->first_assignment = this->current_assignment;
-      }
-
-      lv->num_assignments++;
-   } else if (lv->first_assignment == this->current_assignment) {
-      /* This catches the case where the variable is used in the RHS of an
-       * assignment where it is also in the LHS.
-       */
-      lv->read_before_write = true;
-   }
+   lv->record_reference(this->in_assignee, this->if_statement_depth > 0,
+                        this->current_assignment);
 
    return visit_continue;
 }
diff --git a/src/glsl/loop_analysis.h b/src/glsl/loop_analysis.h
index 769d626..edad8f3 100644
--- a/src/glsl/loop_analysis.h
+++ b/src/glsl/loop_analysis.h
@@ -67,6 +67,7 @@ class loop_variable_state : public exec_node {
 public:
    class loop_variable *get(const ir_variable *);
    class loop_variable *insert(ir_variable *);
+   class loop_variable *get_or_insert(ir_variable *, bool in_assignee);
    class loop_terminator *insert(ir_if *);
 
 
@@ -217,6 +218,9 @@ public:
 
       return is_const;
    }
+
+   void record_reference(bool in_assignee, bool in_conditional_code,
+                         ir_assignment *current_assignment);
 };
 
 
-- 
1.8.4.2



More information about the mesa-dev mailing list