freedreno/ir3: CSE the up/downconversion of SEL's cond's size.
authorEric Anholt <eric@anholt.net>
Fri, 10 Apr 2020 23:10:14 +0000 (16:10 -0700)
committerMarge Bot <eric+marge@anholt.net>
Mon, 13 Apr 2020 19:24:52 +0000 (19:24 +0000)
Not many programs hit this, but if you were, say, selecting between vec4s,
you'd convert the cond 4 times.

instructions in affected programs: 2957 -> 2717 (-8.12%)
nops in affected programs: 989 -> 899 (-9.10%)
non-nops in affected programs: 1968 -> 1818 (-7.62%)
dwords in affected programs: 3232 -> 2752 (-14.85%)
last-baryf in affected programs: 102 -> 90 (-11.76%)
full in affected programs: 5 -> 4 (-20.00%)
sstall in affected programs: 329 -> 329 (0.00%)
(ss) in affected programs: 86 -> 105 (22.09%)
(sy) in affected programs: 14 -> 12 (-14.29%)

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4516>

src/freedreno/ir3/ir3_compiler_nir.c
src/freedreno/ir3/ir3_context.c
src/freedreno/ir3/ir3_context.h

index bc0513f413ef0b66662d577fae1eb923d93ae9a5..752adc8f1b7ec1b2c3e91e2478a4785f030ae06c 100644 (file)
@@ -642,13 +642,22 @@ emit_alu(struct ir3_context *ctx, nir_alu_instr *alu)
                }
 
                compile_assert(ctx, bs[1] == bs[2]);
-               /* Make sure the boolean condition has the same bit size as the other
-                * two arguments, adding a conversion if necessary.
-                */
-               if (bs[1] < bs[0])
-                       cond = ir3_COV(b, cond, TYPE_U32, TYPE_U16);
-               else if (bs[1] > bs[0])
-                       cond = ir3_COV(b, cond, TYPE_U16, TYPE_U32);
+               if (bs[1] != bs[0]) {
+                       struct hash_entry *prev_entry =
+                               _mesa_hash_table_search(ctx->sel_cond_conversions, src[0]);
+                       if (prev_entry) {
+                               cond = prev_entry->data;
+                       } else {
+                               /* Make sure the boolean condition has the same bit size as the other
+                                * two arguments, adding a conversion if necessary.
+                                */
+                               if (bs[1] < bs[0])
+                                       cond = ir3_COV(b, cond, TYPE_U32, TYPE_U16);
+                               else if (bs[1] > bs[0])
+                                       cond = ir3_COV(b, cond, TYPE_U16, TYPE_U32);
+                               _mesa_hash_table_insert(ctx->sel_cond_conversions, src[0], cond);
+                       }
+               }
 
                if (bs[1] > 16)
                        dst[0] = ir3_SEL_B32(b, src[1], 0, cond, 0, src[2], 0);
@@ -2687,6 +2696,8 @@ emit_block(struct ir3_context *ctx, nir_block *nblock)
                if (ctx->error)
                        return;
        }
+
+       _mesa_hash_table_clear(ctx->sel_cond_conversions, NULL);
 }
 
 static void emit_cf_list(struct ir3_context *ctx, struct exec_list *list);
index 6050f3f69d382de6c5eeef0cf0e0fbc17b49af9d..f4511ec77dab1aa0b0f49f4105b5c7e5307b8660 100644 (file)
@@ -63,6 +63,8 @@ ir3_context_init(struct ir3_compiler *compiler,
                        _mesa_hash_pointer, _mesa_key_pointer_equal);
        ctx->block_ht = _mesa_hash_table_create(ctx,
                        _mesa_hash_pointer, _mesa_key_pointer_equal);
+       ctx->sel_cond_conversions = _mesa_hash_table_create(ctx,
+                       _mesa_hash_pointer, _mesa_key_pointer_equal);
 
        /* TODO: maybe generate some sort of bitmask of what key
         * lowers vs what shader has (ie. no need to lower
index a109a9a13be46db0c7e3f4ffa7a0174c592fc452..d1de1a67a262c8f6a35988c5539b35d6dd3cba7a 100644 (file)
@@ -127,6 +127,8 @@ struct ir3_context {
         */
        struct hash_table_u64 *addr1_ht;
 
+       struct hash_table *sel_cond_conversions;
+
        /* last dst array, for indirect we need to insert a var-store.
         */
        struct ir3_instruction **last_dst;