summaryrefslogtreecommitdiffstats
path: root/src/panfrost
diff options
context:
space:
mode:
authorAlyssa Rosenzweig <[email protected]>2019-12-06 10:44:21 -0500
committerAlyssa Rosenzweig <[email protected]>2019-12-12 11:42:06 -0500
commit7cf5bee5aab2499b0c5c51a7f8946e64663155eb (patch)
tree19c1a9c5f9db3faf58436894ee7235c83abd9c31 /src/panfrost
parent9dc3b18e49d97c010747fef9f731e9fb1bc1cbad (diff)
pan/midgard: Split spill node selection/spilling
Instead of having a giant function for both, split into the two subtasks so we can handle errors better. Signed-off-by: Alyssa Rosenzweig <[email protected]>
Diffstat (limited to 'src/panfrost')
-rw-r--r--src/panfrost/midgard/midgard_ra.c50
1 files changed, 30 insertions, 20 deletions
diff --git a/src/panfrost/midgard/midgard_ra.c b/src/panfrost/midgard/midgard_ra.c
index 792654026aa..7bd34f725e6 100644
--- a/src/panfrost/midgard/midgard_ra.c
+++ b/src/panfrost/midgard/midgard_ra.c
@@ -678,18 +678,13 @@ install_registers(compiler_context *ctx, struct lcra_state *l)
}
-/* If register allocation fails, find the best spill node and spill it to fix
- * whatever the issue was. This spill node could be a work register (spilling
- * to thread local storage), but it could also simply be a special register
- * that needs to spill to become a work register. */
+/* If register allocation fails, find the best spill node */
-static void mir_spill_register(
+static signed
+mir_choose_spill_node(
compiler_context *ctx,
- struct lcra_state *l,
- unsigned *spill_count)
+ struct lcra_state *l)
{
- unsigned spill_index = ctx->temp_count;
-
/* Our first step is to calculate spill cost to figure out the best
* spill node. All nodes are equal in spill cost, but we can't spill
* nodes written to from an unspill */
@@ -743,19 +738,28 @@ static void mir_spill_register(
}
}
- int spill_node = lcra_get_best_spill_node(l);
+ free(cost);
- if (spill_node < 0) {
- mir_print_shader(ctx);
- assert(0);
- }
+ return lcra_get_best_spill_node(l);
+}
+
+/* Once we've chosen a spill node, spill it */
+
+static void
+mir_spill_register(
+ compiler_context *ctx,
+ unsigned spill_node,
+ unsigned spill_class,
+ unsigned *spill_count)
+{
+ unsigned spill_index = ctx->temp_count;
/* We have a spill node, so check the class. Work registers
* legitimately spill to TLS, but special registers just spill to work
* registers */
- bool is_special = l->class[spill_node] != REG_CLASS_WORK;
- bool is_special_w = l->class[spill_node] == REG_CLASS_TEXW;
+ bool is_special = spill_class != REG_CLASS_WORK;
+ bool is_special_w = spill_class == REG_CLASS_TEXW;
/* Allocate TLS slot (maybe) */
unsigned spill_slot = !is_special ? (*spill_count)++ : 0;
@@ -876,8 +880,6 @@ static void mir_spill_register(
mir_foreach_instr_global(ctx, ins) {
ins->hint = false;
}
-
- free(cost);
}
/* Run register allocation in a loop, spilling until we succeed */
@@ -896,8 +898,16 @@ mir_ra(compiler_context *ctx)
mir_create_pipeline_registers(ctx);
do {
- if (spilled)
- mir_spill_register(ctx, l, &spill_count);
+ if (spilled) {
+ signed spill_node = mir_choose_spill_node(ctx, l);
+
+ if (spill_node == -1) {
+ fprintf(stderr, "ERROR: Failed to choose spill node\n");
+ return;
+ }
+
+ mir_spill_register(ctx, spill_node, l->spill_class, &spill_count);
+ }
mir_squeeze_index(ctx);
mir_invalidate_liveness(ctx);