[Mesa-dev] [PATCH 03/10] glsl: Move update of max_array_access into a virtual function on ir_rvalue.

Paul Berry stereotype441 at gmail.com
Fri Sep 27 12:05:29 PDT 2013


Currently, when converting an access to an array element from ast to
IR, we need to see if the array is an ir_dereference_variable, and if
so update the variable's max_array_access.

When we add support for unsized arrays in interface blocks, we'll also
need to account for cases where the array is an ir_dereference_record
and the record is an interface block.

To make this easier, move the update into a virtual function on
ir_value, so that the appropriate logic will get invoked based on the
rvalue's type.
---
 src/glsl/ast_array_index.cpp | 19 ++-----------------
 src/glsl/ir.cpp              | 24 ++++++++++++++++++++++++
 src/glsl/ir.h                | 18 ++++++++++++++++++
 3 files changed, 44 insertions(+), 17 deletions(-)

diff --git a/src/glsl/ast_array_index.cpp b/src/glsl/ast_array_index.cpp
index 51f6b10..1614811 100644
--- a/src/glsl/ast_array_index.cpp
+++ b/src/glsl/ast_array_index.cpp
@@ -97,23 +97,8 @@ _mesa_ast_array_index_to_hir(void *mem_ctx,
 			  type_name);
       }
 
-      if (array->type->is_array()) {
-	 /* If the array is a variable dereference, it dereferences the
-	  * whole array, by definition.  Use this to get the variable.
-	  *
-	  * FINISHME: Should some methods for getting / setting / testing
-	  * FINISHME: array access limits be added to ir_dereference?
-	  */
-	 ir_variable *const v = array->whole_variable_referenced();
-	 if ((v != NULL) && (unsigned(idx) > v->max_array_access)) {
-	    v->max_array_access = idx;
-
-	    /* Check whether this access will, as a side effect, implicitly
-	     * cause the size of a built-in array to be too large.
-	     */
-	    check_builtin_array_max_size(v->name, idx+1, loc, state);
-	 }
-      }
+      if (array->type->is_array())
+         array->update_max_array_access(idx, &loc, state);
    } else if (const_index == NULL && array->type->is_array()) {
       if (array->type->array_size() == 0) {
 	 _mesa_glsl_error(&loc, state, "unsized array index must be constant");
diff --git a/src/glsl/ir.cpp b/src/glsl/ir.cpp
index b0f92cb..5d4f2ef 100644
--- a/src/glsl/ir.cpp
+++ b/src/glsl/ir.cpp
@@ -25,6 +25,7 @@
 #include "ir.h"
 #include "ir_visitor.h"
 #include "glsl_types.h"
+#include "ast.h"
 
 ir_rvalue::ir_rvalue()
 {
@@ -1289,6 +1290,21 @@ ir_dereference_variable::ir_dereference_variable(ir_variable *var)
 }
 
 
+void
+ir_dereference_variable::update_max_array_access(unsigned idx, YYLTYPE *loc,
+                                                 struct _mesa_glsl_parse_state *state)
+{
+   if (idx > this->var->max_array_access) {
+      this->var->max_array_access = idx;
+
+      /* Check whether this access will, as a side effect, implicitly cause
+       * the size of a built-in array to be too large.
+       */
+      check_builtin_array_max_size(this->var->name, idx+1, *loc, state);
+   }
+}
+
+
 ir_dereference_array::ir_dereference_array(ir_rvalue *value,
 					   ir_rvalue *array_index)
 {
@@ -1858,6 +1874,14 @@ ir_rvalue::as_rvalue_to_saturate()
 }
 
 
+void
+ir_rvalue::update_max_array_access(unsigned, YYLTYPE *,
+                                   struct _mesa_glsl_parse_state *)
+{
+   /* Nothing to do for a general rvalue. */
+}
+
+
 unsigned
 vertices_per_prim(GLenum prim)
 {
diff --git a/src/glsl/ir.h b/src/glsl/ir.h
index 6c5630b..721b44d 100644
--- a/src/glsl/ir.h
+++ b/src/glsl/ir.h
@@ -36,6 +36,10 @@
 #include "ir_hierarchical_visitor.h"
 #include "main/mtypes.h"
 
+
+struct YYLTYPE;
+
+
 #ifdef __cplusplus
 
 /**
@@ -260,6 +264,18 @@ public:
     */
    static ir_rvalue *error_value(void *mem_ctx);
 
+   /**
+    * If this rvalue is a reference to an array for which we are tracking the
+    * max array element accessed, track that the given element has been
+    * accessed.  Otherwise do nothing.
+    *
+    * This function also checks whether the array is a built-in array whose
+    * maximum size is too small to accommodate the given index, and if so uses
+    * loc and state to report the error.
+    */
+   virtual void update_max_array_access(unsigned idx, YYLTYPE *loc,
+                                        struct _mesa_glsl_parse_state *state);
+
 protected:
    ir_rvalue();
 };
@@ -1807,6 +1823,8 @@ public:
    }
 
    virtual ir_visitor_status accept(ir_hierarchical_visitor *);
+   virtual void update_max_array_access(unsigned idx, YYLTYPE *loc,
+                                        struct _mesa_glsl_parse_state *state);
 
    /**
     * Object being dereferenced.
-- 
1.8.4



More information about the mesa-dev mailing list