broadcom/compiler: make spills of conditional writes also conditional
A spill of a conditional write generates code like this: mov.ifa t5000, 0 mov tmud, t5000 nop t5001; ldunif (0x00008100 / 0.000000) add tmua, t11, t5001 Here, we are spilling t5000, which has a conditional write, and we produce an inconditional spill for it. This implicitly means that our spill requires a correct value for all channels of t5000. If we do a conditional spill, then we emit: mov.ifa t5000, 0 mov tmud.ifa, t5000 nop t5001; ldunif (0x00008100 / 0.000000) add tmua.ifa, t11, t5001 Which only uses channels of t5000 that have been written by the instruction being spilled. By doing the latter, we can then narrow down the liveness for t5000 more effectively, as we can use this to detect that the block only reads (in the tmud instruction) the values that have been written previously in the same block (in the mov instruction). This means that values in other channels are not used, and therefore, we don't need them to be alive at the start of the block. This means that if this is the only write of t5000 in this block, we can consider that the block completely defines t5000. Reviewed-by: Alejandro Piñeiro <apinheiro@igalia.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12278>
This commit is contained in:

committed by
Marge Bot

parent
314eb97dcb
commit
c335c03ae2
@@ -214,13 +214,11 @@ v3d_setup_spill_base(struct v3d_compile *c)
|
||||
c->cursor = vir_after_block(c->cur_block);
|
||||
}
|
||||
|
||||
static void
|
||||
static struct qinst *
|
||||
v3d_emit_spill_tmua(struct v3d_compile *c, uint32_t spill_offset)
|
||||
{
|
||||
vir_ADD_dest(c, vir_reg(QFILE_MAGIC,
|
||||
V3D_QPU_WADDR_TMUA),
|
||||
c->spill_base,
|
||||
vir_uniform_ui(c, spill_offset));
|
||||
return vir_ADD_dest(c, vir_reg(QFILE_MAGIC, V3D_QPU_WADDR_TMUA),
|
||||
c->spill_base, vir_uniform_ui(c, spill_offset));
|
||||
}
|
||||
|
||||
|
||||
@@ -228,12 +226,17 @@ static void
|
||||
v3d_emit_tmu_spill(struct v3d_compile *c, struct qinst *inst,
|
||||
struct qinst *position, uint32_t spill_offset)
|
||||
{
|
||||
assert(inst->qpu.type == V3D_QPU_INSTR_TYPE_ALU);
|
||||
|
||||
c->cursor = vir_after_inst(position);
|
||||
inst->dst = vir_get_temp(c);
|
||||
vir_MOV_dest(c, vir_reg(QFILE_MAGIC,
|
||||
V3D_QPU_WADDR_TMUD),
|
||||
inst->dst);
|
||||
v3d_emit_spill_tmua(c, spill_offset);
|
||||
enum v3d_qpu_cond cond = vir_get_cond(inst);
|
||||
struct qinst *tmp =
|
||||
vir_MOV_dest(c, vir_reg(QFILE_MAGIC, V3D_QPU_WADDR_TMUD),
|
||||
inst->dst);
|
||||
tmp->qpu.flags.mc = cond;
|
||||
tmp = v3d_emit_spill_tmua(c, spill_offset);
|
||||
tmp->qpu.flags.ac = cond;
|
||||
vir_emit_thrsw(c);
|
||||
vir_TMUWT(c);
|
||||
c->spills++;
|
||||
|
Reference in New Issue
Block a user