r300: convert x * 2 into x + x for presubtract
authorPavel Ondračka <pavel.ondracka@gmail.com>
Tue, 22 Aug 2023 14:08:01 +0000 (16:08 +0200)
committerMarge Bot <emma+marge@anholt.net>
Fri, 25 Aug 2023 14:48:15 +0000 (14:48 +0000)
total instructions in shared programs: 128859 -> 128864 (<.01%)
instructions in affected programs: 931 -> 936 (0.54%)
helped: 0
HURT: 5
total presub in shared programs: 7635 -> 7682 (0.62%)
presub in affected programs: 208 -> 255 (22.60%)
helped: 0
HURT: 17
total cycles in shared programs: 194124 -> 194101 (-0.01%)
cycles in affected programs: 1671 -> 1648 (-1.38%)
helped: 9
HURT: 1

Reviewed-by: Filip Gawin <filip.gawin@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24830>

src/gallium/drivers/r300/compiler/r300_nir.h
src/gallium/drivers/r300/compiler/r300_nir_algebraic.py

index 951e0a8..916eb08 100644 (file)
 #include "pipe/p_screen.h"
 #include "compiler/nir/nir.h"
 
+static inline bool
+is_ubo_or_input(UNUSED struct hash_table *ht, const nir_alu_instr *instr,
+                unsigned src, unsigned num_components,
+                const uint8_t *swizzle)
+{
+   nir_instr *parent = instr->src[src].src.ssa->parent_instr;
+   if (parent->type != nir_instr_type_intrinsic)
+      return false;
+
+   nir_intrinsic_instr *intrinsic = nir_instr_as_intrinsic(parent);
+
+   switch (intrinsic->intrinsic) {
+   case nir_intrinsic_load_ubo_vec4:
+   case nir_intrinsic_load_input:
+   case nir_intrinsic_load_interpolated_input:
+      return true;
+   default:
+      return false;
+   }
+}
+
 char *r300_finalize_nir(struct pipe_screen *pscreen, void *nir);
 
 extern bool r300_transform_vs_trig_input(struct nir_shader *shader);
index c27dba9..485943e 100644 (file)
@@ -76,6 +76,10 @@ r300_nir_prepare_presubtract = [
         (('ffma', -2.0, a, 1.0), ('fneg', ('ffma', ('fneg', a), 2.0, 1.0))),
         (('ffma', 2.0, a, -1.0), ('fneg', ('ffma', ('fneg', a), 2.0, 1.0))),
         (('ffma', a, 2.0, -1.0), ('fneg', ('ffma', ('fneg', a), 2.0, 1.0))),
+        # x * 2 can be usually folded into output modifier for the previous
+        # instruction, but that only works if x is a temporary. If it is input or
+        # constant just convert it to add instead.
+        (('fmul', 'a(is_ubo_or_input)', 2.0), ('fadd', a, a)),
 ]
 
 # Previous prepare_presubtract pass can sometimes produce double fneg patterns.