pan/midgard: Use 16-bit liveness masks
authorAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Wed, 16 Oct 2019 02:01:16 +0000 (22:01 -0400)
committerAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Wed, 16 Oct 2019 12:17:56 +0000 (08:17 -0400)
We'll want liveness per-byte, so we need to accomodate up to 16 bytes.

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

index a4d78c2239b7336bf32501cc1a7f781f9b45d4b8..508f7fd3d18d1a46a57a8e52c83959f844befe1d 100644 (file)
@@ -187,11 +187,9 @@ typedef struct midgard_block {
 
         /* In liveness analysis, these are live masks (per-component) for
          * indices for the block. Scalar compilers have the luxury of using
-         * simple bit fields, but for us, liveness is a vector idea. We use
-         * 8-bit to allow finegrained tracking up to vec8. If you're
-         * implementing vec16 on Panfrost... I'm sorry. */
-        uint8_t *live_in;
-        uint8_t *live_out;
+         * simple bit fields, but for us, liveness is a vector idea. */
+        uint16_t *live_in;
+        uint16_t *live_out;
 } midgard_block;
 
 typedef struct midgard_bundle {
@@ -610,7 +608,7 @@ struct ra_graph;
 void mir_lower_special_reads(compiler_context *ctx);
 struct ra_graph* allocate_registers(compiler_context *ctx, bool *spilled);
 void install_registers(compiler_context *ctx, struct ra_graph *g);
-void mir_liveness_ins_update(uint8_t *live, midgard_instruction *ins, unsigned max);
+void mir_liveness_ins_update(uint16_t *live, midgard_instruction *ins, unsigned max);
 void mir_compute_liveness(compiler_context *ctx);
 void mir_invalidate_liveness(compiler_context *ctx);
 bool mir_is_live_after(compiler_context *ctx, midgard_block *block, midgard_instruction *start, int src);
index 6ea36c5e6c690400d7a065a87477c38d6c266f37..8320b918ed2863a2b535185db9954ca243d5886e 100644 (file)
 #include "compiler.h"
 #include "util/u_memory.h"
 
-/* Routines for liveness analysis */
+/* Routines for liveness analysis. Liveness is tracked per byte per node. Per
+ * byte granularity is necessary for proper handling of int8 */
 
 static void
-liveness_gen(uint8_t *live, unsigned node, unsigned max, unsigned mask)
+liveness_gen(uint16_t *live, unsigned node, unsigned max, uint16_t mask)
 {
         if (node >= max)
                 return;
@@ -36,7 +37,7 @@ liveness_gen(uint8_t *live, unsigned node, unsigned max, unsigned mask)
 }
 
 static void
-liveness_kill(uint8_t *live, unsigned node, unsigned max, unsigned mask)
+liveness_kill(uint16_t *live, unsigned node, unsigned max, uint16_t mask)
 {
         if (node >= max)
                 return;
@@ -45,7 +46,7 @@ liveness_kill(uint8_t *live, unsigned node, unsigned max, unsigned mask)
 }
 
 static bool
-liveness_get(uint8_t *live, unsigned node, unsigned max) {
+liveness_get(uint16_t *live, unsigned node, uint16_t max) {
         if (node >= max)
                 return false;
 
@@ -55,7 +56,7 @@ liveness_get(uint8_t *live, unsigned node, unsigned max) {
 /* Updates live_in for a single instruction */
 
 void
-mir_liveness_ins_update(uint8_t *live, midgard_instruction *ins, unsigned max)
+mir_liveness_ins_update(uint16_t *live, midgard_instruction *ins, unsigned max)
 {
         /* live_in[s] = GEN[s] + (live_out[s] - KILL[s]) */
 
@@ -91,7 +92,7 @@ liveness_block_update(compiler_context *ctx, midgard_block *blk)
 
         liveness_block_live_out(ctx, blk);
 
-        uint8_t *live = mem_dup(blk->live_out, ctx->temp_count);
+        uint16_t *live = mem_dup(blk->live_out, ctx->temp_count * sizeof(uint16_t));
 
         mir_foreach_instr_in_block_rev(blk, ins)
                 mir_liveness_ins_update(live, ins, ctx->temp_count);
@@ -130,8 +131,8 @@ mir_compute_liveness(compiler_context *ctx)
         /* Allocate */
 
         mir_foreach_block(ctx, block) {
-                block->live_in = calloc(ctx->temp_count, 1);
-                block->live_out = calloc(ctx->temp_count, 1);
+                block->live_in = calloc(ctx->temp_count, sizeof(uint16_t));
+                block->live_out = calloc(ctx->temp_count, sizeof(uint16_t));
         }
 
         /* Initialize the work list with the exit block */
index afee5b82745fdea1d98e1585e73f5258bba5b90f..199e9ef076ef526d6a49b1934f6a60a98828916f 100644 (file)
@@ -554,7 +554,7 @@ mir_compute_interference(
          * end of each block and walk the block backwards. */
 
         mir_foreach_block(ctx, blk) {
-                uint8_t *live = mem_dup(blk->live_out, ctx->temp_count * sizeof(uint8_t));
+                uint16_t *live = mem_dup(blk->live_out, ctx->temp_count * sizeof(uint16_t));
 
                 mir_foreach_instr_in_block_rev(blk, ins) {
                         /* Mark all registers live after the instruction as