Refactor ir_dereference support for ir_hierarchical_visitor
authorIan Romanick <ian.d.romanick@intel.com>
Wed, 19 May 2010 10:02:19 +0000 (12:02 +0200)
committerIan Romanick <ian.d.romanick@intel.com>
Wed, 26 May 2010 22:23:25 +0000 (15:23 -0700)
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
ir_dead_code.cpp
ir_dead_code_local.cpp
ir_hierarchical_visitor.cpp
ir_hierarchical_visitor.h
ir_hv_accept.cpp

diff --git a/ir.h b/ir.h
index 70fe9f9db6f82addd96bed5d9a3001eadd1405bb..f785ddb63736ed3e032af760c91ac593df5740bd 100644 (file)
--- 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 *);
 };
 
 
index aa8ebf8ad106745e3aa1deec3d217b2a32caa77a..2ede7ff0cf460d1e8b5d2614c588b8a788f87b99 100644 (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,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;
 }
 
 
index f101ccb5ec38c6329321f1efb0aa0c9325e77fc1..668b6f8cd559e2b146c5c3bd7fb50ac9dc68db82 100644 (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();
 
index 4fec0d7c75210f0fdbfbec3e2ec92600695c4ace..ad474878355e11b6b84dd094d5124f674a9637e3 100644 (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_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;
index daf220906ad107f30b611259b310db47d9724016..d3ba508cf1c3fd452eb6a9e39b5f81ef9f499967 100644 (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 *);
index 43422e84aae1e1d24653388fda508443377751c3..08f5394314204f9980a25023e0d92a2570ed0dad 100644 (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);