summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErico Nunes <nunes.erico@gmail.com>2019-08-19 01:04:57 +0200
committerErico Nunes <nunes.erico@gmail.com>2019-08-20 21:16:02 +0000
commit71fb721ca5b6761ff974b64d8f6d5efd51a691e9 (patch)
treebb104aa00adb7853249aac30430c496c1ce5a933
parentc1dc84e71d11ed7e2ca95286522ddbdf3cc12c95 (diff)
lima/ppir: use ra_get_best_spill_node to select spill node19.2-branchpoint
ra_get_best_spill_node is what other users of the mesa register allocator use. Switching to it now also fixes an infinite loop issue with ppir regalloc with the ppir control flow patchset, and also provides a small gain over the previous herusitic on number of spilled nodes testing with shader-db. Signed-off-by: Erico Nunes <nunes.erico@gmail.com> Reviewed-by: Vasily Khoruzhick <anarsoul@gmail.com>
-rw-r--r--src/gallium/drivers/lima/ir/pp/regalloc.c29
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;
}