broadcom/compiler: fix ldunif optimization
When we look back for a previous uniform definition we want to
start looking from the current position of the cursor, not the
end of the current block. The latter only works when translating
from NIR, since in that case both always match, but any optimization
pass may rewrite code and emit uniforms at any place in the middle of
the program.
Also, ntq_store_dest expects result to be written by the last instruction
to handle the case where it is stored to a NIR register. That won't be
the case if the result comes from an optimized uniform, so in that case
we need to insert a MOV, like we do in non-uniform control flow.
v2: fix ntq_store_dest for optimized uniforms.
Fixes: 14af7b3085 ('broadcom/compiler: don't emit redundant ldunif')
Reviewed-by: Alejandro Piñeiro <apinheiro@igalia.com>
Acked-by: Eric Anholt <eric@anholt.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9128>
This commit is contained in:
committed by
Marge Bot
parent
9f30370654
commit
e20ae14978
@@ -655,6 +655,12 @@ is_ld_signal(const struct v3d_qpu_sig *sig)
|
||||
sig->ldtlbu);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
is_ldunif_signal(const struct v3d_qpu_sig *sig)
|
||||
{
|
||||
return sig->ldunif || sig->ldunifrf;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is responsible for getting VIR results into the associated
|
||||
* storage for a NIR instruction.
|
||||
@@ -678,8 +684,12 @@ ntq_store_dest(struct v3d_compile *c, nir_dest *dest, int chan,
|
||||
if (!list_is_empty(&c->cur_block->instructions))
|
||||
last_inst = (struct qinst *)c->cur_block->instructions.prev;
|
||||
|
||||
assert((result.file == QFILE_TEMP &&
|
||||
last_inst && last_inst == c->defs[result.index]));
|
||||
bool is_reused_uniform =
|
||||
is_ldunif_signal(&c->defs[result.index]->qpu.sig) &&
|
||||
last_inst != c->defs[result.index];
|
||||
|
||||
assert(result.file == QFILE_TEMP && last_inst &&
|
||||
(last_inst == c->defs[result.index] || is_reused_uniform));
|
||||
|
||||
if (dest->is_ssa) {
|
||||
assert(chan < dest->ssa.num_components);
|
||||
@@ -706,8 +716,9 @@ ntq_store_dest(struct v3d_compile *c, nir_dest *dest, int chan,
|
||||
* the store into the nir_register, then emit a MOV
|
||||
* that can be.
|
||||
*/
|
||||
if (vir_in_nonuniform_control_flow(c) &&
|
||||
is_ld_signal(&c->defs[last_inst->dst.index]->qpu.sig)) {
|
||||
if (is_reused_uniform ||
|
||||
(vir_in_nonuniform_control_flow(c) &&
|
||||
is_ld_signal(&c->defs[last_inst->dst.index]->qpu.sig))) {
|
||||
result = vir_MOV(c, result);
|
||||
last_inst = c->defs[result.index];
|
||||
}
|
||||
|
||||
@@ -1416,7 +1416,8 @@ try_opt_ldunif(struct v3d_compile *c, uint32_t index, struct qreg *unif)
|
||||
{
|
||||
uint32_t count = 20;
|
||||
struct qinst *prev_inst = NULL;
|
||||
vir_for_each_inst_rev(inst, c->cur_block) {
|
||||
list_for_each_entry_from_rev(struct qinst, inst, c->cursor.link->prev,
|
||||
&c->cur_block->instructions, link) {
|
||||
if ((inst->qpu.sig.ldunif || inst->qpu.sig.ldunifrf) &&
|
||||
inst->uniform == index) {
|
||||
prev_inst = inst;
|
||||
|
||||
Reference in New Issue
Block a user