diff options
author | Alyssa Rosenzweig <alyssa@rosenzweig.io> | 2023-06-20 16:43:22 -0400 |
---|---|---|
committer | Alyssa Rosenzweig <alyssa@rosenzweig.io> | 2023-06-30 16:29:35 -0400 |
commit | 074e5700cc4434d66a8555a5e4161add6b163760 (patch) | |
tree | 2c86deda7daabf2567f3049f2fa8b2ba5d85c2a4 | |
parent | 311bfd0623d8d20d90c6d693ec31483a1f682a02 (diff) |
pan/mdg: Type CSEL with a NIR pass
As an off-shoot of trying to delete modifiers (and nir_register) from NIR, I'd
like to get rid of some of the modifier NIR silliness that Midgard is doing.
The CSEL type selection heuristic at NIR->MIR time is peak backend silly, so
replace it with nir_gather_ssa_types.
Small win on shader-db. I didn't investigate much, but this matches my intution
for how this patch would perform: very small instruction/cycle count
improvements due to slightly better decisions around modifiers, more substantial
space savings due to more float constants getting inlined.
total instructions in shared programs: 1518422 -> 1518414 (<.01%)
instructions in affected programs: 1914 -> 1906 (-0.42%)
helped: 8
HURT: 0
Instructions are helped.
total bundles in shared programs: 646941 -> 646937 (<.01%)
bundles in affected programs: 344 -> 340 (-1.16%)
helped: 4
HURT: 0
Bundles are helped.
total quadwords in shared programs: 1134727 -> 1134324 (-0.04%)
quadwords in affected programs: 66752 -> 66349 (-0.60%)
helped: 351
HURT: 54
Quadwords are helped.
Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Reviewed-by: Italo Nicola <italonicola@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23769>
-rw-r--r-- | src/panfrost/midgard/meson.build | 1 | ||||
-rw-r--r-- | src/panfrost/midgard/midgard_compile.c | 52 | ||||
-rw-r--r-- | src/panfrost/midgard/midgard_nir.h | 1 | ||||
-rw-r--r-- | src/panfrost/midgard/midgard_nir_type_csel.c | 46 |
4 files changed, 53 insertions, 47 deletions
diff --git a/src/panfrost/midgard/meson.build b/src/panfrost/midgard/meson.build index 1723e2652fe..607f0dc72ff 100644 --- a/src/panfrost/midgard/meson.build +++ b/src/panfrost/midgard/meson.build @@ -35,6 +35,7 @@ libpanfrost_midgard_files = files( 'mir_promote_uniforms.c', 'mir_squeeze.c', 'midgard_nir_lower_image_bitsize.c', + 'midgard_nir_type_csel.c', 'midgard_opt_copy_prop.c', 'midgard_opt_dce.c', 'midgard_opt_perspective.c', diff --git a/src/panfrost/midgard/midgard_compile.c b/src/panfrost/midgard/midgard_compile.c index 3bdda47844c..2c609800f9d 100644 --- a/src/panfrost/midgard/midgard_compile.c +++ b/src/panfrost/midgard/midgard_compile.c @@ -459,6 +459,7 @@ optimise_nir(nir_shader *nir, unsigned quirks, bool is_blend) /* Now that booleans are lowered, we can run out late opts */ NIR_PASS(progress, nir, midgard_nir_lower_algebraic_late); NIR_PASS(progress, nir, midgard_nir_cancel_inot); + NIR_PASS_V(nir, midgard_nir_type_csel); NIR_PASS(progress, nir, nir_copy_prop); NIR_PASS(progress, nir, nir_opt_dce); @@ -697,50 +698,6 @@ mir_copy_src(midgard_instruction *ins, nir_alu_instr *instr, unsigned i, } } -/* Midgard features both fcsel and icsel, depending on whether you want int or - * float modifiers. NIR's csel is typeless, so we want a heuristic to guess if - * we should emit an int or float csel depending on what modifiers could be - * placed. In the absense of modifiers, this is probably arbitrary. */ - -static bool -mir_is_bcsel_float(nir_alu_instr *instr) -{ - nir_op intmods[] = {nir_op_i2i8, nir_op_i2i16, nir_op_i2i32, nir_op_i2i64}; - - nir_op floatmods[] = {nir_op_fabs, nir_op_fneg, nir_op_f2f16, nir_op_f2f32, - nir_op_f2f64}; - - nir_op floatdestmods[] = {nir_op_fsat, nir_op_fsat_signed_mali, - nir_op_fclamp_pos_mali, nir_op_f2f16, - nir_op_f2f32}; - - signed score = 0; - - for (unsigned i = 1; i < 3; ++i) { - nir_alu_src s = instr->src[i]; - for (unsigned q = 0; q < ARRAY_SIZE(intmods); ++q) { - if (pan_has_source_mod(&s, intmods[q])) - score--; - } - } - - for (unsigned i = 1; i < 3; ++i) { - nir_alu_src s = instr->src[i]; - for (unsigned q = 0; q < ARRAY_SIZE(floatmods); ++q) { - if (pan_has_source_mod(&s, floatmods[q])) - score++; - } - } - - for (unsigned q = 0; q < ARRAY_SIZE(floatdestmods); ++q) { - nir_dest *dest = &instr->dest.dest; - if (pan_has_dest_mod(&dest, floatdestmods[q])) - score++; - } - - return (score > 0); -} - static void emit_alu(compiler_context *ctx, nir_alu_instr *instr) { @@ -940,9 +897,10 @@ emit_alu(compiler_context *ctx, nir_alu_instr *instr) break; } - case nir_op_b32csel: { + case nir_op_b32csel: + case nir_op_b32fcsel_mdg: { bool mixed = nir_is_non_scalar_swizzle(&instr->src[0], nr_components); - bool is_float = mir_is_bcsel_float(instr); + bool is_float = instr->op == nir_op_b32fcsel_mdg; op = is_float ? (mixed ? midgard_alu_op_fcsel_v : midgard_alu_op_fcsel) : (mixed ? midgard_alu_op_icsel_v : midgard_alu_op_icsel); @@ -1021,7 +979,7 @@ emit_alu(compiler_context *ctx, nir_alu_instr *instr) for (unsigned i = 0; i < nr_inputs; ++i) { unsigned to = i; - if (instr->op == nir_op_b32csel) { + if (instr->op == nir_op_b32csel || instr->op == nir_op_b32fcsel_mdg) { /* The condition is the first argument; move * the other arguments up one to be a binary * instruction for Midgard with the condition diff --git a/src/panfrost/midgard/midgard_nir.h b/src/panfrost/midgard/midgard_nir.h index 2e6fc298be8..980dd75ba6a 100644 --- a/src/panfrost/midgard/midgard_nir.h +++ b/src/panfrost/midgard/midgard_nir.h @@ -4,4 +4,5 @@ bool midgard_nir_lower_algebraic_early(nir_shader *shader); bool midgard_nir_lower_algebraic_late(nir_shader *shader); bool midgard_nir_cancel_inot(nir_shader *shader); +void midgard_nir_type_csel(nir_shader *shader); bool midgard_nir_lower_image_bitsize(nir_shader *shader); diff --git a/src/panfrost/midgard/midgard_nir_type_csel.c b/src/panfrost/midgard/midgard_nir_type_csel.c new file mode 100644 index 00000000000..3cf6e1546df --- /dev/null +++ b/src/panfrost/midgard/midgard_nir_type_csel.c @@ -0,0 +1,46 @@ +/* + * Copyright 2023 Valve Corporation + * SPDX-License-Identifier: MIT + */ + +#include "compiler/nir/nir.h" +#include "compiler/nir/nir_builder.h" +#include "midgard_nir.h" +#include "nir_opcodes.h" + +static bool +pass(nir_builder *b, nir_instr *instr, void *data) +{ + if (instr->type != nir_instr_type_alu) + return false; + + nir_alu_instr *alu = nir_instr_as_alu(instr); + if (alu->op != nir_op_b32csel) + return false; + + BITSET_WORD *float_types = data; + assert(alu->dest.dest.is_ssa); + if (BITSET_TEST(float_types, alu->dest.dest.ssa.index)) { + alu->op = nir_op_b32fcsel_mdg; + return true; + } else { + return false; + } +} + +void +midgard_nir_type_csel(nir_shader *shader) +{ + nir_function_impl *impl = nir_shader_get_entrypoint(shader); + nir_index_ssa_defs(impl); + + BITSET_WORD *float_types = + calloc(BITSET_WORDS(impl->ssa_alloc), sizeof(BITSET_WORD)); + nir_gather_ssa_types(impl, float_types, NULL); + + nir_shader_instructions_pass( + shader, pass, nir_metadata_block_index | nir_metadata_dominance, + float_types); + + free(float_types); +} |