summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Romanick <ian.d.romanick@intel.com>2010-05-19 12:02:19 +0200
committerIan Romanick <ian.d.romanick@intel.com>2010-05-26 15:23:25 -0700
commitf3a002b503542fe2544025c6a42d552fdc4907c2 (patch)
tree647f6bba599e317ced48e8f484f4933b6708e1fb
parent70fe8b66632f4afd87ebb12a450b1e639428e88f (diff)
Refactor ir_dereference support for ir_hierarchical_visitor
Move the accept method for hierarchical visitors from ir_dereference to the derived classes. This was mostly straight-forward, but I suspect that ir_dead_code_local may be broken now.
-rw-r--r--ir.h7
-rw-r--r--ir_dead_code.cpp40
-rw-r--r--ir_dead_code_local.cpp4
-rw-r--r--ir_hierarchical_visitor.cpp25
-rw-r--r--ir_hierarchical_visitor.h22
-rw-r--r--ir_hv_accept.cpp28
6 files changed, 83 insertions, 43 deletions
diff --git a/ir.h b/ir.h
index 70fe9f9db6..f785ddb637 100644
--- a/ir.h
+++ b/ir.h
@@ -798,8 +798,6 @@ public:
v->visit(this);
}
- virtual ir_visitor_status accept(ir_hierarchical_visitor *);
-
bool is_lvalue();
/**
@@ -845,6 +843,8 @@ public:
{
return (ir_variable *) this->var;
}
+
+ virtual ir_visitor_status accept(ir_hierarchical_visitor *);
};
@@ -862,6 +862,7 @@ public:
return ((ir_rvalue *) this->var)->variable_referenced();
}
+ virtual ir_visitor_status accept(ir_hierarchical_visitor *);
private:
void set_array(ir_rvalue *value);
@@ -881,6 +882,8 @@ public:
{
return ((ir_rvalue *) this->var)->variable_referenced();
}
+
+ virtual ir_visitor_status accept(ir_hierarchical_visitor *);
};
diff --git a/ir_dead_code.cpp b/ir_dead_code.cpp
index aa8ebf8ad1..2ede7ff0cf 100644
--- a/ir_dead_code.cpp
+++ b/ir_dead_code.cpp
@@ -60,14 +60,11 @@ public:
class ir_dead_code_visitor : public ir_hierarchical_visitor {
public:
virtual ir_visitor_status visit(ir_variable *);
+ virtual ir_visitor_status visit(ir_dereference_variable *);
virtual ir_visitor_status visit_enter(ir_function *);
- virtual ir_visitor_status visit_enter(ir_dereference *);
- virtual ir_visitor_status visit_leave(ir_dereference *);
virtual ir_visitor_status visit_leave(ir_assignment *);
- ir_dead_code_visitor(void);
-
variable_entry *get_variable_entry(ir_variable *var);
bool (*predicate)(ir_instruction *ir);
@@ -75,16 +72,8 @@ public:
/* List of variable_entry */
exec_list variable_list;
-
- /* Depth of derefernce stack. */
- int in_dereference;
};
-ir_dead_code_visitor::ir_dead_code_visitor(void)
-{
- this->in_dereference = 0;
-}
-
variable_entry *
ir_dead_code_visitor::get_variable_entry(ir_variable *var)
@@ -106,40 +95,31 @@ ir_visitor_status
ir_dead_code_visitor::visit(ir_variable *ir)
{
variable_entry *entry = this->get_variable_entry(ir);
- if (entry) {
- if (this->in_dereference)
- entry->referenced_count++;
- else
- entry->declaration = true;
- }
+ if (entry)
+ entry->declaration = true;
return visit_continue;
}
ir_visitor_status
-ir_dead_code_visitor::visit_enter(ir_function *ir)
+ir_dead_code_visitor::visit(ir_dereference_variable *ir)
{
- (void) ir;
- return visit_continue_with_parent;
-}
+ ir_variable *const var = ir->variable_referenced();
+ variable_entry *entry = this->get_variable_entry(var);
+ if (entry)
+ entry->referenced_count++;
-ir_visitor_status
-ir_dead_code_visitor::visit_enter(ir_dereference *ir)
-{
- (void) ir;
- this->in_dereference++;
return visit_continue;
}
ir_visitor_status
-ir_dead_code_visitor::visit_leave(ir_dereference *ir)
+ir_dead_code_visitor::visit_enter(ir_function *ir)
{
(void) ir;
- this->in_dereference--;
- return visit_continue;
+ return visit_continue_with_parent;
}
diff --git a/ir_dead_code_local.cpp b/ir_dead_code_local.cpp
index f101ccb5ec..668b6f8cd5 100644
--- a/ir_dead_code_local.cpp
+++ b/ir_dead_code_local.cpp
@@ -64,8 +64,10 @@ public:
this->assignments = assignments;
}
- virtual ir_visitor_status visit(ir_variable *var)
+ virtual ir_visitor_status visit(ir_dereference_variable *ir)
{
+ ir_variable *const var = ir->variable_referenced();
+
foreach_iter(exec_list_iterator, iter, *this->assignments) {
assignment_entry *entry = (assignment_entry *)iter.get();
diff --git a/ir_hierarchical_visitor.cpp b/ir_hierarchical_visitor.cpp
index 4fec0d7c75..ad47487835 100644
--- a/ir_hierarchical_visitor.cpp
+++ b/ir_hierarchical_visitor.cpp
@@ -46,6 +46,13 @@ ir_hierarchical_visitor::visit(ir_loop_jump *ir)
}
ir_visitor_status
+ir_hierarchical_visitor::visit(ir_dereference_variable *ir)
+{
+ (void) ir;
+ return visit_continue;
+}
+
+ir_visitor_status
ir_hierarchical_visitor::visit_enter(ir_loop *ir)
{
(void) ir;
@@ -116,14 +123,28 @@ ir_hierarchical_visitor::visit_leave(ir_swizzle *ir)
}
ir_visitor_status
-ir_hierarchical_visitor::visit_enter(ir_dereference *ir)
+ir_hierarchical_visitor::visit_enter(ir_dereference_array *ir)
+{
+ (void) ir;
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_hierarchical_visitor::visit_leave(ir_dereference_array *ir)
+{
+ (void) ir;
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_hierarchical_visitor::visit_enter(ir_dereference_record *ir)
{
(void) ir;
return visit_continue;
}
ir_visitor_status
-ir_hierarchical_visitor::visit_leave(ir_dereference *ir)
+ir_hierarchical_visitor::visit_leave(ir_dereference_record *ir)
{
(void) ir;
return visit_continue;
diff --git a/ir_hierarchical_visitor.h b/ir_hierarchical_visitor.h
index daf220906a..d3ba508cf1 100644
--- a/ir_hierarchical_visitor.h
+++ b/ir_hierarchical_visitor.h
@@ -83,6 +83,22 @@ public:
virtual ir_visitor_status visit(class ir_variable *);
virtual ir_visitor_status visit(class ir_constant *);
virtual ir_visitor_status visit(class ir_loop_jump *);
+
+ /**
+ * ir_dereference_variable isn't technically a leaf, but it is treated as a
+ * leaf here for a couple reasons. By not automatically visiting the one
+ * child ir_variable node from the ir_dereference_variable, ir_variable
+ * nodes can always be handled as variable declarations. Code that used
+ * non-hierarchical visitors had to set an "in a dereference" flag to
+ * determine how to handle an ir_variable. By forcing the visitor to
+ * handle the ir_variable within the ir_dereference_varaible visitor, this
+ * kludge can be avoided.
+ *
+ * In addition, I can envision no use for having separate enter and leave
+ * methods. Anything that could be done in the enter and leave methods
+ * that couldn't just be done in the visit method.
+ */
+ virtual ir_visitor_status visit(class ir_dereference_variable *);
/*@}*/
/**
@@ -99,8 +115,10 @@ public:
virtual ir_visitor_status visit_leave(class ir_expression *);
virtual ir_visitor_status visit_enter(class ir_swizzle *);
virtual ir_visitor_status visit_leave(class ir_swizzle *);
- virtual ir_visitor_status visit_enter(class ir_dereference *);
- virtual ir_visitor_status visit_leave(class ir_dereference *);
+ virtual ir_visitor_status visit_enter(class ir_dereference_array *);
+ virtual ir_visitor_status visit_leave(class ir_dereference_array *);
+ virtual ir_visitor_status visit_enter(class ir_dereference_record *);
+ virtual ir_visitor_status visit_leave(class ir_dereference_record *);
virtual ir_visitor_status visit_enter(class ir_assignment *);
virtual ir_visitor_status visit_leave(class ir_assignment *);
virtual ir_visitor_status visit_enter(class ir_call *);
diff --git a/ir_hv_accept.cpp b/ir_hv_accept.cpp
index 43422e84aa..08f5394314 100644
--- a/ir_hv_accept.cpp
+++ b/ir_hv_accept.cpp
@@ -170,18 +170,34 @@ ir_swizzle::accept(ir_hierarchical_visitor *v)
ir_visitor_status
-ir_dereference::accept(ir_hierarchical_visitor *v)
+ir_dereference_variable::accept(ir_hierarchical_visitor *v)
+{
+ return v->visit(this);
+}
+
+
+ir_visitor_status
+ir_dereference_array::accept(ir_hierarchical_visitor *v)
{
ir_visitor_status s = v->visit_enter(this);
if (s != visit_continue)
return (s == visit_continue_with_parent) ? visit_continue : s;
- if (this->mode == ir_reference_array) {
- s = this->selector.array_index->accept(v);
- if (s != visit_continue)
- return (s == visit_continue_with_parent) ? visit_continue : s;
- }
+ s = this->selector.array_index->accept(v);
+ if (s != visit_continue)
+ return (s == visit_continue_with_parent) ? visit_continue : s;
+ s = this->var->accept(v);
+ return (s == visit_stop) ? s : v->visit_leave(this);
+}
+
+
+ir_visitor_status
+ir_dereference_record::accept(ir_hierarchical_visitor *v)
+{
+ ir_visitor_status s = v->visit_enter(this);
+ if (s != visit_continue)
+ return (s == visit_continue_with_parent) ? visit_continue : s;
s = this->var->accept(v);
return (s == visit_stop) ? s : v->visit_leave(this);