1b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick/*
2b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick * Copyright © 2016 Intel Corporation
3b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick *
4b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick * Permission is hereby granted, free of charge, to any person obtaining a
5b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick * copy of this software and associated documentation files (the "Software"),
6b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick * to deal in the Software without restriction, including without limitation
7b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick * and/or sell copies of the Software, and to permit persons to whom the
9b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick * Software is furnished to do so, subject to the following conditions:
10b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick *
11b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick * The above copyright notice and this permission notice (including the next
12b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick * paragraph) shall be included in all copies or substantial portions of the
13b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick * Software.
14b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick *
15b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick * DEALINGS IN THE SOFTWARE.
22b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick */
23b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick#include <gtest/gtest.h>
24b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick#include "ir.h"
25b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick#include "ir_array_refcount.h"
26d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick#include "ir_builder.h"
27d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick#include "util/hash_table.h"
28d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
29d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanickusing namespace ir_builder;
30b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick
31b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanickclass array_refcount_test : public ::testing::Test {
32b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanickpublic:
33b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick   virtual void SetUp();
34b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick   virtual void TearDown();
35b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick
36d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   exec_list instructions;
37d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   ir_factory *body;
38b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick   void *mem_ctx;
39b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick
40b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick   /**
41b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick    * glsl_type for a vec4[3][4][5].
42b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick    *
43b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick    * The exceptionally verbose name is picked because it matches the syntax
44b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick    * of http://cdecl.org/.
45b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick    */
46b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick   const glsl_type *array_3_of_array_4_of_array_5_of_vec4;
47b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick
48b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick   /**
49d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick    * glsl_type for a int[3].
50d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick    *
51d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick    * The exceptionally verbose name is picked because it matches the syntax
52d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick    * of http://cdecl.org/.
53d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick    */
54d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   const glsl_type *array_3_of_int;
55d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
56d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   /**
57b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick    * Wrapper to access private member "bits" of ir_array_refcount_entry
58b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick    *
59b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick    * The test class is a friend to ir_array_refcount_entry, but the
60b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick    * individual tests are not part of the class.  Since the friendliness of
61b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick    * the test class does not extend to the tests, provide a wrapper.
62b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick    */
63b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick   const BITSET_WORD *get_bits(const ir_array_refcount_entry &entry)
64b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick   {
65b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick      return entry.bits;
66b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick   }
67b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick
68b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick   /**
69b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick    * Wrapper to access private member "num_bits" of ir_array_refcount_entry
70b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick    *
71b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick    * The test class is a friend to ir_array_refcount_entry, but the
72b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick    * individual tests are not part of the class.  Since the friendliness of
73b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick    * the test class does not extend to the tests, provide a wrapper.
74b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick    */
75b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick   unsigned get_num_bits(const ir_array_refcount_entry &entry)
76b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick   {
77b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick      return entry.num_bits;
78b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick   }
79e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick
80e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick   /**
81e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick    * Wrapper to access private member "array_depth" of ir_array_refcount_entry
82e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick    *
83e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick    * The test class is a friend to ir_array_refcount_entry, but the
84e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick    * individual tests are not part of the class.  Since the friendliness of
85e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick    * the test class does not extend to the tests, provide a wrapper.
86e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick    */
87e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick   unsigned get_array_depth(const ir_array_refcount_entry &entry)
88e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick   {
89e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick      return entry.array_depth;
90e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick   }
91b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick};
92b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick
93b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanickvoid
94b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanickarray_refcount_test::SetUp()
95b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick{
96b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick   mem_ctx = ralloc_context(NULL);
97b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick
98d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   instructions.make_empty();
99d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   body = new ir_factory(&instructions, mem_ctx);
100d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
101b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick   /* The type of vec4 x[3][4][5]; */
102b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick   const glsl_type *const array_5_of_vec4 =
103b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick      glsl_type::get_array_instance(glsl_type::vec4_type, 5);
104b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick   const glsl_type *const array_4_of_array_5_of_vec4 =
105b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick      glsl_type::get_array_instance(array_5_of_vec4, 4);
106b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick   array_3_of_array_4_of_array_5_of_vec4 =
107b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick      glsl_type::get_array_instance(array_4_of_array_5_of_vec4, 3);
108d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
109d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   array_3_of_int = glsl_type::get_array_instance(glsl_type::int_type, 3);
110b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick}
111b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick
112b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanickvoid
113b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanickarray_refcount_test::TearDown()
114b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick{
115d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   delete body;
116d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   body = NULL;
117d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
118b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick   ralloc_free(mem_ctx);
119b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick   mem_ctx = NULL;
120b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick}
121b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick
122d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanickstatic operand
123d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanickderef_array(operand array, operand index)
124d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick{
125d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   void *mem_ctx = ralloc_parent(array.val);
126d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
127d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   ir_rvalue *val = new(mem_ctx) ir_dereference_array(array.val, index.val);
128d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
129d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   return operand(val);
130d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick}
131d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
132d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanickstatic operand
133d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanickderef_struct(operand s, const char *field)
134d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick{
135d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   void *mem_ctx = ralloc_parent(s.val);
136d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
137d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   ir_rvalue *val = new(mem_ctx) ir_dereference_record(s.val, field);
138d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
139d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   return operand(val);
140d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick}
141d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
142d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick/**
143d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick * Verify that only the specified set of ir_variables exists in the hash table
144d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick */
145d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanickstatic void
146d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanickvalidate_variables_in_hash_table(struct hash_table *ht,
147d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                                 unsigned count,
148d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                                 ...)
149d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick{
150d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   ir_variable **vars = new ir_variable *[count];
151d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   va_list args;
152d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
153d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   /* Make a copy of the list of expected ir_variables.  The copied list can
154d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick    * be modified during the checking.
155d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick    */
156d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   va_start(args, count);
157d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
158d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   for (unsigned i = 0; i < count; i++)
159d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick      vars[i] = va_arg(args, ir_variable *);
160d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
161d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   va_end(args);
162d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
163d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   struct hash_entry *entry;
164d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   hash_table_foreach(ht, entry) {
165d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick      const ir_instruction *const ir = (ir_instruction *) entry->key;
166d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick      const ir_variable *const v = ir->as_variable();
167d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
168d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick      if (v == NULL) {
169d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick         ADD_FAILURE() << "Invalid junk in hash table: ir_type = "
170d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                       << ir->ir_type << ", address = "
171d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                       << (void *) ir;
172d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick         continue;
173d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick      }
174d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
175d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick      unsigned i;
176d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick      for (i = 0; i < count; i++) {
177d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick         if (vars[i] == NULL)
178d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick            continue;
179d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
180d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick         if (vars[i] == v)
181d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick            break;
182d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick      }
183d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
184d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick      if (i == count) {
185d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick            ADD_FAILURE() << "Invalid variable in hash table: \""
186d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                          << v->name << "\"";
187d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick      } else {
188d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick         /* As each variable is encountered, remove it from the set.  Don't
189d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick          * bother compacting the set because we don't care about
190d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick          * performance here.
191d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick          */
192d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick         vars[i] = NULL;
193d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick      }
194d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   }
195d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
196d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   /* Check that there's nothing left in the set. */
197d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   for (unsigned i = 0; i < count; i++) {
198d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick      if (vars[i] != NULL) {
199d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick         ADD_FAILURE() << "Variable was not in the hash table: \""
200d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                          << vars[i]->name << "\"";
201d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick      }
202d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   }
203d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
204d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   delete [] vars;
205d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick}
206d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
207b7053b80f27091acc8ccc954db99197e3073bff4Ian RomanickTEST_F(array_refcount_test, ir_array_refcount_entry_initial_state_for_scalar)
208b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick{
209b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick   ir_variable *const var =
210b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick      new(mem_ctx) ir_variable(glsl_type::int_type, "a", ir_var_auto);
211b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick
212b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick   ir_array_refcount_entry entry(var);
213b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick
214b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick   ASSERT_NE((void *)0, get_bits(entry));
215b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick   EXPECT_FALSE(entry.is_referenced);
216b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick   EXPECT_EQ(1, get_num_bits(entry));
217e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick   EXPECT_EQ(0, get_array_depth(entry));
218b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick   EXPECT_FALSE(entry.is_linearized_index_referenced(0));
219b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick}
220b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick
221b7053b80f27091acc8ccc954db99197e3073bff4Ian RomanickTEST_F(array_refcount_test, ir_array_refcount_entry_initial_state_for_vector)
222b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick{
223b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick   ir_variable *const var =
224b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick      new(mem_ctx) ir_variable(glsl_type::vec4_type, "a", ir_var_auto);
225b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick
226b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick   ir_array_refcount_entry entry(var);
227b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick
228b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick   ASSERT_NE((void *)0, get_bits(entry));
229b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick   EXPECT_FALSE(entry.is_referenced);
230b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick   EXPECT_EQ(1, get_num_bits(entry));
231e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick   EXPECT_EQ(0, get_array_depth(entry));
232b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick   EXPECT_FALSE(entry.is_linearized_index_referenced(0));
233b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick}
234b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick
235b7053b80f27091acc8ccc954db99197e3073bff4Ian RomanickTEST_F(array_refcount_test, ir_array_refcount_entry_initial_state_for_matrix)
236b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick{
237b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick   ir_variable *const var =
238b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick      new(mem_ctx) ir_variable(glsl_type::mat4_type, "a", ir_var_auto);
239b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick
240b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick   ir_array_refcount_entry entry(var);
241b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick
242b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick   ASSERT_NE((void *)0, get_bits(entry));
243b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick   EXPECT_FALSE(entry.is_referenced);
244b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick   EXPECT_EQ(1, get_num_bits(entry));
245e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick   EXPECT_EQ(0, get_array_depth(entry));
246b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick   EXPECT_FALSE(entry.is_linearized_index_referenced(0));
247b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick}
248b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick
249b7053b80f27091acc8ccc954db99197e3073bff4Ian RomanickTEST_F(array_refcount_test, ir_array_refcount_entry_initial_state_for_array)
250b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick{
251b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick   ir_variable *const var =
252b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick      new(mem_ctx) ir_variable(array_3_of_array_4_of_array_5_of_vec4,
253b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick                               "a",
254b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick                               ir_var_auto);
255b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick   const unsigned total_elements = var->type->arrays_of_arrays_size();
256b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick
257b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick   ir_array_refcount_entry entry(var);
258b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick
259b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick   ASSERT_NE((void *)0, get_bits(entry));
260b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick   EXPECT_FALSE(entry.is_referenced);
261b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick   EXPECT_EQ(total_elements, get_num_bits(entry));
262e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick   EXPECT_EQ(3, get_array_depth(entry));
263b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick
264b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick   for (unsigned i = 0; i < total_elements; i++)
265b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick      EXPECT_FALSE(entry.is_linearized_index_referenced(i)) << "index = " << i;
266b7053b80f27091acc8ccc954db99197e3073bff4Ian Romanick}
267e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick
268e92935089bd9a987027d1f0791e7298bb3a57113Ian RomanickTEST_F(array_refcount_test, mark_array_elements_referenced_simple)
269e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick{
270e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick   ir_variable *const var =
271e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick      new(mem_ctx) ir_variable(array_3_of_array_4_of_array_5_of_vec4,
272e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick                               "a",
273e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick                               ir_var_auto);
274e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick   const unsigned total_elements = var->type->arrays_of_arrays_size();
275e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick
276e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick   ir_array_refcount_entry entry(var);
277e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick
278e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick   static const array_deref_range dr[] = {
279e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick      { 0, 5 }, { 1, 4 }, { 2, 3 }
280e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick   };
281e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick   const unsigned accessed_element = 0 + (1 * 5) + (2 * 4 * 5);
282e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick
283e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick   entry.mark_array_elements_referenced(dr, 3);
284e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick
285e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick   for (unsigned i = 0; i < total_elements; i++)
286e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick      EXPECT_EQ(i == accessed_element, entry.is_linearized_index_referenced(i));
287e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick}
288e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick
289e92935089bd9a987027d1f0791e7298bb3a57113Ian RomanickTEST_F(array_refcount_test, mark_array_elements_referenced_whole_first_array)
290e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick{
291e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick   ir_variable *const var =
292e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick      new(mem_ctx) ir_variable(array_3_of_array_4_of_array_5_of_vec4,
293e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick                               "a",
294e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick                               ir_var_auto);
295e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick
296e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick   ir_array_refcount_entry entry(var);
297e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick
298e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick   static const array_deref_range dr[] = {
299e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick      { 0, 5 }, { 1, 4 }, { 3, 3 }
300e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick   };
301e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick
302e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick   entry.mark_array_elements_referenced(dr, 3);
303e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick
304e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick   for (unsigned i = 0; i < 3; i++) {
305e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick      for (unsigned j = 0; j < 4; j++) {
306e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick         for (unsigned k = 0; k < 5; k++) {
307e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick            const bool accessed = (j == 1) && (k == 0);
308e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick            const unsigned linearized_index = k + (j * 5) + (i * 4 * 5);
309e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick
310e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick            EXPECT_EQ(accessed,
311e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick                      entry.is_linearized_index_referenced(linearized_index));
312e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick         }
313e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick      }
314e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick   }
315e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick}
316e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick
317e92935089bd9a987027d1f0791e7298bb3a57113Ian RomanickTEST_F(array_refcount_test, mark_array_elements_referenced_whole_second_array)
318e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick{
319e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick   ir_variable *const var =
320e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick      new(mem_ctx) ir_variable(array_3_of_array_4_of_array_5_of_vec4,
321e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick                               "a",
322e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick                               ir_var_auto);
323e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick
324e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick   ir_array_refcount_entry entry(var);
325e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick
326e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick   static const array_deref_range dr[] = {
327e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick      { 0, 5 }, { 4, 4 }, { 1, 3 }
328e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick   };
329e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick
330e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick   entry.mark_array_elements_referenced(dr, 3);
331e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick
332e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick   for (unsigned i = 0; i < 3; i++) {
333e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick      for (unsigned j = 0; j < 4; j++) {
334e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick         for (unsigned k = 0; k < 5; k++) {
335e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick            const bool accessed = (i == 1) && (k == 0);
336e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick            const unsigned linearized_index = k + (j * 5) + (i * 4 * 5);
337e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick
338e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick            EXPECT_EQ(accessed,
339e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick                      entry.is_linearized_index_referenced(linearized_index));
340e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick         }
341e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick      }
342e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick   }
343e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick}
344e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick
345e92935089bd9a987027d1f0791e7298bb3a57113Ian RomanickTEST_F(array_refcount_test, mark_array_elements_referenced_whole_third_array)
346e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick{
347e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick   ir_variable *const var =
348e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick      new(mem_ctx) ir_variable(array_3_of_array_4_of_array_5_of_vec4,
349e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick                               "a",
350e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick                               ir_var_auto);
351e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick
352e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick   ir_array_refcount_entry entry(var);
353e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick
354e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick   static const array_deref_range dr[] = {
355e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick      { 5, 5 }, { 2, 4 }, { 1, 3 }
356e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick   };
357e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick
358e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick   entry.mark_array_elements_referenced(dr, 3);
359e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick
360e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick   for (unsigned i = 0; i < 3; i++) {
361e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick      for (unsigned j = 0; j < 4; j++) {
362e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick         for (unsigned k = 0; k < 5; k++) {
363e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick            const bool accessed = (i == 1) && (j == 2);
364e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick            const unsigned linearized_index = k + (j * 5) + (i * 4 * 5);
365e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick
366e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick            EXPECT_EQ(accessed,
367e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick                      entry.is_linearized_index_referenced(linearized_index));
368e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick         }
369e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick      }
370e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick   }
371e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick}
372e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick
373e92935089bd9a987027d1f0791e7298bb3a57113Ian RomanickTEST_F(array_refcount_test, mark_array_elements_referenced_whole_first_and_third_arrays)
374e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick{
375e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick   ir_variable *const var =
376e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick      new(mem_ctx) ir_variable(array_3_of_array_4_of_array_5_of_vec4,
377e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick                               "a",
378e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick                               ir_var_auto);
379e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick
380e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick   ir_array_refcount_entry entry(var);
381e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick
382e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick   static const array_deref_range dr[] = {
383e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick      { 5, 5 }, { 3, 4 }, { 3, 3 }
384e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick   };
385e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick
386e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick   entry.mark_array_elements_referenced(dr, 3);
387e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick
388e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick   for (unsigned i = 0; i < 3; i++) {
389e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick      for (unsigned j = 0; j < 4; j++) {
390e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick         for (unsigned k = 0; k < 5; k++) {
391e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick            const bool accessed = (j == 3);
392e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick            const unsigned linearized_index = k + (j * 5) + (i * 4 * 5);
393e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick
394e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick            EXPECT_EQ(accessed,
395e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick                      entry.is_linearized_index_referenced(linearized_index));
396e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick         }
397e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick      }
398e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick   }
399e92935089bd9a987027d1f0791e7298bb3a57113Ian Romanick}
400d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
401d32956935edf06c8ae6872c707bc65187b4a1d15Ian RomanickTEST_F(array_refcount_test, do_not_process_vector_indexing)
402d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick{
403d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   /* Vectors and matrices can also be indexed in much the same manner as
404d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick    * arrays.  The visitor should not try to track per-element accesses to
405d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick    * these types.
406d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick    */
407d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   ir_variable *var_a = new(mem_ctx) ir_variable(glsl_type::float_type,
408d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                                                 "a",
409d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                                                 ir_var_auto);
410d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   ir_variable *var_b = new(mem_ctx) ir_variable(glsl_type::int_type,
411d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                                                 "b",
412d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                                                 ir_var_auto);
413d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   ir_variable *var_c = new(mem_ctx) ir_variable(glsl_type::vec4_type,
414d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                                                 "c",
415d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                                                 ir_var_auto);
416d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
417d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   body->emit(assign(var_a, deref_array(var_c, var_b)));
418d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
419d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   ir_array_refcount_visitor v;
420d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
421d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   visit_list_elements(&v, &instructions);
422d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
423d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   ir_array_refcount_entry *entry_a = v.get_variable_entry(var_a);
424d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   ir_array_refcount_entry *entry_b = v.get_variable_entry(var_b);
425d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   ir_array_refcount_entry *entry_c = v.get_variable_entry(var_c);
426d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
427d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   EXPECT_TRUE(entry_a->is_referenced);
428d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   EXPECT_TRUE(entry_b->is_referenced);
429d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   EXPECT_TRUE(entry_c->is_referenced);
430d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
431d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   /* As validated by previous tests, for non-array types, num_bits is 1. */
432d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   ASSERT_EQ(1, get_num_bits(*entry_c));
433d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   EXPECT_FALSE(entry_c->is_linearized_index_referenced(0));
434d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick}
435d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
436d32956935edf06c8ae6872c707bc65187b4a1d15Ian RomanickTEST_F(array_refcount_test, do_not_process_matrix_indexing)
437d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick{
438d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   /* Vectors and matrices can also be indexed in much the same manner as
439d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick    * arrays.  The visitor should not try to track per-element accesses to
440d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick    * these types.
441d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick    */
442d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   ir_variable *var_a = new(mem_ctx) ir_variable(glsl_type::vec4_type,
443d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                                                 "a",
444d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                                                 ir_var_auto);
445d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   ir_variable *var_b = new(mem_ctx) ir_variable(glsl_type::int_type,
446d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                                                 "b",
447d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                                                 ir_var_auto);
448d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   ir_variable *var_c = new(mem_ctx) ir_variable(glsl_type::mat4_type,
449d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                                                 "c",
450d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                                                 ir_var_auto);
451d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
452d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   body->emit(assign(var_a, deref_array(var_c, var_b)));
453d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
454d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   ir_array_refcount_visitor v;
455d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
456d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   visit_list_elements(&v, &instructions);
457d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
458d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   ir_array_refcount_entry *entry_a = v.get_variable_entry(var_a);
459d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   ir_array_refcount_entry *entry_b = v.get_variable_entry(var_b);
460d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   ir_array_refcount_entry *entry_c = v.get_variable_entry(var_c);
461d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
462d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   EXPECT_TRUE(entry_a->is_referenced);
463d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   EXPECT_TRUE(entry_b->is_referenced);
464d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   EXPECT_TRUE(entry_c->is_referenced);
465d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
466d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   /* As validated by previous tests, for non-array types, num_bits is 1. */
467d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   ASSERT_EQ(1, get_num_bits(*entry_c));
468d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   EXPECT_FALSE(entry_c->is_linearized_index_referenced(0));
469d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick}
470d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
471d32956935edf06c8ae6872c707bc65187b4a1d15Ian RomanickTEST_F(array_refcount_test, do_not_process_array_inside_structure)
472d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick{
473d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   /* Structures can contain arrays.  The visitor should not try to track
474d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick    * per-element accesses to arrays contained inside structures.
475d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick    */
476d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   const glsl_struct_field fields[] = {
477d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick      glsl_struct_field(array_3_of_int, "i"),
478d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   };
479d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
480d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   const glsl_type *const record_of_array_3_of_int =
481d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick      glsl_type::get_record_instance(fields, ARRAY_SIZE(fields), "S");
482d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
483d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   ir_variable *var_a = new(mem_ctx) ir_variable(glsl_type::int_type,
484d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                                                 "a",
485d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                                                 ir_var_auto);
486d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
487d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   ir_variable *var_b = new(mem_ctx) ir_variable(record_of_array_3_of_int,
488d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                                                 "b",
489d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                                                 ir_var_auto);
490d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
491d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   /* a = b.i[2] */
492d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   body->emit(assign(var_a,
493d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                     deref_array(
494d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                        deref_struct(var_b, "i"),
495d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                        body->constant(int(2)))));
496d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
497d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   ir_array_refcount_visitor v;
498d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
499d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   visit_list_elements(&v, &instructions);
500d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
501d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   ir_array_refcount_entry *entry_a = v.get_variable_entry(var_a);
502d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   ir_array_refcount_entry *entry_b = v.get_variable_entry(var_b);
503d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
504d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   EXPECT_TRUE(entry_a->is_referenced);
505d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   EXPECT_TRUE(entry_b->is_referenced);
506d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
507d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   ASSERT_EQ(1, get_num_bits(*entry_b));
508d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   EXPECT_FALSE(entry_b->is_linearized_index_referenced(0));
509d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
510d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   validate_variables_in_hash_table(v.ht, 2, var_a, var_b);
511d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick}
512d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
513d32956935edf06c8ae6872c707bc65187b4a1d15Ian RomanickTEST_F(array_refcount_test, visit_simple_indexing)
514d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick{
515d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   ir_variable *var_a = new(mem_ctx) ir_variable(glsl_type::vec4_type,
516d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                                                 "a",
517d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                                                 ir_var_auto);
518d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   ir_variable *var_b = new(mem_ctx) ir_variable(array_3_of_array_4_of_array_5_of_vec4,
519d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                                                 "b",
520d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                                                 ir_var_auto);
521d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
522d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   /* a = b[2][1][0] */
523d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   body->emit(assign(var_a,
524d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                     deref_array(
525d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                        deref_array(
526d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                           deref_array(var_b, body->constant(int(2))),
527d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                           body->constant(int(1))),
528d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                        body->constant(int(0)))));
529d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
530d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   ir_array_refcount_visitor v;
531d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
532d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   visit_list_elements(&v, &instructions);
533d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
534d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   const unsigned accessed_element = 0 + (1 * 5) + (2 * 4 * 5);
535d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   ir_array_refcount_entry *entry_b = v.get_variable_entry(var_b);
536d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   const unsigned total_elements = var_b->type->arrays_of_arrays_size();
537d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
538d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   for (unsigned i = 0; i < total_elements; i++)
539d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick      EXPECT_EQ(i == accessed_element, entry_b->is_linearized_index_referenced(i)) <<
540d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick         "i = " << i;
541d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
542d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   validate_variables_in_hash_table(v.ht, 2, var_a, var_b);
543d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick}
544d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
545d32956935edf06c8ae6872c707bc65187b4a1d15Ian RomanickTEST_F(array_refcount_test, visit_whole_second_array_indexing)
546d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick{
547d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   ir_variable *var_a = new(mem_ctx) ir_variable(glsl_type::vec4_type,
548d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                                                 "a",
549d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                                                 ir_var_auto);
550d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   ir_variable *var_b = new(mem_ctx) ir_variable(array_3_of_array_4_of_array_5_of_vec4,
551d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                                                 "b",
552d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                                                 ir_var_auto);
553d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   ir_variable *var_i = new(mem_ctx) ir_variable(glsl_type::int_type,
554d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                                                 "i",
555d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                                                 ir_var_auto);
556d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
557d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   /* a = b[2][i][1] */
558d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   body->emit(assign(var_a,
559d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                     deref_array(
560d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                        deref_array(
561d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                           deref_array(var_b, body->constant(int(2))),
562d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                           var_i),
563d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                        body->constant(int(1)))));
564d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
565d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   ir_array_refcount_visitor v;
566d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
567d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   visit_list_elements(&v, &instructions);
568d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
569d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   ir_array_refcount_entry *const entry_b = v.get_variable_entry(var_b);
570d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   for (unsigned i = 0; i < 3; i++) {
571d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick      for (unsigned j = 0; j < 4; j++) {
572d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick         for (unsigned k = 0; k < 5; k++) {
573d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick            const bool accessed = (i == 2) && (k == 1);
574d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick            const unsigned linearized_index = k + (j * 5) + (i * 4 * 5);
575d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
576d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick            EXPECT_EQ(accessed,
577d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                      entry_b->is_linearized_index_referenced(linearized_index)) <<
578d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick               "i = " << i;
579d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick         }
580d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick      }
581d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   }
582d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
583d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   validate_variables_in_hash_table(v.ht, 3, var_a, var_b, var_i);
584d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick}
585d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
586d32956935edf06c8ae6872c707bc65187b4a1d15Ian RomanickTEST_F(array_refcount_test, visit_array_indexing_an_array)
587d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick{
588d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   ir_variable *var_a = new(mem_ctx) ir_variable(glsl_type::vec4_type,
589d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                                                 "a",
590d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                                                 ir_var_auto);
591d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   ir_variable *var_b = new(mem_ctx) ir_variable(array_3_of_array_4_of_array_5_of_vec4,
592d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                                                 "b",
593d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                                                 ir_var_auto);
594d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   ir_variable *var_c = new(mem_ctx) ir_variable(array_3_of_int,
595d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                                                 "c",
596d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                                                 ir_var_auto);
597d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   ir_variable *var_i = new(mem_ctx) ir_variable(glsl_type::int_type,
598d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                                                 "i",
599d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                                                 ir_var_auto);
600d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
601d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   /* a = b[2][3][c[i]] */
602d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   body->emit(assign(var_a,
603d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                     deref_array(
604d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                        deref_array(
605d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                           deref_array(var_b, body->constant(int(2))),
606d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                           body->constant(int(3))),
607d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                        deref_array(var_c, var_i))));
608d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
609d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   ir_array_refcount_visitor v;
610d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
611d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   visit_list_elements(&v, &instructions);
612d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
613d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   ir_array_refcount_entry *const entry_b = v.get_variable_entry(var_b);
614d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
615d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   for (unsigned i = 0; i < 3; i++) {
616d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick      for (unsigned j = 0; j < 4; j++) {
617d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick         for (unsigned k = 0; k < 5; k++) {
618d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick            const bool accessed = (i == 2) && (j == 3);
619d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick            const unsigned linearized_index = k + (j * 5) + (i * 4 * 5);
620d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
621d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick            EXPECT_EQ(accessed,
622d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                      entry_b->is_linearized_index_referenced(linearized_index)) <<
623d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick               "array b[" << i << "][" << j << "][" << k << "], " <<
624d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick               "linear index = " << linearized_index;
625d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick         }
626d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick      }
627d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   }
628d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
629d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   ir_array_refcount_entry *const entry_c = v.get_variable_entry(var_c);
630d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
631d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   for (unsigned i = 0; i < var_c->type->array_size(); i++) {
632d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick      EXPECT_EQ(true, entry_c->is_linearized_index_referenced(i)) <<
633d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick         "array c, i = " << i;
634d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   }
635d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
636d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   validate_variables_in_hash_table(v.ht, 4, var_a, var_b, var_c, var_i);
637d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick}
638d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
639d32956935edf06c8ae6872c707bc65187b4a1d15Ian RomanickTEST_F(array_refcount_test, visit_array_indexing_with_itself)
640d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick{
641d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   const glsl_type *const array_2_of_array_3_of_int =
642d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick      glsl_type::get_array_instance(array_3_of_int, 2);
643d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
644d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   const glsl_type *const array_2_of_array_2_of_array_3_of_int =
645d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick      glsl_type::get_array_instance(array_2_of_array_3_of_int, 2);
646d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
647d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   ir_variable *var_a = new(mem_ctx) ir_variable(glsl_type::int_type,
648d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                                                 "a",
649d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                                                 ir_var_auto);
650d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   ir_variable *var_b = new(mem_ctx) ir_variable(array_2_of_array_2_of_array_3_of_int,
651d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                                                 "b",
652d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                                                 ir_var_auto);
653d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
654d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   /* Given GLSL code:
655d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick    *
656d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick    *    int b[2][2][3];
657d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick    *    a = b[ b[0][0][0] ][ b[ b[0][1][0] ][ b[1][0][0] ][1] ][2]
658d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick    *
659d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick    * b[0][0][0], b[0][1][0], and b[1][0][0] are trivially accessed.
660d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick    *
661d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick    * b[*][*][1] and b[*][*][2] are accessed.
662d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick    *
663d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick    * Only b[1][1][0] is not accessed.
664d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick    */
665d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   operand b000 = deref_array(
666d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick      deref_array(
667d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick         deref_array(var_b, body->constant(int(0))),
668d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick         body->constant(int(0))),
669d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick      body->constant(int(0)));
670d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
671d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   operand b010 = deref_array(
672d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick      deref_array(
673d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick         deref_array(var_b, body->constant(int(0))),
674d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick         body->constant(int(1))),
675d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick      body->constant(int(0)));
676d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
677d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   operand b100 = deref_array(
678d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick      deref_array(
679d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick         deref_array(var_b, body->constant(int(1))),
680d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick         body->constant(int(0))),
681d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick      body->constant(int(0)));
682d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
683d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   operand b_b010_b100_1 = deref_array(
684d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick      deref_array(
685d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick         deref_array(var_b, b010),
686d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick         b100),
687d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick      body->constant(int(1)));
688d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
689d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   body->emit(assign(var_a,
690d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                     deref_array(
691d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                        deref_array(
692d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                           deref_array(var_b, b000),
693d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                           b_b010_b100_1),
694d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                        body->constant(int(2)))));
695d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
696d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   ir_array_refcount_visitor v;
697d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
698d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   visit_list_elements(&v, &instructions);
699d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
700d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   ir_array_refcount_entry *const entry_b = v.get_variable_entry(var_b);
701d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
702d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   for (unsigned i = 0; i < 2; i++) {
703d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick      for (unsigned j = 0; j < 2; j++) {
704d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick         for (unsigned k = 0; k < 3; k++) {
705d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick            const bool accessed = !(i == 1 && j == 1 && k == 0);
706d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick            const unsigned linearized_index = k + (j * 3) + (i * 2 * 3);
707d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
708d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick            EXPECT_EQ(accessed,
709d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick                      entry_b->is_linearized_index_referenced(linearized_index)) <<
710d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick               "array b[" << i << "][" << j << "][" << k << "], " <<
711d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick               "linear index = " << linearized_index;
712d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick         }
713d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick      }
714d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   }
715d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick
716d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick   validate_variables_in_hash_table(v.ht, 2, var_a, var_b);
717d32956935edf06c8ae6872c707bc65187b4a1d15Ian Romanick}
718