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 <robclark@freedesktop.org>
This commit is contained in:
Rob Clark 2015-11-26 12:25:18 -05:00
parent 2fbe4e7d2f
commit 2181f2cd58
4 changed files with 24 additions and 14 deletions

View file

@ -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:

View file

@ -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;
}
}

View file

@ -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);

View file

@ -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;