pan/bi: Make bi_writemask take a destination
authorAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Thu, 18 Feb 2021 21:56:16 +0000 (16:56 -0500)
committerMarge Bot <eric+marge@anholt.net>
Mon, 22 Feb 2021 19:17:50 +0000 (19:17 +0000)
Assuming it's only the first destination breaks assumptions across the
compiler. Add a destination source and fix up the many corresponding
issues. Nothing to backport as far as I understand since multidest
instruction are new.

Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9164>

src/panfrost/bifrost/bi_liveness.c
src/panfrost/bifrost/bi_opt_dce.c
src/panfrost/bifrost/bi_ra.c
src/panfrost/bifrost/bir.c
src/panfrost/bifrost/compiler.h

index 2b8c569..828e434 100644 (file)
@@ -29,7 +29,10 @@ bi_liveness_ins_update(uint16_t *live, bi_instr *ins, unsigned max)
 {
         /* live_in[s] = GEN[s] + (live_out[s] - KILL[s]) */
 
-        pan_liveness_kill(live, bi_get_node(ins->dest[0]), max, bi_writemask(ins));
+        bi_foreach_dest(ins, d) {
+                pan_liveness_kill(live, bi_get_node(ins->dest[d]), max,
+                                bi_writemask(ins, d));
+        }
 
         bi_foreach_src(ins, src) {
                 unsigned count = bi_count_read_registers(ins, src);
index 4605d20..39fc5d7 100644 (file)
@@ -47,15 +47,22 @@ bi_opt_dead_code_eliminate(bi_context *ctx, bool soft)
                 uint16_t *live = mem_dup(block->base.live_out, temp_count * sizeof(uint16_t));
 
                 bi_foreach_instr_in_block_safe_rev(block, ins) {
-                        unsigned index = bi_get_node(ins->dest[0]);
+                        bool all_null = true;
 
-                        if (index < temp_count && !(live[index] & bi_writemask(ins))) {
-                                if (soft || bi_side_effects(ins->op))
-                                        ins->dest[0] = bi_null();
-                                else
-                                        bi_remove_instruction(ins);
+                        bi_foreach_dest(ins, d) {
+                                unsigned index = bi_get_node(ins->dest[d]);
 
-                                progress |= true;
+                                if (index < temp_count && !(live[index] & bi_writemask(ins, d))) {
+                                        ins->dest[d] = bi_null();
+                                        progress = true;
+                                }
+
+                                all_null &= bi_is_null(ins->dest[d]);
+                        }
+
+                        if (all_null && !soft && !bi_side_effects(ins->op)) {
+                                bi_remove_instruction(ins);
+                                progress = true;
                         }
 
                         bi_liveness_ins_update(live, ins, temp_count);
index eb77e35..9e89207 100644 (file)
@@ -42,11 +42,10 @@ bi_mark_sr_live(bi_block *block, bi_clause *clause, unsigned node_count, uint16_
         bi_foreach_instr_in_clause(block, clause, ins) {
                 if (!bi_opcode_props[ins->op].sr_write) continue;
 
-                bi_foreach_dest(ins, d) {
-                        unsigned node = bi_get_node(ins->dest[d]);
-                        if (node < node_count)
-                                live[node] = bi_writemask(ins);
-                }
+                /* Set liveness for dest 0 which is the staging register */
+                unsigned node = bi_get_node(ins->dest[0]);
+                if (node < node_count)
+                        live[node] = bi_writemask(ins, 0);
 
                 break;
         }
@@ -66,7 +65,7 @@ bi_mark_interference(bi_block *block, bi_clause *clause, struct lcra_state *l, u
                         for (unsigned i = 0; i < node_count; ++i) {
                                 if (live[i]) {
                                         lcra_add_node_interference(l, bi_get_node(ins->dest[d]),
-                                                        bi_writemask(ins), i, live[i]);
+                                                        bi_writemask(ins, d), i, live[i]);
                                 }
                         }
                 }
@@ -229,18 +228,6 @@ bi_rewrite_index_src_single(bi_instr *ins, bi_index old, bi_index new)
         }
 }
 
-static void
-bi_rewrite_index_dst_single(bi_instr *ins, bi_index old, bi_index new)
-{
-        bi_foreach_dest(ins, i) {
-                if (bi_is_equiv(ins->dest[i], old)) {
-                        ins->dest[i].type = new.type;
-                        ins->dest[i].reg = new.reg;
-                        ins->dest[i].value = new.value;
-                }
-        }
-}
-
 /* If register allocation fails, find the best spill node */
 
 static signed
@@ -306,12 +293,18 @@ bi_clause_mark_spill(bi_context *ctx, bi_block *block,
         unsigned channels = 0;
 
         bi_foreach_instr_in_clause(block, clause, ins) {
-                if (!bi_is_equiv(ins->dest[0], index)) continue;
-                if (bi_is_null(*temp)) *temp = bi_temp_reg(ctx);
-                ins->no_spill = true;
-                bi_rewrite_index_dst_single(ins, index, *temp);
-                unsigned newc = util_last_bit(bi_writemask(ins)) >> 2;
-                channels = MAX2(channels, newc);
+                bi_foreach_dest(ins, d) {
+                        if (!bi_is_equiv(ins->dest[d], index)) continue;
+                        if (bi_is_null(*temp)) *temp = bi_temp_reg(ctx);
+                        ins->no_spill = true;
+
+                        unsigned offset = ins->dest[d].offset;
+                        ins->dest[d] = bi_replace_index(ins->dest[d], *temp);
+                        ins->dest[d].offset = offset;
+
+                        unsigned newc = util_last_bit(bi_writemask(ins, d)) >> 2;
+                        channels = MAX2(channels, newc);
+                }
         }
 
         return channels;
index 567c7c1..3a62f55 100644 (file)
@@ -93,12 +93,12 @@ bi_count_read_registers(bi_instr *ins, unsigned s)
 }
 
 unsigned
-bi_writemask(bi_instr *ins)
+bi_writemask(bi_instr *ins, unsigned d)
 {
         /* Assume we write a scalar */
         unsigned mask = 0xF;
 
-        if (bi_opcode_props[ins->op].sr_write) {
+        if (d == 0 && bi_opcode_props[ins->op].sr_write) {
                 unsigned count = bi_count_staging_registers(ins);
 
                 /* TODO: this special case is even more special, TEXC has a
@@ -109,7 +109,7 @@ bi_writemask(bi_instr *ins)
                 mask = (1 << (count * 4)) - 1;
         }
 
-        unsigned shift = ins->dest[0].offset * 4; /* 32-bit words */
+        unsigned shift = ins->dest[d].offset * 4; /* 32-bit words */
         return (mask << shift);
 }
 
index 9a82d0f..044a562 100644 (file)
@@ -730,7 +730,7 @@ pan_next_block(pan_block *block)
 
 bool bi_has_arg(bi_instr *ins, bi_index arg);
 unsigned bi_count_read_registers(bi_instr *ins, unsigned src);
-unsigned bi_writemask(bi_instr *ins);
+unsigned bi_writemask(bi_instr *ins, unsigned dest);
 bi_clause * bi_next_clause(bi_context *ctx, pan_block *block, bi_clause *clause);
 bool bi_side_effects(enum bi_opcode op);