mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-02-23 22:40:34 +01:00
broadcom/compiler: remove unused leading ldunifa
This requires that we go back to the unifa write and update the address to jump over the unused leading component. Reviewed-by: Alejandro Piñeiro <apinheiro@igalia.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9128>
This commit is contained in:
parent
9d16d2d0be
commit
89de085055
1 changed files with 80 additions and 2 deletions
|
|
@ -91,7 +91,9 @@ vir_dce_flags(struct v3d_compile *c, struct qinst *inst)
|
|||
}
|
||||
|
||||
static bool
|
||||
is_last_ldunifa(struct v3d_compile *c, struct qinst *inst, struct qblock *block)
|
||||
check_last_ldunifa(struct v3d_compile *c,
|
||||
struct qinst *inst,
|
||||
struct qblock *block)
|
||||
{
|
||||
if (!inst->qpu.sig.ldunifa && !inst->qpu.sig.ldunifarf)
|
||||
return false;
|
||||
|
|
@ -116,6 +118,66 @@ is_last_ldunifa(struct v3d_compile *c, struct qinst *inst, struct qblock *block)
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
check_first_ldunifa(struct v3d_compile *c,
|
||||
struct qinst *inst,
|
||||
struct qblock *block,
|
||||
struct qinst **unifa)
|
||||
{
|
||||
if (!inst->qpu.sig.ldunifa && !inst->qpu.sig.ldunifarf)
|
||||
return false;
|
||||
|
||||
list_for_each_entry_from_rev(struct qinst, scan_inst, inst->link.prev,
|
||||
&block->instructions, link) {
|
||||
/* If we find a write to unifa, then this was the first
|
||||
* ldunifa in its sequence and is safe to remove.
|
||||
*/
|
||||
if (scan_inst->dst.file == QFILE_MAGIC &&
|
||||
scan_inst->dst.index == V3D_QPU_WADDR_UNIFA) {
|
||||
*unifa = scan_inst;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* If we find another ldunifa in the same sequence then we
|
||||
* can't remove it.
|
||||
*/
|
||||
if (scan_inst->qpu.sig.ldunifa || scan_inst->qpu.sig.ldunifarf)
|
||||
return false;
|
||||
}
|
||||
|
||||
unreachable("could not find starting unifa for ldunifa sequence");
|
||||
}
|
||||
|
||||
static bool
|
||||
increment_unifa_address(struct v3d_compile *c, struct qinst *unifa)
|
||||
{
|
||||
if (unifa->qpu.type == V3D_QPU_INSTR_TYPE_ALU &&
|
||||
unifa->qpu.alu.mul.op == V3D_QPU_M_MOV) {
|
||||
c->cursor = vir_after_inst(unifa);
|
||||
struct qreg unifa_reg = vir_reg(QFILE_MAGIC, V3D_QPU_WADDR_UNIFA);
|
||||
vir_ADD_dest(c, unifa_reg, unifa->src[0], vir_uniform_ui(c, 4u));
|
||||
vir_remove_instruction(c, unifa);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* FIXME: we can optimize this further by implementing a constant
|
||||
* ALU pass in the backend, for the case where we are skipping
|
||||
* multiple leading ldunifa.
|
||||
*/
|
||||
if (unifa->qpu.type == V3D_QPU_INSTR_TYPE_ALU &&
|
||||
unifa->qpu.alu.add.op == V3D_QPU_A_ADD) {
|
||||
c->cursor = vir_after_inst(unifa);
|
||||
struct qreg unifa_reg = vir_reg(QFILE_MAGIC, V3D_QPU_WADDR_UNIFA);
|
||||
struct qreg tmp =
|
||||
vir_ADD(c, unifa->src[1], vir_uniform_ui(c, 4u));
|
||||
vir_ADD_dest(c, unifa_reg, unifa->src[0], tmp);
|
||||
vir_remove_instruction(c, unifa);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
vir_opt_dead_code(struct v3d_compile *c)
|
||||
{
|
||||
|
|
@ -151,8 +213,15 @@ vir_opt_dead_code(struct v3d_compile *c)
|
|||
continue;
|
||||
}
|
||||
|
||||
const bool is_last_ldunifa =
|
||||
check_last_ldunifa(c, inst, block);
|
||||
|
||||
struct qinst *unifa = NULL;
|
||||
const bool is_first_ldunifa =
|
||||
check_first_ldunifa(c, inst, block, &unifa);
|
||||
|
||||
if (vir_has_side_effects(c, inst) &&
|
||||
!is_last_ldunifa(c, inst, block)) {
|
||||
!is_last_ldunifa && !is_first_ldunifa) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -195,6 +264,15 @@ vir_opt_dead_code(struct v3d_compile *c)
|
|||
continue;
|
||||
}
|
||||
|
||||
/* If we are removing the first ldunifa in a sequence
|
||||
* we need to update the unifa address.
|
||||
*/
|
||||
if (is_first_ldunifa) {
|
||||
assert(unifa);
|
||||
if (!increment_unifa_address(c, unifa))
|
||||
continue;
|
||||
}
|
||||
|
||||
assert(inst != last_flags_write);
|
||||
dce(c, inst);
|
||||
progress = true;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue