Rather than magic depth value, which won't be available in later stages.
Signed-off-by: Rob Clark <robclark@freedesktop.org>
* before register assignment is done:
*/
IR3_INSTR_MARK = 0x1000,
+ IR3_INSTR_UNUSED= 0x2000,
} flags;
int repeat;
#ifdef DEBUG
* 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:
/* 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);
}
*/
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;
}
}
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)
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;
*/
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;
*sz = MAX2(*sz, dsz);
*off = doff;
- if (dd->ip < d->ip) {
+ if (instr_before(dd, d)) {
d = dd;
}
}
foreach_src(src, d) {
if (!src->instr)
continue;
- if (src->instr->ip < dd->ip)
+ if (instr_before(src->instr, dd))
dd = src->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);
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;