1a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt/* 2a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * Copyright © 2010 Intel Corporation 3a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * 4a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * Permission is hereby granted, free of charge, to any person obtaining a 5a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * copy of this software and associated documentation files (the "Software"), 6a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * to deal in the Software without restriction, including without limitation 7a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * and/or sell copies of the Software, and to permit persons to whom the 9a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * Software is furnished to do so, subject to the following conditions: 10a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * 11a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * The above copyright notice and this permission notice (including the next 12a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * paragraph) shall be included in all copies or substantial portions of the 13a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * Software. 14a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * 15a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * DEALINGS IN THE SOFTWARE. 22a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt */ 23a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt 24a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt/** 25df883eb1575a740bf91e01cbe2eaa4dbc1f9f154Chad Versace * \file lower_vec_index_to_cond_assign.cpp 26a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * 27a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * Turns indexing into vector types to a series of conditional moves 28a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * of each channel's swizzle into a temporary. 29a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * 30a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * Most GPUs don't have a native way to do this operation, and this 31a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * works around that. For drivers using both this pass and 32a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * ir_vec_index_to_swizzle, there's a risk that this pass will happen 33a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * before sufficient constant folding to find that the array index is 34a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * constant. However, we hope that other optimization passes, 35a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * particularly constant folding of assignment conditions and copy 36a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * propagation, will result in the same code in the end. 37a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt */ 38a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt 39a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt#include "ir.h" 40a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt#include "ir_visitor.h" 41a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt#include "ir_optimization.h" 42a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt#include "glsl_types.h" 43a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt 44a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt/** 45a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * Visitor class for replacing expressions with ir_constant values. 46a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt */ 47a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt 48a36334be02cb0a2b834667116bfeb680bf365857Eric Anholtclass ir_vec_index_to_cond_assign_visitor : public ir_hierarchical_visitor { 49a36334be02cb0a2b834667116bfeb680bf365857Eric Anholtpublic: 50a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt ir_vec_index_to_cond_assign_visitor() 51a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt { 52a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt progress = false; 53a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt } 54a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt 55a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt ir_rvalue *convert_vec_index_to_cond_assign(ir_rvalue *val); 56a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt 57a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt virtual ir_visitor_status visit_enter(ir_expression *); 58a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt virtual ir_visitor_status visit_enter(ir_swizzle *); 597b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt virtual ir_visitor_status visit_leave(ir_assignment *); 60a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt virtual ir_visitor_status visit_enter(ir_return *); 61a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt virtual ir_visitor_status visit_enter(ir_call *); 62a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt virtual ir_visitor_status visit_enter(ir_if *); 63a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt 64a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt bool progress; 65a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt}; 66a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt 67a36334be02cb0a2b834667116bfeb680bf365857Eric Anholtir_rvalue * 68a36334be02cb0a2b834667116bfeb680bf365857Eric Anholtir_vec_index_to_cond_assign_visitor::convert_vec_index_to_cond_assign(ir_rvalue *ir) 69a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt{ 70a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt ir_dereference_array *orig_deref = ir->as_dereference_array(); 71a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt ir_assignment *assign; 72a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt ir_variable *index, *var; 73a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt ir_dereference *deref; 74a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt int i; 75a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt 76a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt if (!orig_deref) 77a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt return ir; 78a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt 79a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt if (orig_deref->array->type->is_matrix() || 80a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt orig_deref->array->type->is_array()) 81a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt return ir; 82a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt 83d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke void *mem_ctx = ralloc_parent(ir); 848273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt 85a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt assert(orig_deref->array_index->type->base_type == GLSL_TYPE_INT); 86a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt 876c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick exec_list list; 886c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick 89a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt /* Store the index to a temporary to avoid reusing its tree. */ 90a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt index = new(base_ir) ir_variable(glsl_type::int_type, 917e2aa91507a5883e33473e0a94215ee3985baad1Ian Romanick "vec_index_tmp_i", 927e2aa91507a5883e33473e0a94215ee3985baad1Ian Romanick ir_var_temporary); 936c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick list.push_tail(index); 94a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt deref = new(base_ir) ir_dereference_variable(index); 95a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt assign = new(base_ir) ir_assignment(deref, orig_deref->array_index, NULL); 966c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick list.push_tail(assign); 97a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt 98a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt /* Temporary where we store whichever value we swizzle out. */ 997e2aa91507a5883e33473e0a94215ee3985baad1Ian Romanick var = new(base_ir) ir_variable(ir->type, "vec_index_tmp_v", 1007e2aa91507a5883e33473e0a94215ee3985baad1Ian Romanick ir_var_temporary); 1016c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick list.push_tail(var); 1026c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick 1036c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick /* Generate a single comparison condition "mask" for all of the components 1046c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick * in the vector. 1056c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick */ 1066c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick ir_rvalue *const cond_deref = 1076c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick compare_index_block(&list, index, 0, 1086c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick orig_deref->array->type->vector_elements, 1096c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick mem_ctx); 110a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt 111a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt /* Generate a conditional move of each vector element to the temp. */ 112a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt for (i = 0; i < orig_deref->array->type->vector_elements; i++) { 1136c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick ir_rvalue *condition_swizzle = 1146c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick new(base_ir) ir_swizzle(cond_deref->clone(ir, NULL), i, 0, 0, 0, 1); 115a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt 116a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt /* Just clone the rest of the deref chain when trying to get at the 117a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * underlying variable. 118a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt */ 1196c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick ir_rvalue *swizzle = 1206c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick new(base_ir) ir_swizzle(orig_deref->array->clone(mem_ctx, NULL), 1216c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick i, 0, 0, 0, 1); 122a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt 123a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt deref = new(base_ir) ir_dereference_variable(var); 1246c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick assign = new(base_ir) ir_assignment(deref, swizzle, condition_swizzle); 1256c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick list.push_tail(assign); 126a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt } 127a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt 1286c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick /* Put all of the new instructions in the IR stream before the old 1296c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick * instruction. 1306c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick */ 1316c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick base_ir->insert_before(&list); 1326c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick 133a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt this->progress = true; 134a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt return new(base_ir) ir_dereference_variable(var); 135a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt} 136a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt 137a36334be02cb0a2b834667116bfeb680bf365857Eric Anholtir_visitor_status 138a36334be02cb0a2b834667116bfeb680bf365857Eric Anholtir_vec_index_to_cond_assign_visitor::visit_enter(ir_expression *ir) 139a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt{ 140a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt unsigned int i; 141a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt 142a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt for (i = 0; i < ir->get_num_operands(); i++) { 143a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt ir->operands[i] = convert_vec_index_to_cond_assign(ir->operands[i]); 144a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt } 145a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt 146a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt return visit_continue; 147a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt} 148a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt 149a36334be02cb0a2b834667116bfeb680bf365857Eric Anholtir_visitor_status 150a36334be02cb0a2b834667116bfeb680bf365857Eric Anholtir_vec_index_to_cond_assign_visitor::visit_enter(ir_swizzle *ir) 151a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt{ 152a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt /* Can't be hit from normal GLSL, since you can't swizzle a scalar (which 153a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * the result of indexing a vector is. But maybe at some point we'll end up 154a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * using swizzling of scalars for vector construction. 155a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt */ 156a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt ir->val = convert_vec_index_to_cond_assign(ir->val); 157a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt 158a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt return visit_continue; 159a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt} 160a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt 161a36334be02cb0a2b834667116bfeb680bf365857Eric Anholtir_visitor_status 1627b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholtir_vec_index_to_cond_assign_visitor::visit_leave(ir_assignment *ir) 163a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt{ 1647b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt ir_variable *index, *var; 1657b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt ir_dereference_variable *deref; 1667b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt ir_assignment *assign; 1677b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt int i; 1687b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt 169a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt ir->rhs = convert_vec_index_to_cond_assign(ir->rhs); 1707b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt if (ir->condition) 1717b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt ir->condition = convert_vec_index_to_cond_assign(ir->condition); 1727b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt 1737b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt /* Last, handle the LHS */ 1747b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt ir_dereference_array *orig_deref = ir->lhs->as_dereference_array(); 1757b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt 1767b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt if (!orig_deref || 1777b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt orig_deref->array->type->is_matrix() || 1787b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt orig_deref->array->type->is_array()) 1797b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt return visit_continue; 1807b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt 181d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke void *mem_ctx = ralloc_parent(ir); 1828273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt 1837b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt assert(orig_deref->array_index->type->base_type == GLSL_TYPE_INT); 1847b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt 185601428d2bbcf650c746f7a10b47228948f0ea912Ian Romanick exec_list list; 186601428d2bbcf650c746f7a10b47228948f0ea912Ian Romanick 1877b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt /* Store the index to a temporary to avoid reusing its tree. */ 1887e2aa91507a5883e33473e0a94215ee3985baad1Ian Romanick index = new(ir) ir_variable(glsl_type::int_type, "vec_index_tmp_i", 1897e2aa91507a5883e33473e0a94215ee3985baad1Ian Romanick ir_var_temporary); 190601428d2bbcf650c746f7a10b47228948f0ea912Ian Romanick list.push_tail(index); 1917b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt deref = new(ir) ir_dereference_variable(index); 1927b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt assign = new(ir) ir_assignment(deref, orig_deref->array_index, NULL); 193601428d2bbcf650c746f7a10b47228948f0ea912Ian Romanick list.push_tail(assign); 1947b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt 1957b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt /* Store the RHS to a temporary to avoid reusing its tree. */ 1967e2aa91507a5883e33473e0a94215ee3985baad1Ian Romanick var = new(ir) ir_variable(ir->rhs->type, "vec_index_tmp_v", 1977e2aa91507a5883e33473e0a94215ee3985baad1Ian Romanick ir_var_temporary); 198601428d2bbcf650c746f7a10b47228948f0ea912Ian Romanick list.push_tail(var); 1997b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt deref = new(ir) ir_dereference_variable(var); 2007b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt assign = new(ir) ir_assignment(deref, ir->rhs, NULL); 201601428d2bbcf650c746f7a10b47228948f0ea912Ian Romanick list.push_tail(assign); 2027b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt 2036c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick /* Generate a single comparison condition "mask" for all of the components 2046c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick * in the vector. 2056c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick */ 2066c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick ir_rvalue *const cond_deref = 2076c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick compare_index_block(&list, index, 0, 2086c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick orig_deref->array->type->vector_elements, 2096c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick mem_ctx); 2106c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick 2117b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt /* Generate a conditional move of each vector element to the temp. */ 2127b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt for (i = 0; i < orig_deref->array->type->vector_elements; i++) { 2136c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick ir_rvalue *condition_swizzle = 2146c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick new(ir) ir_swizzle(cond_deref->clone(ir, NULL), i, 0, 0, 0, 1); 2157b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt 2167b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt 2177b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt /* Just clone the rest of the deref chain when trying to get at the 2187b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt * underlying variable. 2197b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt */ 2206c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick ir_rvalue *swizzle = 2216c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick new(ir) ir_swizzle(orig_deref->array->clone(mem_ctx, NULL), 2226c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick i, 0, 0, 0, 1); 2237b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt 2247b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt deref = new(ir) ir_dereference_variable(var); 2256c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick assign = new(ir) ir_assignment(swizzle, deref, condition_swizzle); 226601428d2bbcf650c746f7a10b47228948f0ea912Ian Romanick list.push_tail(assign); 2277b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt } 228601428d2bbcf650c746f7a10b47228948f0ea912Ian Romanick 229601428d2bbcf650c746f7a10b47228948f0ea912Ian Romanick /* If the original assignment has a condition, respect that original 230601428d2bbcf650c746f7a10b47228948f0ea912Ian Romanick * condition! This is acomplished by wrapping the new conditional 231601428d2bbcf650c746f7a10b47228948f0ea912Ian Romanick * assignments in an if-statement that uses the original condition. 232601428d2bbcf650c746f7a10b47228948f0ea912Ian Romanick */ 233601428d2bbcf650c746f7a10b47228948f0ea912Ian Romanick if (ir->condition != NULL) { 234601428d2bbcf650c746f7a10b47228948f0ea912Ian Romanick /* No need to clone the condition because the IR that it hangs on is 235601428d2bbcf650c746f7a10b47228948f0ea912Ian Romanick * going to be removed from the instruction sequence. 236601428d2bbcf650c746f7a10b47228948f0ea912Ian Romanick */ 237601428d2bbcf650c746f7a10b47228948f0ea912Ian Romanick ir_if *if_stmt = new(mem_ctx) ir_if(ir->condition); 238601428d2bbcf650c746f7a10b47228948f0ea912Ian Romanick 239601428d2bbcf650c746f7a10b47228948f0ea912Ian Romanick list.move_nodes_to(&if_stmt->then_instructions); 240601428d2bbcf650c746f7a10b47228948f0ea912Ian Romanick ir->insert_before(if_stmt); 241601428d2bbcf650c746f7a10b47228948f0ea912Ian Romanick } else { 242601428d2bbcf650c746f7a10b47228948f0ea912Ian Romanick ir->insert_before(&list); 243601428d2bbcf650c746f7a10b47228948f0ea912Ian Romanick } 244601428d2bbcf650c746f7a10b47228948f0ea912Ian Romanick 2457b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt ir->remove(); 2467b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt 2477b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt this->progress = true; 248a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt 249a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt return visit_continue; 250a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt} 251a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt 252a36334be02cb0a2b834667116bfeb680bf365857Eric Anholtir_visitor_status 253a36334be02cb0a2b834667116bfeb680bf365857Eric Anholtir_vec_index_to_cond_assign_visitor::visit_enter(ir_call *ir) 254a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt{ 255a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt foreach_iter(exec_list_iterator, iter, *ir) { 256a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt ir_rvalue *param = (ir_rvalue *)iter.get(); 257a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt ir_rvalue *new_param = convert_vec_index_to_cond_assign(param); 258a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt 259a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt if (new_param != param) { 260c7a18da69022d3f9b05c21ff2473e8ea390f77f1Kenneth Graunke param->replace_with(new_param); 261a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt } 262a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt } 263a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt 264a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt return visit_continue; 265a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt} 266a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt 267a36334be02cb0a2b834667116bfeb680bf365857Eric Anholtir_visitor_status 268a36334be02cb0a2b834667116bfeb680bf365857Eric Anholtir_vec_index_to_cond_assign_visitor::visit_enter(ir_return *ir) 269a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt{ 270a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt if (ir->value) { 271a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt ir->value = convert_vec_index_to_cond_assign(ir->value); 272a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt } 273a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt 274a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt return visit_continue; 275a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt} 276a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt 277a36334be02cb0a2b834667116bfeb680bf365857Eric Anholtir_visitor_status 278a36334be02cb0a2b834667116bfeb680bf365857Eric Anholtir_vec_index_to_cond_assign_visitor::visit_enter(ir_if *ir) 279a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt{ 280a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt ir->condition = convert_vec_index_to_cond_assign(ir->condition); 281a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt 282a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt return visit_continue; 283a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt} 284a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt 285a36334be02cb0a2b834667116bfeb680bf365857Eric Anholtbool 286a36334be02cb0a2b834667116bfeb680bf365857Eric Anholtdo_vec_index_to_cond_assign(exec_list *instructions) 287a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt{ 288a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt ir_vec_index_to_cond_assign_visitor v; 289a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt 290a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt visit_list_elements(&v, instructions); 291a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt 292a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt return v.progress; 293a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt} 294