pan/mdg: Precompute mir_special_index
authorAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Wed, 6 May 2020 20:06:54 +0000 (16:06 -0400)
committerMarge Bot <eric+marge@anholt.net>
Wed, 20 May 2020 17:06:34 +0000 (17:06 +0000)
Rather than O(N) each call, we can precompute the whole set - also O(N)
- and then subsequent checks are O(1).

Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5123>

src/panfrost/midgard/compiler.h
src/panfrost/midgard/mir.c
src/panfrost/midgard/mir_promote_uniforms.c

index 618c0d792655f05ff6ae5c89986416a1e1cf8db6..93ff96055422bcee9632514b7558ddae22d5623e 100644 (file)
@@ -481,7 +481,6 @@ void mir_rewrite_index_dst_single(midgard_instruction *ins, unsigned old, unsign
 void mir_rewrite_index_src_single(midgard_instruction *ins, unsigned old, unsigned new);
 void mir_rewrite_index_src_swizzle(compiler_context *ctx, unsigned old, unsigned new, unsigned *swizzle);
 bool mir_single_use(compiler_context *ctx, unsigned value);
-bool mir_special_index(compiler_context *ctx, unsigned idx);
 unsigned mir_use_count(compiler_context *ctx, unsigned value);
 uint16_t mir_bytemask_of_read_components(midgard_instruction *ins, unsigned node);
 uint16_t mir_bytemask_of_read_components_index(midgard_instruction *ins, unsigned i);
index 68f6286c590efc3a9b4847fb1d97143291b29eef..0289e5e34965749250fec4f9e2d81397e3f2482a 100644 (file)
@@ -176,27 +176,6 @@ mir_nontrivial_outmod(midgard_instruction *ins)
                 return mod != midgard_outmod_none;
 }
 
-/* Checks if an index will be used as a special register -- basically, if we're
- * used as the input to a non-ALU op */
-
-bool
-mir_special_index(compiler_context *ctx, unsigned idx)
-{
-        mir_foreach_instr_global(ctx, ins) {
-                bool is_ldst = ins->type == TAG_LOAD_STORE_4;
-                bool is_tex = ins->type == TAG_TEXTURE_4;
-                bool is_writeout = ins->compact_branch && ins->writeout;
-
-                if (!(is_ldst || is_tex || is_writeout))
-                        continue;
-
-                if (mir_has_arg(ins, idx))
-                        return true;
-        }
-
-        return false;
-}
-
 /* Grabs the type size. */
 
 midgard_reg_mode
index 620b443d314d90056fea76fcb8d3e980197fc3cd..d78484c3568dd5891e189e40d7cec7e40162fb17 100644 (file)
@@ -127,12 +127,46 @@ mir_work_heuristic(compiler_context *ctx)
         return 8;
 }
 
+/* Bitset of indices that will be used as a special register -- inputs to a
+ * non-ALU op. We precompute this set so that testing is efficient, otherwise
+ * we end up O(mn) behaviour for n instructions and m uniform reads */
+
+static BITSET_WORD *
+mir_special_indices(compiler_context *ctx)
+{
+        mir_compute_temp_count(ctx);
+        BITSET_WORD *bset = calloc(BITSET_WORDS(ctx->temp_count), sizeof(BITSET_WORD));
+
+        mir_foreach_instr_global(ctx, ins) {
+                /* Look for special instructions */
+                bool is_ldst = ins->type == TAG_LOAD_STORE_4;
+                bool is_tex = ins->type == TAG_TEXTURE_4;
+                bool is_writeout = ins->compact_branch && ins->writeout;
+
+                if (!(is_ldst || is_tex || is_writeout))
+                        continue;
+
+                /* Anything read by a special instruction is itself special */
+                mir_foreach_src(ins, i) {
+                        unsigned idx = ins->src[i];
+
+                        if (idx < ctx->temp_count)
+                                BITSET_SET(bset, idx);
+                }
+        }
+
+        return bset;
+}
+
 void
 midgard_promote_uniforms(compiler_context *ctx)
 {
         unsigned work_count = mir_work_heuristic(ctx);
         unsigned promoted_count = 24 - work_count;
 
+        /* First, figure out special indices a priori so we don't recompute a lot */
+        BITSET_WORD *special = mir_special_indices(ctx);
+
         mir_foreach_instr_global_safe(ctx, ins) {
                 if (!mir_is_promoteable_ubo(ins)) continue;
 
@@ -153,7 +187,9 @@ midgard_promote_uniforms(compiler_context *ctx)
                  * we're being fed into a special class */
 
                 bool needs_move = ins->dest & PAN_IS_REG;
-                needs_move |= mir_special_index(ctx, ins->dest);
+
+                if (ins->dest < ctx->temp_count)
+                        needs_move |= BITSET_TEST(special, ins->dest);
 
                 if (needs_move) {
                         midgard_instruction mov = v_mov(promoted, ins->dest);
@@ -170,4 +206,6 @@ midgard_promote_uniforms(compiler_context *ctx)
 
                 mir_remove_instruction(ins);
         }
+
+        free(special);
 }