From: Alyssa Rosenzweig Date: Fri, 26 Jul 2019 16:37:58 +0000 (-0700) Subject: pan/midgard: Pipeline non-SSA registers X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c7fc5f35674f53f2ba4870ceaa367354e4849497;p=mesa.git pan/midgard: Pipeline non-SSA registers Rather than bailing if we see something that's not SSA, do out the analysis to check if we can pipeline and do so if we can. total registers in shared programs: 392 -> 391 (-0.26%) registers in affected programs: 3 -> 2 (-33.33%) helped: 1 HURT: 0 Signed-off-by: Alyssa Rosenzweig --- diff --git a/src/panfrost/midgard/midgard_ra_pipeline.c b/src/panfrost/midgard/midgard_ra_pipeline.c index cd64bdf29e5..7bbf8a93759 100644 --- a/src/panfrost/midgard/midgard_ra_pipeline.c +++ b/src/panfrost/midgard/midgard_ra_pipeline.c @@ -53,15 +53,37 @@ mir_pipeline_ins( if (ins->compact_branch) return false; - /* Don't allow non-SSA. Pipelining registers is theoretically possible, - * but the analysis is much hairier, so don't bother quite yet */ - if ((dest < 0) || (dest >= ctx->func->impl->ssa_alloc)) + /* We could be pipelining a register, so we need to make sure that all + * of the components read in this bundle are written in this bundle, + * and that no components are written before this bundle */ + + unsigned node = ins->ssa_args.dest; + unsigned read_mask = 0; + + /* Analyze the bundle for a read mask */ + + for (unsigned i = 0; i < bundle->instruction_count; ++i) { + midgard_instruction *q = bundle->instructions[i]; + read_mask |= mir_mask_of_read_components(q, node); + } + + /* Now analyze for a write mask */ + for (unsigned i = 0; i < bundle->instruction_count; ++i) { + midgard_instruction *q = bundle->instructions[i]; + if (q->ssa_args.dest != node) continue; + + /* Remove the written mask from the read requirements */ + read_mask &= ~q->mask; + } + + /* Check for leftovers */ + if (read_mask) return false; - /* Make sure they're not lying to us. Blend shaders lie. TODO: Fix your - * bad code Alyssa */ + /* Now, check outside the bundle */ + midgard_instruction *start = bundle->instructions[0]; - if (mir_has_multiple_writes(ctx, dest)) + if (mir_is_written_before(ctx, start, node)) return false; /* We want to know if we live after this bundle, so check if