1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* 2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright © 2010 Intel Corporation 3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a 5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the "Software"), 6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to deal in the Software without restriction, including without limitation 7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and/or sell copies of the Software, and to permit persons to whom the 9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software is furnished to do so, subject to the following conditions: 10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the next 12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * paragraph) shall be included in all copies or substantial portions of the 13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software. 14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * DEALINGS IN THE SOFTWARE. 22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \file opt_structure_splitting.cpp 26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * If a structure is only ever referenced by its components, then 28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * split those components out to individual variables so they can be 29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * handled normally by other optimization passes. 30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This skips structures like uniforms, which need to be accessible as 32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * structures for their access by the GL. 33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "ir.h" 36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "ir_visitor.h" 37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "ir_print_visitor.h" 38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "ir_rvalue_visitor.h" 39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "glsl_types.h" 40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnamespace { 42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic bool debug = false; 44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// XXX using variable_entry2 here to avoid collision (MSVC multiply-defined 46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// function) with the variable_entry class seen in ir_variable_refcount.h 47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// Perhaps we can use the one in ir_variable_refcount.h and make this class 48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// here go away? 49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass variable_entry2 : public exec_node 50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpublic: 52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org variable_entry2(ir_variable *var) 53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->var = var; 55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->whole_structure_access = 0; 56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->declaration = false; 57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->components = NULL; 58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->mem_ctx = NULL; 59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_variable *var; /* The key: the variable's pointer. */ 62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /** Number of times the variable is referenced, including assignments. */ 64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned whole_structure_access; 65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* If the variable had a decl we can work with in the instruction 67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * stream. We can't do splitting on function arguments, which 68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * don't get this variable set. 69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool declaration; 71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_variable **components; 73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /** ralloc_parent(this->var) -- the shader's ralloc context. */ 75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *mem_ctx; 76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass ir_structure_reference_visitor : public ir_hierarchical_visitor { 80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpublic: 81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_structure_reference_visitor(void) 82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->mem_ctx = ralloc_context(NULL); 84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->variable_list.make_empty(); 85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ~ir_structure_reference_visitor(void) 88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ralloc_free(mem_ctx); 90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual ir_visitor_status visit(ir_variable *); 93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual ir_visitor_status visit(ir_dereference_variable *); 94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual ir_visitor_status visit_enter(ir_dereference_record *); 95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual ir_visitor_status visit_enter(ir_assignment *); 96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual ir_visitor_status visit_enter(ir_function_signature *); 97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org variable_entry2 *get_variable_entry2(ir_variable *var); 99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* List of variable_entry */ 101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org exec_list variable_list; 102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *mem_ctx; 104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvariable_entry2 * 107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_structure_reference_visitor::get_variable_entry2(ir_variable *var) 108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(var); 110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!var->type->is_record() || var->mode == ir_var_uniform) 112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach_iter(exec_list_iterator, iter, this->variable_list) { 115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org variable_entry2 *entry = (variable_entry2 *)iter.get(); 116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (entry->var == var) 117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return entry; 118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org variable_entry2 *entry = new(mem_ctx) variable_entry2(var); 121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->variable_list.push_tail(entry); 122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return entry; 123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_visitor_status 127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_structure_reference_visitor::visit(ir_variable *ir) 128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org variable_entry2 *entry = this->get_variable_entry2(ir); 130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (entry) 132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org entry->declaration = true; 133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return visit_continue; 135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_visitor_status 138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_structure_reference_visitor::visit(ir_dereference_variable *ir) 139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_variable *const var = ir->variable_referenced(); 141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org variable_entry2 *entry = this->get_variable_entry2(var); 142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (entry) 144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org entry->whole_structure_access++; 145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return visit_continue; 147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_visitor_status 150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_structure_reference_visitor::visit_enter(ir_dereference_record *ir) 151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (void) ir; 153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Don't descend into the ir_dereference_variable below. */ 154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return visit_continue_with_parent; 155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_visitor_status 158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_structure_reference_visitor::visit_enter(ir_assignment *ir) 159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* If there are no structure references yet, no need to bother with 161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * processing the expression tree. 162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (this->variable_list.is_empty()) 164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return visit_continue_with_parent; 165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ir->lhs->as_dereference_variable() && 167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir->rhs->as_dereference_variable() && 168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org !ir->condition) { 169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* We'll split copies of a structure to copies of components, so don't 170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * descend to the ir_dereference_variables. 171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return visit_continue_with_parent; 173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return visit_continue; 175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_visitor_status 178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_structure_reference_visitor::visit_enter(ir_function_signature *ir) 179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* We don't have logic for structure-splitting function arguments, 181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * so just look at the body instructions and not the parameter 182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * declarations. 183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org visit_list_elements(this, &ir->body); 185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return visit_continue_with_parent; 186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass ir_structure_splitting_visitor : public ir_rvalue_visitor { 189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpublic: 190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_structure_splitting_visitor(exec_list *vars) 191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->variable_list = vars; 193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual ~ir_structure_splitting_visitor() 196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual ir_visitor_status visit_leave(ir_assignment *); 200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void split_deref(ir_dereference **deref); 202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void handle_rvalue(ir_rvalue **rvalue); 203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org variable_entry2 *get_splitting_entry(ir_variable *var); 204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org exec_list *variable_list; 206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvariable_entry2 * 209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_structure_splitting_visitor::get_splitting_entry(ir_variable *var) 210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(var); 212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!var->type->is_record()) 214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach_iter(exec_list_iterator, iter, *this->variable_list) { 217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org variable_entry2 *entry = (variable_entry2 *)iter.get(); 218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (entry->var == var) { 219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return entry; 220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_structure_splitting_visitor::split_deref(ir_dereference **deref) 228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ((*deref)->ir_type != ir_type_dereference_record) 230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_dereference_record *deref_record = (ir_dereference_record *)*deref; 233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_dereference_variable *deref_var = deref_record->record->as_dereference_variable(); 234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!deref_var) 235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org variable_entry2 *entry = get_splitting_entry(deref_var->var); 238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!entry) 239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int i; 242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < entry->var->type->length; i++) { 243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (strcmp(deref_record->field, 244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org entry->var->type->fields.structure[i].name) == 0) 245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(i != entry->var->type->length); 248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *deref = new(entry->mem_ctx) ir_dereference_variable(entry->components[i]); 250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_structure_splitting_visitor::handle_rvalue(ir_rvalue **rvalue) 254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!*rvalue) 256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_dereference *deref = (*rvalue)->as_dereference(); 259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!deref) 261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org split_deref(&deref); 264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *rvalue = deref; 265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_visitor_status 268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_structure_splitting_visitor::visit_leave(ir_assignment *ir) 269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_dereference_variable *lhs_deref = ir->lhs->as_dereference_variable(); 271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_dereference_variable *rhs_deref = ir->rhs->as_dereference_variable(); 272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org variable_entry2 *lhs_entry = lhs_deref ? get_splitting_entry(lhs_deref->var) : NULL; 273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org variable_entry2 *rhs_entry = rhs_deref ? get_splitting_entry(rhs_deref->var) : NULL; 274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const glsl_type *type = ir->rhs->type; 275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ((lhs_entry || rhs_entry) && !ir->condition) { 277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (unsigned int i = 0; i < type->length; i++) { 278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_dereference *new_lhs, *new_rhs; 279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *mem_ctx = lhs_entry ? lhs_entry->mem_ctx : rhs_entry->mem_ctx; 280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (lhs_entry) { 282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new_lhs = new(mem_ctx) ir_dereference_variable(lhs_entry->components[i]); 283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new_lhs = new(mem_ctx) 285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_dereference_record(ir->lhs->clone(mem_ctx, NULL), 286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type->fields.structure[i].name); 287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (rhs_entry) { 290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new_rhs = new(mem_ctx) ir_dereference_variable(rhs_entry->components[i]); 291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new_rhs = new(mem_ctx) 293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_dereference_record(ir->rhs->clone(mem_ctx, NULL), 294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type->fields.structure[i].name); 295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir->insert_before(new(mem_ctx) ir_assignment(new_lhs, 298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new_rhs, 299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org NULL)); 300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir->remove(); 302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org handle_rvalue(&ir->rhs); 304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org split_deref(&ir->lhs); 305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org handle_rvalue(&ir->condition); 308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return visit_continue; 310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} /* unnamed namespace */ 313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool 315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdo_structure_splitting(exec_list *instructions) 316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_structure_reference_visitor refs; 318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org visit_list_elements(&refs, instructions); 320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Trim out variables we can't split. */ 322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach_iter(exec_list_iterator, iter, refs.variable_list) { 323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org variable_entry2 *entry = (variable_entry2 *)iter.get(); 324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (debug) { 326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org printf("structure %s@%p: decl %d, whole_access %d\n", 327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org entry->var->name, (void *) entry->var, entry->declaration, 328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org entry->whole_structure_access); 329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!entry->declaration || entry->whole_structure_access) { 332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org entry->remove(); 333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (refs.variable_list.is_empty()) 337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return false; 338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *mem_ctx = ralloc_context(NULL); 340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Replace the decls of the structures to be split with their split 342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * components. 343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach_iter(exec_list_iterator, iter, refs.variable_list) { 345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org variable_entry2 *entry = (variable_entry2 *)iter.get(); 346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct glsl_type *type = entry->var->type; 347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org entry->mem_ctx = ralloc_parent(entry->var); 349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org entry->components = ralloc_array(mem_ctx, 351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_variable *, 352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type->length); 353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (unsigned int i = 0; i < entry->var->type->length; i++) { 355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const char *name = ralloc_asprintf(mem_ctx, "%s_%s", 356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org entry->var->name, 357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type->fields.structure[i].name); 358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org entry->components[i] = 360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new(entry->mem_ctx) ir_variable(type->fields.structure[i].type, 361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org name, 362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_var_temporary); 363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org entry->var->insert_before(entry->components[i]); 364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org entry->var->remove(); 367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_structure_splitting_visitor split(&refs.variable_list); 370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org visit_list_elements(&split, instructions); 371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ralloc_free(mem_ctx); 373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return true; 375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 376