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