Rather than magic depth value, which won't be available in later stages. Signed-off-by: Rob Clark <robclark@freedesktop.org>tags/11.2-branchpoint
| @@ -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: | |||
| @@ -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; | |||
| } | |||
| } | |||
| @@ -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); | |||
| @@ -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; | |||