11591693c7b415e9869157c711fe11263c95d74eDavid Li/* 21591693c7b415e9869157c711fe11263c95d74eDavid Li * Copyright © 2010 Intel Corporation 31591693c7b415e9869157c711fe11263c95d74eDavid Li * 41591693c7b415e9869157c711fe11263c95d74eDavid Li * Permission is hereby granted, free of charge, to any person obtaining a 51591693c7b415e9869157c711fe11263c95d74eDavid Li * copy of this software and associated documentation files (the "Software"), 61591693c7b415e9869157c711fe11263c95d74eDavid Li * to deal in the Software without restriction, including without limitation 71591693c7b415e9869157c711fe11263c95d74eDavid Li * the rights to use, copy, modify, merge, publish, distribute, sublicense, 81591693c7b415e9869157c711fe11263c95d74eDavid Li * and/or sell copies of the Software, and to permit persons to whom the 91591693c7b415e9869157c711fe11263c95d74eDavid Li * Software is furnished to do so, subject to the following conditions: 101591693c7b415e9869157c711fe11263c95d74eDavid Li * 111591693c7b415e9869157c711fe11263c95d74eDavid Li * The above copyright notice and this permission notice (including the next 121591693c7b415e9869157c711fe11263c95d74eDavid Li * paragraph) shall be included in all copies or substantial portions of the 131591693c7b415e9869157c711fe11263c95d74eDavid Li * Software. 141591693c7b415e9869157c711fe11263c95d74eDavid Li * 151591693c7b415e9869157c711fe11263c95d74eDavid Li * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 161591693c7b415e9869157c711fe11263c95d74eDavid Li * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 171591693c7b415e9869157c711fe11263c95d74eDavid Li * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 181591693c7b415e9869157c711fe11263c95d74eDavid Li * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 191591693c7b415e9869157c711fe11263c95d74eDavid Li * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 201591693c7b415e9869157c711fe11263c95d74eDavid Li * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 211591693c7b415e9869157c711fe11263c95d74eDavid Li * DEALINGS IN THE SOFTWARE. 221591693c7b415e9869157c711fe11263c95d74eDavid Li */ 231591693c7b415e9869157c711fe11263c95d74eDavid Li 241591693c7b415e9869157c711fe11263c95d74eDavid Li/** 251591693c7b415e9869157c711fe11263c95d74eDavid Li * \file opt_structure_splitting.cpp 261591693c7b415e9869157c711fe11263c95d74eDavid Li * 271591693c7b415e9869157c711fe11263c95d74eDavid Li * If a structure is only ever referenced by its components, then 281591693c7b415e9869157c711fe11263c95d74eDavid Li * split those components out to individual variables so they can be 291591693c7b415e9869157c711fe11263c95d74eDavid Li * handled normally by other optimization passes. 301591693c7b415e9869157c711fe11263c95d74eDavid Li * 311591693c7b415e9869157c711fe11263c95d74eDavid Li * This skips structures like uniforms, which need to be accessible as 321591693c7b415e9869157c711fe11263c95d74eDavid Li * structures for their access by the GL. 331591693c7b415e9869157c711fe11263c95d74eDavid Li */ 341591693c7b415e9869157c711fe11263c95d74eDavid Li 351591693c7b415e9869157c711fe11263c95d74eDavid Li#include "ir.h" 361591693c7b415e9869157c711fe11263c95d74eDavid Li#include "ir_visitor.h" 371591693c7b415e9869157c711fe11263c95d74eDavid Li#include "ir_print_visitor.h" 381591693c7b415e9869157c711fe11263c95d74eDavid Li#include "ir_rvalue_visitor.h" 391591693c7b415e9869157c711fe11263c95d74eDavid Li#include "glsl_types.h" 401591693c7b415e9869157c711fe11263c95d74eDavid Li 411591693c7b415e9869157c711fe11263c95d74eDavid Listatic bool debug = false; 421591693c7b415e9869157c711fe11263c95d74eDavid Li 431591693c7b415e9869157c711fe11263c95d74eDavid Li// XXX using variable_entry2 here to avoid collision (MSVC multiply-defined 441591693c7b415e9869157c711fe11263c95d74eDavid Li// function) with the variable_entry class seen in ir_variable_refcount.h 451591693c7b415e9869157c711fe11263c95d74eDavid Li// Perhaps we can use the one in ir_variable_refcount.h and make this class 461591693c7b415e9869157c711fe11263c95d74eDavid Li// here go away? 471591693c7b415e9869157c711fe11263c95d74eDavid Liclass variable_entry2 : public exec_node 481591693c7b415e9869157c711fe11263c95d74eDavid Li{ 491591693c7b415e9869157c711fe11263c95d74eDavid Lipublic: 501591693c7b415e9869157c711fe11263c95d74eDavid Li variable_entry2(ir_variable *var) 511591693c7b415e9869157c711fe11263c95d74eDavid Li { 521591693c7b415e9869157c711fe11263c95d74eDavid Li this->var = var; 531591693c7b415e9869157c711fe11263c95d74eDavid Li this->whole_structure_access = 0; 541591693c7b415e9869157c711fe11263c95d74eDavid Li this->declaration = false; 551591693c7b415e9869157c711fe11263c95d74eDavid Li this->components = NULL; 561591693c7b415e9869157c711fe11263c95d74eDavid Li this->mem_ctx = NULL; 571591693c7b415e9869157c711fe11263c95d74eDavid Li } 581591693c7b415e9869157c711fe11263c95d74eDavid Li 591591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *var; /* The key: the variable's pointer. */ 601591693c7b415e9869157c711fe11263c95d74eDavid Li 611591693c7b415e9869157c711fe11263c95d74eDavid Li /** Number of times the variable is referenced, including assignments. */ 621591693c7b415e9869157c711fe11263c95d74eDavid Li unsigned whole_structure_access; 631591693c7b415e9869157c711fe11263c95d74eDavid Li 641591693c7b415e9869157c711fe11263c95d74eDavid Li bool declaration; /* If the variable had a decl in the instruction stream */ 651591693c7b415e9869157c711fe11263c95d74eDavid Li 661591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable **components; 671591693c7b415e9869157c711fe11263c95d74eDavid Li 68d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li /** hieralloc_parent(this->var) -- the shader's hieralloc context. */ 691591693c7b415e9869157c711fe11263c95d74eDavid Li void *mem_ctx; 701591693c7b415e9869157c711fe11263c95d74eDavid Li}; 711591693c7b415e9869157c711fe11263c95d74eDavid Li 721591693c7b415e9869157c711fe11263c95d74eDavid Li 731591693c7b415e9869157c711fe11263c95d74eDavid Liclass ir_structure_reference_visitor : public ir_hierarchical_visitor { 741591693c7b415e9869157c711fe11263c95d74eDavid Lipublic: 751591693c7b415e9869157c711fe11263c95d74eDavid Li ir_structure_reference_visitor(void) 761591693c7b415e9869157c711fe11263c95d74eDavid Li { 77d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li this->mem_ctx = hieralloc_new(NULL); 781591693c7b415e9869157c711fe11263c95d74eDavid Li this->variable_list.make_empty(); 791591693c7b415e9869157c711fe11263c95d74eDavid Li } 801591693c7b415e9869157c711fe11263c95d74eDavid Li 811591693c7b415e9869157c711fe11263c95d74eDavid Li ~ir_structure_reference_visitor(void) 821591693c7b415e9869157c711fe11263c95d74eDavid Li { 83d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li hieralloc_free(mem_ctx); 841591693c7b415e9869157c711fe11263c95d74eDavid Li } 851591693c7b415e9869157c711fe11263c95d74eDavid Li 861591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit(ir_variable *); 871591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit(ir_dereference_variable *); 881591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit_enter(ir_dereference_record *); 891591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit_enter(ir_assignment *); 901591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit_enter(ir_function_signature *); 911591693c7b415e9869157c711fe11263c95d74eDavid Li 921591693c7b415e9869157c711fe11263c95d74eDavid Li variable_entry2 *get_variable_entry2(ir_variable *var); 931591693c7b415e9869157c711fe11263c95d74eDavid Li 941591693c7b415e9869157c711fe11263c95d74eDavid Li /* List of variable_entry */ 951591693c7b415e9869157c711fe11263c95d74eDavid Li exec_list variable_list; 961591693c7b415e9869157c711fe11263c95d74eDavid Li 971591693c7b415e9869157c711fe11263c95d74eDavid Li void *mem_ctx; 981591693c7b415e9869157c711fe11263c95d74eDavid Li}; 991591693c7b415e9869157c711fe11263c95d74eDavid Li 1001591693c7b415e9869157c711fe11263c95d74eDavid Livariable_entry2 * 1011591693c7b415e9869157c711fe11263c95d74eDavid Liir_structure_reference_visitor::get_variable_entry2(ir_variable *var) 1021591693c7b415e9869157c711fe11263c95d74eDavid Li{ 1031591693c7b415e9869157c711fe11263c95d74eDavid Li assert(var); 1041591693c7b415e9869157c711fe11263c95d74eDavid Li 1051591693c7b415e9869157c711fe11263c95d74eDavid Li if (!var->type->is_record() || var->mode == ir_var_uniform) 1061591693c7b415e9869157c711fe11263c95d74eDavid Li return NULL; 1071591693c7b415e9869157c711fe11263c95d74eDavid Li 1081591693c7b415e9869157c711fe11263c95d74eDavid Li foreach_iter(exec_list_iterator, iter, this->variable_list) { 1091591693c7b415e9869157c711fe11263c95d74eDavid Li variable_entry2 *entry = (variable_entry2 *)iter.get(); 1101591693c7b415e9869157c711fe11263c95d74eDavid Li if (entry->var == var) 1111591693c7b415e9869157c711fe11263c95d74eDavid Li return entry; 1121591693c7b415e9869157c711fe11263c95d74eDavid Li } 1131591693c7b415e9869157c711fe11263c95d74eDavid Li 1141591693c7b415e9869157c711fe11263c95d74eDavid Li variable_entry2 *entry = new(mem_ctx) variable_entry2(var); 1151591693c7b415e9869157c711fe11263c95d74eDavid Li this->variable_list.push_tail(entry); 1161591693c7b415e9869157c711fe11263c95d74eDavid Li return entry; 1171591693c7b415e9869157c711fe11263c95d74eDavid Li} 1181591693c7b415e9869157c711fe11263c95d74eDavid Li 1191591693c7b415e9869157c711fe11263c95d74eDavid Li 1201591693c7b415e9869157c711fe11263c95d74eDavid Liir_visitor_status 1211591693c7b415e9869157c711fe11263c95d74eDavid Liir_structure_reference_visitor::visit(ir_variable *ir) 1221591693c7b415e9869157c711fe11263c95d74eDavid Li{ 1231591693c7b415e9869157c711fe11263c95d74eDavid Li variable_entry2 *entry = this->get_variable_entry2(ir); 1241591693c7b415e9869157c711fe11263c95d74eDavid Li 1251591693c7b415e9869157c711fe11263c95d74eDavid Li if (entry) 1261591693c7b415e9869157c711fe11263c95d74eDavid Li entry->declaration = true; 1271591693c7b415e9869157c711fe11263c95d74eDavid Li 1281591693c7b415e9869157c711fe11263c95d74eDavid Li return visit_continue; 1291591693c7b415e9869157c711fe11263c95d74eDavid Li} 1301591693c7b415e9869157c711fe11263c95d74eDavid Li 1311591693c7b415e9869157c711fe11263c95d74eDavid Liir_visitor_status 1321591693c7b415e9869157c711fe11263c95d74eDavid Liir_structure_reference_visitor::visit(ir_dereference_variable *ir) 1331591693c7b415e9869157c711fe11263c95d74eDavid Li{ 1341591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *const var = ir->variable_referenced(); 1351591693c7b415e9869157c711fe11263c95d74eDavid Li variable_entry2 *entry = this->get_variable_entry2(var); 1361591693c7b415e9869157c711fe11263c95d74eDavid Li 1371591693c7b415e9869157c711fe11263c95d74eDavid Li if (entry) 1381591693c7b415e9869157c711fe11263c95d74eDavid Li entry->whole_structure_access++; 1391591693c7b415e9869157c711fe11263c95d74eDavid Li 1401591693c7b415e9869157c711fe11263c95d74eDavid Li return visit_continue; 1411591693c7b415e9869157c711fe11263c95d74eDavid Li} 1421591693c7b415e9869157c711fe11263c95d74eDavid Li 1431591693c7b415e9869157c711fe11263c95d74eDavid Liir_visitor_status 1441591693c7b415e9869157c711fe11263c95d74eDavid Liir_structure_reference_visitor::visit_enter(ir_dereference_record *ir) 1451591693c7b415e9869157c711fe11263c95d74eDavid Li{ 1461591693c7b415e9869157c711fe11263c95d74eDavid Li (void) ir; 1471591693c7b415e9869157c711fe11263c95d74eDavid Li /* Don't descend into the ir_dereference_variable below. */ 1481591693c7b415e9869157c711fe11263c95d74eDavid Li return visit_continue_with_parent; 1491591693c7b415e9869157c711fe11263c95d74eDavid Li} 1501591693c7b415e9869157c711fe11263c95d74eDavid Li 1511591693c7b415e9869157c711fe11263c95d74eDavid Liir_visitor_status 1521591693c7b415e9869157c711fe11263c95d74eDavid Liir_structure_reference_visitor::visit_enter(ir_assignment *ir) 1531591693c7b415e9869157c711fe11263c95d74eDavid Li{ 1541591693c7b415e9869157c711fe11263c95d74eDavid Li if (ir->lhs->as_dereference_variable() && 1551591693c7b415e9869157c711fe11263c95d74eDavid Li ir->rhs->as_dereference_variable() && 1561591693c7b415e9869157c711fe11263c95d74eDavid Li !ir->condition) { 1571591693c7b415e9869157c711fe11263c95d74eDavid Li /* We'll split copies of a structure to copies of components, so don't 1581591693c7b415e9869157c711fe11263c95d74eDavid Li * descend to the ir_dereference_variables. 1591591693c7b415e9869157c711fe11263c95d74eDavid Li */ 1601591693c7b415e9869157c711fe11263c95d74eDavid Li return visit_continue_with_parent; 1611591693c7b415e9869157c711fe11263c95d74eDavid Li } 1621591693c7b415e9869157c711fe11263c95d74eDavid Li return visit_continue; 1631591693c7b415e9869157c711fe11263c95d74eDavid Li} 1641591693c7b415e9869157c711fe11263c95d74eDavid Li 1651591693c7b415e9869157c711fe11263c95d74eDavid Liir_visitor_status 1661591693c7b415e9869157c711fe11263c95d74eDavid Liir_structure_reference_visitor::visit_enter(ir_function_signature *ir) 1671591693c7b415e9869157c711fe11263c95d74eDavid Li{ 1681591693c7b415e9869157c711fe11263c95d74eDavid Li /* We don't want to descend into the function parameters and 1691591693c7b415e9869157c711fe11263c95d74eDavid Li * dead-code eliminate them, so just accept the body here. 1701591693c7b415e9869157c711fe11263c95d74eDavid Li */ 1711591693c7b415e9869157c711fe11263c95d74eDavid Li visit_list_elements(this, &ir->body); 1721591693c7b415e9869157c711fe11263c95d74eDavid Li return visit_continue_with_parent; 1731591693c7b415e9869157c711fe11263c95d74eDavid Li} 1741591693c7b415e9869157c711fe11263c95d74eDavid Li 1751591693c7b415e9869157c711fe11263c95d74eDavid Liclass ir_structure_splitting_visitor : public ir_rvalue_visitor { 1761591693c7b415e9869157c711fe11263c95d74eDavid Lipublic: 1771591693c7b415e9869157c711fe11263c95d74eDavid Li ir_structure_splitting_visitor(exec_list *vars) 1781591693c7b415e9869157c711fe11263c95d74eDavid Li { 1791591693c7b415e9869157c711fe11263c95d74eDavid Li this->variable_list = vars; 1801591693c7b415e9869157c711fe11263c95d74eDavid Li } 1811591693c7b415e9869157c711fe11263c95d74eDavid Li 1821591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ~ir_structure_splitting_visitor() 1831591693c7b415e9869157c711fe11263c95d74eDavid Li { 1841591693c7b415e9869157c711fe11263c95d74eDavid Li } 1851591693c7b415e9869157c711fe11263c95d74eDavid Li 1861591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit_leave(ir_assignment *); 1871591693c7b415e9869157c711fe11263c95d74eDavid Li 1881591693c7b415e9869157c711fe11263c95d74eDavid Li void split_deref(ir_dereference **deref); 1891591693c7b415e9869157c711fe11263c95d74eDavid Li void handle_rvalue(ir_rvalue **rvalue); 1901591693c7b415e9869157c711fe11263c95d74eDavid Li variable_entry2 *get_splitting_entry(ir_variable *var); 1911591693c7b415e9869157c711fe11263c95d74eDavid Li 1921591693c7b415e9869157c711fe11263c95d74eDavid Li exec_list *variable_list; 1931591693c7b415e9869157c711fe11263c95d74eDavid Li void *mem_ctx; 1941591693c7b415e9869157c711fe11263c95d74eDavid Li}; 1951591693c7b415e9869157c711fe11263c95d74eDavid Li 1961591693c7b415e9869157c711fe11263c95d74eDavid Livariable_entry2 * 1971591693c7b415e9869157c711fe11263c95d74eDavid Liir_structure_splitting_visitor::get_splitting_entry(ir_variable *var) 1981591693c7b415e9869157c711fe11263c95d74eDavid Li{ 1991591693c7b415e9869157c711fe11263c95d74eDavid Li assert(var); 2001591693c7b415e9869157c711fe11263c95d74eDavid Li 2011591693c7b415e9869157c711fe11263c95d74eDavid Li if (!var->type->is_record()) 2021591693c7b415e9869157c711fe11263c95d74eDavid Li return NULL; 2031591693c7b415e9869157c711fe11263c95d74eDavid Li 2041591693c7b415e9869157c711fe11263c95d74eDavid Li foreach_iter(exec_list_iterator, iter, *this->variable_list) { 2051591693c7b415e9869157c711fe11263c95d74eDavid Li variable_entry2 *entry = (variable_entry2 *)iter.get(); 2061591693c7b415e9869157c711fe11263c95d74eDavid Li if (entry->var == var) { 2071591693c7b415e9869157c711fe11263c95d74eDavid Li return entry; 2081591693c7b415e9869157c711fe11263c95d74eDavid Li } 2091591693c7b415e9869157c711fe11263c95d74eDavid Li } 2101591693c7b415e9869157c711fe11263c95d74eDavid Li 2111591693c7b415e9869157c711fe11263c95d74eDavid Li return NULL; 2121591693c7b415e9869157c711fe11263c95d74eDavid Li} 2131591693c7b415e9869157c711fe11263c95d74eDavid Li 2141591693c7b415e9869157c711fe11263c95d74eDavid Livoid 2151591693c7b415e9869157c711fe11263c95d74eDavid Liir_structure_splitting_visitor::split_deref(ir_dereference **deref) 2161591693c7b415e9869157c711fe11263c95d74eDavid Li{ 2171591693c7b415e9869157c711fe11263c95d74eDavid Li if ((*deref)->ir_type != ir_type_dereference_record) 2181591693c7b415e9869157c711fe11263c95d74eDavid Li return; 2191591693c7b415e9869157c711fe11263c95d74eDavid Li 2201591693c7b415e9869157c711fe11263c95d74eDavid Li ir_dereference_record *deref_record = (ir_dereference_record *)*deref; 2211591693c7b415e9869157c711fe11263c95d74eDavid Li ir_dereference_variable *deref_var = deref_record->record->as_dereference_variable(); 2221591693c7b415e9869157c711fe11263c95d74eDavid Li if (!deref_var) 2231591693c7b415e9869157c711fe11263c95d74eDavid Li return; 2241591693c7b415e9869157c711fe11263c95d74eDavid Li 2251591693c7b415e9869157c711fe11263c95d74eDavid Li variable_entry2 *entry = get_splitting_entry(deref_var->var); 2261591693c7b415e9869157c711fe11263c95d74eDavid Li if (!entry) 2271591693c7b415e9869157c711fe11263c95d74eDavid Li return; 2281591693c7b415e9869157c711fe11263c95d74eDavid Li 2291591693c7b415e9869157c711fe11263c95d74eDavid Li unsigned int i; 2301591693c7b415e9869157c711fe11263c95d74eDavid Li for (i = 0; i < entry->var->type->length; i++) { 2311591693c7b415e9869157c711fe11263c95d74eDavid Li if (strcmp(deref_record->field, 2321591693c7b415e9869157c711fe11263c95d74eDavid Li entry->var->type->fields.structure[i].name) == 0) 2331591693c7b415e9869157c711fe11263c95d74eDavid Li break; 2341591693c7b415e9869157c711fe11263c95d74eDavid Li } 2351591693c7b415e9869157c711fe11263c95d74eDavid Li assert(i != entry->var->type->length); 2361591693c7b415e9869157c711fe11263c95d74eDavid Li 2371591693c7b415e9869157c711fe11263c95d74eDavid Li *deref = new(entry->mem_ctx) ir_dereference_variable(entry->components[i]); 2381591693c7b415e9869157c711fe11263c95d74eDavid Li} 2391591693c7b415e9869157c711fe11263c95d74eDavid Li 2401591693c7b415e9869157c711fe11263c95d74eDavid Livoid 2411591693c7b415e9869157c711fe11263c95d74eDavid Liir_structure_splitting_visitor::handle_rvalue(ir_rvalue **rvalue) 2421591693c7b415e9869157c711fe11263c95d74eDavid Li{ 2431591693c7b415e9869157c711fe11263c95d74eDavid Li if (!*rvalue) 2441591693c7b415e9869157c711fe11263c95d74eDavid Li return; 2451591693c7b415e9869157c711fe11263c95d74eDavid Li 2461591693c7b415e9869157c711fe11263c95d74eDavid Li ir_dereference *deref = (*rvalue)->as_dereference(); 2471591693c7b415e9869157c711fe11263c95d74eDavid Li 2481591693c7b415e9869157c711fe11263c95d74eDavid Li if (!deref) 2491591693c7b415e9869157c711fe11263c95d74eDavid Li return; 2501591693c7b415e9869157c711fe11263c95d74eDavid Li 2511591693c7b415e9869157c711fe11263c95d74eDavid Li split_deref(&deref); 2521591693c7b415e9869157c711fe11263c95d74eDavid Li *rvalue = deref; 2531591693c7b415e9869157c711fe11263c95d74eDavid Li} 2541591693c7b415e9869157c711fe11263c95d74eDavid Li 2551591693c7b415e9869157c711fe11263c95d74eDavid Liir_visitor_status 2561591693c7b415e9869157c711fe11263c95d74eDavid Liir_structure_splitting_visitor::visit_leave(ir_assignment *ir) 2571591693c7b415e9869157c711fe11263c95d74eDavid Li{ 2581591693c7b415e9869157c711fe11263c95d74eDavid Li ir_dereference_variable *lhs_deref = ir->lhs->as_dereference_variable(); 2591591693c7b415e9869157c711fe11263c95d74eDavid Li ir_dereference_variable *rhs_deref = ir->rhs->as_dereference_variable(); 2601591693c7b415e9869157c711fe11263c95d74eDavid Li variable_entry2 *lhs_entry = lhs_deref ? get_splitting_entry(lhs_deref->var) : NULL; 2611591693c7b415e9869157c711fe11263c95d74eDavid Li variable_entry2 *rhs_entry = rhs_deref ? get_splitting_entry(rhs_deref->var) : NULL; 2621591693c7b415e9869157c711fe11263c95d74eDavid Li const glsl_type *type = ir->rhs->type; 2631591693c7b415e9869157c711fe11263c95d74eDavid Li 2641591693c7b415e9869157c711fe11263c95d74eDavid Li if ((lhs_entry || rhs_entry) && !ir->condition) { 2651591693c7b415e9869157c711fe11263c95d74eDavid Li for (unsigned int i = 0; i < type->length; i++) { 2661591693c7b415e9869157c711fe11263c95d74eDavid Li ir_dereference *new_lhs, *new_rhs; 2671591693c7b415e9869157c711fe11263c95d74eDavid Li void *mem_ctx = lhs_entry ? lhs_entry->mem_ctx : rhs_entry->mem_ctx; 2681591693c7b415e9869157c711fe11263c95d74eDavid Li 2691591693c7b415e9869157c711fe11263c95d74eDavid Li if (lhs_entry) { 2701591693c7b415e9869157c711fe11263c95d74eDavid Li new_lhs = new(mem_ctx) ir_dereference_variable(lhs_entry->components[i]); 2711591693c7b415e9869157c711fe11263c95d74eDavid Li } else { 2721591693c7b415e9869157c711fe11263c95d74eDavid Li new_lhs = new(mem_ctx) 2731591693c7b415e9869157c711fe11263c95d74eDavid Li ir_dereference_record(ir->lhs->clone(mem_ctx, NULL), 2741591693c7b415e9869157c711fe11263c95d74eDavid Li type->fields.structure[i].name); 2751591693c7b415e9869157c711fe11263c95d74eDavid Li } 2761591693c7b415e9869157c711fe11263c95d74eDavid Li 2771591693c7b415e9869157c711fe11263c95d74eDavid Li if (rhs_entry) { 2781591693c7b415e9869157c711fe11263c95d74eDavid Li new_rhs = new(mem_ctx) ir_dereference_variable(rhs_entry->components[i]); 2791591693c7b415e9869157c711fe11263c95d74eDavid Li } else { 2801591693c7b415e9869157c711fe11263c95d74eDavid Li new_rhs = new(mem_ctx) 2811591693c7b415e9869157c711fe11263c95d74eDavid Li ir_dereference_record(ir->rhs->clone(mem_ctx, NULL), 2821591693c7b415e9869157c711fe11263c95d74eDavid Li type->fields.structure[i].name); 2831591693c7b415e9869157c711fe11263c95d74eDavid Li } 2841591693c7b415e9869157c711fe11263c95d74eDavid Li 2851591693c7b415e9869157c711fe11263c95d74eDavid Li ir->insert_before(new(mem_ctx) ir_assignment(new_lhs, 2861591693c7b415e9869157c711fe11263c95d74eDavid Li new_rhs, 2871591693c7b415e9869157c711fe11263c95d74eDavid Li NULL)); 2881591693c7b415e9869157c711fe11263c95d74eDavid Li } 2891591693c7b415e9869157c711fe11263c95d74eDavid Li ir->remove(); 2901591693c7b415e9869157c711fe11263c95d74eDavid Li } else { 2911591693c7b415e9869157c711fe11263c95d74eDavid Li handle_rvalue(&ir->rhs); 2921591693c7b415e9869157c711fe11263c95d74eDavid Li split_deref(&ir->lhs); 2931591693c7b415e9869157c711fe11263c95d74eDavid Li } 2941591693c7b415e9869157c711fe11263c95d74eDavid Li 2951591693c7b415e9869157c711fe11263c95d74eDavid Li handle_rvalue(&ir->condition); 2961591693c7b415e9869157c711fe11263c95d74eDavid Li 2971591693c7b415e9869157c711fe11263c95d74eDavid Li return visit_continue; 2981591693c7b415e9869157c711fe11263c95d74eDavid Li} 2991591693c7b415e9869157c711fe11263c95d74eDavid Li 3001591693c7b415e9869157c711fe11263c95d74eDavid Libool 3011591693c7b415e9869157c711fe11263c95d74eDavid Lido_structure_splitting(exec_list *instructions) 3021591693c7b415e9869157c711fe11263c95d74eDavid Li{ 3031591693c7b415e9869157c711fe11263c95d74eDavid Li ir_structure_reference_visitor refs; 3041591693c7b415e9869157c711fe11263c95d74eDavid Li 3051591693c7b415e9869157c711fe11263c95d74eDavid Li visit_list_elements(&refs, instructions); 3061591693c7b415e9869157c711fe11263c95d74eDavid Li 3071591693c7b415e9869157c711fe11263c95d74eDavid Li /* Trim out variables we can't split. */ 3081591693c7b415e9869157c711fe11263c95d74eDavid Li foreach_iter(exec_list_iterator, iter, refs.variable_list) { 3091591693c7b415e9869157c711fe11263c95d74eDavid Li variable_entry2 *entry = (variable_entry2 *)iter.get(); 3101591693c7b415e9869157c711fe11263c95d74eDavid Li 3111591693c7b415e9869157c711fe11263c95d74eDavid Li if (debug) { 3121591693c7b415e9869157c711fe11263c95d74eDavid Li printf("structure %s@%p: decl %d, whole_access %d\n", 3131591693c7b415e9869157c711fe11263c95d74eDavid Li entry->var->name, (void *) entry->var, entry->declaration, 3141591693c7b415e9869157c711fe11263c95d74eDavid Li entry->whole_structure_access); 3151591693c7b415e9869157c711fe11263c95d74eDavid Li } 3161591693c7b415e9869157c711fe11263c95d74eDavid Li 3171591693c7b415e9869157c711fe11263c95d74eDavid Li if (!entry->declaration || entry->whole_structure_access) { 3181591693c7b415e9869157c711fe11263c95d74eDavid Li entry->remove(); 3191591693c7b415e9869157c711fe11263c95d74eDavid Li } 3201591693c7b415e9869157c711fe11263c95d74eDavid Li } 3211591693c7b415e9869157c711fe11263c95d74eDavid Li 3221591693c7b415e9869157c711fe11263c95d74eDavid Li if (refs.variable_list.is_empty()) 3231591693c7b415e9869157c711fe11263c95d74eDavid Li return false; 3241591693c7b415e9869157c711fe11263c95d74eDavid Li 325d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li void *mem_ctx = hieralloc_new(NULL); 3261591693c7b415e9869157c711fe11263c95d74eDavid Li 3271591693c7b415e9869157c711fe11263c95d74eDavid Li /* Replace the decls of the structures to be split with their split 3281591693c7b415e9869157c711fe11263c95d74eDavid Li * components. 3291591693c7b415e9869157c711fe11263c95d74eDavid Li */ 3301591693c7b415e9869157c711fe11263c95d74eDavid Li foreach_iter(exec_list_iterator, iter, refs.variable_list) { 3311591693c7b415e9869157c711fe11263c95d74eDavid Li variable_entry2 *entry = (variable_entry2 *)iter.get(); 3321591693c7b415e9869157c711fe11263c95d74eDavid Li const struct glsl_type *type = entry->var->type; 3331591693c7b415e9869157c711fe11263c95d74eDavid Li 334d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li entry->mem_ctx = hieralloc_parent(entry->var); 3351591693c7b415e9869157c711fe11263c95d74eDavid Li 336d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li entry->components = hieralloc_array(mem_ctx, 3371591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *, 3381591693c7b415e9869157c711fe11263c95d74eDavid Li type->length); 3391591693c7b415e9869157c711fe11263c95d74eDavid Li 3401591693c7b415e9869157c711fe11263c95d74eDavid Li for (unsigned int i = 0; i < entry->var->type->length; i++) { 341d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li const char *name = hieralloc_asprintf(mem_ctx, "%s_%s", 3421591693c7b415e9869157c711fe11263c95d74eDavid Li entry->var->name, 3431591693c7b415e9869157c711fe11263c95d74eDavid Li type->fields.structure[i].name); 3441591693c7b415e9869157c711fe11263c95d74eDavid Li 3451591693c7b415e9869157c711fe11263c95d74eDavid Li entry->components[i] = 3461591693c7b415e9869157c711fe11263c95d74eDavid Li new(entry->mem_ctx) ir_variable(type->fields.structure[i].type, 3471591693c7b415e9869157c711fe11263c95d74eDavid Li name, 3481591693c7b415e9869157c711fe11263c95d74eDavid Li ir_var_temporary); 3491591693c7b415e9869157c711fe11263c95d74eDavid Li entry->var->insert_before(entry->components[i]); 3501591693c7b415e9869157c711fe11263c95d74eDavid Li } 3511591693c7b415e9869157c711fe11263c95d74eDavid Li 3521591693c7b415e9869157c711fe11263c95d74eDavid Li entry->var->remove(); 3531591693c7b415e9869157c711fe11263c95d74eDavid Li } 3541591693c7b415e9869157c711fe11263c95d74eDavid Li 3551591693c7b415e9869157c711fe11263c95d74eDavid Li ir_structure_splitting_visitor split(&refs.variable_list); 3561591693c7b415e9869157c711fe11263c95d74eDavid Li visit_list_elements(&split, instructions); 3571591693c7b415e9869157c711fe11263c95d74eDavid Li 358d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li hieralloc_free(mem_ctx); 3591591693c7b415e9869157c711fe11263c95d74eDavid Li 3601591693c7b415e9869157c711fe11263c95d74eDavid Li return true; 3611591693c7b415e9869157c711fe11263c95d74eDavid Li} 362