From 176b075129fbca397d5cbb4031310e4c5ae2d83f Mon Sep 17 00:00:00 2001 From: Rhys Perry Date: Thu, 15 Jan 2026 15:31:07 +0000 Subject: [PATCH] aco: prefer spilling smaller temporaries if it finishes spilling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Reviewed-by: Daniel Schürmann Part-of: --- src/amd/compiler/aco_spill.cpp | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/src/amd/compiler/aco_spill.cpp b/src/amd/compiler/aco_spill.cpp index 6b57a47e235..c8b2467504d 100644 --- a/src/amd/compiler/aco_spill.cpp +++ b/src/amd/compiler/aco_spill.cpp @@ -169,6 +169,12 @@ struct spill_ctx { return next_spill_id++; } + std::pair 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 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 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 score{INT_MIN, 0.0}; Temp to_spill = Temp(); RegType type = get_spill_regtype(spills_needed); for (aco_ptr& 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 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::iterator it = partial_spills.begin(); Temp to_spill = Temp(); bool is_partial_spill = false; - float score = 0.0; + std::pair 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 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; }