We are already calling constant folding functions in our constant propagation pass. So there is no point in also running a separate constant folding pass. Port over the remaining functionality from constant folding, and delete the pass. --- src/compiler/Makefile.sources | 1 - src/compiler/glsl/glsl_parser_extras.cpp | 1 - src/compiler/glsl/ir_optimization.h | 2 - src/compiler/glsl/opt_constant_folding.cpp | 211 ------------------------- src/compiler/glsl/opt_constant_propagation.cpp | 97 ++++++++++++ 5 files changed, 97 insertions(+), 215 deletions(-) delete mode 100644 src/compiler/glsl/opt_constant_folding.cpp
diff --git a/src/compiler/Makefile.sources b/src/compiler/Makefile.sources index 817ab3a755..c0be25bb66 100644 --- a/src/compiler/Makefile.sources +++ b/src/compiler/Makefile.sources @@ -114,7 +114,6 @@ LIBGLSL_FILES = \ glsl/lower_ubo_reference.cpp \ glsl/opt_algebraic.cpp \ glsl/opt_array_splitting.cpp \ - glsl/opt_constant_folding.cpp \ glsl/opt_constant_propagation.cpp \ glsl/opt_constant_variable.cpp \ glsl/opt_copy_propagation.cpp \ diff --git a/src/compiler/glsl/glsl_parser_extras.cpp b/src/compiler/glsl/glsl_parser_extras.cpp index fe25c23ccc..5c47f0bd25 100644 --- a/src/compiler/glsl/glsl_parser_extras.cpp +++ b/src/compiler/glsl/glsl_parser_extras.cpp @@ -2160,7 +2160,6 @@ do_common_optimization(exec_list *ir, bool linked, OPT(do_constant_variable, ir); else OPT(do_constant_variable_unlinked, ir); - OPT(do_constant_folding, ir); OPT(do_minmax_prune, ir); OPT(do_rebalance_tree, ir); OPT(do_algebraic, ir, native_integers, options); diff --git a/src/compiler/glsl/ir_optimization.h b/src/compiler/glsl/ir_optimization.h index 022b7ab12f..165a2c68ca 100644 --- a/src/compiler/glsl/ir_optimization.h +++ b/src/compiler/glsl/ir_optimization.h @@ -88,8 +88,6 @@ bool do_common_optimization(exec_list *ir, bool linked, const struct gl_shader_compiler_options *options, bool native_integers); -bool ir_constant_fold(ir_rvalue **rvalue); - bool do_rebalance_tree(exec_list *instructions); bool do_algebraic(exec_list *instructions, bool native_integers, const struct gl_shader_compiler_options *options); diff --git a/src/compiler/glsl/opt_constant_folding.cpp b/src/compiler/glsl/opt_constant_folding.cpp deleted file mode 100644 index 97dcc7e1ac..0000000000 --- a/src/compiler/glsl/opt_constant_folding.cpp +++ /dev/null @@ -1,211 +0,0 @@ -/* - * 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 opt_constant_folding.cpp - * Replace constant-valued expressions with references to constant values. - */ - -#include "ir.h" -#include "ir_visitor.h" -#include "ir_rvalue_visitor.h" -#include "ir_optimization.h" -#include "compiler/glsl_types.h" - -namespace { - -/** - * Visitor class for replacing expressions with ir_constant values. - */ - -class ir_constant_folding_visitor : public ir_rvalue_visitor { -public: - ir_constant_folding_visitor() - { - this->progress = false; - } - - virtual ~ir_constant_folding_visitor() - { - /* empty */ - } - - virtual ir_visitor_status visit_enter(ir_discard *ir); - virtual ir_visitor_status visit_enter(ir_assignment *ir); - virtual ir_visitor_status visit_enter(ir_call *ir); - - virtual void handle_rvalue(ir_rvalue **rvalue); - - bool progress; -}; - -} /* unnamed namespace */ - -bool -ir_constant_fold(ir_rvalue **rvalue) -{ - if (*rvalue == NULL || (*rvalue)->ir_type == ir_type_constant) - return false; - - /* Note that we do rvalue visitoring on leaving. So if an - * expression has a non-constant operand, no need to go looking - * down it to find if it's constant. This cuts the time of this - * pass down drastically. - */ - ir_expression *expr = (*rvalue)->as_expression(); - if (expr) { - for (unsigned int i = 0; i < expr->get_num_operands(); i++) { - if (!expr->operands[i]->as_constant()) - return false; - } - } - - /* Ditto for swizzles. */ - ir_swizzle *swiz = (*rvalue)->as_swizzle(); - if (swiz && !swiz->val->as_constant()) - return false; - - /* Ditto for array dereferences */ - ir_dereference_array *array_ref = (*rvalue)->as_dereference_array(); - if (array_ref && (!array_ref->array->as_constant() || - !array_ref->array_index->as_constant())) - return false; - - /* No constant folding can be performed on variable dereferences. We need - * to explicitly avoid them, as calling constant_expression_value() on a - * variable dereference will return a clone of var->constant_value. This - * would make us propagate the value into the tree, which isn't our job. - */ - ir_dereference_variable *var_ref = (*rvalue)->as_dereference_variable(); - if (var_ref) - return false; - - ir_constant *constant = (*rvalue)->constant_expression_value(); - if (constant) { - *rvalue = constant; - return true; - } - return false; -} - -void -ir_constant_folding_visitor::handle_rvalue(ir_rvalue **rvalue) -{ - if (ir_constant_fold(rvalue)) - this->progress = true; -} - -ir_visitor_status -ir_constant_folding_visitor::visit_enter(ir_discard *ir) -{ - if (ir->condition) { - ir->condition->accept(this); - handle_rvalue(&ir->condition); - - ir_constant *const_val = ir->condition->as_constant(); - /* If the condition is constant, either remove the condition or - * remove the never-executed assignment. - */ - if (const_val) { - if (const_val->value.b[0]) - ir->condition = NULL; - else - ir->remove(); - this->progress = true; - } - } - - return visit_continue_with_parent; -} - -ir_visitor_status -ir_constant_folding_visitor::visit_enter(ir_assignment *ir) -{ - ir->rhs->accept(this); - handle_rvalue(&ir->rhs); - - if (ir->condition) { - ir->condition->accept(this); - handle_rvalue(&ir->condition); - - ir_constant *const_val = ir->condition->as_constant(); - /* If the condition is constant, either remove the condition or - * remove the never-executed assignment. - */ - if (const_val) { - if (const_val->value.b[0]) - ir->condition = NULL; - else - ir->remove(); - this->progress = true; - } - } - - /* Don't descend into the LHS because we want it to stay as a - * variable dereference. FINISHME: We probably should to get array - * indices though. - */ - return visit_continue_with_parent; -} - -ir_visitor_status -ir_constant_folding_visitor::visit_enter(ir_call *ir) -{ - /* Attempt to constant fold parameters */ - foreach_two_lists(formal_node, &ir->callee->parameters, - actual_node, &ir->actual_parameters) { - ir_rvalue *param_rval = (ir_rvalue *) actual_node; - ir_variable *sig_param = (ir_variable *) formal_node; - - if (sig_param->data.mode == ir_var_function_in - || sig_param->data.mode == ir_var_const_in) { - ir_rvalue *new_param = param_rval; - - handle_rvalue(&new_param); - if (new_param != param_rval) { - param_rval->replace_with(new_param); - } - } - } - - /* Next, see if the call can be replaced with an assignment of a constant */ - ir_constant *const_val = ir->constant_expression_value(); - - if (const_val != NULL) { - ir_assignment *assignment = - new(ralloc_parent(ir)) ir_assignment(ir->return_deref, const_val); - ir->replace_with(assignment); - } - - return visit_continue_with_parent; -} - -bool -do_constant_folding(exec_list *instructions) -{ - ir_constant_folding_visitor constant_folding; - - visit_list_elements(&constant_folding, instructions); - - return constant_folding.progress; -} diff --git a/src/compiler/glsl/opt_constant_propagation.cpp b/src/compiler/glsl/opt_constant_propagation.cpp index 4039512097..055587f7e1 100644 --- a/src/compiler/glsl/opt_constant_propagation.cpp +++ b/src/compiler/glsl/opt_constant_propagation.cpp @@ -115,6 +115,7 @@ public: virtual ir_visitor_status visit_enter(class ir_function_signature *); virtual ir_visitor_status visit_enter(class ir_function *); virtual ir_visitor_status visit_leave(class ir_assignment *); + virtual ir_visitor_status visit_enter(ir_discard *ir); virtual ir_visitor_status visit_enter(class ir_call *); virtual ir_visitor_status visit_enter(class ir_if *); @@ -142,6 +143,52 @@ public: void *lin_ctx; }; +bool +ir_constant_fold(ir_rvalue **rvalue) +{ + if (*rvalue == NULL || (*rvalue)->ir_type == ir_type_constant) + return false; + + /* Note that we do rvalue visitoring on leaving. So if an + * expression has a non-constant operand, no need to go looking + * down it to find if it's constant. This cuts the time of this + * pass down drastically. + */ + ir_expression *expr = (*rvalue)->as_expression(); + if (expr) { + for (unsigned int i = 0; i < expr->get_num_operands(); i++) { + if (!expr->operands[i]->as_constant()) + return false; + } + } + + /* Ditto for swizzles. */ + ir_swizzle *swiz = (*rvalue)->as_swizzle(); + if (swiz && !swiz->val->as_constant()) + return false; + + /* Ditto for array dereferences */ + ir_dereference_array *array_ref = (*rvalue)->as_dereference_array(); + if (array_ref && (!array_ref->array->as_constant() || + !array_ref->array_index->as_constant())) + return false; + + /* No constant folding can be performed on variable dereferences. We need + * to explicitly avoid them, as calling constant_expression_value() on a + * variable dereference will return a clone of var->constant_value. This + * would make us propagate the value into the tree, which isn't our job. + */ + ir_dereference_variable *var_ref = (*rvalue)->as_dereference_variable(); + if (var_ref) + return false; + + ir_constant *constant = (*rvalue)->constant_expression_value(); + if (constant) { + *rvalue = constant; + return true; + } + return false; +} void ir_constant_propagation_visitor::constant_folding(ir_rvalue **rvalue) @@ -284,6 +331,24 @@ ir_constant_propagation_visitor::visit_leave(ir_assignment *ir) { constant_folding(&ir->rhs); + if (ir->condition) { + ir->condition->accept(this); + constant_folding(&ir->condition); + + ir_constant *const_val = ir->condition->as_constant(); + /* If the condition is constant, either remove the condition or + * remove the never-executed assignment. + */ + if (const_val) { + if (const_val->value.b[0]) + ir->condition = NULL; + else + ir->remove(); + this->progress = true; + return visit_continue; + } + } + if (this->in_assignee) return visit_continue; @@ -339,6 +404,15 @@ ir_constant_propagation_visitor::visit_enter(ir_call *ir) } } + /* Next, see if the call can be replaced with an assignment of a constant */ + ir_constant *const_val = ir->constant_expression_value(); + + if (const_val != NULL) { + ir_assignment *assignment = + new(ralloc_parent(ir)) ir_assignment(ir->return_deref, const_val); + ir->replace_with(assignment); + } + /* Since we're unlinked, we don't (necssarily) know the side effects of * this call. So kill all copies. */ @@ -465,6 +539,29 @@ ir_constant_propagation_visitor::kill(ir_variable *var, unsigned write_mask) new(this->lin_ctx) kill_entry(var, write_mask)); } +ir_visitor_status +ir_constant_propagation_visitor::visit_enter(ir_discard *ir) +{ + if (ir->condition) { + ir->condition->accept(this); + handle_rvalue(&ir->condition); + + ir_constant *const_val = ir->condition->as_constant(); + /* If the condition is constant, either remove the condition or + * remove the never-executed assignment. + */ + if (const_val) { + if (const_val->value.b[0]) + ir->condition = NULL; + else + ir->remove(); + this->progress = true; + } + } + + return visit_continue_with_parent; +} + /** * Adds an entry to the available constant list if it's a plain assignment * of a variable to a variable. -- 2.11.1 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev