Add ir_rvalue::variable_referenced
authorIan Romanick <ian.d.romanick@intel.com>
Sat, 15 May 2010 00:35:42 +0000 (17:35 -0700)
committerIan Romanick <ian.d.romanick@intel.com>
Sat, 15 May 2010 00:35:42 +0000 (17:35 -0700)
ir.cpp
ir.h

diff --git a/ir.cpp b/ir.cpp
index eb12b5fe77fa108b5cfb8fc78159568adafd621e..696feb23f6fb431eca4f8c36e2640e4b1b0d1b4b 100644 (file)
--- a/ir.cpp
+++ b/ir.cpp
@@ -283,6 +283,36 @@ ir_dereference::is_lvalue()
    return this->var->as_rvalue()->is_lvalue();
 }
 
+
+ir_variable *
+ir_dereference::variable_referenced()
+{
+   /* Walk down the dereference chain to find the variable at the end.
+    *
+    * This could be implemented recurrsively, but it would still need to call
+    * as_variable and as_rvalue, so the code wouldn't be any cleaner.
+    */
+   for (ir_instruction *current = this->var; current != NULL; /* empty */ ) {
+      ir_dereference *deref;
+      ir_variable *v;
+
+      if ((deref = current->as_dereference())) {
+        current = deref->var;
+      } else if ((v = current->as_variable())) {
+        return v;
+      } else {
+        /* This is the case of, for example, an array dereference of the
+         * value returned by a function call.
+         */
+        return NULL;
+      }
+   }
+
+   assert(!"Should not get here.");
+   return NULL;
+}
+
+
 ir_swizzle::ir_swizzle(ir_rvalue *val, unsigned x, unsigned y, unsigned z,
                       unsigned w, unsigned count)
    : val(val)
@@ -402,6 +432,11 @@ ir_swizzle::create(ir_rvalue *val, const char *str, unsigned vector_length)
 #undef S
 #undef I
 
+ir_variable *
+ir_swizzle::variable_referenced()
+{
+   return this->val->variable_referenced();
+}
 
 ir_variable::ir_variable(const struct glsl_type *type, const char *name)
    : max_array_access(0), read_only(false), centroid(false), invariant(false),
diff --git a/ir.h b/ir.h
index df9a8c4174d7902aa679a22c1dd1dbe55d11c8e6..a533eee960dcbe641a499be1d9a8b08c65408903 100644 (file)
--- a/ir.h
+++ b/ir.h
@@ -85,6 +85,14 @@ public:
       return false;
    }
 
+   /**
+    * Get the variable that is ultimately referenced by an r-value
+    */
+   virtual ir_variable *variable_referenced()
+   {
+      return NULL;
+   }
+
 protected:
    ir_rvalue()
    {
@@ -744,6 +752,11 @@ public:
       return val->is_lvalue() && !mask.has_duplicates;
    }
 
+   /**
+    * Get the variable that is ultimately referenced by an r-value
+    */
+   virtual ir_variable *variable_referenced();
+
    ir_rvalue *val;
    ir_swizzle_mask mask;
 };
@@ -769,6 +782,11 @@ public:
 
    bool is_lvalue();
 
+   /**
+    * Get the variable that is ultimately referenced by an r-value
+    */
+   virtual ir_variable *variable_referenced();
+
    enum {
       ir_reference_variable,
       ir_reference_array,