On Thursday, December 15, 2016 8:10:20 PM PST Ian Romanick wrote: > From: Ian Romanick <ian.d.roman...@intel.com> > > Signed-off-by: Ian Romanick <ian.d.roman...@intel.com> > Cc: mesa-sta...@lists.freedesktop.org > --- > src/compiler/glsl/ir_array_refcount.cpp | 73 +++- > src/compiler/glsl/ir_array_refcount.h | 10 + > src/compiler/glsl/tests/array_refcount_test.cpp | 425 > ++++++++++++++++++++++++ > 3 files changed, 507 insertions(+), 1 deletion(-) > > diff --git a/src/compiler/glsl/ir_array_refcount.cpp > b/src/compiler/glsl/ir_array_refcount.cpp > index 75dca0a..7c9ab8e 100644 > --- a/src/compiler/glsl/ir_array_refcount.cpp > +++ b/src/compiler/glsl/ir_array_refcount.cpp > @@ -34,7 +34,7 @@ > #include "util/hash_table.h" > > ir_array_refcount_visitor::ir_array_refcount_visitor() > - : derefs(0), num_derefs(0), derefs_size(0) > + : last_array_deref(0), derefs(0), num_derefs(0), derefs_size(0) > { > this->mem_ctx = ralloc_context(NULL); > this->ht = _mesa_hash_table_create(NULL, _mesa_hash_pointer, > @@ -159,6 +159,77 @@ ir_array_refcount_visitor::get_array_deref() > return d; > } > > +ir_visitor_status > +ir_array_refcount_visitor::visit_enter(ir_dereference_array *ir) > +{ > + /* It could also be a vector or a matrix. Individual elements of vectors > + * are natrices are not tracked, so bail.
and matrices > + */ > + if (!ir->array->type->is_array()) > + return visit_continue; > + > + /* If this array dereference is a child of an array dereference that was > + * already visited, just continue on. Otherwise, for an arrays-of-arrays > + * dereference like x[1][2][3][4], we'd process the [1][2][3][4] sequence, > + * the [1][2][3] sequence, the [1][2] sequence, and the [1] sequence. > This > + * ensures that we only process the full sequence. > + */ > + if (last_array_deref && last_array_deref->array == ir) { > + last_array_deref = ir; > + return visit_continue; > + } > + > + last_array_deref = ir; > + > + num_derefs = 0; > + > + ir_rvalue *rv = ir; > + while (rv->ir_type == ir_type_dereference_array) { > + ir_dereference_array *const deref = rv->as_dereference_array(); > + > + assert(deref != NULL); > + assert(deref->array->type->is_array()); > + > + ir_rvalue *const array = deref->array; > + const ir_constant *const idx = deref->array_index->as_constant(); > + array_deref_range *const dr = get_array_deref(); > + > + dr->size = array->type->array_size(); > + > + if (idx != NULL) { > + dr->index = idx->get_int_component(0); > + } else { > + /* An unsized array can occur at the end of an SSBO. We can't track > + * accesses to such an array, so bail. > + */ > + if (array->type->array_size() == 0) > + return visit_continue; > + > + dr->index = dr->size; > + } > + > + rv = array; > + } > + > + ir_dereference_variable *const var_deref = rv->as_dereference_variable(); > + > + /* If the array being dereferenced is not a variable, bail. At the very > + * least, ir_constant and ir_dereference_record are possible. > + */ > + if (var_deref == NULL) > + return visit_continue; > + > + ir_array_refcount_entry *const entry = > + this->get_variable_entry(var_deref->var); > + > + if (entry == NULL) > + return visit_stop; > + > + entry->mark_array_elements_referenced(derefs, num_derefs); > + > + return visit_continue; > +} > + > > ir_visitor_status > ir_array_refcount_visitor::visit(ir_dereference_variable *ir) > diff --git a/src/compiler/glsl/ir_array_refcount.h > b/src/compiler/glsl/ir_array_refcount.h > index 2988046..46ba36c 100644 > --- a/src/compiler/glsl/ir_array_refcount.h > +++ b/src/compiler/glsl/ir_array_refcount.h > @@ -140,6 +140,7 @@ public: > virtual ir_visitor_status visit(ir_dereference_variable *); > > virtual ir_visitor_status visit_enter(ir_function_signature *); > + virtual ir_visitor_status visit_enter(ir_dereference_array *); > > /** > * Find variable in the hash table, and insert it if not present > @@ -158,6 +159,15 @@ private: > array_deref_range *get_array_deref(); > > /** > + * Last ir_dereference_array that was visited > + * > + * Used to prevent some redundant calculations. > + * > + * \sa ::visit_enter(ir_dereference_array *) > + */ > + ir_dereference_array *last_array_deref; > + > + /** > * \name array_deref_range tracking > */ > /*@{*/ > diff --git a/src/compiler/glsl/tests/array_refcount_test.cpp > b/src/compiler/glsl/tests/array_refcount_test.cpp > index 29bb133..ecd7f46 100644 > --- a/src/compiler/glsl/tests/array_refcount_test.cpp > +++ b/src/compiler/glsl/tests/array_refcount_test.cpp > @@ -23,12 +23,18 @@ > #include <gtest/gtest.h> > #include "ir.h" > #include "ir_array_refcount.h" > +#include "ir_builder.h" > +#include "util/hash_table.h" > + > +using namespace ir_builder; > > class array_refcount_test : public ::testing::Test { > public: > virtual void SetUp(); > virtual void TearDown(); > > + exec_list instructions; > + ir_factory *body; > void *mem_ctx; > > /** > @@ -40,6 +46,14 @@ public: > const glsl_type *array_3_of_array_4_of_array_5_of_vec4; > > /** > + * glsl_type for a int[3]. > + * > + * The exceptionally verbose name is picked because it matches the syntax > + * of http://cdecl.org/. > + */ > + const glsl_type *array_3_of_int; > + > + /** > * Wrapper to access private member "bits" of ir_array_refcount_entry > * > * The test class is a friend to ir_array_refcount_entry, but the > @@ -81,6 +95,9 @@ array_refcount_test::SetUp() > { > mem_ctx = ralloc_context(NULL); > > + instructions.make_empty(); > + body = new ir_factory(&instructions, mem_ctx); > + > /* The type of vec4 x[3][4][5]; */ > const glsl_type *const array_5_of_vec4 = > glsl_type::get_array_instance(glsl_type::vec4_type, 5); > @@ -88,15 +105,105 @@ array_refcount_test::SetUp() > glsl_type::get_array_instance(array_5_of_vec4, 4); > array_3_of_array_4_of_array_5_of_vec4 = > glsl_type::get_array_instance(array_4_of_array_5_of_vec4, 3); > + > + array_3_of_int = glsl_type::get_array_instance(glsl_type::int_type, 3); > } > > void > array_refcount_test::TearDown() > { > + delete body; > + body = NULL; > + > ralloc_free(mem_ctx); > mem_ctx = NULL; > } > > +static operand > +deref_array(operand array, operand index) I'd suggest just making this return the ir_rvalue *, rather than wrapping it in an operand. It's not necessary - if you take the resulting ir_rvalue *, and pass it to anything expecting an operand, it'll automatically create one for you. But you can also just use it as a normal piece of IR that way. > +{ > + void *mem_ctx = ralloc_parent(array.val); > + > + ir_rvalue *val = new(mem_ctx) ir_dereference_array(array.val, index.val); > + > + return operand(val); > +} > + > +static operand > +deref_struct(operand s, const char *field) Ditto. It might also make sense to just put these in ir_builder, as well. Either way, the series is: Reviewed-by: Kenneth Graunke <kenn...@whitecape.org>
signature.asc
Description: This is a digitally signed message part.
_______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev