lower_vec_index_to_swizzle.cpp revision b145e903694fa932ab1e0d955e889555193ab604
1/* 2 * Copyright © 2010 Intel Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 * DEALINGS IN THE SOFTWARE. 22 */ 23 24/** 25 * \file ir_vec_index_to_swizzle.cpp 26 * 27 * Turns constant indexing into vector types to swizzles. This will 28 * let other swizzle-aware optimization passes catch these constructs, 29 * and codegen backends not have to worry about this case. 30 */ 31 32#include <stdio.h> 33#include "ir.h" 34#include "ir_visitor.h" 35#include "ir_optimization.h" 36#include "ir_print_visitor.h" 37#include "glsl_types.h" 38 39/** 40 * Visitor class for replacing expressions with ir_constant values. 41 */ 42 43class ir_vec_index_to_swizzle_visitor : public ir_hierarchical_visitor { 44public: 45 ir_vec_index_to_swizzle_visitor() 46 { 47 progress = false; 48 } 49 50 ir_rvalue *convert_vec_index_to_swizzle(ir_rvalue *val); 51 52 virtual ir_visitor_status visit_enter(ir_expression *); 53 virtual ir_visitor_status visit_enter(ir_swizzle *); 54 virtual ir_visitor_status visit_enter(ir_assignment *); 55 virtual ir_visitor_status visit_enter(ir_return *); 56 virtual ir_visitor_status visit_enter(ir_call *); 57 virtual ir_visitor_status visit_enter(ir_if *); 58 59 bool progress; 60}; 61 62ir_rvalue * 63ir_vec_index_to_swizzle_visitor::convert_vec_index_to_swizzle(ir_rvalue *ir) 64{ 65 ir_dereference_array *deref = ir->as_dereference_array(); 66 ir_constant *ir_constant; 67 ir_rvalue *deref_var; 68 69 if (!deref) 70 return ir; 71 72 if (deref->array->type->is_matrix() || deref->array->type->is_array()) 73 return ir; 74 75 deref_var = deref->array->as_rvalue(); 76 if (!deref_var) { 77 ir_variable *var = deref->array->as_variable(); 78 assert(var); 79 deref_var = new ir_dereference_variable(var); 80 } 81 82 assert(deref->array_index->type->base_type == GLSL_TYPE_INT); 83 ir_constant = deref->array_index->constant_expression_value(); 84 if (!ir_constant) 85 return ir; 86 87 this->progress = true; 88 return new ir_swizzle(deref_var, ir_constant->value.i[0], 0, 0, 0, 1); 89} 90 91ir_visitor_status 92ir_vec_index_to_swizzle_visitor::visit_enter(ir_expression *ir) 93{ 94 unsigned int i; 95 96 for (i = 0; i < ir->get_num_operands(); i++) { 97 ir->operands[i] = convert_vec_index_to_swizzle(ir->operands[i]); 98 } 99 100 return visit_continue; 101} 102 103ir_visitor_status 104ir_vec_index_to_swizzle_visitor::visit_enter(ir_swizzle *ir) 105{ 106 /* Can't be hit from normal GLSL, since you can't swizzle a scalar (which 107 * the result of indexing a vector is. But maybe at some point we'll end up 108 * using swizzling of scalars for vector construction. 109 */ 110 ir->val = convert_vec_index_to_swizzle(ir->val); 111 112 return visit_continue; 113} 114 115ir_visitor_status 116ir_vec_index_to_swizzle_visitor::visit_enter(ir_assignment *ir) 117{ 118 ir->lhs = convert_vec_index_to_swizzle(ir->lhs); 119 ir->rhs = convert_vec_index_to_swizzle(ir->rhs); 120 121 return visit_continue; 122} 123 124ir_visitor_status 125ir_vec_index_to_swizzle_visitor::visit_enter(ir_call *ir) 126{ 127 foreach_iter(exec_list_iterator, iter, *ir) { 128 ir_rvalue *param = (ir_rvalue *)iter.get(); 129 ir_rvalue *new_param = convert_vec_index_to_swizzle(param); 130 131 if (new_param != param) { 132 param->insert_before(new_param); 133 param->remove(); 134 } 135 } 136 137 return visit_continue; 138} 139 140ir_visitor_status 141ir_vec_index_to_swizzle_visitor::visit_enter(ir_return *ir) 142{ 143 if (ir->value) { 144 ir->value = convert_vec_index_to_swizzle(ir->value); 145 } 146 147 return visit_continue; 148} 149 150ir_visitor_status 151ir_vec_index_to_swizzle_visitor::visit_enter(ir_if *ir) 152{ 153 ir->condition = convert_vec_index_to_swizzle(ir->condition); 154 155 return visit_continue; 156} 157 158bool 159do_vec_index_to_swizzle(exec_list *instructions) 160{ 161 ir_vec_index_to_swizzle_visitor v; 162 163 v.run(instructions); 164 165 return false; 166} 167