From 480b5024438628614f0fedfe188235789e1022d9 Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Wed, 24 Jul 2019 07:23:19 -0700 Subject: [PATCH] pan/midgard: Move copy propagation into its own file We also expose some utilities it uses as general MIR helpers. Signed-off-by: Alyssa Rosenzweig --- src/panfrost/midgard/compiler.h | 6 ++ src/panfrost/midgard/meson.build | 1 + src/panfrost/midgard/midgard_compile.c | 83 -------------------- src/panfrost/midgard/midgard_opt_copy_prop.c | 78 ++++++++++++++++++ src/panfrost/midgard/mir.c | 35 +++++++++ 5 files changed, 120 insertions(+), 83 deletions(-) create mode 100644 src/panfrost/midgard/midgard_opt_copy_prop.c diff --git a/src/panfrost/midgard/compiler.h b/src/panfrost/midgard/compiler.h index 50e1846f893..326e351f7ff 100644 --- a/src/panfrost/midgard/compiler.h +++ b/src/panfrost/midgard/compiler.h @@ -381,6 +381,8 @@ void mir_print_instruction(midgard_instruction *ins); void mir_print_bundle(midgard_bundle *ctx); void mir_print_block(midgard_block *block); void mir_print_shader(compiler_context *ctx); +bool mir_nontrivial_source2_mod(midgard_instruction *ins); +bool mir_nontrivial_mod(midgard_vector_alu_src src, bool is_int, unsigned mask); /* MIR goodies */ @@ -480,4 +482,8 @@ nir_undef_to_zero(nir_shader *shader); void nir_clamp_psiz(nir_shader *shader, float min_size, float max_size); +/* Optimizations */ + +bool midgard_opt_copy_prop(compiler_context *ctx, midgard_block *block); + #endif diff --git a/src/panfrost/midgard/meson.build b/src/panfrost/midgard/meson.build index b467f835032..ead81cf2a5b 100644 --- a/src/panfrost/midgard/meson.build +++ b/src/panfrost/midgard/meson.build @@ -30,6 +30,7 @@ libpanfrost_midgard_files = files( 'midgard_liveness.c', 'midgard_ops.c', 'mir_promote_uniforms.c', + 'midgard_opt_copy_prop.c', 'cppwrap.cpp', 'disassemble.c', ) diff --git a/src/panfrost/midgard/midgard_compile.c b/src/panfrost/midgard/midgard_compile.c index 86d97e37095..7fa9c4b598f 100644 --- a/src/panfrost/midgard/midgard_compile.c +++ b/src/panfrost/midgard/midgard_compile.c @@ -2012,89 +2012,6 @@ midgard_opt_cull_dead_branch(compiler_context *ctx, midgard_block *block) } } -static bool -mir_nontrivial_mod(midgard_vector_alu_src src, bool is_int, unsigned mask) -{ - /* abs or neg */ - if (!is_int && src.mod) return true; - - /* Other int mods don't matter in isolation */ - if (is_int && src.mod == midgard_int_shift) return true; - - /* size-conversion */ - if (src.half) return true; - - /* swizzle */ - for (unsigned c = 0; c < 4; ++c) { - if (!(mask & (1 << c))) continue; - if (((src.swizzle >> (2*c)) & 3) != c) return true; - } - - return false; -} - -static bool -mir_nontrivial_source2_mod(midgard_instruction *ins) -{ - bool is_int = midgard_is_integer_op(ins->alu.op); - - midgard_vector_alu_src src2 = - vector_alu_from_unsigned(ins->alu.src2); - - return mir_nontrivial_mod(src2, is_int, ins->mask); -} - -static bool -mir_nontrivial_outmod(midgard_instruction *ins) -{ - bool is_int = midgard_is_integer_op(ins->alu.op); - unsigned mod = ins->alu.outmod; - - /* Type conversion is a sort of outmod */ - if (ins->alu.dest_override != midgard_dest_override_none) - return true; - - if (is_int) - return mod != midgard_outmod_int_wrap; - else - return mod != midgard_outmod_none; -} - -static bool -midgard_opt_copy_prop(compiler_context *ctx, midgard_block *block) -{ - bool progress = false; - - mir_foreach_instr_in_block_safe(block, ins) { - if (ins->type != TAG_ALU_4) continue; - if (!OP_IS_MOVE(ins->alu.op)) continue; - - unsigned from = ins->ssa_args.src1; - unsigned to = ins->ssa_args.dest; - - /* We only work on pure SSA */ - - if (to >= SSA_FIXED_MINIMUM) continue; - if (from >= SSA_FIXED_MINIMUM) continue; - if (to >= ctx->func->impl->ssa_alloc) continue; - if (from >= ctx->func->impl->ssa_alloc) continue; - - /* Constant propagation is not handled here, either */ - if (ins->ssa_args.inline_constant) continue; - if (ins->has_constants) continue; - - if (mir_nontrivial_source2_mod(ins)) continue; - if (mir_nontrivial_outmod(ins)) continue; - - /* We're clear -- rewrite */ - mir_rewrite_index_src(ctx, to, from); - mir_remove_instruction(ins); - progress |= true; - } - - return progress; -} - /* fmov.pos is an idiom for fpos. Propoagate the .pos up to the source, so then * the move can be propagated away entirely */ diff --git a/src/panfrost/midgard/midgard_opt_copy_prop.c b/src/panfrost/midgard/midgard_opt_copy_prop.c new file mode 100644 index 00000000000..30fe1c7cb4f --- /dev/null +++ b/src/panfrost/midgard/midgard_opt_copy_prop.c @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2018 Alyssa Rosenzweig + * Copyright (C) 2019 Collabora, Ltd. + * + * 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. + */ + +#include "compiler.h" +#include "midgard_ops.h" + +static bool +mir_nontrivial_outmod(midgard_instruction *ins) +{ + bool is_int = midgard_is_integer_op(ins->alu.op); + unsigned mod = ins->alu.outmod; + + /* Type conversion is a sort of outmod */ + if (ins->alu.dest_override != midgard_dest_override_none) + return true; + + if (is_int) + return mod != midgard_outmod_int_wrap; + else + return mod != midgard_outmod_none; +} + +bool +midgard_opt_copy_prop(compiler_context *ctx, midgard_block *block) +{ + bool progress = false; + + mir_foreach_instr_in_block_safe(block, ins) { + if (ins->type != TAG_ALU_4) continue; + if (!OP_IS_MOVE(ins->alu.op)) continue; + + unsigned from = ins->ssa_args.src1; + unsigned to = ins->ssa_args.dest; + + /* We only work on pure SSA */ + + if (to >= SSA_FIXED_MINIMUM) continue; + if (from >= SSA_FIXED_MINIMUM) continue; + if (to >= ctx->func->impl->ssa_alloc) continue; + if (from >= ctx->func->impl->ssa_alloc) continue; + + /* Constant propagation is not handled here, either */ + if (ins->ssa_args.inline_constant) continue; + if (ins->has_constants) continue; + + /* Modifier propagation is not handled here */ + if (mir_nontrivial_source2_mod(ins)) continue; + if (mir_nontrivial_outmod(ins)) continue; + + /* We're clear -- rewrite */ + mir_rewrite_index_src(ctx, to, from); + mir_remove_instruction(ins); + progress |= true; + } + + return progress; +} diff --git a/src/panfrost/midgard/mir.c b/src/panfrost/midgard/mir.c index ea7c65110b4..03a47f44acb 100644 --- a/src/panfrost/midgard/mir.c +++ b/src/panfrost/midgard/mir.c @@ -22,6 +22,7 @@ */ #include "compiler.h" +#include "midgard_ops.h" void mir_rewrite_index_src_single(midgard_instruction *ins, unsigned old, unsigned new) { @@ -78,3 +79,37 @@ mir_single_use(compiler_context *ctx, unsigned value) return used_count <= 1; } + +bool +mir_nontrivial_mod(midgard_vector_alu_src src, bool is_int, unsigned mask) +{ + /* abs or neg */ + if (!is_int && src.mod) return true; + + /* Other int mods don't matter in isolation */ + if (is_int && src.mod == midgard_int_shift) return true; + + /* size-conversion */ + if (src.half) return true; + + /* swizzle */ + for (unsigned c = 0; c < 4; ++c) { + if (!(mask & (1 << c))) continue; + if (((src.swizzle >> (2*c)) & 3) != c) return true; + } + + return false; +} + +bool +mir_nontrivial_source2_mod(midgard_instruction *ins) +{ + bool is_int = midgard_is_integer_op(ins->alu.op); + + midgard_vector_alu_src src2 = + vector_alu_from_unsigned(ins->alu.src2); + + return mir_nontrivial_mod(src2, is_int, ins->mask); +} + + -- 2.30.2