On Thu, Nov 28, 2013 at 11:41:06AM -0800, Paul Berry wrote: > 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 ^ recorded
> + * 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 > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/mesa-dev _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev