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.
This commit is contained in:
Ian Romanick 2010-05-19 12:02:19 +02:00
parent 70fe8b6663
commit f3a002b503
6 changed files with 89 additions and 49 deletions

7
ir.h
View File

@ -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 *);
};

View File

@ -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,12 +95,21 @@ 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(ir_dereference_variable *ir)
{
ir_variable *const var = ir->variable_referenced();
variable_entry *entry = this->get_variable_entry(var);
if (entry)
entry->referenced_count++;
return visit_continue;
}
@ -125,24 +123,6 @@ ir_dead_code_visitor::visit_enter(ir_function *ir)
}
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)
{
(void) ir;
this->in_dereference--;
return visit_continue;
}
ir_visitor_status
ir_dead_code_visitor::visit_leave(ir_assignment *ir)
{

View File

@ -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();

View File

@ -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 *ir)
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_record *ir)
{
(void) ir;
return visit_continue;

View File

@ -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 *);

View File

@ -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);