From 2181f2cd58f2af1e216618fc6889e23697cec325 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Thu, 26 Nov 2015 12:25:18 -0500 Subject: [PATCH] freedreno/ir3: use instr flag to mark unused instructions Rather than magic depth value, which won't be available in later stages. Signed-off-by: Rob Clark --- src/gallium/drivers/freedreno/ir3/ir3.h | 5 +--- src/gallium/drivers/freedreno/ir3/ir3_depth.c | 6 ++--- src/gallium/drivers/freedreno/ir3/ir3_ra.c | 25 ++++++++++++++----- src/gallium/drivers/freedreno/ir3/ir3_sched.c | 2 +- 4 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/gallium/drivers/freedreno/ir3/ir3.h b/src/gallium/drivers/freedreno/ir3/ir3.h index 12f2ebe18db..cac7d4d6e58 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3.h +++ b/src/gallium/drivers/freedreno/ir3/ir3.h @@ -177,6 +177,7 @@ struct ir3_instruction { * before register assignment is done: */ IR3_INSTR_MARK = 0x1000, + IR3_INSTR_UNUSED= 0x2000, } flags; int repeat; #ifdef DEBUG @@ -243,11 +244,7 @@ struct ir3_instruction { * result of moving a const to a reg would have a low cost, so to * it could make sense to duplicate the instruction at various * points where the result is needed to reduce register footprint. - * - * DEPTH_UNUSED used to mark unused instructions after depth - * calculation pass. */ -#define DEPTH_UNUSED ~0 unsigned depth; /* When we get to the RA stage, we no longer need depth, but * we do need instruction's position/name: diff --git a/src/gallium/drivers/freedreno/ir3/ir3_depth.c b/src/gallium/drivers/freedreno/ir3/ir3_depth.c index 97df0c2ac99..4bbc0458790 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_depth.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_depth.c @@ -139,7 +139,7 @@ remove_unused_by_block(struct ir3_block *block) /* mark it, in case it is input, so we can * remove unused inputs: */ - instr->depth = DEPTH_UNUSED; + instr->flags |= IR3_INSTR_UNUSED; /* and remove from instruction list: */ list_delinit(&instr->node); } @@ -175,14 +175,14 @@ ir3_depth(struct ir3 *ir) */ for (i = 0; i < ir->indirects_count; i++) { struct ir3_instruction *instr = ir->indirects[i]; - if (instr->depth == DEPTH_UNUSED) + if (instr->flags & IR3_INSTR_UNUSED) ir->indirects[i] = NULL; } /* cleanup unused inputs: */ for (i = 0; i < ir->ninputs; i++) { struct ir3_instruction *in = ir->inputs[i]; - if (in && (in->depth == DEPTH_UNUSED)) + if (in && (in->flags & IR3_INSTR_UNUSED)) ir->inputs[i] = NULL; } } diff --git a/src/gallium/drivers/freedreno/ir3/ir3_ra.c b/src/gallium/drivers/freedreno/ir3/ir3_ra.c index 88018398e96..ae7282e0b5b 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_ra.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_ra.c @@ -314,6 +314,14 @@ writes_gpr(struct ir3_instruction *instr) return is_temp(instr->regs[0]); } +static bool +instr_before(struct ir3_instruction *a, struct ir3_instruction *b) +{ + if (a->flags & IR3_INSTR_UNUSED) + return false; + return (a->ip < b->ip); +} + static struct ir3_instruction * get_definer(struct ir3_ra_ctx *ctx, struct ir3_instruction *instr, int *sz, int *off) @@ -348,7 +356,7 @@ get_definer(struct ir3_ra_ctx *ctx, struct ir3_instruction *instr, dd = get_definer(ctx, src->instr, &dsz, &doff); - if ((!d) || (dd->ip < d->ip)) { + if ((!d) || instr_before(dd, d)) { d = dd; *sz = dsz; *off = doff - n; @@ -369,9 +377,14 @@ get_definer(struct ir3_ra_ctx *ctx, struct ir3_instruction *instr, */ int cnt = 0; - d = f; + /* need to skip over unused in the group: */ + while (f && (f->flags & IR3_INSTR_UNUSED)) { + f = f->cp.right; + cnt++; + } + while (f) { - if (f->ip < d->ip) + if ((!d) || instr_before(f, d)) d = f; if (f == instr) *off = cnt; @@ -414,7 +427,7 @@ get_definer(struct ir3_ra_ctx *ctx, struct ir3_instruction *instr, *sz = MAX2(*sz, dsz); *off = doff; - if (dd->ip < d->ip) { + if (instr_before(dd, d)) { d = dd; } } @@ -432,7 +445,7 @@ get_definer(struct ir3_ra_ctx *ctx, struct ir3_instruction *instr, foreach_src(src, d) { if (!src->instr) continue; - if (src->instr->ip < dd->ip) + if (instr_before(src->instr, dd)) dd = src->instr; } @@ -446,7 +459,7 @@ get_definer(struct ir3_ra_ctx *ctx, struct ir3_instruction *instr, dd = get_definer(ctx, d->regs[1]->instr, &dsz, &doff); /* by definition, should come before: */ - debug_assert(dd->ip < d->ip); + debug_assert(instr_before(dd, d)); *sz = MAX2(*sz, dsz); diff --git a/src/gallium/drivers/freedreno/ir3/ir3_sched.c b/src/gallium/drivers/freedreno/ir3/ir3_sched.c index 2ee325518f7..08f5cac0cf4 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_sched.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_sched.c @@ -246,7 +246,7 @@ instr_eligibility(struct ir3_sched_ctx *ctx, struct ir3_sched_notes *notes, for (unsigned i = 0; i < ir->baryfs_count; i++) { struct ir3_instruction *baryf = ir->baryfs[i]; - if (baryf->depth == DEPTH_UNUSED) + if (baryf->flags & IR3_INSTR_UNUSED) continue; if (!is_scheduled(baryf)) { notes->blocked_kill = true; -- 2.30.2