From f3a002b503542fe2544025c6a42d552fdc4907c2 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Wed, 19 May 2010 12:02:19 +0200 Subject: [PATCH] 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. --- ir.h | 7 +++++-- ir_dead_code.cpp | 40 ++++++++++--------------------------- ir_dead_code_local.cpp | 4 +++- ir_hierarchical_visitor.cpp | 25 +++++++++++++++++++++-- ir_hierarchical_visitor.h | 22 ++++++++++++++++++-- ir_hv_accept.cpp | 28 ++++++++++++++++++++------ 6 files changed, 83 insertions(+), 43 deletions(-) diff --git a/ir.h b/ir.h index 70fe9f9db6f..f785ddb6373 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 aa8ebf8ad10..2ede7ff0cf4 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 f101ccb5ec3..668b6f8cd55 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 4fec0d7c752..ad474878355 100644 --- a/ir_hierarchical_visitor.cpp +++ b/ir_hierarchical_visitor.cpp @@ -45,6 +45,13 @@ ir_hierarchical_visitor::visit(ir_loop_jump *ir) return visit_continue; } +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) { @@ -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 daf220906ad..d3ba508cf1c 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 43422e84aae..08f53943142 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); -- 2.30.2