aco: prefer spilling smaller temporaries if it finishes spilling

fossil-db stats seemed less positive when updating process_block() too.

fossil-db (navi31):
Totals from 41 (0.05% of 84369) affected shaders:
Instrs: 294758 -> 294694 (-0.02%); split: -0.11%, +0.09%
CodeSize: 1566136 -> 1564392 (-0.11%); split: -0.21%, +0.10%
SpillSGPRs: 2306 -> 2143 (-7.07%); split: -8.37%, +1.30%
Latency: 3877251 -> 3868194 (-0.23%); split: -0.29%, +0.05%
InvThroughput: 881747 -> 882352 (+0.07%); split: -0.01%, +0.08%
SClause: 6498 -> 6494 (-0.06%); split: -0.09%, +0.03%
Copies: 33582 -> 33900 (+0.95%); split: -0.23%, +1.18%
Branches: 6799 -> 6801 (+0.03%)
VALU: 192977 -> 192646 (-0.17%); split: -0.21%, +0.04%
SALU: 28082 -> 28395 (+1.11%); split: -0.27%, +1.39%
VOPD: 1939 -> 1959 (+1.03%); split: +1.19%, -0.15%

Signed-off-by: Rhys Perry <pendingchaos02@gmail.com>
Reviewed-by: Daniel Schürmann <daniel@schuermann.dev>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39690>
This commit is contained in:
Rhys Perry 2026-01-15 15:31:07 +00:00 committed by Marge Bot
parent 0ffbc30d7f
commit 176b075129

View file

@ -169,6 +169,12 @@ struct spill_ctx {
return next_spill_id++;
}
std::pair<int, float> get_score(Temp var, RegisterDemand spills_needed)
{
int wasted = MAX2((int)var.size() - spills_needed[var.type()], 0);
return {-wasted, ssa_infos[var.id()].score()};
}
uint32_t next_spill_id = 0;
};
@ -373,7 +379,7 @@ init_live_in_vars(spill_ctx& ctx, Block* block, unsigned block_idx)
spills_needed.update(loop_call_spills);
while (!spills_needed.empty()) {
RegType type = get_spill_regtype(spills_needed);
float score = 0.0;
std::pair<int, float> score{INT_MIN, 0.0};
unsigned remat = 0;
Temp to_spill;
for (unsigned t : live_in) {
@ -383,14 +389,15 @@ init_live_in_vars(spill_ctx& ctx, Block* block, unsigned block_idx)
continue;
unsigned can_remat = ctx.remat.count(var);
if (can_remat > remat || (can_remat == remat && ctx.ssa_infos[t].score() > score)) {
std::pair<int, float> var_score = ctx.get_score(var, spills_needed);
if (can_remat > remat || (can_remat == remat && var_score > score)) {
to_spill = var;
score = ctx.ssa_infos[t].score();
score = var_score;
remat = can_remat;
}
}
if (score == 0.0) {
if (score.second == 0.0) {
spills_needed[type] = 0;
continue;
}
@ -414,7 +421,7 @@ init_live_in_vars(spill_ctx& ctx, Block* block, unsigned block_idx)
spills_needed = reg_pressure - ctx.target_pressure;
while (!spills_needed.empty()) {
float score = 0;
std::pair<int, float> score{INT_MIN, 0.0};
Temp to_spill = Temp();
RegType type = get_spill_regtype(spills_needed);
for (aco_ptr<Instruction>& phi : block->instructions) {
@ -423,10 +430,11 @@ init_live_in_vars(spill_ctx& ctx, Block* block, unsigned block_idx)
if (!phi->definitions[0].isTemp() || phi->definitions[0].isKill())
continue;
Temp var = phi->definitions[0].getTemp();
std::pair<int, float> var_score = ctx.get_score(var, spills_needed);
if (var.type() == type && !ctx.spills_entry[block_idx].count(var) &&
ctx.ssa_infos[var.id()].score() > score && is_spillable(ctx, var)) {
var_score > score && is_spillable(ctx, var)) {
to_spill = var;
score = ctx.ssa_infos[var.id()].score();
score = var_score;
}
}
assert(to_spill != Temp());
@ -554,16 +562,17 @@ init_live_in_vars(spill_ctx& ctx, Block* block, unsigned block_idx)
std::map<Temp, bool>::iterator it = partial_spills.begin();
Temp to_spill = Temp();
bool is_partial_spill = false;
float score = 0.0;
std::pair<int, float> score{INT_MIN, 0.0};
RegType type = get_spill_regtype(spills_needed);
while (it != partial_spills.end()) {
assert(!ctx.spills_entry[block_idx].count(it->first));
std::pair<int, float> var_score = ctx.get_score(it->first, spills_needed);
if (it->first.type() == type && is_spillable(ctx, it->first) &&
((it->second && !is_partial_spill) ||
(it->second == is_partial_spill && ctx.ssa_infos[it->first.id()].score() > score))) {
score = ctx.ssa_infos[it->first.id()].score();
(it->second == is_partial_spill && var_score > score))) {
score = var_score;
to_spill = it->first;
is_partial_spill = it->second;
}