pan/midgard: Call scheduler/RA in a loop
authorAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Tue, 16 Jul 2019 16:45:11 +0000 (09:45 -0700)
committerAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Mon, 22 Jul 2019 15:20:33 +0000 (08:20 -0700)
This will allow us to insert instructions as a result of register
allocation, permitting spilling to be implemented. As a side effect,
with the assert commented out this would fix a bunch of glamor crashes
(due to RA failures) so MATE becomes useable.

Ideally we'll have scheduling or RA actually sorted out before the
branch point but if not this gives us a one-line out to get X working...

Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
src/panfrost/midgard/compiler.h
src/panfrost/midgard/midgard_ra.c
src/panfrost/midgard/midgard_schedule.c

index 59176f3c0ee2d20385281681e40b4e8c6610ea54..bd7c11efab373935d5367dc37c240986b5c940b5 100644 (file)
@@ -433,7 +433,7 @@ void schedule_program(compiler_context *ctx);
 
 struct ra_graph;
 
-struct ra_graph* allocate_registers(compiler_context *ctx);
+struct ra_graph* allocate_registers(compiler_context *ctx, bool *spilled);
 void install_registers(compiler_context *ctx, struct ra_graph *g);
 bool mir_is_live_after(compiler_context *ctx, midgard_block *block, midgard_instruction *start, int src);
 bool mir_has_multiple_writes(compiler_context *ctx, int src);
index c089a7be3e8cf08583fb99cc8c31a515e7114f5a..1505022f4515d9d6e6a768b54c46de5c335c3077 100644 (file)
@@ -186,7 +186,7 @@ index_to_reg(compiler_context *ctx, struct ra_graph *g, int reg)
  * by install_registers */
 
 struct ra_graph *
-allocate_registers(compiler_context *ctx)
+allocate_registers(compiler_context *ctx, bool *spilled)
 {
         /* The number of vec4 work registers available depends on when the
          * uniforms start, so compute that first */
@@ -372,14 +372,15 @@ allocate_registers(compiler_context *ctx)
                 }
         }
 
-        if (!ra_allocate(g)) {
-                unreachable("Error allocating registers\n");
-        }
-
         /* Cleanup */
         free(live_start);
         free(live_end);
 
+        if (!ra_allocate(g)) {
+                *spilled = true;
+                return NULL;
+        }
+
         return g;
 }
 
index 7a3841e4d44dc6e0001a2e245d40649d7426869d..ccc641c7b86ce310c122285cd4fda19584f3201c 100644 (file)
@@ -527,15 +527,28 @@ schedule_block(compiler_context *ctx, midgard_block *block)
 void
 schedule_program(compiler_context *ctx)
 {
-        /* We run RA prior to scheduling */
+        struct ra_graph *g = NULL;
+        bool spilled = false;
+        int iter_count = 10; /* max iterations */
 
-        mir_foreach_block(ctx, block) {
-                schedule_block(ctx, block);
-        }
+        do {
+                /* We would like to run RA after scheduling, but spilling can
+                 * complicate this */
+
+                mir_foreach_block(ctx, block) {
+                        schedule_block(ctx, block);
+                }
 
-        /* Pipeline registers creation is a prepass before RA */
-        mir_create_pipeline_registers(ctx);
+                /* Pipeline registers creation is a prepass before RA */
+                mir_create_pipeline_registers(ctx);
+
+                g = allocate_registers(ctx, &spilled);
+        } while(spilled && ((iter_count--) > 0));
+
+        if (iter_count <= 0) {
+                fprintf(stderr, "panfrost: Gave up allocating registers, rendering will be incomplete\n");
+                assert(0);
+        }
 
-        struct ra_graph *g = allocate_registers(ctx);
         install_registers(ctx, g);
 }