diff options
Diffstat (limited to 'src/gallium/drivers/lima')
-rw-r--r-- | src/gallium/drivers/lima/ir/pp/regalloc.c | 29 |
1 files changed, 22 insertions, 7 deletions
diff --git a/src/gallium/drivers/lima/ir/pp/regalloc.c b/src/gallium/drivers/lima/ir/pp/regalloc.c index 4735dd407eb..0d6808d27fd 100644 --- a/src/gallium/drivers/lima/ir/pp/regalloc.c +++ b/src/gallium/drivers/lima/ir/pp/regalloc.c @@ -545,20 +545,35 @@ static bool ppir_regalloc_spill_reg(ppir_compiler *comp, ppir_reg *chosen) static ppir_reg *ppir_regalloc_choose_spill_node(ppir_compiler *comp, struct ra_graph *g) { - int max_range = -1; + int i = 0; ppir_reg *chosen = NULL; list_for_each_entry(ppir_reg, reg, &comp->reg_list, list) { - int range = reg->live_out - reg->live_in; + if (reg->spilled || reg->live_out == INT_MAX) { + /* not considered for spilling */ + ra_set_node_spill_cost(g, i++, 0.0f); + continue; + } + + /* It is beneficial to spill registers with higher component number, + * so increase the cost of spilling registers with few components */ + float spill_cost = 4.0f / (float)reg->num_components; + ra_set_node_spill_cost(g, i++, spill_cost); + } + + int r = ra_get_best_spill_node(g); + if (r == -1) + return NULL; - if (!reg->spilled && reg->live_out != INT_MAX && range > max_range) { + i = 0; + list_for_each_entry(ppir_reg, reg, &comp->reg_list, list) { + if (i++ == r) { chosen = reg; - max_range = range; + break; } } - - if (chosen) - chosen->spilled = true; + assert(chosen); + chosen->spilled = true; return chosen; } |