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 lower_vec_index_to_swizzle.cpp 261591693c7b415e9869157c711fe11263c95d74eDavid Li * 271591693c7b415e9869157c711fe11263c95d74eDavid Li * Turns constant indexing into vector types to swizzles. This will 281591693c7b415e9869157c711fe11263c95d74eDavid Li * let other swizzle-aware optimization passes catch these constructs, 291591693c7b415e9869157c711fe11263c95d74eDavid Li * and codegen backends not have to worry about this case. 301591693c7b415e9869157c711fe11263c95d74eDavid Li */ 311591693c7b415e9869157c711fe11263c95d74eDavid Li 321591693c7b415e9869157c711fe11263c95d74eDavid Li#include "ir.h" 331591693c7b415e9869157c711fe11263c95d74eDavid Li#include "ir_visitor.h" 341591693c7b415e9869157c711fe11263c95d74eDavid Li#include "ir_optimization.h" 351591693c7b415e9869157c711fe11263c95d74eDavid Li#include "glsl_types.h" 361591693c7b415e9869157c711fe11263c95d74eDavid Li 371591693c7b415e9869157c711fe11263c95d74eDavid Li/** 381591693c7b415e9869157c711fe11263c95d74eDavid Li * Visitor class for replacing expressions with ir_constant values. 391591693c7b415e9869157c711fe11263c95d74eDavid Li */ 401591693c7b415e9869157c711fe11263c95d74eDavid Li 411591693c7b415e9869157c711fe11263c95d74eDavid Liclass ir_vec_index_to_swizzle_visitor : public ir_hierarchical_visitor { 421591693c7b415e9869157c711fe11263c95d74eDavid Lipublic: 431591693c7b415e9869157c711fe11263c95d74eDavid Li ir_vec_index_to_swizzle_visitor() 441591693c7b415e9869157c711fe11263c95d74eDavid Li { 451591693c7b415e9869157c711fe11263c95d74eDavid Li progress = false; 461591693c7b415e9869157c711fe11263c95d74eDavid Li } 471591693c7b415e9869157c711fe11263c95d74eDavid Li 481591693c7b415e9869157c711fe11263c95d74eDavid Li ir_rvalue *convert_vec_index_to_swizzle(ir_rvalue *val); 491591693c7b415e9869157c711fe11263c95d74eDavid Li 501591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit_enter(ir_expression *); 511591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit_enter(ir_swizzle *); 521591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit_enter(ir_assignment *); 531591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit_enter(ir_return *); 541591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit_enter(ir_call *); 551591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit_enter(ir_if *); 561591693c7b415e9869157c711fe11263c95d74eDavid Li 571591693c7b415e9869157c711fe11263c95d74eDavid Li bool progress; 581591693c7b415e9869157c711fe11263c95d74eDavid Li}; 591591693c7b415e9869157c711fe11263c95d74eDavid Li 601591693c7b415e9869157c711fe11263c95d74eDavid Liir_rvalue * 611591693c7b415e9869157c711fe11263c95d74eDavid Liir_vec_index_to_swizzle_visitor::convert_vec_index_to_swizzle(ir_rvalue *ir) 621591693c7b415e9869157c711fe11263c95d74eDavid Li{ 631591693c7b415e9869157c711fe11263c95d74eDavid Li ir_dereference_array *deref = ir->as_dereference_array(); 641591693c7b415e9869157c711fe11263c95d74eDavid Li ir_constant *ir_constant; 651591693c7b415e9869157c711fe11263c95d74eDavid Li 661591693c7b415e9869157c711fe11263c95d74eDavid Li if (!deref) 671591693c7b415e9869157c711fe11263c95d74eDavid Li return ir; 681591693c7b415e9869157c711fe11263c95d74eDavid Li 691591693c7b415e9869157c711fe11263c95d74eDavid Li if (deref->array->type->is_matrix() || deref->array->type->is_array()) 701591693c7b415e9869157c711fe11263c95d74eDavid Li return ir; 711591693c7b415e9869157c711fe11263c95d74eDavid Li 721591693c7b415e9869157c711fe11263c95d74eDavid Li assert(deref->array_index->type->base_type == GLSL_TYPE_INT); 731591693c7b415e9869157c711fe11263c95d74eDavid Li ir_constant = deref->array_index->constant_expression_value(); 741591693c7b415e9869157c711fe11263c95d74eDavid Li if (!ir_constant) 751591693c7b415e9869157c711fe11263c95d74eDavid Li return ir; 761591693c7b415e9869157c711fe11263c95d74eDavid Li 77d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li void *ctx = hieralloc_parent(ir); 781591693c7b415e9869157c711fe11263c95d74eDavid Li this->progress = true; 791591693c7b415e9869157c711fe11263c95d74eDavid Li return new(ctx) ir_swizzle(deref->array, 801591693c7b415e9869157c711fe11263c95d74eDavid Li ir_constant->value.i[0], 0, 0, 0, 1); 811591693c7b415e9869157c711fe11263c95d74eDavid Li} 821591693c7b415e9869157c711fe11263c95d74eDavid Li 831591693c7b415e9869157c711fe11263c95d74eDavid Liir_visitor_status 841591693c7b415e9869157c711fe11263c95d74eDavid Liir_vec_index_to_swizzle_visitor::visit_enter(ir_expression *ir) 851591693c7b415e9869157c711fe11263c95d74eDavid Li{ 861591693c7b415e9869157c711fe11263c95d74eDavid Li unsigned int i; 871591693c7b415e9869157c711fe11263c95d74eDavid Li 881591693c7b415e9869157c711fe11263c95d74eDavid Li for (i = 0; i < ir->get_num_operands(); i++) { 891591693c7b415e9869157c711fe11263c95d74eDavid Li ir->operands[i] = convert_vec_index_to_swizzle(ir->operands[i]); 901591693c7b415e9869157c711fe11263c95d74eDavid Li } 911591693c7b415e9869157c711fe11263c95d74eDavid Li 921591693c7b415e9869157c711fe11263c95d74eDavid Li return visit_continue; 931591693c7b415e9869157c711fe11263c95d74eDavid Li} 941591693c7b415e9869157c711fe11263c95d74eDavid Li 951591693c7b415e9869157c711fe11263c95d74eDavid Liir_visitor_status 961591693c7b415e9869157c711fe11263c95d74eDavid Liir_vec_index_to_swizzle_visitor::visit_enter(ir_swizzle *ir) 971591693c7b415e9869157c711fe11263c95d74eDavid Li{ 981591693c7b415e9869157c711fe11263c95d74eDavid Li /* Can't be hit from normal GLSL, since you can't swizzle a scalar (which 991591693c7b415e9869157c711fe11263c95d74eDavid Li * the result of indexing a vector is. But maybe at some point we'll end up 1001591693c7b415e9869157c711fe11263c95d74eDavid Li * using swizzling of scalars for vector construction. 1011591693c7b415e9869157c711fe11263c95d74eDavid Li */ 1021591693c7b415e9869157c711fe11263c95d74eDavid Li ir->val = convert_vec_index_to_swizzle(ir->val); 1031591693c7b415e9869157c711fe11263c95d74eDavid Li 1041591693c7b415e9869157c711fe11263c95d74eDavid Li return visit_continue; 1051591693c7b415e9869157c711fe11263c95d74eDavid Li} 1061591693c7b415e9869157c711fe11263c95d74eDavid Li 1071591693c7b415e9869157c711fe11263c95d74eDavid Liir_visitor_status 1081591693c7b415e9869157c711fe11263c95d74eDavid Liir_vec_index_to_swizzle_visitor::visit_enter(ir_assignment *ir) 1091591693c7b415e9869157c711fe11263c95d74eDavid Li{ 1101591693c7b415e9869157c711fe11263c95d74eDavid Li ir->set_lhs(convert_vec_index_to_swizzle(ir->lhs)); 1111591693c7b415e9869157c711fe11263c95d74eDavid Li ir->rhs = convert_vec_index_to_swizzle(ir->rhs); 1121591693c7b415e9869157c711fe11263c95d74eDavid Li 1131591693c7b415e9869157c711fe11263c95d74eDavid Li return visit_continue; 1141591693c7b415e9869157c711fe11263c95d74eDavid Li} 1151591693c7b415e9869157c711fe11263c95d74eDavid Li 1161591693c7b415e9869157c711fe11263c95d74eDavid Liir_visitor_status 1171591693c7b415e9869157c711fe11263c95d74eDavid Liir_vec_index_to_swizzle_visitor::visit_enter(ir_call *ir) 1181591693c7b415e9869157c711fe11263c95d74eDavid Li{ 1191591693c7b415e9869157c711fe11263c95d74eDavid Li foreach_iter(exec_list_iterator, iter, *ir) { 1201591693c7b415e9869157c711fe11263c95d74eDavid Li ir_rvalue *param = (ir_rvalue *)iter.get(); 1211591693c7b415e9869157c711fe11263c95d74eDavid Li ir_rvalue *new_param = convert_vec_index_to_swizzle(param); 1221591693c7b415e9869157c711fe11263c95d74eDavid Li 1231591693c7b415e9869157c711fe11263c95d74eDavid Li if (new_param != param) { 1241591693c7b415e9869157c711fe11263c95d74eDavid Li param->replace_with(new_param); 1251591693c7b415e9869157c711fe11263c95d74eDavid Li } 1261591693c7b415e9869157c711fe11263c95d74eDavid Li } 1271591693c7b415e9869157c711fe11263c95d74eDavid Li 1281591693c7b415e9869157c711fe11263c95d74eDavid Li return visit_continue; 1291591693c7b415e9869157c711fe11263c95d74eDavid Li} 1301591693c7b415e9869157c711fe11263c95d74eDavid Li 1311591693c7b415e9869157c711fe11263c95d74eDavid Liir_visitor_status 1321591693c7b415e9869157c711fe11263c95d74eDavid Liir_vec_index_to_swizzle_visitor::visit_enter(ir_return *ir) 1331591693c7b415e9869157c711fe11263c95d74eDavid Li{ 1341591693c7b415e9869157c711fe11263c95d74eDavid Li if (ir->value) { 1351591693c7b415e9869157c711fe11263c95d74eDavid Li ir->value = convert_vec_index_to_swizzle(ir->value); 1361591693c7b415e9869157c711fe11263c95d74eDavid Li } 1371591693c7b415e9869157c711fe11263c95d74eDavid Li 1381591693c7b415e9869157c711fe11263c95d74eDavid Li return visit_continue; 1391591693c7b415e9869157c711fe11263c95d74eDavid Li} 1401591693c7b415e9869157c711fe11263c95d74eDavid Li 1411591693c7b415e9869157c711fe11263c95d74eDavid Liir_visitor_status 1421591693c7b415e9869157c711fe11263c95d74eDavid Liir_vec_index_to_swizzle_visitor::visit_enter(ir_if *ir) 1431591693c7b415e9869157c711fe11263c95d74eDavid Li{ 1441591693c7b415e9869157c711fe11263c95d74eDavid Li ir->condition = convert_vec_index_to_swizzle(ir->condition); 1451591693c7b415e9869157c711fe11263c95d74eDavid Li 1461591693c7b415e9869157c711fe11263c95d74eDavid Li return visit_continue; 1471591693c7b415e9869157c711fe11263c95d74eDavid Li} 1481591693c7b415e9869157c711fe11263c95d74eDavid Li 1491591693c7b415e9869157c711fe11263c95d74eDavid Libool 1501591693c7b415e9869157c711fe11263c95d74eDavid Lido_vec_index_to_swizzle(exec_list *instructions) 1511591693c7b415e9869157c711fe11263c95d74eDavid Li{ 1521591693c7b415e9869157c711fe11263c95d74eDavid Li ir_vec_index_to_swizzle_visitor v; 1531591693c7b415e9869157c711fe11263c95d74eDavid Li 1541591693c7b415e9869157c711fe11263c95d74eDavid Li v.run(instructions); 1551591693c7b415e9869157c711fe11263c95d74eDavid Li 1561591693c7b415e9869157c711fe11263c95d74eDavid Li return v.progress; 1571591693c7b415e9869157c711fe11263c95d74eDavid Li} 158