diff --git a/src/compiler/glsl/ir_array_refcount.cpp b/src/compiler/glsl/ir_array_refcount.cpp deleted file mode 100644 index ba8fce6067a..00000000000 --- a/src/compiler/glsl/ir_array_refcount.cpp +++ /dev/null @@ -1,207 +0,0 @@ -/* - * 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. - */ - -/** - * \file ir_array_refcount.cpp - * - * Provides a visitor which produces a list of variables referenced. - */ - -#include "ir.h" -#include "ir_visitor.h" -#include "ir_array_refcount.h" -#include "compiler/glsl_types.h" -#include "util/hash_table.h" - -ir_array_refcount_visitor::ir_array_refcount_visitor() - : last_array_deref(0), derefs(0), num_derefs(0), derefs_size(0) -{ - this->mem_ctx = ralloc_context(NULL); - this->ht = _mesa_pointer_hash_table_create(NULL); -} - -static void -free_entry(struct hash_entry *entry) -{ - ir_array_refcount_entry *ivre = (ir_array_refcount_entry *) entry->data; - delete ivre; -} - -ir_array_refcount_visitor::~ir_array_refcount_visitor() -{ - ralloc_free(this->mem_ctx); - _mesa_hash_table_destroy(this->ht, free_entry); -} - -ir_array_refcount_entry::ir_array_refcount_entry(ir_variable *var) - : var(var), is_referenced(false) -{ - num_bits = MAX2(1, glsl_get_aoa_size(var->type)); - bits = new BITSET_WORD[BITSET_WORDS(num_bits)]; - memset(bits, 0, BITSET_WORDS(num_bits) * sizeof(bits[0])); - - /* Count the "depth" of the arrays-of-arrays. */ - array_depth = 0; - for (const glsl_type *type = var->type; - glsl_type_is_array(type); - type = type->fields.array) { - array_depth++; - } -} - - -ir_array_refcount_entry::~ir_array_refcount_entry() -{ - delete [] bits; -} - -ir_array_refcount_entry * -ir_array_refcount_visitor::get_variable_entry(ir_variable *var) -{ - assert(var); - - struct hash_entry *e = _mesa_hash_table_search(this->ht, var); - if (e) - return (ir_array_refcount_entry *)e->data; - - ir_array_refcount_entry *entry = new ir_array_refcount_entry(var); - _mesa_hash_table_insert(this->ht, var, entry); - - return entry; -} - - -array_deref_range * -ir_array_refcount_visitor::get_array_deref() -{ - if ((num_derefs + 1) * sizeof(array_deref_range) > derefs_size) { - void *ptr = reralloc_size(mem_ctx, derefs, derefs_size + 4096); - - if (ptr == NULL) - return NULL; - - derefs_size += 4096; - derefs = (array_deref_range *)ptr; - } - - array_deref_range *d = &derefs[num_derefs]; - num_derefs++; - - 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. - */ - if (!glsl_type_is_array(ir->array->type)) - 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(glsl_type_is_array(deref->array->type)); - - 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 = glsl_array_size(array->type); - - 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 (glsl_array_size(array->type) == 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; - - link_util_mark_array_elements_referenced(derefs, num_derefs, - entry->array_depth, - entry->bits); - - return visit_continue; -} - - -ir_visitor_status -ir_array_refcount_visitor::visit(ir_dereference_variable *ir) -{ - ir_variable *const var = ir->variable_referenced(); - ir_array_refcount_entry *entry = this->get_variable_entry(var); - - entry->is_referenced = true; - - return visit_continue; -} - - -ir_visitor_status -ir_array_refcount_visitor::visit_enter(ir_function_signature *ir) -{ - /* We don't want to descend into the function parameters and - * dead-code eliminate them, so just accept the body here. - */ - visit_list_elements(this, &ir->body); - return visit_continue_with_parent; -} diff --git a/src/compiler/glsl/ir_array_refcount.h b/src/compiler/glsl/ir_array_refcount.h deleted file mode 100644 index 3ae18ccb815..00000000000 --- a/src/compiler/glsl/ir_array_refcount.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - * 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. - */ - -/** - * \file ir_array_refcount.h - * - * Provides a visitor which produces a list of variables referenced. - */ - -#ifndef GLSL_IR_ARRAY_REFCOUNT_H -#define GLSL_IR_ARRAY_REFCOUNT_H - -#include "ir.h" -#include "ir_visitor.h" -#include "linker_util.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(const ir_array_refcount_entry &) = delete; - ~ir_array_refcount_entry(); - ir_array_refcount_entry & operator=(const ir_array_refcount_entry &) = delete; - - ir_variable *var; /* The key: the variable's pointer. */ - - /** Has the variable been referenced? */ - bool is_referenced; - - /** Count of nested arrays in the type. */ - unsigned array_depth; - - /** Set of bit-flags to note which array elements have been accessed. */ - BITSET_WORD *bits; - - /** 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: - - /** - * 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 { -public: - ir_array_refcount_visitor(void); - ~ir_array_refcount_visitor(void); - - 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 - */ - ir_array_refcount_entry *get_variable_entry(ir_variable *var); - - /** - * Hash table mapping ir_variable to ir_array_refcount_entry. - */ - struct hash_table *ht; - - void *mem_ctx; - -private: - /** Get an array_deref_range element from private tracking. */ - 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 - */ - /*@{*/ - /** Currently allocated block of derefs. */ - array_deref_range *derefs; - - /** Number of derefs used in current processing. */ - unsigned num_derefs; - - /** Size of the derefs buffer in bytes. */ - unsigned derefs_size; - /*@}*/ -}; - -#endif /* GLSL_IR_ARRAY_REFCOUNT_H */ diff --git a/src/compiler/glsl/meson.build b/src/compiler/glsl/meson.build index 6489ac79c30..55cf04b1a83 100644 --- a/src/compiler/glsl/meson.build +++ b/src/compiler/glsl/meson.build @@ -139,8 +139,6 @@ files_libglsl = files( 'glsl_to_nir.cpp', 'glsl_to_nir.h', 'hir_field_selection.cpp', - 'ir_array_refcount.cpp', - 'ir_array_refcount.h', 'ir_basic_block.cpp', 'ir_basic_block.h', 'ir_builder.cpp', diff --git a/src/compiler/glsl/tests/array_refcount_test.cpp b/src/compiler/glsl/tests/array_refcount_test.cpp deleted file mode 100644 index 72fa743256c..00000000000 --- a/src/compiler/glsl/tests/array_refcount_test.cpp +++ /dev/null @@ -1,725 +0,0 @@ -/* - * 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" -#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; - - /** - * 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; - - /** - * 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 - * 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; - } - - /** - * Wrapper to access private member "array_depth" 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_array_depth(const ir_array_refcount_entry &entry) - { - return entry.array_depth; - } -}; - -void -array_refcount_test::SetUp() -{ - glsl_type_singleton_init_or_ref(); - - 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_array_type(&glsl_type_builtin_vec4, 5, 0); - const glsl_type *const array_4_of_array_5_of_vec4 = - glsl_array_type(array_5_of_vec4, 4, 0); - array_3_of_array_4_of_array_5_of_vec4 = - glsl_array_type(array_4_of_array_5_of_vec4, 3, 0); - - array_3_of_int = glsl_array_type(&glsl_type_builtin_int, 3, 0); -} - -void -array_refcount_test::TearDown() -{ - delete body; - body = NULL; - - ralloc_free(mem_ctx); - mem_ctx = NULL; - - glsl_type_singleton_decref(); -} - -static operand -deref_array(operand array, operand index) -{ - 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) -{ - void *mem_ctx = ralloc_parent(s.val); - - ir_rvalue *val = new(mem_ctx) ir_dereference_record(s.val, field); - - return operand(val); -} - -/** - * Verify that only the specified set of ir_variables exists in the hash table - */ -static void -validate_variables_in_hash_table(struct hash_table *ht, - unsigned count, - ...) -{ - ir_variable **vars = new ir_variable *[count]; - va_list args; - - /* Make a copy of the list of expected ir_variables. The copied list can - * be modified during the checking. - */ - va_start(args, count); - - for (unsigned i = 0; i < count; i++) - vars[i] = va_arg(args, ir_variable *); - - va_end(args); - - hash_table_foreach(ht, entry) { - const ir_instruction *const ir = (ir_instruction *) entry->key; - const ir_variable *const v = ir->as_variable(); - - if (v == NULL) { - ADD_FAILURE() << "Invalid junk in hash table: ir_type = " - << ir->ir_type << ", address = " - << (void *) ir; - continue; - } - - unsigned i; - for (i = 0; i < count; i++) { - if (vars[i] == NULL) - continue; - - if (vars[i] == v) - break; - } - - if (i == count) { - ADD_FAILURE() << "Invalid variable in hash table: \"" - << v->name << "\""; - } else { - /* As each variable is encountered, remove it from the set. Don't - * bother compacting the set because we don't care about - * performance here. - */ - vars[i] = NULL; - } - } - - /* Check that there's nothing left in the set. */ - for (unsigned i = 0; i < count; i++) { - if (vars[i] != NULL) { - ADD_FAILURE() << "Variable was not in the hash table: \"" - << vars[i]->name << "\""; - } - } - - delete [] vars; -} - -TEST_F(array_refcount_test, ir_array_refcount_entry_initial_state_for_scalar) -{ - ir_variable *const var = - new(mem_ctx) ir_variable(&glsl_type_builtin_int, "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_EQ(0, get_array_depth(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_builtin_vec4, "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_EQ(0, get_array_depth(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_builtin_mat4, "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_EQ(0, get_array_depth(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 = glsl_get_aoa_size(var->type); - - 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)); - EXPECT_EQ(3, get_array_depth(entry)); - - for (unsigned i = 0; i < total_elements; i++) - EXPECT_FALSE(entry.is_linearized_index_referenced(i)) << "index = " << i; -} - -TEST_F(array_refcount_test, mark_array_elements_referenced_simple) -{ - 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 = glsl_get_aoa_size(var->type); - - ir_array_refcount_entry entry(var); - - static const array_deref_range dr[] = { - { 0, 5 }, { 1, 4 }, { 2, 3 } - }; - const unsigned accessed_element = 0 + (1 * 5) + (2 * 4 * 5); - - link_util_mark_array_elements_referenced(dr, 3, entry.array_depth, - entry.bits); - - for (unsigned i = 0; i < total_elements; i++) - EXPECT_EQ(i == accessed_element, entry.is_linearized_index_referenced(i)); -} - -TEST_F(array_refcount_test, mark_array_elements_referenced_whole_first_array) -{ - ir_variable *const var = - new(mem_ctx) ir_variable(array_3_of_array_4_of_array_5_of_vec4, - "a", - ir_var_auto); - - ir_array_refcount_entry entry(var); - - static const array_deref_range dr[] = { - { 0, 5 }, { 1, 4 }, { 3, 3 } - }; - - link_util_mark_array_elements_referenced(dr, 3, entry.array_depth, - entry.bits); - - for (unsigned i = 0; i < 3; i++) { - for (unsigned j = 0; j < 4; j++) { - for (unsigned k = 0; k < 5; k++) { - const bool accessed = (j == 1) && (k == 0); - const unsigned linearized_index = k + (j * 5) + (i * 4 * 5); - - EXPECT_EQ(accessed, - entry.is_linearized_index_referenced(linearized_index)); - } - } - } -} - -TEST_F(array_refcount_test, mark_array_elements_referenced_whole_second_array) -{ - ir_variable *const var = - new(mem_ctx) ir_variable(array_3_of_array_4_of_array_5_of_vec4, - "a", - ir_var_auto); - - ir_array_refcount_entry entry(var); - - static const array_deref_range dr[] = { - { 0, 5 }, { 4, 4 }, { 1, 3 } - }; - - link_util_mark_array_elements_referenced(dr, 3, entry.array_depth, - entry.bits); - - for (unsigned i = 0; i < 3; i++) { - for (unsigned j = 0; j < 4; j++) { - for (unsigned k = 0; k < 5; k++) { - const bool accessed = (i == 1) && (k == 0); - const unsigned linearized_index = k + (j * 5) + (i * 4 * 5); - - EXPECT_EQ(accessed, - entry.is_linearized_index_referenced(linearized_index)); - } - } - } -} - -TEST_F(array_refcount_test, mark_array_elements_referenced_whole_third_array) -{ - ir_variable *const var = - new(mem_ctx) ir_variable(array_3_of_array_4_of_array_5_of_vec4, - "a", - ir_var_auto); - - ir_array_refcount_entry entry(var); - - static const array_deref_range dr[] = { - { 5, 5 }, { 2, 4 }, { 1, 3 } - }; - - link_util_mark_array_elements_referenced(dr, 3, entry.array_depth, - entry.bits); - - for (unsigned i = 0; i < 3; i++) { - for (unsigned j = 0; j < 4; j++) { - for (unsigned k = 0; k < 5; k++) { - const bool accessed = (i == 1) && (j == 2); - const unsigned linearized_index = k + (j * 5) + (i * 4 * 5); - - EXPECT_EQ(accessed, - entry.is_linearized_index_referenced(linearized_index)); - } - } - } -} - -TEST_F(array_refcount_test, mark_array_elements_referenced_whole_first_and_third_arrays) -{ - ir_variable *const var = - new(mem_ctx) ir_variable(array_3_of_array_4_of_array_5_of_vec4, - "a", - ir_var_auto); - - ir_array_refcount_entry entry(var); - - static const array_deref_range dr[] = { - { 5, 5 }, { 3, 4 }, { 3, 3 } - }; - - link_util_mark_array_elements_referenced(dr, 3, entry.array_depth, - entry.bits); - - for (unsigned i = 0; i < 3; i++) { - for (unsigned j = 0; j < 4; j++) { - for (unsigned k = 0; k < 5; k++) { - const bool accessed = (j == 3); - const unsigned linearized_index = k + (j * 5) + (i * 4 * 5); - - EXPECT_EQ(accessed, - entry.is_linearized_index_referenced(linearized_index)); - } - } - } -} - -TEST_F(array_refcount_test, do_not_process_vector_indexing) -{ - /* Vectors and matrices can also be indexed in much the same manner as - * arrays. The visitor should not try to track per-element accesses to - * these types. - */ - ir_variable *var_a = new(mem_ctx) ir_variable(&glsl_type_builtin_float, - "a", - ir_var_auto); - ir_variable *var_b = new(mem_ctx) ir_variable(&glsl_type_builtin_int, - "b", - ir_var_auto); - ir_variable *var_c = new(mem_ctx) ir_variable(&glsl_type_builtin_vec4, - "c", - ir_var_auto); - - body->emit(assign(var_a, deref_array(var_c, var_b))); - - ir_array_refcount_visitor v; - - visit_list_elements(&v, &instructions); - - ir_array_refcount_entry *entry_a = v.get_variable_entry(var_a); - ir_array_refcount_entry *entry_b = v.get_variable_entry(var_b); - ir_array_refcount_entry *entry_c = v.get_variable_entry(var_c); - - EXPECT_TRUE(entry_a->is_referenced); - EXPECT_TRUE(entry_b->is_referenced); - EXPECT_TRUE(entry_c->is_referenced); - - /* As validated by previous tests, for non-array types, num_bits is 1. */ - ASSERT_EQ(1, get_num_bits(*entry_c)); - EXPECT_FALSE(entry_c->is_linearized_index_referenced(0)); -} - -TEST_F(array_refcount_test, do_not_process_matrix_indexing) -{ - /* Vectors and matrices can also be indexed in much the same manner as - * arrays. The visitor should not try to track per-element accesses to - * these types. - */ - ir_variable *var_a = new(mem_ctx) ir_variable(&glsl_type_builtin_vec4, - "a", - ir_var_auto); - ir_variable *var_b = new(mem_ctx) ir_variable(&glsl_type_builtin_int, - "b", - ir_var_auto); - ir_variable *var_c = new(mem_ctx) ir_variable(&glsl_type_builtin_mat4, - "c", - ir_var_auto); - - body->emit(assign(var_a, deref_array(var_c, var_b))); - - ir_array_refcount_visitor v; - - visit_list_elements(&v, &instructions); - - ir_array_refcount_entry *entry_a = v.get_variable_entry(var_a); - ir_array_refcount_entry *entry_b = v.get_variable_entry(var_b); - ir_array_refcount_entry *entry_c = v.get_variable_entry(var_c); - - EXPECT_TRUE(entry_a->is_referenced); - EXPECT_TRUE(entry_b->is_referenced); - EXPECT_TRUE(entry_c->is_referenced); - - /* As validated by previous tests, for non-array types, num_bits is 1. */ - ASSERT_EQ(1, get_num_bits(*entry_c)); - EXPECT_FALSE(entry_c->is_linearized_index_referenced(0)); -} - -TEST_F(array_refcount_test, do_not_process_array_inside_structure) -{ - /* Structures can contain arrays. The visitor should not try to track - * per-element accesses to arrays contained inside structures. - */ - const glsl_struct_field fields[] = { - glsl_struct_field(array_3_of_int, "i"), - }; - - const glsl_type *const record_of_array_3_of_int = - glsl_struct_type(fields, ARRAY_SIZE(fields), "S", false /* packed */); - - ir_variable *var_a = new(mem_ctx) ir_variable(&glsl_type_builtin_int, - "a", - ir_var_auto); - - ir_variable *var_b = new(mem_ctx) ir_variable(record_of_array_3_of_int, - "b", - ir_var_auto); - - /* a = b.i[2] */ - body->emit(assign(var_a, - deref_array( - deref_struct(var_b, "i"), - body->constant(int(2))))); - - ir_array_refcount_visitor v; - - visit_list_elements(&v, &instructions); - - ir_array_refcount_entry *entry_a = v.get_variable_entry(var_a); - ir_array_refcount_entry *entry_b = v.get_variable_entry(var_b); - - EXPECT_TRUE(entry_a->is_referenced); - EXPECT_TRUE(entry_b->is_referenced); - - ASSERT_EQ(1, get_num_bits(*entry_b)); - EXPECT_FALSE(entry_b->is_linearized_index_referenced(0)); - - validate_variables_in_hash_table(v.ht, 2, var_a, var_b); -} - -TEST_F(array_refcount_test, visit_simple_indexing) -{ - ir_variable *var_a = new(mem_ctx) ir_variable(&glsl_type_builtin_vec4, - "a", - ir_var_auto); - ir_variable *var_b = new(mem_ctx) ir_variable(array_3_of_array_4_of_array_5_of_vec4, - "b", - ir_var_auto); - - /* a = b[2][1][0] */ - body->emit(assign(var_a, - deref_array( - deref_array( - deref_array(var_b, body->constant(int(2))), - body->constant(int(1))), - body->constant(int(0))))); - - ir_array_refcount_visitor v; - - visit_list_elements(&v, &instructions); - - const unsigned accessed_element = 0 + (1 * 5) + (2 * 4 * 5); - ir_array_refcount_entry *entry_b = v.get_variable_entry(var_b); - const unsigned total_elements = glsl_get_aoa_size(var_b->type); - - for (unsigned i = 0; i < total_elements; i++) - EXPECT_EQ(i == accessed_element, entry_b->is_linearized_index_referenced(i)) << - "i = " << i; - - validate_variables_in_hash_table(v.ht, 2, var_a, var_b); -} - -TEST_F(array_refcount_test, visit_whole_second_array_indexing) -{ - ir_variable *var_a = new(mem_ctx) ir_variable(&glsl_type_builtin_vec4, - "a", - ir_var_auto); - ir_variable *var_b = new(mem_ctx) ir_variable(array_3_of_array_4_of_array_5_of_vec4, - "b", - ir_var_auto); - ir_variable *var_i = new(mem_ctx) ir_variable(&glsl_type_builtin_int, - "i", - ir_var_auto); - - /* a = b[2][i][1] */ - body->emit(assign(var_a, - deref_array( - deref_array( - deref_array(var_b, body->constant(int(2))), - var_i), - body->constant(int(1))))); - - ir_array_refcount_visitor v; - - visit_list_elements(&v, &instructions); - - ir_array_refcount_entry *const entry_b = v.get_variable_entry(var_b); - for (unsigned i = 0; i < 3; i++) { - for (unsigned j = 0; j < 4; j++) { - for (unsigned k = 0; k < 5; k++) { - const bool accessed = (i == 2) && (k == 1); - const unsigned linearized_index = k + (j * 5) + (i * 4 * 5); - - EXPECT_EQ(accessed, - entry_b->is_linearized_index_referenced(linearized_index)) << - "i = " << i; - } - } - } - - validate_variables_in_hash_table(v.ht, 3, var_a, var_b, var_i); -} - -TEST_F(array_refcount_test, visit_array_indexing_an_array) -{ - ir_variable *var_a = new(mem_ctx) ir_variable(&glsl_type_builtin_vec4, - "a", - ir_var_auto); - ir_variable *var_b = new(mem_ctx) ir_variable(array_3_of_array_4_of_array_5_of_vec4, - "b", - ir_var_auto); - ir_variable *var_c = new(mem_ctx) ir_variable(array_3_of_int, - "c", - ir_var_auto); - ir_variable *var_i = new(mem_ctx) ir_variable(&glsl_type_builtin_int, - "i", - ir_var_auto); - - /* a = b[2][3][c[i]] */ - body->emit(assign(var_a, - deref_array( - deref_array( - deref_array(var_b, body->constant(int(2))), - body->constant(int(3))), - deref_array(var_c, var_i)))); - - ir_array_refcount_visitor v; - - visit_list_elements(&v, &instructions); - - ir_array_refcount_entry *const entry_b = v.get_variable_entry(var_b); - - for (unsigned i = 0; i < 3; i++) { - for (unsigned j = 0; j < 4; j++) { - for (unsigned k = 0; k < 5; k++) { - const bool accessed = (i == 2) && (j == 3); - const unsigned linearized_index = k + (j * 5) + (i * 4 * 5); - - EXPECT_EQ(accessed, - entry_b->is_linearized_index_referenced(linearized_index)) << - "array b[" << i << "][" << j << "][" << k << "], " << - "linear index = " << linearized_index; - } - } - } - - ir_array_refcount_entry *const entry_c = v.get_variable_entry(var_c); - - for (int i = 0; i < glsl_array_size(var_c->type); i++) { - EXPECT_EQ(true, entry_c->is_linearized_index_referenced(i)) << - "array c, i = " << i; - } - - validate_variables_in_hash_table(v.ht, 4, var_a, var_b, var_c, var_i); -} - -TEST_F(array_refcount_test, visit_array_indexing_with_itself) -{ - const glsl_type *const array_2_of_array_3_of_int = - glsl_array_type(array_3_of_int, 2, 0); - - const glsl_type *const array_2_of_array_2_of_array_3_of_int = - glsl_array_type(array_2_of_array_3_of_int, 2, 0); - - ir_variable *var_a = new(mem_ctx) ir_variable(&glsl_type_builtin_int, - "a", - ir_var_auto); - ir_variable *var_b = new(mem_ctx) ir_variable(array_2_of_array_2_of_array_3_of_int, - "b", - ir_var_auto); - - /* Given GLSL code: - * - * int b[2][2][3]; - * a = b[ b[0][0][0] ][ b[ b[0][1][0] ][ b[1][0][0] ][1] ][2] - * - * b[0][0][0], b[0][1][0], and b[1][0][0] are trivially accessed. - * - * b[*][*][1] and b[*][*][2] are accessed. - * - * Only b[1][1][0] is not accessed. - */ - operand b000 = deref_array( - deref_array( - deref_array(var_b, body->constant(int(0))), - body->constant(int(0))), - body->constant(int(0))); - - operand b010 = deref_array( - deref_array( - deref_array(var_b, body->constant(int(0))), - body->constant(int(1))), - body->constant(int(0))); - - operand b100 = deref_array( - deref_array( - deref_array(var_b, body->constant(int(1))), - body->constant(int(0))), - body->constant(int(0))); - - operand b_b010_b100_1 = deref_array( - deref_array( - deref_array(var_b, b010), - b100), - body->constant(int(1))); - - body->emit(assign(var_a, - deref_array( - deref_array( - deref_array(var_b, b000), - b_b010_b100_1), - body->constant(int(2))))); - - ir_array_refcount_visitor v; - - visit_list_elements(&v, &instructions); - - ir_array_refcount_entry *const entry_b = v.get_variable_entry(var_b); - - for (unsigned i = 0; i < 2; i++) { - for (unsigned j = 0; j < 2; j++) { - for (unsigned k = 0; k < 3; k++) { - const bool accessed = !(i == 1 && j == 1 && k == 0); - const unsigned linearized_index = k + (j * 3) + (i * 2 * 3); - - EXPECT_EQ(accessed, - entry_b->is_linearized_index_referenced(linearized_index)) << - "array b[" << i << "][" << j << "][" << k << "], " << - "linear index = " << linearized_index; - } - } - } - - validate_variables_in_hash_table(v.ht, 2, var_a, var_b); -} diff --git a/src/compiler/glsl/tests/meson.build b/src/compiler/glsl/tests/meson.build index 3d0773039b6..895309829ed 100644 --- a/src/compiler/glsl/tests/meson.build +++ b/src/compiler/glsl/tests/meson.build @@ -2,7 +2,6 @@ # SPDX-License-Identifier: MIT general_ir_test_files = files( - 'array_refcount_test.cpp', 'builtin_variable_test.cpp', 'general_ir_test.cpp', )