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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev