summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>2021-01-07 18:02:40 -0500
committerMarge Bot <eric+marge@anholt.net>2021-01-29 16:55:43 +0000
commit44726101d1e8c28c2aba2f4eda651840ab099bb3 (patch)
treef01605b0263074bade4faba7d4287f7c9b0245fd
parentee7aaa27b814343c91705d68de6eebadbe65830b (diff)
pan/bi: Don't fill garbage
If an index is an SSA form and we haven't even written to it yet, there is absolutely no value in filling it, it'd just be uninitialized garbage that won't get used. Saves some fills in STK. 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/8723>
-rw-r--r--src/panfrost/bifrost/bi_ra.c38
1 files changed, 35 insertions, 3 deletions
diff --git a/src/panfrost/bifrost/bi_ra.c b/src/panfrost/bifrost/bi_ra.c
index 4768171d363..ed2b1c3de71 100644
--- a/src/panfrost/bifrost/bi_ra.c
+++ b/src/panfrost/bifrost/bi_ra.c
@@ -29,6 +29,29 @@
#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 */
+
+static void
+bi_mark_sr_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;
+
+ bi_foreach_dest(ins, d) {
+ unsigned node = bi_get_node(ins->dest[d]);
+ if (node < node_count)
+ live[node] = bi_writemask(ins);
+ }
+
+ break;
+ }
+}
+
static void
bi_mark_interference(bi_block *block, bi_clause *clause, struct lcra_state *l, uint16_t *live, unsigned node_count, bool is_blend)
{
@@ -80,6 +103,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_interference(blk, clause, l, live, node_count, ctx->is_blend);
}
@@ -330,9 +354,17 @@ bi_spill_register(bi_context *ctx, bi_index index, uint32_t offset)
clause, block, channels);
}
- if (bi_clause_mark_fill(ctx, block, clause, index, &tmp)) {
- bi_fill_src(&_b, index, tmp, offset,
- clause, block, channels);
+ /* For SSA form, if we write/spill, there was no prior
+ * contents to fill, so don't waste time reading
+ * garbage */
+
+ bool should_fill = !local_channels || index.reg;
+ should_fill &= bi_clause_mark_fill(ctx, block, clause,
+ index, &tmp);
+
+ if (should_fill) {
+ bi_fill_src(&_b, index, tmp, offset, clause,
+ block, channels);
}
}
}