From 329ab85a89c9bc05211b7eae769269f11b598895 Mon Sep 17 00:00:00 2001 From: Emma Anholt Date: Thu, 2 Mar 2023 15:44:38 -0800 Subject: [PATCH] glsl: Delete constant folding pass. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit NIR is happy to take care of constant folding for us, and it's easier to do in SSA. This required adjusting of lower_precision unit tests to have un-folded constants. freedreno results look like noise. Some excerpts: total instructions in shared programs: 2718343 -> 2718412 (<.01%) instructions in affected programs: 6847 -> 6916 (1.01%) total last-baryf in shared programs: 109992 -> 110015 (0.02%) last-baryf in affected programs: 117 -> 140 (19.66%) total sstall in shared programs: 198312 -> 198297 (<.01%) sstall in affected programs: 148 -> 133 (-10.14%) total systall in shared programs: 432163 -> 432150 (<.01%) systall in affected programs: 1016 -> 1003 (-1.28%) Reviewed-by: Alyssa Rosenzweig Reviewed-by: Timothy Arceri Reviewed-by: Marek Olšák Part-of: --- src/compiler/glsl/glsl_parser_extras.cpp | 1 - src/compiler/glsl/ir_optimization.h | 3 - src/compiler/glsl/meson.build | 1 - src/compiler/glsl/opt_constant_folding.cpp | 195 ------------------------ src/compiler/glsl/test_optpass.cpp | 2 - src/compiler/glsl/tests/lower_precision_test.py | 54 +++---- 6 files changed, 27 insertions(+), 229 deletions(-) delete mode 100644 src/compiler/glsl/opt_constant_folding.cpp diff --git a/src/compiler/glsl/glsl_parser_extras.cpp b/src/compiler/glsl/glsl_parser_extras.cpp index eb8e8a4..b02fb33 100644 --- a/src/compiler/glsl/glsl_parser_extras.cpp +++ b/src/compiler/glsl/glsl_parser_extras.cpp @@ -2402,7 +2402,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 5645036..9be8ac3 100644 --- a/src/compiler/glsl/ir_optimization.h +++ b/src/compiler/glsl/ir_optimization.h @@ -41,12 +41,9 @@ 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); -bool do_constant_folding(exec_list *instructions); bool do_constant_variable(exec_list *instructions); bool do_constant_variable_unlinked(exec_list *instructions); bool do_dead_code(exec_list *instructions); diff --git a/src/compiler/glsl/meson.build b/src/compiler/glsl/meson.build index 5f6fd26..7956787 100644 --- a/src/compiler/glsl/meson.build +++ b/src/compiler/glsl/meson.build @@ -214,7 +214,6 @@ files_libglsl = files( 'lower_vec_index_to_cond_assign.cpp', 'lower_vector_derefs.cpp', 'opt_algebraic.cpp', - 'opt_constant_folding.cpp', 'opt_constant_variable.cpp', 'opt_dead_builtin_variables.cpp', 'opt_dead_code.cpp', diff --git a/src/compiler/glsl/opt_constant_folding.cpp b/src/compiler/glsl/opt_constant_folding.cpp deleted file mode 100644 index bcf88b5..0000000 --- a/src/compiler/glsl/opt_constant_folding.cpp +++ /dev/null @@ -1,195 +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->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(ralloc_parent(*rvalue)); - 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); - - /* 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(ralloc_parent(ir)); - - 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/test_optpass.cpp b/src/compiler/glsl/test_optpass.cpp index 7f8de6a..701dc5a 100644 --- a/src/compiler/glsl/test_optpass.cpp +++ b/src/compiler/glsl/test_optpass.cpp @@ -66,8 +66,6 @@ do_optimization(struct exec_list *ir, const char *optimization, return do_common_optimization(ir, int_0 != 0, options, true); } else if (strcmp(optimization, "do_algebraic") == 0) { return do_algebraic(ir, true, options); - } else if (strcmp(optimization, "do_constant_folding") == 0) { - return do_constant_folding(ir); } else if (strcmp(optimization, "do_constant_variable") == 0) { return do_constant_variable(ir); } else if (strcmp(optimization, "do_constant_variable_unlinked") == 0) { diff --git a/src/compiler/glsl/tests/lower_precision_test.py b/src/compiler/glsl/tests/lower_precision_test.py index 21fc572..b968ce3 100644 --- a/src/compiler/glsl/tests/lower_precision_test.py +++ b/src/compiler/glsl/tests/lower_precision_test.py @@ -1640,7 +1640,7 @@ TESTS = [ color = (var.x > var.y) ? var : vec4(10.0); } """, - r'\(constant +f16vec4 \(10'), + r'\(expression f16vec4 f2fmp \(constant vec4 \(10'), Test("i32 csel", """ #version 310 es @@ -1654,7 +1654,7 @@ TESTS = [ color = (var.x > var.y) ? var : ivec4(10); } """, - r'\(constant +i16vec4 \(10'), + r'\(expression i16vec4 i2imp \(constant ivec4 \(10'), Test("u32 csel", """ #version 310 es @@ -1668,7 +1668,7 @@ TESTS = [ color = (var.x > var.y) ? var : uvec4(10); } """, - r'\(constant +u16vec4 \(10'), + r'\(expression u16vec4 u2ump \(constant uvec4 \(10'), Test("f32 loop counter", """ #version 300 es @@ -1735,7 +1735,7 @@ TESTS = [ color = a[0] + a[1]; } """, - r'\(constant float16_t \(3'), + r'\(expression float16_t f2fmp \(constant float \(3'), Test("i32 temp array", """ #version 310 es @@ -1752,7 +1752,7 @@ TESTS = [ color = a[0] + a[1]; } """, - r'\(constant int16_t \(3'), + r'\(expression int16_t i2imp \(constant int \(3'), Test("u32 temp array", """ #version 310 es @@ -1769,7 +1769,7 @@ TESTS = [ color = a[0] + a[1]; } """, - r'\(constant uint16_t \(3'), + r'\(expression uint16_t u2ump \(constant uint \(3'), Test("f32 temp array of array", """ #version 310 es @@ -1786,7 +1786,7 @@ TESTS = [ color = a[0][0] + a[1][1]; } """, - r'\(constant float16_t \(3'), + r'\(expression float16_t f2fmp \(constant float \(3'), Test("i32 temp array of array", """ #version 310 es @@ -1803,7 +1803,7 @@ TESTS = [ color = a[0][0] + a[1][1]; } """, - r'\(constant int16_t \(3'), + r'\(expression int16_t i2imp \(constant int \(3'), Test("u32 temp array of array", """ #version 310 es @@ -1820,7 +1820,7 @@ TESTS = [ color = a[0][0] + a[1][1]; } """, - r'\(constant uint16_t \(3'), + r'\(expression uint16_t u2ump \(constant uint \(3'), Test("f32 temp array of array assigned from highp", """ #version 310 es @@ -1839,7 +1839,7 @@ TESTS = [ color = a[0][0] + a[1][1]; } """, - r'\(constant float16_t \(3'), + r'\(expression float16_t f2fmp \(constant float \(3'), Test("i32 temp array of array assigned from highp", """ #version 310 es @@ -1858,7 +1858,7 @@ TESTS = [ color = a[0][0] + a[1][1]; } """, - r'\(constant int16_t \(3'), + r'\(expression int16_t i2imp \(constant int \(3'), Test("u32 temp array of array assigned from highp", """ #version 310 es @@ -1877,7 +1877,7 @@ TESTS = [ color = a[0][0] + a[1][1]; } """, - r'\(constant uint16_t \(3'), + r'\(expression uint16_t u2ump \(constant uint \(3'), Test("f32 temp array of array assigned to highp", """ #version 310 es @@ -1897,7 +1897,7 @@ TESTS = [ color = a[0][0] + a[1][1]; } """, - r'\(constant float16_t \(3'), + r'\(expression float16_t f2fmp \(constant float \(3'), Test("i32 temp array of array assigned to highp", """ #version 310 es @@ -1917,7 +1917,7 @@ TESTS = [ color = a[0][0] + a[1][1]; } """, - r'\(constant int16_t \(3'), + r'\(expression int16_t i2imp \(constant int \(3'), Test("u32 temp array of array assigned to highp", """ #version 310 es @@ -1937,7 +1937,7 @@ TESTS = [ color = a[0][0] + a[1][1]; } """, - r'\(constant uint16_t \(3'), + r'\(expression uint16_t u2ump \(constant uint \(3'), Test("f32 temp array of array returned by function", """ #version 310 es @@ -1959,7 +1959,7 @@ TESTS = [ color = a[0][0] + a[1][1]; } """, - r'\(constant float16_t \(3'), + r'\(expression float16_t f2fmp \(constant float \(3'), Test("i32 temp array of array returned by function", """ #version 310 es @@ -1981,7 +1981,7 @@ TESTS = [ color = a[0][0] + a[1][1]; } """, - r'\(constant int16_t \(3'), + r'\(expression int16_t i2imp \(constant int \(3'), Test("u32 temp array of array returned by function", """ #version 310 es @@ -2003,7 +2003,7 @@ TESTS = [ color = a[0][0] + a[1][1]; } """, - r'\(constant uint16_t \(3'), + r'\(expression uint16_t u2ump \(constant uint \(3'), Test("f32 temp array of array as function out", """ #version 310 es @@ -2026,7 +2026,7 @@ TESTS = [ color = a[0][0] + a[1][1]; } """, - r'\(constant float16_t \(3'), + r'\(expression float16_t f2fmp \(constant float \(3'), Test("i32 temp array of array as function out", """ #version 310 es @@ -2049,7 +2049,7 @@ TESTS = [ color = a[0][0] + a[1][1]; } """, - r'\(constant int16_t \(3'), + r'\(expression int16_t i2imp \(constant int \(3'), Test("u32 temp array of array as function out", """ #version 310 es @@ -2072,7 +2072,7 @@ TESTS = [ color = a[0][0] + a[1][1]; } """, - r'\(constant uint16_t \(3'), + r'\(expression uint16_t u2ump \(constant uint \(3'), Test("f32 temp array of array as function in", """ #version 310 es @@ -2096,7 +2096,7 @@ TESTS = [ color = a[0][0] + a[1][1]; } """, - r'\(constant float16_t \(3'), + r'\(expression float16_t f2fmp \(constant float \(3'), Test("i32 temp array of array as function in", """ #version 310 es @@ -2120,7 +2120,7 @@ TESTS = [ color = a[0][0] + a[1][1]; } """, - r'\(constant int16_t \(3'), + r'\(expression int16_t i2imp \(constant int \(3'), Test("u32 temp array of array as function in", """ #version 310 es @@ -2144,7 +2144,7 @@ TESTS = [ color = a[0][0] + a[1][1]; } """, - r'\(constant uint16_t \(3'), + r'\(expression uint16_t u2ump \(constant uint \(3'), Test("f32 temp array of array as function inout", """ #version 310 es @@ -2168,7 +2168,7 @@ TESTS = [ color = a[0][0] + a[1][1]; } """, - r'\(constant float16_t \(3'), + r'\(expression float16_t f2fmp \(constant float \(3'), Test("i32 temp array of array as function inout", """ #version 310 es @@ -2192,7 +2192,7 @@ TESTS = [ color = a[0][0] + a[1][1]; } """, - r'\(constant int16_t \(3'), + r'\(expression int16_t i2imp \(constant int \(3'), Test("u32 temp array of array as function inout", """ #version 310 es @@ -2216,7 +2216,7 @@ TESTS = [ color = a[0][0] + a[1][1]; } """, - r'\(constant uint16_t \(3'), + r'\(expression uint16_t u2ump \(constant uint \(3'), Test("f32 temp struct (not lowered in the presence of control flow - TODO)", """ #version 300 es -- 2.7.4