pan/bi: Mark message-passing sources/dests live

More general, same data race.

Fixes: 44726101d1 ("pan/bi: Don't fill garbage")
Signed-off-by: Alyssa Rosenzweig <alyssa@collabora.com>
Tested-by: Icecream95 <ixn@disroot.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9446>
This commit is contained in:
Alyssa Rosenzweig 2021-03-07 01:58:46 +00:00
parent 91755300ec
commit 6322bc544e

View file

@ -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);
}