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_function_inlining.cpp 261591693c7b415e9869157c711fe11263c95d74eDavid Li * 271591693c7b415e9869157c711fe11263c95d74eDavid Li * Replaces calls to functions with the body of the function. 281591693c7b415e9869157c711fe11263c95d74eDavid Li */ 291591693c7b415e9869157c711fe11263c95d74eDavid Li 301591693c7b415e9869157c711fe11263c95d74eDavid Li#include <inttypes.h> 311591693c7b415e9869157c711fe11263c95d74eDavid Li#include "ir.h" 321591693c7b415e9869157c711fe11263c95d74eDavid Li#include "ir_visitor.h" 331591693c7b415e9869157c711fe11263c95d74eDavid Li#include "ir_function_inlining.h" 341591693c7b415e9869157c711fe11263c95d74eDavid Li#include "ir_expression_flattening.h" 351591693c7b415e9869157c711fe11263c95d74eDavid Li#include "glsl_types.h" 361591693c7b415e9869157c711fe11263c95d74eDavid Li#include "program/hash_table.h" 371591693c7b415e9869157c711fe11263c95d74eDavid Li 381591693c7b415e9869157c711fe11263c95d74eDavid Listatic void 391591693c7b415e9869157c711fe11263c95d74eDavid Lido_sampler_replacement(exec_list *instructions, 401591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *sampler, 411591693c7b415e9869157c711fe11263c95d74eDavid Li ir_dereference *deref); 421591693c7b415e9869157c711fe11263c95d74eDavid Li 431591693c7b415e9869157c711fe11263c95d74eDavid Liclass ir_function_inlining_visitor : public ir_hierarchical_visitor { 441591693c7b415e9869157c711fe11263c95d74eDavid Lipublic: 451591693c7b415e9869157c711fe11263c95d74eDavid Li ir_function_inlining_visitor() 461591693c7b415e9869157c711fe11263c95d74eDavid Li { 471591693c7b415e9869157c711fe11263c95d74eDavid Li progress = false; 481591693c7b415e9869157c711fe11263c95d74eDavid Li } 491591693c7b415e9869157c711fe11263c95d74eDavid Li 501591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ~ir_function_inlining_visitor() 511591693c7b415e9869157c711fe11263c95d74eDavid Li { 521591693c7b415e9869157c711fe11263c95d74eDavid Li /* empty */ 531591693c7b415e9869157c711fe11263c95d74eDavid Li } 541591693c7b415e9869157c711fe11263c95d74eDavid Li 551591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit_enter(ir_expression *); 561591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit_enter(ir_call *); 571591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit_enter(ir_assignment *); 581591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit_enter(ir_return *); 591591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit_enter(ir_texture *); 601591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit_enter(ir_swizzle *); 611591693c7b415e9869157c711fe11263c95d74eDavid Li 621591693c7b415e9869157c711fe11263c95d74eDavid Li bool progress; 631591693c7b415e9869157c711fe11263c95d74eDavid Li}; 641591693c7b415e9869157c711fe11263c95d74eDavid Li 651591693c7b415e9869157c711fe11263c95d74eDavid Li 661591693c7b415e9869157c711fe11263c95d74eDavid Libool 671591693c7b415e9869157c711fe11263c95d74eDavid Liautomatic_inlining_predicate(ir_instruction *ir) 681591693c7b415e9869157c711fe11263c95d74eDavid Li{ 691591693c7b415e9869157c711fe11263c95d74eDavid Li ir_call *call = ir->as_call(); 701591693c7b415e9869157c711fe11263c95d74eDavid Li 711591693c7b415e9869157c711fe11263c95d74eDavid Li if (call && can_inline(call)) 721591693c7b415e9869157c711fe11263c95d74eDavid Li return true; 731591693c7b415e9869157c711fe11263c95d74eDavid Li 741591693c7b415e9869157c711fe11263c95d74eDavid Li return false; 751591693c7b415e9869157c711fe11263c95d74eDavid Li} 761591693c7b415e9869157c711fe11263c95d74eDavid Li 771591693c7b415e9869157c711fe11263c95d74eDavid Libool 781591693c7b415e9869157c711fe11263c95d74eDavid Lido_function_inlining(exec_list *instructions) 791591693c7b415e9869157c711fe11263c95d74eDavid Li{ 801591693c7b415e9869157c711fe11263c95d74eDavid Li ir_function_inlining_visitor v; 811591693c7b415e9869157c711fe11263c95d74eDavid Li 821591693c7b415e9869157c711fe11263c95d74eDavid Li do_expression_flattening(instructions, automatic_inlining_predicate); 831591693c7b415e9869157c711fe11263c95d74eDavid Li 841591693c7b415e9869157c711fe11263c95d74eDavid Li v.run(instructions); 851591693c7b415e9869157c711fe11263c95d74eDavid Li 861591693c7b415e9869157c711fe11263c95d74eDavid Li return v.progress; 871591693c7b415e9869157c711fe11263c95d74eDavid Li} 881591693c7b415e9869157c711fe11263c95d74eDavid Li 891591693c7b415e9869157c711fe11263c95d74eDavid Listatic void 901591693c7b415e9869157c711fe11263c95d74eDavid Lireplace_return_with_assignment(ir_instruction *ir, void *data) 911591693c7b415e9869157c711fe11263c95d74eDavid Li{ 92d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li void *ctx = hieralloc_parent(ir); 931591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *retval = (ir_variable *)data; 941591693c7b415e9869157c711fe11263c95d74eDavid Li ir_return *ret = ir->as_return(); 951591693c7b415e9869157c711fe11263c95d74eDavid Li 961591693c7b415e9869157c711fe11263c95d74eDavid Li if (ret) { 971591693c7b415e9869157c711fe11263c95d74eDavid Li if (ret->value) { 981591693c7b415e9869157c711fe11263c95d74eDavid Li ir_rvalue *lhs = new(ctx) ir_dereference_variable(retval); 991591693c7b415e9869157c711fe11263c95d74eDavid Li ret->replace_with(new(ctx) ir_assignment(lhs, ret->value, NULL)); 1001591693c7b415e9869157c711fe11263c95d74eDavid Li } else { 1011591693c7b415e9869157c711fe11263c95d74eDavid Li /* un-valued return has to be the last return, or we shouldn't 1021591693c7b415e9869157c711fe11263c95d74eDavid Li * have reached here. (see can_inline()). 1031591693c7b415e9869157c711fe11263c95d74eDavid Li */ 1041591693c7b415e9869157c711fe11263c95d74eDavid Li assert(ret->next->is_tail_sentinel()); 1051591693c7b415e9869157c711fe11263c95d74eDavid Li ret->remove(); 1061591693c7b415e9869157c711fe11263c95d74eDavid Li } 1071591693c7b415e9869157c711fe11263c95d74eDavid Li } 1081591693c7b415e9869157c711fe11263c95d74eDavid Li} 1091591693c7b415e9869157c711fe11263c95d74eDavid Li 1101591693c7b415e9869157c711fe11263c95d74eDavid Liir_rvalue * 1111591693c7b415e9869157c711fe11263c95d74eDavid Liir_call::generate_inline(ir_instruction *next_ir) 1121591693c7b415e9869157c711fe11263c95d74eDavid Li{ 113d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li void *ctx = hieralloc_parent(this); 1141591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable **parameters; 1151591693c7b415e9869157c711fe11263c95d74eDavid Li int num_parameters; 1161591693c7b415e9869157c711fe11263c95d74eDavid Li int i; 1171591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *retval = NULL; 1181591693c7b415e9869157c711fe11263c95d74eDavid Li struct hash_table *ht; 1191591693c7b415e9869157c711fe11263c95d74eDavid Li 1201591693c7b415e9869157c711fe11263c95d74eDavid Li ht = hash_table_ctor(0, hash_table_pointer_hash, hash_table_pointer_compare); 1211591693c7b415e9869157c711fe11263c95d74eDavid Li 1221591693c7b415e9869157c711fe11263c95d74eDavid Li num_parameters = 0; 1231591693c7b415e9869157c711fe11263c95d74eDavid Li foreach_iter(exec_list_iterator, iter_sig, this->callee->parameters) 1241591693c7b415e9869157c711fe11263c95d74eDavid Li num_parameters++; 1251591693c7b415e9869157c711fe11263c95d74eDavid Li 1261591693c7b415e9869157c711fe11263c95d74eDavid Li parameters = new ir_variable *[num_parameters]; 1271591693c7b415e9869157c711fe11263c95d74eDavid Li 1281591693c7b415e9869157c711fe11263c95d74eDavid Li /* Generate storage for the return value. */ 1291591693c7b415e9869157c711fe11263c95d74eDavid Li if (this->callee->return_type) { 1301591693c7b415e9869157c711fe11263c95d74eDavid Li retval = new(ctx) ir_variable(this->callee->return_type, "_ret_val", 1311591693c7b415e9869157c711fe11263c95d74eDavid Li ir_var_auto); 1321591693c7b415e9869157c711fe11263c95d74eDavid Li next_ir->insert_before(retval); 1331591693c7b415e9869157c711fe11263c95d74eDavid Li } 1341591693c7b415e9869157c711fe11263c95d74eDavid Li 1351591693c7b415e9869157c711fe11263c95d74eDavid Li /* Generate the declarations for the parameters to our inlined code, 1361591693c7b415e9869157c711fe11263c95d74eDavid Li * and set up the mapping of real function body variables to ours. 1371591693c7b415e9869157c711fe11263c95d74eDavid Li */ 1381591693c7b415e9869157c711fe11263c95d74eDavid Li i = 0; 1391591693c7b415e9869157c711fe11263c95d74eDavid Li exec_list_iterator sig_param_iter = this->callee->parameters.iterator(); 1401591693c7b415e9869157c711fe11263c95d74eDavid Li exec_list_iterator param_iter = this->actual_parameters.iterator(); 1411591693c7b415e9869157c711fe11263c95d74eDavid Li for (i = 0; i < num_parameters; i++) { 1421591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *sig_param = (ir_variable *) sig_param_iter.get(); 1431591693c7b415e9869157c711fe11263c95d74eDavid Li ir_rvalue *param = (ir_rvalue *) param_iter.get(); 1441591693c7b415e9869157c711fe11263c95d74eDavid Li 1451591693c7b415e9869157c711fe11263c95d74eDavid Li /* Generate a new variable for the parameter. */ 1461591693c7b415e9869157c711fe11263c95d74eDavid Li if (sig_param->type->base_type == GLSL_TYPE_SAMPLER) { 1471591693c7b415e9869157c711fe11263c95d74eDavid Li /* For samplers, we want the inlined sampler references 1481591693c7b415e9869157c711fe11263c95d74eDavid Li * referencing the passed in sampler variable, since that 1491591693c7b415e9869157c711fe11263c95d74eDavid Li * will have the location information, which an assignment of 1501591693c7b415e9869157c711fe11263c95d74eDavid Li * a sampler wouldn't. Fix it up below. 1511591693c7b415e9869157c711fe11263c95d74eDavid Li */ 1521591693c7b415e9869157c711fe11263c95d74eDavid Li parameters[i] = NULL; 1531591693c7b415e9869157c711fe11263c95d74eDavid Li } else { 1541591693c7b415e9869157c711fe11263c95d74eDavid Li parameters[i] = sig_param->clone(ctx, ht); 1551591693c7b415e9869157c711fe11263c95d74eDavid Li parameters[i]->mode = ir_var_auto; 1561591693c7b415e9869157c711fe11263c95d74eDavid Li 1571591693c7b415e9869157c711fe11263c95d74eDavid Li /* Remove the read-only decoration becuase we're going to write 1581591693c7b415e9869157c711fe11263c95d74eDavid Li * directly to this variable. If the cloned variable is left 1591591693c7b415e9869157c711fe11263c95d74eDavid Li * read-only and the inlined function is inside a loop, the loop 1601591693c7b415e9869157c711fe11263c95d74eDavid Li * analysis code will get confused. 1611591693c7b415e9869157c711fe11263c95d74eDavid Li */ 1621591693c7b415e9869157c711fe11263c95d74eDavid Li parameters[i]->read_only = false; 1631591693c7b415e9869157c711fe11263c95d74eDavid Li next_ir->insert_before(parameters[i]); 1641591693c7b415e9869157c711fe11263c95d74eDavid Li } 1651591693c7b415e9869157c711fe11263c95d74eDavid Li 1661591693c7b415e9869157c711fe11263c95d74eDavid Li /* Move the actual param into our param variable if it's an 'in' type. */ 1671591693c7b415e9869157c711fe11263c95d74eDavid Li if (parameters[i] && (sig_param->mode == ir_var_in || 1681591693c7b415e9869157c711fe11263c95d74eDavid Li sig_param->mode == ir_var_inout)) { 1691591693c7b415e9869157c711fe11263c95d74eDavid Li ir_assignment *assign; 1701591693c7b415e9869157c711fe11263c95d74eDavid Li 1711591693c7b415e9869157c711fe11263c95d74eDavid Li assign = new(ctx) ir_assignment(new(ctx) ir_dereference_variable(parameters[i]), 1721591693c7b415e9869157c711fe11263c95d74eDavid Li param, NULL); 1731591693c7b415e9869157c711fe11263c95d74eDavid Li next_ir->insert_before(assign); 1741591693c7b415e9869157c711fe11263c95d74eDavid Li } 1751591693c7b415e9869157c711fe11263c95d74eDavid Li 1761591693c7b415e9869157c711fe11263c95d74eDavid Li sig_param_iter.next(); 1771591693c7b415e9869157c711fe11263c95d74eDavid Li param_iter.next(); 1781591693c7b415e9869157c711fe11263c95d74eDavid Li } 1791591693c7b415e9869157c711fe11263c95d74eDavid Li 1801591693c7b415e9869157c711fe11263c95d74eDavid Li exec_list new_instructions; 1811591693c7b415e9869157c711fe11263c95d74eDavid Li 1821591693c7b415e9869157c711fe11263c95d74eDavid Li /* Generate the inlined body of the function to a new list */ 1831591693c7b415e9869157c711fe11263c95d74eDavid Li foreach_iter(exec_list_iterator, iter, callee->body) { 1841591693c7b415e9869157c711fe11263c95d74eDavid Li ir_instruction *ir = (ir_instruction *)iter.get(); 1851591693c7b415e9869157c711fe11263c95d74eDavid Li ir_instruction *new_ir = ir->clone(ctx, ht); 1861591693c7b415e9869157c711fe11263c95d74eDavid Li 1871591693c7b415e9869157c711fe11263c95d74eDavid Li new_instructions.push_tail(new_ir); 1881591693c7b415e9869157c711fe11263c95d74eDavid Li visit_tree(new_ir, replace_return_with_assignment, retval); 1891591693c7b415e9869157c711fe11263c95d74eDavid Li } 1901591693c7b415e9869157c711fe11263c95d74eDavid Li 1911591693c7b415e9869157c711fe11263c95d74eDavid Li /* If any samplers were passed in, replace any deref of the sampler 1921591693c7b415e9869157c711fe11263c95d74eDavid Li * with a deref of the sampler argument. 1931591693c7b415e9869157c711fe11263c95d74eDavid Li */ 1941591693c7b415e9869157c711fe11263c95d74eDavid Li param_iter = this->actual_parameters.iterator(); 1951591693c7b415e9869157c711fe11263c95d74eDavid Li sig_param_iter = this->callee->parameters.iterator(); 1961591693c7b415e9869157c711fe11263c95d74eDavid Li for (i = 0; i < num_parameters; i++) { 1971591693c7b415e9869157c711fe11263c95d74eDavid Li ir_instruction *const param = (ir_instruction *) param_iter.get(); 1981591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *sig_param = (ir_variable *) sig_param_iter.get(); 1991591693c7b415e9869157c711fe11263c95d74eDavid Li 2001591693c7b415e9869157c711fe11263c95d74eDavid Li if (sig_param->type->base_type == GLSL_TYPE_SAMPLER) { 2011591693c7b415e9869157c711fe11263c95d74eDavid Li ir_dereference *deref = param->as_dereference(); 2021591693c7b415e9869157c711fe11263c95d74eDavid Li 2031591693c7b415e9869157c711fe11263c95d74eDavid Li assert(deref); 2041591693c7b415e9869157c711fe11263c95d74eDavid Li do_sampler_replacement(&new_instructions, sig_param, deref); 2051591693c7b415e9869157c711fe11263c95d74eDavid Li } 2061591693c7b415e9869157c711fe11263c95d74eDavid Li param_iter.next(); 2071591693c7b415e9869157c711fe11263c95d74eDavid Li sig_param_iter.next(); 2081591693c7b415e9869157c711fe11263c95d74eDavid Li } 2091591693c7b415e9869157c711fe11263c95d74eDavid Li 2101591693c7b415e9869157c711fe11263c95d74eDavid Li /* Now push those new instructions in. */ 2111591693c7b415e9869157c711fe11263c95d74eDavid Li foreach_iter(exec_list_iterator, iter, new_instructions) { 2121591693c7b415e9869157c711fe11263c95d74eDavid Li ir_instruction *ir = (ir_instruction *)iter.get(); 2131591693c7b415e9869157c711fe11263c95d74eDavid Li next_ir->insert_before(ir); 2141591693c7b415e9869157c711fe11263c95d74eDavid Li } 2151591693c7b415e9869157c711fe11263c95d74eDavid Li 2161591693c7b415e9869157c711fe11263c95d74eDavid Li /* Copy back the value of any 'out' parameters from the function body 2171591693c7b415e9869157c711fe11263c95d74eDavid Li * variables to our own. 2181591693c7b415e9869157c711fe11263c95d74eDavid Li */ 2191591693c7b415e9869157c711fe11263c95d74eDavid Li i = 0; 2201591693c7b415e9869157c711fe11263c95d74eDavid Li param_iter = this->actual_parameters.iterator(); 2211591693c7b415e9869157c711fe11263c95d74eDavid Li sig_param_iter = this->callee->parameters.iterator(); 2221591693c7b415e9869157c711fe11263c95d74eDavid Li for (i = 0; i < num_parameters; i++) { 2231591693c7b415e9869157c711fe11263c95d74eDavid Li ir_instruction *const param = (ir_instruction *) param_iter.get(); 2241591693c7b415e9869157c711fe11263c95d74eDavid Li const ir_variable *const sig_param = (ir_variable *) sig_param_iter.get(); 2251591693c7b415e9869157c711fe11263c95d74eDavid Li 2261591693c7b415e9869157c711fe11263c95d74eDavid Li /* Move our param variable into the actual param if it's an 'out' type. */ 2271591693c7b415e9869157c711fe11263c95d74eDavid Li if (parameters[i] && (sig_param->mode == ir_var_out || 2281591693c7b415e9869157c711fe11263c95d74eDavid Li sig_param->mode == ir_var_inout)) { 2291591693c7b415e9869157c711fe11263c95d74eDavid Li ir_assignment *assign; 2301591693c7b415e9869157c711fe11263c95d74eDavid Li 2311591693c7b415e9869157c711fe11263c95d74eDavid Li assign = new(ctx) ir_assignment(param->clone(ctx, NULL)->as_rvalue(), 2321591693c7b415e9869157c711fe11263c95d74eDavid Li new(ctx) ir_dereference_variable(parameters[i]), 2331591693c7b415e9869157c711fe11263c95d74eDavid Li NULL); 2341591693c7b415e9869157c711fe11263c95d74eDavid Li next_ir->insert_before(assign); 2351591693c7b415e9869157c711fe11263c95d74eDavid Li } 2361591693c7b415e9869157c711fe11263c95d74eDavid Li 2371591693c7b415e9869157c711fe11263c95d74eDavid Li param_iter.next(); 2381591693c7b415e9869157c711fe11263c95d74eDavid Li sig_param_iter.next(); 2391591693c7b415e9869157c711fe11263c95d74eDavid Li } 2401591693c7b415e9869157c711fe11263c95d74eDavid Li 2411591693c7b415e9869157c711fe11263c95d74eDavid Li delete [] parameters; 2421591693c7b415e9869157c711fe11263c95d74eDavid Li 2431591693c7b415e9869157c711fe11263c95d74eDavid Li hash_table_dtor(ht); 2441591693c7b415e9869157c711fe11263c95d74eDavid Li 2451591693c7b415e9869157c711fe11263c95d74eDavid Li if (retval) 2461591693c7b415e9869157c711fe11263c95d74eDavid Li return new(ctx) ir_dereference_variable(retval); 2471591693c7b415e9869157c711fe11263c95d74eDavid Li else 2481591693c7b415e9869157c711fe11263c95d74eDavid Li return NULL; 2491591693c7b415e9869157c711fe11263c95d74eDavid Li} 2501591693c7b415e9869157c711fe11263c95d74eDavid Li 2511591693c7b415e9869157c711fe11263c95d74eDavid Li 2521591693c7b415e9869157c711fe11263c95d74eDavid Liir_visitor_status 2531591693c7b415e9869157c711fe11263c95d74eDavid Liir_function_inlining_visitor::visit_enter(ir_expression *ir) 2541591693c7b415e9869157c711fe11263c95d74eDavid Li{ 2551591693c7b415e9869157c711fe11263c95d74eDavid Li (void) ir; 2561591693c7b415e9869157c711fe11263c95d74eDavid Li return visit_continue_with_parent; 2571591693c7b415e9869157c711fe11263c95d74eDavid Li} 2581591693c7b415e9869157c711fe11263c95d74eDavid Li 2591591693c7b415e9869157c711fe11263c95d74eDavid Li 2601591693c7b415e9869157c711fe11263c95d74eDavid Liir_visitor_status 2611591693c7b415e9869157c711fe11263c95d74eDavid Liir_function_inlining_visitor::visit_enter(ir_return *ir) 2621591693c7b415e9869157c711fe11263c95d74eDavid Li{ 2631591693c7b415e9869157c711fe11263c95d74eDavid Li (void) ir; 2641591693c7b415e9869157c711fe11263c95d74eDavid Li return visit_continue_with_parent; 2651591693c7b415e9869157c711fe11263c95d74eDavid Li} 2661591693c7b415e9869157c711fe11263c95d74eDavid Li 2671591693c7b415e9869157c711fe11263c95d74eDavid Li 2681591693c7b415e9869157c711fe11263c95d74eDavid Liir_visitor_status 2691591693c7b415e9869157c711fe11263c95d74eDavid Liir_function_inlining_visitor::visit_enter(ir_texture *ir) 2701591693c7b415e9869157c711fe11263c95d74eDavid Li{ 2711591693c7b415e9869157c711fe11263c95d74eDavid Li (void) ir; 2721591693c7b415e9869157c711fe11263c95d74eDavid Li return visit_continue_with_parent; 2731591693c7b415e9869157c711fe11263c95d74eDavid Li} 2741591693c7b415e9869157c711fe11263c95d74eDavid Li 2751591693c7b415e9869157c711fe11263c95d74eDavid Li 2761591693c7b415e9869157c711fe11263c95d74eDavid Liir_visitor_status 2771591693c7b415e9869157c711fe11263c95d74eDavid Liir_function_inlining_visitor::visit_enter(ir_swizzle *ir) 2781591693c7b415e9869157c711fe11263c95d74eDavid Li{ 2791591693c7b415e9869157c711fe11263c95d74eDavid Li (void) ir; 2801591693c7b415e9869157c711fe11263c95d74eDavid Li return visit_continue_with_parent; 2811591693c7b415e9869157c711fe11263c95d74eDavid Li} 2821591693c7b415e9869157c711fe11263c95d74eDavid Li 2831591693c7b415e9869157c711fe11263c95d74eDavid Li 2841591693c7b415e9869157c711fe11263c95d74eDavid Liir_visitor_status 2851591693c7b415e9869157c711fe11263c95d74eDavid Liir_function_inlining_visitor::visit_enter(ir_call *ir) 2861591693c7b415e9869157c711fe11263c95d74eDavid Li{ 2871591693c7b415e9869157c711fe11263c95d74eDavid Li if (can_inline(ir)) { 2881591693c7b415e9869157c711fe11263c95d74eDavid Li /* If the call was part of some tree, then it should have been 2891591693c7b415e9869157c711fe11263c95d74eDavid Li * flattened out or we shouldn't have seen it because of a 2901591693c7b415e9869157c711fe11263c95d74eDavid Li * visit_continue_with_parent in this visitor. 2911591693c7b415e9869157c711fe11263c95d74eDavid Li */ 2921591693c7b415e9869157c711fe11263c95d74eDavid Li assert(ir == base_ir); 2931591693c7b415e9869157c711fe11263c95d74eDavid Li 2941591693c7b415e9869157c711fe11263c95d74eDavid Li (void) ir->generate_inline(ir); 2951591693c7b415e9869157c711fe11263c95d74eDavid Li ir->remove(); 2961591693c7b415e9869157c711fe11263c95d74eDavid Li this->progress = true; 2971591693c7b415e9869157c711fe11263c95d74eDavid Li } 2981591693c7b415e9869157c711fe11263c95d74eDavid Li 2991591693c7b415e9869157c711fe11263c95d74eDavid Li return visit_continue; 3001591693c7b415e9869157c711fe11263c95d74eDavid Li} 3011591693c7b415e9869157c711fe11263c95d74eDavid Li 3021591693c7b415e9869157c711fe11263c95d74eDavid Li 3031591693c7b415e9869157c711fe11263c95d74eDavid Liir_visitor_status 3041591693c7b415e9869157c711fe11263c95d74eDavid Liir_function_inlining_visitor::visit_enter(ir_assignment *ir) 3051591693c7b415e9869157c711fe11263c95d74eDavid Li{ 3061591693c7b415e9869157c711fe11263c95d74eDavid Li ir_call *call = ir->rhs->as_call(); 3071591693c7b415e9869157c711fe11263c95d74eDavid Li if (!call || !can_inline(call)) 3081591693c7b415e9869157c711fe11263c95d74eDavid Li return visit_continue; 3091591693c7b415e9869157c711fe11263c95d74eDavid Li 3101591693c7b415e9869157c711fe11263c95d74eDavid Li /* generates the parameter setup, function body, and returns the return 3111591693c7b415e9869157c711fe11263c95d74eDavid Li * value of the function 3121591693c7b415e9869157c711fe11263c95d74eDavid Li */ 3131591693c7b415e9869157c711fe11263c95d74eDavid Li ir_rvalue *rhs = call->generate_inline(ir); 3141591693c7b415e9869157c711fe11263c95d74eDavid Li assert(rhs); 3151591693c7b415e9869157c711fe11263c95d74eDavid Li 3161591693c7b415e9869157c711fe11263c95d74eDavid Li ir->rhs = rhs; 3171591693c7b415e9869157c711fe11263c95d74eDavid Li this->progress = true; 3181591693c7b415e9869157c711fe11263c95d74eDavid Li 3191591693c7b415e9869157c711fe11263c95d74eDavid Li return visit_continue; 3201591693c7b415e9869157c711fe11263c95d74eDavid Li} 3211591693c7b415e9869157c711fe11263c95d74eDavid Li 3221591693c7b415e9869157c711fe11263c95d74eDavid Li/** 3231591693c7b415e9869157c711fe11263c95d74eDavid Li * Replaces references to the "sampler" variable with a clone of "deref." 3241591693c7b415e9869157c711fe11263c95d74eDavid Li * 3251591693c7b415e9869157c711fe11263c95d74eDavid Li * From the spec, samplers can appear in the tree as function 3261591693c7b415e9869157c711fe11263c95d74eDavid Li * (non-out) parameters and as the result of array indexing and 3271591693c7b415e9869157c711fe11263c95d74eDavid Li * structure field selection. In our builtin implementation, they 3281591693c7b415e9869157c711fe11263c95d74eDavid Li * also appear in the sampler field of an ir_tex instruction. 3291591693c7b415e9869157c711fe11263c95d74eDavid Li */ 3301591693c7b415e9869157c711fe11263c95d74eDavid Li 3311591693c7b415e9869157c711fe11263c95d74eDavid Liclass ir_sampler_replacement_visitor : public ir_hierarchical_visitor { 3321591693c7b415e9869157c711fe11263c95d74eDavid Lipublic: 3331591693c7b415e9869157c711fe11263c95d74eDavid Li ir_sampler_replacement_visitor(ir_variable *sampler, ir_dereference *deref) 3341591693c7b415e9869157c711fe11263c95d74eDavid Li { 3351591693c7b415e9869157c711fe11263c95d74eDavid Li this->sampler = sampler; 3361591693c7b415e9869157c711fe11263c95d74eDavid Li this->deref = deref; 3371591693c7b415e9869157c711fe11263c95d74eDavid Li } 3381591693c7b415e9869157c711fe11263c95d74eDavid Li 3391591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ~ir_sampler_replacement_visitor() 3401591693c7b415e9869157c711fe11263c95d74eDavid Li { 3411591693c7b415e9869157c711fe11263c95d74eDavid Li } 3421591693c7b415e9869157c711fe11263c95d74eDavid Li 3431591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit_leave(ir_call *); 3441591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit_leave(ir_dereference_array *); 3451591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit_leave(ir_dereference_record *); 3461591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit_leave(ir_texture *); 3471591693c7b415e9869157c711fe11263c95d74eDavid Li 3481591693c7b415e9869157c711fe11263c95d74eDavid Li void replace_deref(ir_dereference **deref); 3491591693c7b415e9869157c711fe11263c95d74eDavid Li void replace_rvalue(ir_rvalue **rvalue); 3501591693c7b415e9869157c711fe11263c95d74eDavid Li 3511591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *sampler; 3521591693c7b415e9869157c711fe11263c95d74eDavid Li ir_dereference *deref; 3531591693c7b415e9869157c711fe11263c95d74eDavid Li}; 3541591693c7b415e9869157c711fe11263c95d74eDavid Li 3551591693c7b415e9869157c711fe11263c95d74eDavid Livoid 3561591693c7b415e9869157c711fe11263c95d74eDavid Liir_sampler_replacement_visitor::replace_deref(ir_dereference **deref) 3571591693c7b415e9869157c711fe11263c95d74eDavid Li{ 3581591693c7b415e9869157c711fe11263c95d74eDavid Li ir_dereference_variable *deref_var = (*deref)->as_dereference_variable(); 3591591693c7b415e9869157c711fe11263c95d74eDavid Li if (deref_var && deref_var->var == this->sampler) { 360d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li *deref = this->deref->clone(hieralloc_parent(*deref), NULL); 3611591693c7b415e9869157c711fe11263c95d74eDavid Li } 3621591693c7b415e9869157c711fe11263c95d74eDavid Li} 3631591693c7b415e9869157c711fe11263c95d74eDavid Li 3641591693c7b415e9869157c711fe11263c95d74eDavid Livoid 3651591693c7b415e9869157c711fe11263c95d74eDavid Liir_sampler_replacement_visitor::replace_rvalue(ir_rvalue **rvalue) 3661591693c7b415e9869157c711fe11263c95d74eDavid Li{ 3671591693c7b415e9869157c711fe11263c95d74eDavid Li if (!*rvalue) 3681591693c7b415e9869157c711fe11263c95d74eDavid Li return; 3691591693c7b415e9869157c711fe11263c95d74eDavid Li 3701591693c7b415e9869157c711fe11263c95d74eDavid Li ir_dereference *deref = (*rvalue)->as_dereference(); 3711591693c7b415e9869157c711fe11263c95d74eDavid Li 3721591693c7b415e9869157c711fe11263c95d74eDavid Li if (!deref) 3731591693c7b415e9869157c711fe11263c95d74eDavid Li return; 3741591693c7b415e9869157c711fe11263c95d74eDavid Li 3751591693c7b415e9869157c711fe11263c95d74eDavid Li replace_deref(&deref); 3761591693c7b415e9869157c711fe11263c95d74eDavid Li *rvalue = deref; 3771591693c7b415e9869157c711fe11263c95d74eDavid Li} 3781591693c7b415e9869157c711fe11263c95d74eDavid Li 3791591693c7b415e9869157c711fe11263c95d74eDavid Liir_visitor_status 3801591693c7b415e9869157c711fe11263c95d74eDavid Liir_sampler_replacement_visitor::visit_leave(ir_texture *ir) 3811591693c7b415e9869157c711fe11263c95d74eDavid Li{ 3821591693c7b415e9869157c711fe11263c95d74eDavid Li replace_deref(&ir->sampler); 3831591693c7b415e9869157c711fe11263c95d74eDavid Li 3841591693c7b415e9869157c711fe11263c95d74eDavid Li return visit_continue; 3851591693c7b415e9869157c711fe11263c95d74eDavid Li} 3861591693c7b415e9869157c711fe11263c95d74eDavid Li 3871591693c7b415e9869157c711fe11263c95d74eDavid Liir_visitor_status 3881591693c7b415e9869157c711fe11263c95d74eDavid Liir_sampler_replacement_visitor::visit_leave(ir_dereference_array *ir) 3891591693c7b415e9869157c711fe11263c95d74eDavid Li{ 3901591693c7b415e9869157c711fe11263c95d74eDavid Li replace_rvalue(&ir->array); 3911591693c7b415e9869157c711fe11263c95d74eDavid Li return visit_continue; 3921591693c7b415e9869157c711fe11263c95d74eDavid Li} 3931591693c7b415e9869157c711fe11263c95d74eDavid Li 3941591693c7b415e9869157c711fe11263c95d74eDavid Liir_visitor_status 3951591693c7b415e9869157c711fe11263c95d74eDavid Liir_sampler_replacement_visitor::visit_leave(ir_dereference_record *ir) 3961591693c7b415e9869157c711fe11263c95d74eDavid Li{ 3971591693c7b415e9869157c711fe11263c95d74eDavid Li replace_rvalue(&ir->record); 3981591693c7b415e9869157c711fe11263c95d74eDavid Li return visit_continue; 3991591693c7b415e9869157c711fe11263c95d74eDavid Li} 4001591693c7b415e9869157c711fe11263c95d74eDavid Li 4011591693c7b415e9869157c711fe11263c95d74eDavid Liir_visitor_status 4021591693c7b415e9869157c711fe11263c95d74eDavid Liir_sampler_replacement_visitor::visit_leave(ir_call *ir) 4031591693c7b415e9869157c711fe11263c95d74eDavid Li{ 4041591693c7b415e9869157c711fe11263c95d74eDavid Li foreach_iter(exec_list_iterator, iter, *ir) { 4051591693c7b415e9869157c711fe11263c95d74eDavid Li ir_rvalue *param = (ir_rvalue *)iter.get(); 4061591693c7b415e9869157c711fe11263c95d74eDavid Li ir_rvalue *new_param = param; 4071591693c7b415e9869157c711fe11263c95d74eDavid Li replace_rvalue(&new_param); 4081591693c7b415e9869157c711fe11263c95d74eDavid Li 4091591693c7b415e9869157c711fe11263c95d74eDavid Li if (new_param != param) { 4101591693c7b415e9869157c711fe11263c95d74eDavid Li param->replace_with(new_param); 4111591693c7b415e9869157c711fe11263c95d74eDavid Li } 4121591693c7b415e9869157c711fe11263c95d74eDavid Li } 4131591693c7b415e9869157c711fe11263c95d74eDavid Li return visit_continue; 4141591693c7b415e9869157c711fe11263c95d74eDavid Li} 4151591693c7b415e9869157c711fe11263c95d74eDavid Li 4161591693c7b415e9869157c711fe11263c95d74eDavid Listatic void 4171591693c7b415e9869157c711fe11263c95d74eDavid Lido_sampler_replacement(exec_list *instructions, 4181591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *sampler, 4191591693c7b415e9869157c711fe11263c95d74eDavid Li ir_dereference *deref) 4201591693c7b415e9869157c711fe11263c95d74eDavid Li{ 4211591693c7b415e9869157c711fe11263c95d74eDavid Li ir_sampler_replacement_visitor v(sampler, deref); 4221591693c7b415e9869157c711fe11263c95d74eDavid Li 4231591693c7b415e9869157c711fe11263c95d74eDavid Li visit_list_elements(&v, instructions); 4241591693c7b415e9869157c711fe11263c95d74eDavid Li} 425