freedreno/ir3: clean up dangling false-dep's
Maybe there is a better way for this.. where it comes useful is "array" loads, which end up as a false-dep for a later array store. If all the uses of an array load are CP'd into their consumer, it still leaves the dangling array load, leading to funny things like: mov.u32u32 r5.y, r0.y mov.u32u32 r5.y, r0.z Signed-off-by: Rob Clark <robdclark@gmail.com>
This commit is contained in:
@@ -360,6 +360,8 @@ struct ir3_instruction {
|
|||||||
/* Entry in ir3_block's instruction list: */
|
/* Entry in ir3_block's instruction list: */
|
||||||
struct list_head node;
|
struct list_head node;
|
||||||
|
|
||||||
|
int use_count; /* currently just updated/used by cp */
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
uint32_t serialno;
|
uint32_t serialno;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -309,6 +309,26 @@ lower_immed(struct ir3_cp_ctx *ctx, struct ir3_register *reg, unsigned new_flags
|
|||||||
return reg;
|
return reg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
unuse(struct ir3_instruction *instr)
|
||||||
|
{
|
||||||
|
debug_assert(instr->use_count > 0);
|
||||||
|
|
||||||
|
if (--instr->use_count == 0) {
|
||||||
|
struct ir3_block *block = instr->block;
|
||||||
|
|
||||||
|
instr->barrier_class = 0;
|
||||||
|
instr->barrier_conflict = 0;
|
||||||
|
|
||||||
|
/* we don't want to remove anything in keeps (which could
|
||||||
|
* be things like array store's)
|
||||||
|
*/
|
||||||
|
for (unsigned i = 0; i < block->keeps_count; i++) {
|
||||||
|
debug_assert(block->keeps[i] != instr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle cp for a given src register. This additionally handles
|
* Handle cp for a given src register. This additionally handles
|
||||||
* the cases of collapsing immedate/const (which replace the src
|
* the cases of collapsing immedate/const (which replace the src
|
||||||
@@ -339,6 +359,8 @@ reg_cp(struct ir3_cp_ctx *ctx, struct ir3_instruction *instr,
|
|||||||
|
|
||||||
instr->barrier_class |= src->barrier_class;
|
instr->barrier_class |= src->barrier_class;
|
||||||
instr->barrier_conflict |= src->barrier_conflict;
|
instr->barrier_conflict |= src->barrier_conflict;
|
||||||
|
|
||||||
|
unuse(src);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (is_same_type_mov(src) &&
|
} else if (is_same_type_mov(src) &&
|
||||||
@@ -558,6 +580,7 @@ instr_cp(struct ir3_cp_ctx *ctx, struct ir3_instruction *instr)
|
|||||||
instr->regs[2] = cond->regs[2];
|
instr->regs[2] = cond->regs[2];
|
||||||
instr->barrier_class |= cond->barrier_class;
|
instr->barrier_class |= cond->barrier_class;
|
||||||
instr->barrier_conflict |= cond->barrier_conflict;
|
instr->barrier_conflict |= cond->barrier_conflict;
|
||||||
|
unuse(cond);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -573,6 +596,27 @@ ir3_cp(struct ir3 *ir, struct ir3_shader_variant *so)
|
|||||||
.so = so,
|
.so = so,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* This is a bit annoying, and probably wouldn't be necessary if we
|
||||||
|
* tracked a reverse link from producing instruction to consumer.
|
||||||
|
* But we need to know when we've eliminated the last consumer of
|
||||||
|
* a mov, so we need to do a pass to first count consumers of a
|
||||||
|
* mov.
|
||||||
|
*/
|
||||||
|
list_for_each_entry (struct ir3_block, block, &ir->block_list, node) {
|
||||||
|
list_for_each_entry (struct ir3_instruction, instr, &block->instr_list, node) {
|
||||||
|
struct ir3_instruction *src;
|
||||||
|
|
||||||
|
/* by the way, we don't acount for false-dep's, so the CP
|
||||||
|
* pass should always happen before false-dep's are inserted
|
||||||
|
*/
|
||||||
|
debug_assert(instr->deps_count == 0);
|
||||||
|
|
||||||
|
foreach_ssa_src(src, instr) {
|
||||||
|
src->use_count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ir3_clear_mark(ir);
|
ir3_clear_mark(ir);
|
||||||
|
|
||||||
for (unsigned i = 0; i < ir->noutputs; i++) {
|
for (unsigned i = 0; i < ir->noutputs; i++) {
|
||||||
|
|||||||
Reference in New Issue
Block a user