Mesa (main): pan/midg: Add intra-bundle interferences

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Feb 4 23:24:20 UTC 2022


Module: Mesa
Branch: main
Commit: 967eb4988e444f881e63f80f843e8573576cd802
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=967eb4988e444f881e63f80f843e8573576cd802

Author: Boris Brezillon <boris.brezillon at collabora.com>
Date:   Mon Sep  6 11:49:10 2021 +0200

pan/midg: Add intra-bundle interferences

The register allocator assumes instructions are executed sequentially
and allows one instruction to overwrite a portion of a register written
by a previous instruction if this portion is never used. But scalar and
vector ALUs might be executed in parallel if they are part of the same
bundle, and when such instructions write to the same portion of the
register file, the result is undefined.

Let's add intra-bundle interferences to avoid this situation.

Signed-off-by: Boris Brezillon <boris.brezillon at collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14885>

---

 src/panfrost/midgard/midgard_ra.c | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/src/panfrost/midgard/midgard_ra.c b/src/panfrost/midgard/midgard_ra.c
index 704cfc87466..40605df8f42 100644
--- a/src/panfrost/midgard/midgard_ra.c
+++ b/src/panfrost/midgard/midgard_ra.c
@@ -350,6 +350,44 @@ mir_compute_interference(
 
         mir_foreach_block(ctx, _blk) {
                 midgard_block *blk = (midgard_block *) _blk;
+
+                /* The scalar and vector units run in parallel. We need to make
+                 * sure they don't write to same portion of the register file
+                 * otherwise the result is undefined. Add interferences to
+                 * avoid this situation.
+                 */
+                util_dynarray_foreach(&blk->bundles, midgard_bundle, bundle) {
+                        midgard_instruction *instrs[2][3];
+                        unsigned instr_count[2] = { 0, 0 };
+
+                        for (unsigned i = 0; i < bundle->instruction_count; i++) {
+                                if (bundle->instructions[i]->unit == UNIT_VMUL ||
+                                    bundle->instructions[i]->unit == UNIT_SADD)
+                                        instrs[0][instr_count[0]++] = bundle->instructions[i];
+                                else
+                                        instrs[1][instr_count[1]++] = bundle->instructions[i];
+                        }
+
+                        for (unsigned i = 0; i < ARRAY_SIZE(instr_count); i++) {
+                                for (unsigned j = 0; j < instr_count[i]; j++) {
+                                        midgard_instruction *ins_a = instrs[i][j];
+
+                                        if (ins_a->dest >= ctx->temp_count) continue;
+
+                                        for (unsigned k = j + 1; k < instr_count[i]; k++) {
+                                                midgard_instruction *ins_b = instrs[i][k];
+
+                                                if (ins_b->dest >= ctx->temp_count) continue;
+
+                                                lcra_add_node_interference(l, ins_b->dest,
+                                                                           mir_bytemask(ins_b),
+                                                                           ins_a->dest,
+                                                                           mir_bytemask(ins_a));
+                                        }
+                                }
+                        }
+                }
+
                 uint16_t *live = mem_dup(_blk->live_out, ctx->temp_count * sizeof(uint16_t));
 
                 mir_foreach_instr_in_block_rev(blk, ins) {



More information about the mesa-commit mailing list