summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlyssa Rosenzweig <alyssa@rosenzweig.io>2023-06-20 16:43:22 -0400
committerAlyssa Rosenzweig <alyssa@rosenzweig.io>2023-06-30 16:29:35 -0400
commit074e5700cc4434d66a8555a5e4161add6b163760 (patch)
tree2c86deda7daabf2567f3049f2fa8b2ba5d85c2a4
parent311bfd0623d8d20d90c6d693ec31483a1f682a02 (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.build1
-rw-r--r--src/panfrost/midgard/midgard_compile.c52
-rw-r--r--src/panfrost/midgard/midgard_nir.h1
-rw-r--r--src/panfrost/midgard/midgard_nir_type_csel.c46
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);
+}