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