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