glsl: Extract functions from loop_analysis::visit(ir_dereference_variable *).
authorPaul Berry <stereotype441@gmail.com>
Thu, 28 Nov 2013 18:42:01 +0000 (10:42 -0800)
committerPaul Berry <stereotype441@gmail.com>
Mon, 9 Dec 2013 18:54:13 +0000 (10:54 -0800)
This function is about to get more complex.

Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
src/glsl/loop_analysis.cpp
src/glsl/loop_analysis.h

index b08241af52706be9bffd9d2181147416ef74c7eb..9f1b1d2b1f95ef04e0726fea837c5167b64799a2 100644 (file)
@@ -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,33 @@ loop_variable_state::insert(ir_if *if_stmt)
    return t;
 }
 
+
+/**
+ * If the given variable already is recorded 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 +245,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;
 }
index 98414b3c6149dc4e78c5b907138ef2f59b6f1ed4..4fae829c3ab3663011f25dbf356ec2634269d403 100644 (file)
@@ -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 *);
 
 
@@ -212,6 +213,9 @@ public:
 
       return is_const;
    }
+
+   void record_reference(bool in_assignee, bool in_conditional_code,
+                         ir_assignment *current_assignment);
 };