From 6322bc544ef68104f1cefc8bd483f1981ab7c7c7 Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Sun, 7 Mar 2021 01:58:46 +0000 Subject: [PATCH] pan/bi: Mark message-passing sources/dests live More general, same data race. Fixes: 44726101d1e ("pan/bi: Don't fill garbage") Signed-off-by: Alyssa Rosenzweig Tested-by: Icecream95 Part-of: --- src/panfrost/bifrost/bi_ra.c | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/src/panfrost/bifrost/bi_ra.c b/src/panfrost/bifrost/bi_ra.c index 2843b04..cde291c 100644 --- a/src/panfrost/bifrost/bi_ra.c +++ b/src/panfrost/bifrost/bi_ra.c @@ -29,23 +29,33 @@ #include "panfrost/util/lcra.h" #include "util/u_memory.h" -/* A clause may contain 1 message-passing instruction writing to a staging - * register. No instruction following it in the clause may access that staging - * register to prevent data races. Scheduling ensures this is possible but RA - * needs to preserve this. The simplest solution is forcing the staging - * register live in _all_ words at the end (and consequently throughout) the - * clause, addressing corner cases where a single component is masked out */ +/* A clause may contain 1 message-passing instruction. No subsequent + * instruction in the clause may access its registers due to data races. + * Scheduling ensures this is possible but RA needs to preserve this. The + * simplest solution is forcing accessed registers live in _all_ words at the + * end (and consequently throughout) the clause, addressing corner cases where + * a single component is masked out */ static void -bi_mark_sr_live(bi_block *block, bi_clause *clause, unsigned node_count, uint16_t *live) +bi_mark_msg_live(bi_block *block, bi_clause *clause, unsigned node_count, uint16_t *live) { bi_foreach_instr_in_clause(block, clause, ins) { - if (!bi_opcode_props[ins->op].sr_write) continue; + if (!bi_opcode_props[ins->op].message) continue; - /* 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); + bi_foreach_dest(ins, d) { + unsigned node = bi_get_node(ins->dest[d]); + if (node < node_count) + live[node] |= bi_writemask(ins, d); + } + + bi_foreach_src(ins, s) { + unsigned node = bi_get_node(ins->src[s]); + if (node < node_count) { + unsigned count = bi_count_read_registers(ins, s); + unsigned rmask = (1 << (4 * count)) - 1; + live[node] |= (rmask << (4 * ins->src[s].offset)); + } + } break; } @@ -102,7 +112,7 @@ bi_compute_interference(bi_context *ctx, struct lcra_state *l) uint16_t *live = mem_dup(_blk->live_out, node_count * sizeof(uint16_t)); bi_foreach_clause_in_block_rev(blk, clause) { - bi_mark_sr_live(blk, clause, node_count, live); + bi_mark_msg_live(blk, clause, node_count, live); bi_mark_interference(blk, clause, l, live, node_count, ctx->inputs->is_blend); } -- 2.7.4