[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