From 32aaf89823de11e98cb59d5ec78c66cd3e74bcd4 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Mon, 15 Nov 2010 14:35:46 -0800 Subject: glsl: Rename various ir_* files to lower_* and opt_*. This helps distinguish between lowering passes, optimization passes, and other compiler code. --- src/glsl/lower_vec_index_to_cond_assign.cpp | 258 ++++++++++++++++++++++++++++ 1 file changed, 258 insertions(+) create mode 100644 src/glsl/lower_vec_index_to_cond_assign.cpp (limited to 'src/glsl/lower_vec_index_to_cond_assign.cpp') diff --git a/src/glsl/lower_vec_index_to_cond_assign.cpp b/src/glsl/lower_vec_index_to_cond_assign.cpp new file mode 100644 index 0000000000..cd8dedf2fe --- /dev/null +++ b/src/glsl/lower_vec_index_to_cond_assign.cpp @@ -0,0 +1,258 @@ +/* + * Copyright © 2010 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * \file ir_vec_index_to_cond_assign.cpp + * + * Turns indexing into vector types to a series of conditional moves + * of each channel's swizzle into a temporary. + * + * Most GPUs don't have a native way to do this operation, and this + * works around that. For drivers using both this pass and + * ir_vec_index_to_swizzle, there's a risk that this pass will happen + * before sufficient constant folding to find that the array index is + * constant. However, we hope that other optimization passes, + * particularly constant folding of assignment conditions and copy + * propagation, will result in the same code in the end. + */ + +#include "ir.h" +#include "ir_visitor.h" +#include "ir_optimization.h" +#include "glsl_types.h" + +/** + * Visitor class for replacing expressions with ir_constant values. + */ + +class ir_vec_index_to_cond_assign_visitor : public ir_hierarchical_visitor { +public: + ir_vec_index_to_cond_assign_visitor() + { + progress = false; + } + + ir_rvalue *convert_vec_index_to_cond_assign(ir_rvalue *val); + + virtual ir_visitor_status visit_enter(ir_expression *); + virtual ir_visitor_status visit_enter(ir_swizzle *); + virtual ir_visitor_status visit_leave(ir_assignment *); + virtual ir_visitor_status visit_enter(ir_return *); + virtual ir_visitor_status visit_enter(ir_call *); + virtual ir_visitor_status visit_enter(ir_if *); + + bool progress; +}; + +ir_rvalue * +ir_vec_index_to_cond_assign_visitor::convert_vec_index_to_cond_assign(ir_rvalue *ir) +{ + ir_dereference_array *orig_deref = ir->as_dereference_array(); + ir_assignment *assign; + ir_variable *index, *var; + ir_dereference *deref; + ir_expression *condition; + ir_swizzle *swizzle; + int i; + + if (!orig_deref) + return ir; + + if (orig_deref->array->type->is_matrix() || + orig_deref->array->type->is_array()) + return ir; + + void *mem_ctx = talloc_parent(ir); + + assert(orig_deref->array_index->type->base_type == GLSL_TYPE_INT); + + /* Store the index to a temporary to avoid reusing its tree. */ + index = new(base_ir) ir_variable(glsl_type::int_type, + "vec_index_tmp_i", + ir_var_temporary); + base_ir->insert_before(index); + deref = new(base_ir) ir_dereference_variable(index); + assign = new(base_ir) ir_assignment(deref, orig_deref->array_index, NULL); + base_ir->insert_before(assign); + + /* Temporary where we store whichever value we swizzle out. */ + var = new(base_ir) ir_variable(ir->type, "vec_index_tmp_v", + ir_var_temporary); + base_ir->insert_before(var); + + /* Generate a conditional move of each vector element to the temp. */ + for (i = 0; i < orig_deref->array->type->vector_elements; i++) { + deref = new(base_ir) ir_dereference_variable(index); + condition = new(base_ir) ir_expression(ir_binop_equal, + glsl_type::bool_type, + deref, + new(base_ir) ir_constant(i)); + + /* Just clone the rest of the deref chain when trying to get at the + * underlying variable. + */ + swizzle = new(base_ir) ir_swizzle(orig_deref->array->clone(mem_ctx, NULL), + i, 0, 0, 0, 1); + + deref = new(base_ir) ir_dereference_variable(var); + assign = new(base_ir) ir_assignment(deref, swizzle, condition); + base_ir->insert_before(assign); + } + + this->progress = true; + return new(base_ir) ir_dereference_variable(var); +} + +ir_visitor_status +ir_vec_index_to_cond_assign_visitor::visit_enter(ir_expression *ir) +{ + unsigned int i; + + for (i = 0; i < ir->get_num_operands(); i++) { + ir->operands[i] = convert_vec_index_to_cond_assign(ir->operands[i]); + } + + return visit_continue; +} + +ir_visitor_status +ir_vec_index_to_cond_assign_visitor::visit_enter(ir_swizzle *ir) +{ + /* Can't be hit from normal GLSL, since you can't swizzle a scalar (which + * the result of indexing a vector is. But maybe at some point we'll end up + * using swizzling of scalars for vector construction. + */ + ir->val = convert_vec_index_to_cond_assign(ir->val); + + return visit_continue; +} + +ir_visitor_status +ir_vec_index_to_cond_assign_visitor::visit_leave(ir_assignment *ir) +{ + ir_variable *index, *var; + ir_dereference_variable *deref; + ir_assignment *assign; + int i; + + ir->rhs = convert_vec_index_to_cond_assign(ir->rhs); + if (ir->condition) + ir->condition = convert_vec_index_to_cond_assign(ir->condition); + + /* Last, handle the LHS */ + ir_dereference_array *orig_deref = ir->lhs->as_dereference_array(); + + if (!orig_deref || + orig_deref->array->type->is_matrix() || + orig_deref->array->type->is_array()) + return visit_continue; + + void *mem_ctx = talloc_parent(ir); + + assert(orig_deref->array_index->type->base_type == GLSL_TYPE_INT); + + /* Store the index to a temporary to avoid reusing its tree. */ + index = new(ir) ir_variable(glsl_type::int_type, "vec_index_tmp_i", + ir_var_temporary); + ir->insert_before(index); + deref = new(ir) ir_dereference_variable(index); + assign = new(ir) ir_assignment(deref, orig_deref->array_index, NULL); + ir->insert_before(assign); + + /* Store the RHS to a temporary to avoid reusing its tree. */ + var = new(ir) ir_variable(ir->rhs->type, "vec_index_tmp_v", + ir_var_temporary); + ir->insert_before(var); + deref = new(ir) ir_dereference_variable(var); + assign = new(ir) ir_assignment(deref, ir->rhs, NULL); + ir->insert_before(assign); + + /* Generate a conditional move of each vector element to the temp. */ + for (i = 0; i < orig_deref->array->type->vector_elements; i++) { + ir_rvalue *condition, *swizzle; + + deref = new(ir) ir_dereference_variable(index); + condition = new(ir) ir_expression(ir_binop_equal, + glsl_type::bool_type, + deref, + new(ir) ir_constant(i)); + + /* Just clone the rest of the deref chain when trying to get at the + * underlying variable. + */ + swizzle = new(ir) ir_swizzle(orig_deref->array->clone(mem_ctx, NULL), + i, 0, 0, 0, 1); + + deref = new(ir) ir_dereference_variable(var); + assign = new(ir) ir_assignment(swizzle, deref, condition); + ir->insert_before(assign); + } + ir->remove(); + + this->progress = true; + + return visit_continue; +} + +ir_visitor_status +ir_vec_index_to_cond_assign_visitor::visit_enter(ir_call *ir) +{ + foreach_iter(exec_list_iterator, iter, *ir) { + ir_rvalue *param = (ir_rvalue *)iter.get(); + ir_rvalue *new_param = convert_vec_index_to_cond_assign(param); + + if (new_param != param) { + param->replace_with(new_param); + } + } + + return visit_continue; +} + +ir_visitor_status +ir_vec_index_to_cond_assign_visitor::visit_enter(ir_return *ir) +{ + if (ir->value) { + ir->value = convert_vec_index_to_cond_assign(ir->value); + } + + return visit_continue; +} + +ir_visitor_status +ir_vec_index_to_cond_assign_visitor::visit_enter(ir_if *ir) +{ + ir->condition = convert_vec_index_to_cond_assign(ir->condition); + + return visit_continue; +} + +bool +do_vec_index_to_cond_assign(exec_list *instructions) +{ + ir_vec_index_to_cond_assign_visitor v; + + visit_list_elements(&v, instructions); + + return v.progress; +} -- cgit v1.2.3 From df883eb1575a740bf91e01cbe2eaa4dbc1f9f154 Mon Sep 17 00:00:00 2001 From: Chad Versace Date: Wed, 17 Nov 2010 10:43:10 -0800 Subject: glsl: Fix Doxygen tag \file in recently renamed files --- src/glsl/lower_div_to_mul_rcp.cpp | 2 +- src/glsl/lower_explog_to_explog2.cpp | 2 +- src/glsl/lower_if_to_cond_assign.cpp | 2 +- src/glsl/lower_jumps.cpp | 2 +- src/glsl/lower_mat_op_to_vec.cpp | 2 +- src/glsl/lower_mod_to_fract.cpp | 2 +- src/glsl/lower_sub_to_add_neg.cpp | 2 +- src/glsl/lower_vec_index_to_cond_assign.cpp | 2 +- src/glsl/lower_vec_index_to_swizzle.cpp | 2 +- src/glsl/opt_algebraic.cpp | 2 +- src/glsl/opt_constant_folding.cpp | 2 +- src/glsl/opt_constant_propagation.cpp | 2 +- src/glsl/opt_constant_variable.cpp | 2 +- src/glsl/opt_copy_propagation.cpp | 2 +- src/glsl/opt_dead_code.cpp | 2 +- src/glsl/opt_dead_code_local.cpp | 2 +- src/glsl/opt_dead_functions.cpp | 2 +- src/glsl/opt_function_inlining.cpp | 2 +- src/glsl/opt_if_simplification.cpp | 2 +- src/glsl/opt_noop_swizzle.cpp | 2 +- src/glsl/opt_structure_splitting.cpp | 2 +- src/glsl/opt_swizzle_swizzle.cpp | 2 +- src/glsl/opt_tree_grafting.cpp | 2 +- 23 files changed, 23 insertions(+), 23 deletions(-) (limited to 'src/glsl/lower_vec_index_to_cond_assign.cpp') diff --git a/src/glsl/lower_div_to_mul_rcp.cpp b/src/glsl/lower_div_to_mul_rcp.cpp index 640d5d64f9..d34c4bc46d 100644 --- a/src/glsl/lower_div_to_mul_rcp.cpp +++ b/src/glsl/lower_div_to_mul_rcp.cpp @@ -22,7 +22,7 @@ */ /** - * \file ir_div_to_mul_rcp.cpp + * \file lower_div_to_mul_rcp.cpp * * Breaks an ir_unop_div expression down to op0 * (rcp(op1)). * diff --git a/src/glsl/lower_explog_to_explog2.cpp b/src/glsl/lower_explog_to_explog2.cpp index 78694a2029..8ad0262544 100644 --- a/src/glsl/lower_explog_to_explog2.cpp +++ b/src/glsl/lower_explog_to_explog2.cpp @@ -22,7 +22,7 @@ */ /** - * \file ir_explog_to_explog2.cpp + * \file lower_explog_to_explog2.cpp * * Many GPUs don't have a base e log or exponent instruction, but they * do have base 2 versions, so this pass converts exp and log to exp2 diff --git a/src/glsl/lower_if_to_cond_assign.cpp b/src/glsl/lower_if_to_cond_assign.cpp index 0b87413941..cf48cfb8d6 100644 --- a/src/glsl/lower_if_to_cond_assign.cpp +++ b/src/glsl/lower_if_to_cond_assign.cpp @@ -22,7 +22,7 @@ */ /** - * \file ir_if_to_cond_assign.cpp + * \file lower_if_to_cond_assign.cpp * * This attempts to flatten all if statements to conditional * assignments for GPUs that don't do control flow. diff --git a/src/glsl/lower_jumps.cpp b/src/glsl/lower_jumps.cpp index b69cc1ec31..e1e7a5b007 100644 --- a/src/glsl/lower_jumps.cpp +++ b/src/glsl/lower_jumps.cpp @@ -22,7 +22,7 @@ */ /** - * \file ir_lower_jumps.cpp + * \file lower_jumps.cpp */ #include "glsl_types.h" diff --git a/src/glsl/lower_mat_op_to_vec.cpp b/src/glsl/lower_mat_op_to_vec.cpp index 244fe48928..4965df8976 100644 --- a/src/glsl/lower_mat_op_to_vec.cpp +++ b/src/glsl/lower_mat_op_to_vec.cpp @@ -22,7 +22,7 @@ */ /** - * \file ir_mat_op_to_vec.cpp + * \file lower_mat_op_to_vec.cpp * * Breaks matrix operation expressions down to a series of vector operations. * diff --git a/src/glsl/lower_mod_to_fract.cpp b/src/glsl/lower_mod_to_fract.cpp index c82a1f64fd..ff907ae97c 100644 --- a/src/glsl/lower_mod_to_fract.cpp +++ b/src/glsl/lower_mod_to_fract.cpp @@ -22,7 +22,7 @@ */ /** - * \file ir_mod_to_fract.cpp + * \file lower_mod_to_fract.cpp * * Breaks an ir_unop_mod expression down to (op1 * fract(op0 / op1)) * diff --git a/src/glsl/lower_sub_to_add_neg.cpp b/src/glsl/lower_sub_to_add_neg.cpp index 7ed8c1495e..9e4019709b 100644 --- a/src/glsl/lower_sub_to_add_neg.cpp +++ b/src/glsl/lower_sub_to_add_neg.cpp @@ -22,7 +22,7 @@ */ /** - * \file ir_sub_to_add_neg.cpp + * \file lower_sub_to_add_neg.cpp * * Breaks an ir_binop_sub expression down to add(op0, neg(op1)) * diff --git a/src/glsl/lower_vec_index_to_cond_assign.cpp b/src/glsl/lower_vec_index_to_cond_assign.cpp index cd8dedf2fe..f8011a16e5 100644 --- a/src/glsl/lower_vec_index_to_cond_assign.cpp +++ b/src/glsl/lower_vec_index_to_cond_assign.cpp @@ -22,7 +22,7 @@ */ /** - * \file ir_vec_index_to_cond_assign.cpp + * \file lower_vec_index_to_cond_assign.cpp * * Turns indexing into vector types to a series of conditional moves * of each channel's swizzle into a temporary. diff --git a/src/glsl/lower_vec_index_to_swizzle.cpp b/src/glsl/lower_vec_index_to_swizzle.cpp index 969dc8f94a..9ae43c0db1 100644 --- a/src/glsl/lower_vec_index_to_swizzle.cpp +++ b/src/glsl/lower_vec_index_to_swizzle.cpp @@ -22,7 +22,7 @@ */ /** - * \file ir_vec_index_to_swizzle.cpp + * \file lower_vec_index_to_swizzle.cpp * * Turns constant indexing into vector types to swizzles. This will * let other swizzle-aware optimization passes catch these constructs, diff --git a/src/glsl/opt_algebraic.cpp b/src/glsl/opt_algebraic.cpp index c7f5c3b4d6..88b6c485d3 100644 --- a/src/glsl/opt_algebraic.cpp +++ b/src/glsl/opt_algebraic.cpp @@ -22,7 +22,7 @@ */ /** - * \file ir_algebraic.cpp + * \file opt_algebraic.cpp * * Takes advantage of association, commutivity, and other algebraic * properties to simplify expressions. diff --git a/src/glsl/opt_constant_folding.cpp b/src/glsl/opt_constant_folding.cpp index 554c54fae3..d69ca75fe0 100644 --- a/src/glsl/opt_constant_folding.cpp +++ b/src/glsl/opt_constant_folding.cpp @@ -22,7 +22,7 @@ */ /** - * \file ir_constant_folding.cpp + * \file opt_constant_folding.cpp * Replace constant-valued expressions with references to constant values. */ diff --git a/src/glsl/opt_constant_propagation.cpp b/src/glsl/opt_constant_propagation.cpp index 5d875b7be0..6719fc8186 100644 --- a/src/glsl/opt_constant_propagation.cpp +++ b/src/glsl/opt_constant_propagation.cpp @@ -22,7 +22,7 @@ */ /** - * \file ir_constant_propagation.cpp + * \file opt_constant_propagation.cpp * * Tracks assignments of constants to channels of variables, and * usage of those constant channels with direct usage of the constants. diff --git a/src/glsl/opt_constant_variable.cpp b/src/glsl/opt_constant_variable.cpp index 1fb73e765e..8068d0c143 100644 --- a/src/glsl/opt_constant_variable.cpp +++ b/src/glsl/opt_constant_variable.cpp @@ -22,7 +22,7 @@ */ /** - * \file ir_constant_variable.cpp + * \file opt_constant_variable.cpp * * Marks variables assigned a single constant value over the course * of the program as constant. diff --git a/src/glsl/opt_copy_propagation.cpp b/src/glsl/opt_copy_propagation.cpp index 0fe8fa6c41..8d07fefbfd 100644 --- a/src/glsl/opt_copy_propagation.cpp +++ b/src/glsl/opt_copy_propagation.cpp @@ -22,7 +22,7 @@ */ /** - * \file ir_copy_propagation.cpp + * \file opt_copy_propagation.cpp * * Moves usage of recently-copied variables to the previous copy of * the variable. diff --git a/src/glsl/opt_dead_code.cpp b/src/glsl/opt_dead_code.cpp index 5cf5e99add..cb500d2d10 100644 --- a/src/glsl/opt_dead_code.cpp +++ b/src/glsl/opt_dead_code.cpp @@ -22,7 +22,7 @@ */ /** - * \file ir_dead_code.cpp + * \file opt_dead_code.cpp * * Eliminates dead assignments and variable declarations from the code. */ diff --git a/src/glsl/opt_dead_code_local.cpp b/src/glsl/opt_dead_code_local.cpp index 4bbedf0ff9..5689e7d20d 100644 --- a/src/glsl/opt_dead_code_local.cpp +++ b/src/glsl/opt_dead_code_local.cpp @@ -22,7 +22,7 @@ */ /** - * \file ir_dead_code_local.cpp + * \file opt_dead_code_local.cpp * * Eliminates local dead assignments from the code. * diff --git a/src/glsl/opt_dead_functions.cpp b/src/glsl/opt_dead_functions.cpp index 16037a2632..cf91cb6d36 100644 --- a/src/glsl/opt_dead_functions.cpp +++ b/src/glsl/opt_dead_functions.cpp @@ -22,7 +22,7 @@ */ /** - * \file ir_dead_functions.cpp + * \file opt_dead_functions.cpp * * Eliminates unused functions from the linked program. */ diff --git a/src/glsl/opt_function_inlining.cpp b/src/glsl/opt_function_inlining.cpp index 147c1824c1..169fd82688 100644 --- a/src/glsl/opt_function_inlining.cpp +++ b/src/glsl/opt_function_inlining.cpp @@ -22,7 +22,7 @@ */ /** - * \file ir_function_inlining.cpp + * \file opt_function_inlining.cpp * * Replaces calls to functions with the body of the function. */ diff --git a/src/glsl/opt_if_simplification.cpp b/src/glsl/opt_if_simplification.cpp index 021615ebd1..618bacfecf 100644 --- a/src/glsl/opt_if_simplification.cpp +++ b/src/glsl/opt_if_simplification.cpp @@ -22,7 +22,7 @@ */ /** - * \file ir_if_simplification.cpp + * \file opt_if_simplification.cpp * * Moves constant branches of if statements out to the surrounding * instruction stream. diff --git a/src/glsl/opt_noop_swizzle.cpp b/src/glsl/opt_noop_swizzle.cpp index 0403dfa4e9..0a906aaf1d 100644 --- a/src/glsl/opt_noop_swizzle.cpp +++ b/src/glsl/opt_noop_swizzle.cpp @@ -22,7 +22,7 @@ */ /** - * \file ir_noop_swizzle.cpp + * \file opt_noop_swizzle.cpp * * If a swizzle doesn't change the order or count of components, then * remove the swizzle so that other optimization passes see the value diff --git a/src/glsl/opt_structure_splitting.cpp b/src/glsl/opt_structure_splitting.cpp index ff3ec936eb..d6191002c2 100644 --- a/src/glsl/opt_structure_splitting.cpp +++ b/src/glsl/opt_structure_splitting.cpp @@ -22,7 +22,7 @@ */ /** - * \file ir_structure_splitting.cpp + * \file opt_structure_splitting.cpp * * If a structure is only ever referenced by its components, then * split those components out to individual variables so they can be diff --git a/src/glsl/opt_swizzle_swizzle.cpp b/src/glsl/opt_swizzle_swizzle.cpp index 0ffb4fa313..bc442fa869 100644 --- a/src/glsl/opt_swizzle_swizzle.cpp +++ b/src/glsl/opt_swizzle_swizzle.cpp @@ -22,7 +22,7 @@ */ /** - * \file ir_swizzle_swizzle.cpp + * \file opt_swizzle_swizzle.cpp * * Eliminates the second swizzle in a swizzle chain. */ diff --git a/src/glsl/opt_tree_grafting.cpp b/src/glsl/opt_tree_grafting.cpp index 9b569b8284..9917c045b1 100644 --- a/src/glsl/opt_tree_grafting.cpp +++ b/src/glsl/opt_tree_grafting.cpp @@ -22,7 +22,7 @@ */ /** - * \file ir_tree_grafting.cpp + * \file opt_tree_grafting.cpp * * Takes assignments to variables that are dereferenced only once and * pastes the RHS expression into where the variable is dereferenced. -- cgit v1.2.3