ir3/ra: reset merge set preferred reg when unavailable

When a reg's merge set has a preferred reg but is currently unavailable,
it's often preferable to reset its preferred reg and assign a new one,
as this potentially reduces the number of movs needed for the as of yet
unallocated regs.

Totals from 18278 (11.10% of 164705) affected shaders:
Instrs: 14380961 -> 14340094 (-0.28%); split: -0.58%, +0.29%
CodeSize: 28522270 -> 28460942 (-0.22%); split: -0.44%, +0.23%
NOPs: 2771602 -> 2759456 (-0.44%); split: -1.17%, +0.73%
MOVs: 589951 -> 577832 (-2.05%); split: -6.63%, +4.57%
COVs: 233094 -> 232938 (-0.07%); split: -0.11%, +0.05%
Full: 276629 -> 276632 (+0.00%); split: -0.00%, +0.00%
(ss): 364508 -> 365702 (+0.33%); split: -0.73%, +1.06%
(sy): 177032 -> 176310 (-0.41%); split: -0.98%, +0.57%
(ss)-stall: 1512210 -> 1512312 (+0.01%); split: -0.92%, +0.93%
(sy)-stall: 5783986 -> 5723012 (-1.05%); split: -1.93%, +0.88%
Preamble Instrs: 2905654 -> 2904919 (-0.03%); split: -0.09%, +0.07%
Last helper: 3397081 -> 3390054 (-0.21%); split: -0.57%, +0.36%
Last baryf: 136198 -> 136439 (+0.18%); split: -0.07%, +0.25%
Cat0: 3061954 -> 3051187 (-0.35%); split: -1.11%, +0.76%
Cat1: 874681 -> 843044 (-3.62%); split: -6.57%, +2.96%
Cat2: 5226994 -> 5226663 (-0.01%); split: -0.01%, +0.00%
Cat7: 357258 -> 359126 (+0.52%); split: -0.33%, +0.85%

Signed-off-by: Job Noorman <jnoorman@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/37811>
This commit is contained in:
Job Noorman 2025-10-10 11:25:30 +02:00 committed by Marge Bot
parent f58b24467a
commit c544f42a79
3 changed files with 33 additions and 0 deletions

View file

@ -1438,6 +1438,33 @@ rpt_has_unique_merge_set(struct ir3_instruction *instr)
return true;
}
/* Handles this case when a reg's merge set has a preferred reg but is currently
* unavailable. In this case, it's often preferable to reset its preferred reg
* and assign a new one, as this potentially reduces the number of movs needed
* for the as of yet unallocated regs.
*/
void
ir3_ra_handle_unavailable_merge_set(struct ir3_register *reg)
{
unsigned num_unallocated = 0;
for (unsigned i = 0; i < reg->merge_set->regs_count; i++) {
if (reg->merge_set->regs[i]->num == INVALID_REG) {
num_unallocated++;
/* Only reset the preferred reg if there are at least two still
* unallocated regs. It doesn't make sense to reassign the merge set
* for a single reg, and increasing the bound more doesn't seem to
* improve shader stats.
*/
if (num_unallocated >= 2) {
reg->merge_set->preferred_reg = (physreg_t)~0;
return;
}
}
}
}
/* This is the main entrypoint for picking a register. Pick a free register
* for "reg", shuffling around sources if necessary. In the normal case where
* "is_source" is false, this register can overlap with killed sources
@ -1458,6 +1485,8 @@ get_reg(struct ra_ctx *ctx, struct ra_file *file, struct ir3_register *reg)
preferred_reg % reg_elem_size(reg) == 0 &&
get_reg_specified(ctx, file, reg, preferred_reg, false))
return preferred_reg;
ir3_ra_handle_unavailable_merge_set(reg);
}
/* For repeated instructions whose merge set is unique (i.e., only used for

View file

@ -294,4 +294,6 @@ void ir3_reg_interval_remove_all(struct ir3_reg_ctx *ctx,
void ra_update_affinity(unsigned file_size, struct ir3_register *reg,
physreg_t physreg);
void ir3_ra_handle_unavailable_merge_set(struct ir3_register *reg);
#endif

View file

@ -677,6 +677,8 @@ get_reg(struct ra_ctx *ctx, struct ir3_register *reg, bool src)
preferred_reg % reg_elem_size(reg) == 0 &&
get_reg_specified(ctx, reg, preferred_reg))
return preferred_reg;
ir3_ra_handle_unavailable_merge_set(reg);
}
/* If this register is a subset of a merge set which we have not picked a