diff options
author | Rob Clark <[email protected]> | 2020-03-11 15:06:51 -0700 |
---|---|---|
committer | Marge Bot <[email protected]> | 2020-06-16 20:56:15 +0000 |
commit | 9eed0c601137a6657d6c0de4c2362549456f9465 (patch) | |
tree | a1a887a226e7e33d0a7e91a6d0967cd74082428b /src | |
parent | c3b30963dd7fbca6bbc849f9f89bc0dec4b3fc1e (diff) |
freedreno/ir3/delay: calculate delay properly for (rptN)'d instructions
When a sequence of same instruction is encoded with repeat flag,
destination registers are written on successive cycles. Teach the
delay calculation about this.
Signed-off-by: Rob Clark <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5280>
Diffstat (limited to 'src')
-rw-r--r-- | src/freedreno/ir3/ir3_delay.c | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/src/freedreno/ir3/ir3_delay.c b/src/freedreno/ir3/ir3_delay.c index 2ea8ee5ed6e..247ff6ee250 100644 --- a/src/freedreno/ir3/ir3_delay.c +++ b/src/freedreno/ir3/ir3_delay.c @@ -197,13 +197,35 @@ delay_calc_srcn(struct ir3_block *block, unsigned delay = 0; if (is_meta(assigner)) { - foreach_src (src, assigner) { + foreach_src_n (src, n, assigner) { unsigned d; if (!src->instr) continue; d = delay_calc_srcn(block, src->instr, consumer, srcn, soft, pred); + + /* A (rptN) instruction executes in consecutive cycles so + * it's outputs are written in successive cycles. And + * likewise for it's (r)'d (incremented) inputs, they are + * read on successive cycles. + * + * So we need to adjust the delay for (rptN)'s assigners + * and consumers accordingly. + * + * Note that the dst of a (rptN) instruction is implicitly + * (r) (the assigner case), although that is not the case + * for src registers. There is exactly one case, bary.f, + * which has a vecN (collect) src that is not (r)'d. + */ + if ((assigner->opc == OPC_META_SPLIT) && src->instr->repeat) { + /* (rptN) assigner case: */ + d -= MIN2(d, src->instr->repeat - assigner->split.off); + } else if ((assigner->opc == OPC_META_COLLECT) && consumer->repeat && + (consumer->regs[srcn]->flags & IR3_REG_R)) { + d -= MIN2(d, n); + } + delay = MAX2(delay, d); } } else { |