From b7053b80f27091acc8ccc954db99197e3073bff4 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Tue, 13 Dec 2016 20:29:23 -0800 Subject: [PATCH] glsl: Add tracking for elements of an array-of-arrays that have been accessed If there's a better way to provide access to ir_array_refcount_entry private members to the test functions, I am very interested to know about it. Signed-off-by: Ian Romanick Cc: Francisco Jerez Cc: mesa-stable@lists.freedesktop.org Reviewed-by: Kenneth Graunke --- src/compiler/Makefile.glsl.am | 1 + src/compiler/glsl/ir_array_refcount.cpp | 10 +- src/compiler/glsl/ir_array_refcount.h | 24 ++++ src/compiler/glsl/tests/array_refcount_test.cpp | 143 ++++++++++++++++++++++++ 4 files changed, 177 insertions(+), 1 deletion(-) create mode 100644 src/compiler/glsl/tests/array_refcount_test.cpp diff --git a/src/compiler/Makefile.glsl.am b/src/compiler/Makefile.glsl.am index 5b1d74e..5520aca 100644 --- a/src/compiler/Makefile.glsl.am +++ b/src/compiler/Makefile.glsl.am @@ -69,6 +69,7 @@ glsl_tests_cache_test_LDADD = \ $(PTHREAD_LIBS) glsl_tests_general_ir_test_SOURCES = \ + glsl/tests/array_refcount_test.cpp \ glsl/tests/builtin_variable_test.cpp \ glsl/tests/invalidate_locations_test.cpp \ glsl/tests/general_ir_test.cpp \ diff --git a/src/compiler/glsl/ir_array_refcount.cpp b/src/compiler/glsl/ir_array_refcount.cpp index b997d41..36b22742 100644 --- a/src/compiler/glsl/ir_array_refcount.cpp +++ b/src/compiler/glsl/ir_array_refcount.cpp @@ -56,7 +56,15 @@ ir_array_refcount_visitor::~ir_array_refcount_visitor() ir_array_refcount_entry::ir_array_refcount_entry(ir_variable *var) : var(var), is_referenced(false) { - /* empty */ + num_bits = MAX2(1, var->type->arrays_of_arrays_size()); + bits = new BITSET_WORD[BITSET_WORDS(num_bits)]; + memset(bits, 0, BITSET_WORDS(num_bits) * sizeof(bits[0])); +} + + +ir_array_refcount_entry::~ir_array_refcount_entry() +{ + delete [] bits; } diff --git a/src/compiler/glsl/ir_array_refcount.h b/src/compiler/glsl/ir_array_refcount.h index 9ec46d2..4296e4b 100644 --- a/src/compiler/glsl/ir_array_refcount.h +++ b/src/compiler/glsl/ir_array_refcount.h @@ -30,16 +30,40 @@ #include "ir.h" #include "ir_visitor.h" #include "compiler/glsl_types.h" +#include "util/bitset.h" class ir_array_refcount_entry { public: ir_array_refcount_entry(ir_variable *var); + ~ir_array_refcount_entry(); ir_variable *var; /* The key: the variable's pointer. */ /** Has the variable been referenced? */ bool is_referenced; + + /** Has a linearized array index been referenced? */ + bool is_linearized_index_referenced(unsigned linearized_index) const + { + assert(bits != 0); + assert(linearized_index <= num_bits); + + return BITSET_TEST(bits, linearized_index); + } + +private: + /** Set of bit-flags to note which array elements have been accessed. */ + BITSET_WORD *bits; + + /** + * Total number of bits referenced by \c bits. + * + * Also the total number of array(s-of-arrays) elements of \c var. + */ + unsigned num_bits; + + friend class array_refcount_test; }; class ir_array_refcount_visitor : public ir_hierarchical_visitor { diff --git a/src/compiler/glsl/tests/array_refcount_test.cpp b/src/compiler/glsl/tests/array_refcount_test.cpp new file mode 100644 index 0000000..d80ea81 --- /dev/null +++ b/src/compiler/glsl/tests/array_refcount_test.cpp @@ -0,0 +1,143 @@ +/* + * Copyright © 2016 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#include +#include "ir.h" +#include "ir_array_refcount.h" + +class array_refcount_test : public ::testing::Test { +public: + virtual void SetUp(); + virtual void TearDown(); + + void *mem_ctx; + + /** + * glsl_type for a vec4[3][4][5]. + * + * The exceptionally verbose name is picked because it matches the syntax + * of http://cdecl.org/. + */ + const glsl_type *array_3_of_array_4_of_array_5_of_vec4; + + /** + * Wrapper to access private member "bits" of ir_array_refcount_entry + * + * The test class is a friend to ir_array_refcount_entry, but the + * individual tests are not part of the class. Since the friendliness of + * the test class does not extend to the tests, provide a wrapper. + */ + const BITSET_WORD *get_bits(const ir_array_refcount_entry &entry) + { + return entry.bits; + } + + /** + * Wrapper to access private member "num_bits" of ir_array_refcount_entry + * + * The test class is a friend to ir_array_refcount_entry, but the + * individual tests are not part of the class. Since the friendliness of + * the test class does not extend to the tests, provide a wrapper. + */ + unsigned get_num_bits(const ir_array_refcount_entry &entry) + { + return entry.num_bits; + } +}; + +void +array_refcount_test::SetUp() +{ + mem_ctx = ralloc_context(NULL); + + /* 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); + const glsl_type *const array_4_of_array_5_of_vec4 = + 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); +} + +void +array_refcount_test::TearDown() +{ + ralloc_free(mem_ctx); + mem_ctx = NULL; +} + +TEST_F(array_refcount_test, ir_array_refcount_entry_initial_state_for_scalar) +{ + ir_variable *const var = + new(mem_ctx) ir_variable(glsl_type::int_type, "a", ir_var_auto); + + ir_array_refcount_entry entry(var); + + ASSERT_NE((void *)0, get_bits(entry)); + EXPECT_FALSE(entry.is_referenced); + EXPECT_EQ(1, get_num_bits(entry)); + EXPECT_FALSE(entry.is_linearized_index_referenced(0)); +} + +TEST_F(array_refcount_test, ir_array_refcount_entry_initial_state_for_vector) +{ + ir_variable *const var = + new(mem_ctx) ir_variable(glsl_type::vec4_type, "a", ir_var_auto); + + ir_array_refcount_entry entry(var); + + ASSERT_NE((void *)0, get_bits(entry)); + EXPECT_FALSE(entry.is_referenced); + EXPECT_EQ(1, get_num_bits(entry)); + EXPECT_FALSE(entry.is_linearized_index_referenced(0)); +} + +TEST_F(array_refcount_test, ir_array_refcount_entry_initial_state_for_matrix) +{ + ir_variable *const var = + new(mem_ctx) ir_variable(glsl_type::mat4_type, "a", ir_var_auto); + + ir_array_refcount_entry entry(var); + + ASSERT_NE((void *)0, get_bits(entry)); + EXPECT_FALSE(entry.is_referenced); + EXPECT_EQ(1, get_num_bits(entry)); + EXPECT_FALSE(entry.is_linearized_index_referenced(0)); +} + +TEST_F(array_refcount_test, ir_array_refcount_entry_initial_state_for_array) +{ + ir_variable *const var = + new(mem_ctx) ir_variable(array_3_of_array_4_of_array_5_of_vec4, + "a", + ir_var_auto); + const unsigned total_elements = var->type->arrays_of_arrays_size(); + + ir_array_refcount_entry entry(var); + + ASSERT_NE((void *)0, get_bits(entry)); + EXPECT_FALSE(entry.is_referenced); + EXPECT_EQ(total_elements, get_num_bits(entry)); + + for (unsigned i = 0; i < total_elements; i++) + EXPECT_FALSE(entry.is_linearized_index_referenced(i)) << "index = " << i; +} -- 2.7.4