summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Romanick <ian.d.romanick@intel.com>2010-05-14 17:35:42 -0700
committerIan Romanick <ian.d.romanick@intel.com>2010-05-14 17:35:42 -0700
commit2b3c476fa08e33a0ee1633b173a7df31ecaca582 (patch)
tree5f17eed99b540a8a3d7cbfcf7aa7afd2f89da8c6
parent67e07ad3a33192ebf8e296c1c652d29dee467ae2 (diff)
Add ir_rvalue::variable_referenced
-rw-r--r--ir.cpp35
-rw-r--r--ir.h18
2 files changed, 53 insertions, 0 deletions
diff --git a/ir.cpp b/ir.cpp
index eb12b5fe77..696feb23f6 100644
--- 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 df9a8c4174..a533eee960 100644
--- 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,