pan/mdg: Optimize liveness computation in DCE
authorAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Wed, 6 May 2020 21:34:09 +0000 (17:34 -0400)
committerMarge Bot <eric+marge@anholt.net>
Wed, 20 May 2020 17:06:34 +0000 (17:06 +0000)
Rather than recompute liveness every block, compute it just once for the
whole shader, which ends up more efficient.

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/midgard_compile.c
src/panfrost/midgard/midgard_opt_dce.c

index 93ff96055422bcee9632514b7558ddae22d5623e..8132a9e91a9ccf8931ce5c7f338286890e186091 100644 (file)
@@ -649,7 +649,7 @@ void midgard_nir_lod_errata(nir_shader *shader);
 bool midgard_opt_copy_prop(compiler_context *ctx, midgard_block *block);
 bool midgard_opt_combine_projection(compiler_context *ctx, midgard_block *block);
 bool midgard_opt_varying_projection(compiler_context *ctx, midgard_block *block);
-bool midgard_opt_dead_code_eliminate(compiler_context *ctx, midgard_block *block);
+bool midgard_opt_dead_code_eliminate(compiler_context *ctx);
 bool midgard_opt_dead_move_eliminate(compiler_context *ctx, midgard_block *block);
 bool midgard_opt_promote_fmov(compiler_context *ctx, midgard_block *block);
 
index 0e5e9844591391b3da5d8231a949c73991adebca..b7e11e334d0e940893040c4d5bd9672608d7973b 100644 (file)
@@ -2622,11 +2622,11 @@ midgard_compile_shader_nir(nir_shader *nir, panfrost_program *program, bool is_b
 
         do {
                 progress = false;
+                progress |= midgard_opt_dead_code_eliminate(ctx);
 
                 mir_foreach_block(ctx, _block) {
                         midgard_block *block = (midgard_block *) _block;
                         progress |= midgard_opt_copy_prop(ctx, block);
-                        progress |= midgard_opt_dead_code_eliminate(ctx, block);
                         progress |= midgard_opt_combine_projection(ctx, block);
                         progress |= midgard_opt_varying_projection(ctx, block);
                 }
index 71395ca36c71fb0e47d5bc2128d0ae4373ea1fef..e9e51a6451dffee59b7cf29ca69aed9ba7557787 100644 (file)
@@ -63,14 +63,11 @@ can_dce(midgard_instruction *ins)
         return true;
 }
 
-bool
-midgard_opt_dead_code_eliminate(compiler_context *ctx, midgard_block *block)
+static bool
+midgard_opt_dead_code_eliminate_block(compiler_context *ctx, midgard_block *block)
 {
         bool progress = false;
 
-        mir_invalidate_liveness(ctx);
-        mir_compute_liveness(ctx);
-
         uint16_t *live = mem_dup(block->base.live_out, ctx->temp_count * sizeof(uint16_t));
 
         mir_foreach_instr_in_block_rev(block, ins) {
@@ -100,6 +97,27 @@ midgard_opt_dead_code_eliminate(compiler_context *ctx, midgard_block *block)
         return progress;
 }
 
+bool
+midgard_opt_dead_code_eliminate(compiler_context *ctx)
+{
+        /* We track liveness. In fact, it's ok if we assume more things are
+         * live than they actually are, that just reduces the effectiveness of
+         * this iterations lightly. And DCE has the effect of strictly reducing
+         * liveness, so we can run DCE across all blocks while only computing
+         * liveness at the beginning. */
+
+        mir_invalidate_liveness(ctx);
+        mir_compute_liveness(ctx);
+
+        bool progress = false;
+
+        mir_foreach_block(ctx, block) {
+                progress |= midgard_opt_dead_code_eliminate_block(ctx, (midgard_block *) block);
+        }
+
+        return progress;
+}
+
 /* Removes dead moves, that is, moves with a destination overwritten before
  * being read. Normally handled implicitly as part of DCE, but this has to run
  * after the out-of-SSA pass */