diff options
Diffstat (limited to 'src/freedreno')
-rw-r--r-- | src/freedreno/ir3/ir3_depth.c | 27 | ||||
-rw-r--r-- | src/freedreno/ir3/ir3_ra.c | 2 |
2 files changed, 29 insertions, 0 deletions
diff --git a/src/freedreno/ir3/ir3_depth.c b/src/freedreno/ir3/ir3_depth.c index 73bf5e19926..77f9af6173f 100644 --- a/src/freedreno/ir3/ir3_depth.c +++ b/src/freedreno/ir3/ir3_depth.c @@ -174,6 +174,33 @@ remove_unused_by_block(struct ir3_block *block) if (instr->opc == OPC_END) continue; if (instr->flags & IR3_INSTR_UNUSED) { + if (instr->opc == OPC_META_FO) { + struct ir3_instruction *src = ssa(instr->regs[1]); + if (src->regs[0]->wrmask > 1) { + unsigned newn, lastn; + + lastn = util_last_bit(src->regs[0]->wrmask); + src->regs[0]->wrmask &= ~(1 << instr->fo.off); + newn = util_last_bit(src->regs[0]->wrmask); + + /* prune no-longer needed right-neighbors. We could + * probably do the same for left-neighbors (ie. tex + * fetch that only need .yw components), but that + * makes RA a bit more confusing than it already is + */ + if (newn < lastn) { + struct ir3_instruction *n = ir3_neighbor_first(instr); + for (unsigned i = 1; i < newn; i++) { + n = n->cp.right; + } + // XXX I don't think n should be null here! + if (n) { + debug_assert(n->cp.right->flags & IR3_INSTR_UNUSED); + n->cp.right = NULL; + } + } + } + } list_delinit(&instr->node); progress = true; } diff --git a/src/freedreno/ir3/ir3_ra.c b/src/freedreno/ir3/ir3_ra.c index ad09c4018d3..b202c141378 100644 --- a/src/freedreno/ir3/ir3_ra.c +++ b/src/freedreno/ir3/ir3_ra.c @@ -509,6 +509,8 @@ get_definer(struct ir3_ra_ctx *ctx, struct ir3_instruction *instr, d = dd; } + debug_assert(d->opc != OPC_META_FO); + id->defn = d; id->sz = *sz; id->off = *off; |