v->visit(this);
}
- virtual ir_visitor_status accept(ir_hierarchical_visitor *);
-
bool is_lvalue();
/**
{
return (ir_variable *) this->var;
}
+
+ virtual ir_visitor_status accept(ir_hierarchical_visitor *);
};
return ((ir_rvalue *) this->var)->variable_referenced();
}
+ virtual ir_visitor_status accept(ir_hierarchical_visitor *);
private:
void set_array(ir_rvalue *value);
{
return ((ir_rvalue *) this->var)->variable_referenced();
}
+
+ virtual ir_visitor_status accept(ir_hierarchical_visitor *);
};
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);
/* 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)
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;
}
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();
}
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;
}
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;
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 *);
/*@}*/
/**
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 *);
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);