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:
parent
70fe8b6663
commit
f3a002b503
7
ir.h
7
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 *);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 *);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue