[Mesa-dev] [PATCH v2 5/6] i965/vec4: Adjust spilling cost for consecutive instructions
Francisco Jerez
currojerez at riseup.net
Thu Jul 30 06:17:23 PDT 2015
Iago Toral Quiroga <itoral at igalia.com> writes:
> Previous patches made it so that we do not need to unspill the same vgrf
> with every instruction as long as these instructions come right after
> the register was spilled or unspilled. This means that actually spilling
> the register is now cheaper in these scenarios, so adjust the spilling
> cost calculation accordingly.
> ---
> .../drivers/dri/i965/brw_vec4_reg_allocate.cpp | 61 +++++++++++++++++++---
> 1 file changed, 55 insertions(+), 6 deletions(-)
>
> diff --git a/src/mesa/drivers/dri/i965/brw_vec4_reg_allocate.cpp b/src/mesa/drivers/dri/i965/brw_vec4_reg_allocate.cpp
> index 9a69fac..652a68c 100644
> --- a/src/mesa/drivers/dri/i965/brw_vec4_reg_allocate.cpp
> +++ b/src/mesa/drivers/dri/i965/brw_vec4_reg_allocate.cpp
> @@ -269,6 +269,21 @@ vec4_visitor::evaluate_spill_costs(float *spill_costs, bool *no_spill)
> {
> float loop_scale = 1.0;
>
> + /* If a spilled register is written (or unspilled) and then immediately read,
> + * we will avoid to emit scratch reads for that register for as long as
> + * consecutive instructions keep reading that register. This makes spilling
> + * the register cheaper, so we need to account for this here. Since any
> + * instruction can only have at most 3 src operands we can only have up to
> + * 3 cached registers (i.e. registers that we do not need to unspill if they
> + * are read in a consecutive instruction) at any given time.
> + *
> + * We keep two lists, cached[0] has the registers that are cached before
> + * the current instruction, and cached[1] has the registers that are
> + * cached after the current instruction. We copy cached[1] into cached[0]
> + * after processing each instruction.
> + */
> + int cached[2][3] = { -1, -1, -1, -1, -1, -1 };
> +
Wouldn't it be easier to drop the array and just compare the sources of
each instruction with the previous one?
> for (unsigned i = 0; i < this->alloc.count; i++) {
> spill_costs[i] = 0.0;
> no_spill[i] = alloc.sizes[i] != 1;
> @@ -279,18 +294,52 @@ vec4_visitor::evaluate_spill_costs(float *spill_costs, bool *no_spill)
> * loops run 10 times.
> */
> foreach_block_and_inst(block, vec4_instruction, inst, cfg) {
> + memset(cached[1], -1, sizeof(cached[1]));
> +
> for (unsigned int i = 0; i < 3; i++) {
> - if (inst->src[i].file == GRF) {
> - spill_costs[inst->src[i].reg] += loop_scale;
> - assert(!inst->src[i].reladdr);
> - }
> + if (inst->src[i].file == GRF) {
> + /* Don't increase spilling cost if src[i] isn't going
> + * to be unspilled
> + */
> + int slot;
> + for (slot = 0; slot < 3; slot++) {
> + if (inst->src[i].reg == cached[0][slot])
I guess this should take the reg_offset and writemask of the cached
register into account. I suggest you use backend_reg::in_range() to
check if there is overlap.
> + break;
> + }
> + if (slot == 3) {
> + /* Not cached, we will unspill src[i] */
> + spill_costs[inst->src[i].reg] += loop_scale;
> + assert(!inst->src[i].reladdr);
> + } else {
> + /* It is cached. Since it is read in this instruction it
> + * stays cached for the next.
> + */
> + cached[1][slot] = inst->src[i].reg;
> + }
> + }
> }
>
> if (inst->dst.file == GRF) {
> - spill_costs[inst->dst.reg] += loop_scale;
> - assert(!inst->dst.reladdr);
> + int slot;
> + /* Mark this reg as cached because if the next instruction reads it
> + * we won't unspill it.
> + */
> + for (slot = 0; slot < 3; slot++) {
> + if (cached[1][slot] == -1) {
> + cached[1][slot] = inst->dst.reg;
> + break;
> + }
> + }
> + assert(slot < 3);
> + spill_costs[inst->dst.reg] += loop_scale;
> + assert(!inst->dst.reladdr);
> }
>
> + /* Cached registers after this instruction are the cached registers
> + * for the next instruction
> + */
> + memcpy(cached[0], cached[1], sizeof(cached[0]));
> +
> switch (inst->opcode) {
>
> case BRW_OPCODE_DO:
> --
> 1.9.1
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 212 bytes
Desc: not available
URL: <http://lists.freedesktop.org/archives/mesa-dev/attachments/20150730/6a1910ba/attachment-0001.sig>
More information about the mesa-dev
mailing list