From 26e2906382054073de7be88c5607a7bafceb1a62 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Tue, 26 Mar 2019 15:21:12 -0400 Subject: [PATCH] freedreno/ir3: reads/writes to unrelated arrays are not dependent Signed-off-by: Rob Clark --- src/freedreno/ir3/ir3_sched.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/freedreno/ir3/ir3_sched.c b/src/freedreno/ir3/ir3_sched.c index 94a7fed4c95..dd9567764f7 100644 --- a/src/freedreno/ir3/ir3_sched.c +++ b/src/freedreno/ir3/ir3_sched.c @@ -807,6 +807,20 @@ int ir3_sched(struct ir3 *ir) return 0; } +static unsigned +get_array_id(struct ir3_instruction *instr) +{ + /* The expectation is that there is only a single array + * src or dst, ir3_cp should enforce this. + */ + + for (unsigned i = 0; i < instr->regs_count; i++) + if (instr->regs[i]->flags & IR3_REG_ARRAY) + return instr->regs[i]->array.id; + + unreachable("this was unexpected"); +} + /* does instruction 'prior' need to be scheduled before 'instr'? */ static bool depends_on(struct ir3_instruction *instr, struct ir3_instruction *prior) @@ -819,7 +833,22 @@ depends_on(struct ir3_instruction *instr, struct ir3_instruction *prior) if (((instr->barrier_class & IR3_BARRIER_EVERYTHING) && prior->barrier_class) || ((prior->barrier_class & IR3_BARRIER_EVERYTHING) && instr->barrier_class)) return true; - return !!(instr->barrier_class & prior->barrier_conflict); + + if (instr->barrier_class & prior->barrier_conflict) { + if (!(instr->barrier_class & ~(IR3_BARRIER_ARRAY_R | IR3_BARRIER_ARRAY_W))) { + /* if only array barrier, then we can further limit false-deps + * by considering the array-id, ie reads/writes to different + * arrays do not depend on each other (no aliasing) + */ + if (get_array_id(instr) != get_array_id(prior)) { + return false; + } + } + + return true; + } + + return false; } static void -- 2.30.2