Mesa (master): pan/midgard: Implement SIMD-aware dead code elimination

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Sun Oct 20 12:32:20 UTC 2019


Module: Mesa
Branch: master
Commit: b8c4fb235ef4055a14a9a2aec07f3f906ef8a841
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=b8c4fb235ef4055a14a9a2aec07f3f906ef8a841

Author: Alyssa Rosenzweig <alyssa.rosenzweig at collabora.com>
Date:   Wed Oct 16 13:19:49 2019 -0400

pan/midgard: Implement SIMD-aware dead code elimination

We would like to eliminate not just entire dead instructions, but also
dead components, which increases scheduler flexibility (since some
vector instructions can become scalar after eliminating dead
components). This also will allow better RA in the future.

Results are meh.

total instructions in shared programs: 3453 -> 3451 (-0.06%)
instructions in affected programs: 60 -> 58 (-3.33%)
helped: 2
HURT: 0

total bundles in shared programs: 1826 -> 1824 (-0.11%)
bundles in affected programs: 33 -> 31 (-6.06%)
helped: 2
HURT: 0

total quadwords in shared programs: 3144 -> 3144 (0.00%)
quadwords in affected programs: 0 -> 0
helped: 0
HURT: 0

total registers in shared programs: 321 -> 321 (0.00%)
registers in affected programs: 45 -> 45 (0.00%)
helped: 11
HURT: 11
helped stats (abs) min: 1 max: 1 x̄: 1.00 x̃: 1
helped stats (rel) min: 16.67% max: 50.00% x̄: 39.70% x̃: 50.00%
HURT stats (abs)   min: 1 max: 1 x̄: 1.00 x̃: 1
HURT stats (rel)   min: 100.00% max: 100.00% x̄: 100.00% x̃: 100.00%
95% mean confidence interval for registers value: -0.45 0.45
95% mean confidence interval for registers %-change: -1.87% 62.18%
Inconclusive result (value mean confidence interval includes 0).

total threads in shared programs: 445 -> 447 (0.45%)
threads in affected programs: 2 -> 4 (100.00%)
helped: 1
HURT: 0

Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig at collabora.com>

---

 src/panfrost/midgard/midgard_opt_dce.c | 65 +++++++++++++++++++++++++++++-----
 1 file changed, 57 insertions(+), 8 deletions(-)

diff --git a/src/panfrost/midgard/midgard_opt_dce.c b/src/panfrost/midgard/midgard_opt_dce.c
index 613eb6e5b1d..aaac84fe16e 100644
--- a/src/panfrost/midgard/midgard_opt_dce.c
+++ b/src/panfrost/midgard/midgard_opt_dce.c
@@ -23,8 +23,41 @@
  */
 
 #include "compiler.h"
+#include "util/u_memory.h"
+#include "midgard_ops.h"
 
-/* Basic dead code elimination on the MIR itself */
+/* SIMD-aware dead code elimination. Perform liveness analysis step-by-step,
+ * removing dead components. If an instruction ends up with a zero mask, the
+ * instruction in total is dead and should be removed. */
+
+static bool
+can_cull_mask(compiler_context *ctx, midgard_instruction *ins)
+{
+        if (ins->dest >= ctx->temp_count)
+                return false;
+
+        if (ins->type == TAG_LOAD_STORE_4)
+                if (load_store_opcode_props[ins->load_store.op].props & LDST_SPECIAL_MASK)
+                        return false;
+
+        return true;
+}
+
+static bool
+can_dce(midgard_instruction *ins)
+{
+        if (ins->mask)
+                return false;
+
+        if (ins->compact_branch)
+                return false;
+
+        if (ins->type == TAG_LOAD_STORE_4)
+                if (load_store_opcode_props[ins->load_store.op].props & LDST_SIDE_FX)
+                        return false;
+
+        return true;
+}
 
 bool
 midgard_opt_dead_code_eliminate(compiler_context *ctx, midgard_block *block)
@@ -32,18 +65,34 @@ midgard_opt_dead_code_eliminate(compiler_context *ctx, midgard_block *block)
         bool progress = false;
 
         mir_invalidate_liveness(ctx);
+        mir_compute_liveness(ctx);
 
-        mir_foreach_instr_in_block_safe(block, ins) {
-                if (ins->type != TAG_ALU_4) continue;
-                if (ins->compact_branch) continue;
+        uint16_t *live = mem_dup(block->live_out, ctx->temp_count * sizeof(uint16_t));
+
+        mir_foreach_instr_in_block_rev(block, ins) {
+                if (can_cull_mask(ctx, ins)) {
+                        midgard_reg_mode mode = mir_typesize(ins);
+                        unsigned oldmask = ins->mask;
+
+                        unsigned rounded = mir_round_bytemask_down(live[ins->dest], mode);
+                        unsigned cmask = mir_from_bytemask(rounded, mode);
+
+                        ins->mask &= cmask;
+                        progress |= (ins->mask != oldmask);
+                }
 
-                if (ins->dest >= SSA_FIXED_MINIMUM) continue;
-                if (mir_is_live_after(ctx, block, ins, ins->dest)) continue;
+                mir_liveness_ins_update(live, ins, ctx->temp_count);
+        }
 
-                mir_remove_instruction(ins);
-                progress = true;
+        mir_foreach_instr_in_block_safe(block, ins) {
+                if (can_dce(ins)) {
+                        mir_remove_instruction(ins);
+                        progress = true;
+                }
         }
 
+        free(live);
+
         return progress;
 }
 




More information about the mesa-commit mailing list