pan/lcra: Allow per-variable bounds to be set
authorAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Mon, 11 May 2020 19:03:58 +0000 (15:03 -0400)
committerMarge Bot <eric+marge@anholt.net>
Thu, 21 May 2020 17:49:14 +0000 (17:49 +0000)
Different variables need to respect different bounds. In general,
16-bytes is okay, but for 4-channel 16-bit vectors, we can't cross 8
byte boundaries (else the swizzles will not be packable after), so we
update LCRA to allow this more general form.

Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5151>

src/panfrost/bifrost/bi_ra.c
src/panfrost/midgard/midgard_ra.c
src/panfrost/util/lcra.c
src/panfrost/util/lcra.h

index b305afdf574d248b3bed1d52efe299a69561ee14..1936958c28f33dc76c48b298c41a0e7380686110 100644 (file)
@@ -67,7 +67,7 @@ bi_allocate_registers(bi_context *ctx, bool *success)
         unsigned node_count = bi_max_temp(ctx);
 
         struct lcra_state *l =
-                lcra_alloc_equations(node_count, 16, 1);
+                lcra_alloc_equations(node_count, 1);
 
         l->class_start[BI_REG_CLASS_WORK] = 0;
         l->class_size[BI_REG_CLASS_WORK] = 64 * 4; /* R0 - R63, all 32-bit */
@@ -79,7 +79,7 @@ bi_allocate_registers(bi_context *ctx, bool *success)
                         continue;
 
                 l->class[dest] = BI_REG_CLASS_WORK;
-                lcra_set_alignment(l, dest, 2); /* 2^2 = 4 */
+                lcra_set_alignment(l, dest, 2, 16); /* 2^2 = 4 */
                 lcra_restrict_range(l, dest, 4);
         }
 
index b2844ae9f38bfb8f9b8882004b469f581d514d1f..52f6f11f0a0fde914d57b35e176e973db0a8a52b 100644 (file)
@@ -449,7 +449,7 @@ allocate_registers(compiler_context *ctx, bool *spilled)
         if (!ctx->temp_count)
                 return NULL;
 
-        struct lcra_state *l = lcra_alloc_equations(ctx->temp_count, 16, 5);
+        struct lcra_state *l = lcra_alloc_equations(ctx->temp_count, 5);
 
         /* Starts of classes, in bytes */
         l->class_start[REG_CLASS_WORK]  = 16 * 0;
@@ -476,6 +476,7 @@ allocate_registers(compiler_context *ctx, bool *spilled)
 
         unsigned *found_class = calloc(sizeof(unsigned), ctx->temp_count);
         unsigned *min_alignment = calloc(sizeof(unsigned), ctx->temp_count);
+        unsigned *min_bound = calloc(sizeof(unsigned), ctx->temp_count);
 
         mir_foreach_instr_global(ctx, ins) {
                 /* Swizzles of 32-bit sources on 64-bit instructions need to be
@@ -535,12 +536,14 @@ allocate_registers(compiler_context *ctx, bool *spilled)
         }
 
         for (unsigned i = 0; i < ctx->temp_count; ++i) {
-                lcra_set_alignment(l, i, min_alignment[i] ? min_alignment[i] : 2);
+                lcra_set_alignment(l, i, min_alignment[i] ? min_alignment[i] : 2,
+                                min_bound[i] ? min_bound[i] : 16);
                 lcra_restrict_range(l, i, found_class[i]);
         }
         
         free(found_class);
         free(min_alignment);
+        free(min_bound);
 
         /* Next, we'll determine semantic class. We default to zero (work).
          * But, if we're used with a special operation, that will force us to a
index 0e30c1d10829fe59efe69a6c919ae50e33ff6136..d922972b6196c001ae04f46a364ba064e75da472 100644 (file)
 
 struct lcra_state *
 lcra_alloc_equations(
-                unsigned node_count,
-                unsigned bound, unsigned class_count)
+                unsigned node_count, unsigned class_count)
 {
         struct lcra_state *l = calloc(1, sizeof(*l));
 
         l->node_count = node_count;
         l->class_count = class_count;
-        l->bound = bound;
 
         l->alignment = calloc(sizeof(l->alignment[0]), node_count);
         l->linear = calloc(sizeof(l->linear[0]), node_count * node_count);
@@ -85,9 +83,9 @@ lcra_free(struct lcra_state *l)
 }
 
 void
-lcra_set_alignment(struct lcra_state *l, unsigned node, unsigned align_log2)
+lcra_set_alignment(struct lcra_state *l, unsigned node, unsigned align_log2, unsigned bound)
 {
-        l->alignment[node] = align_log2 + 1;
+        l->alignment[node] = (align_log2 + 1) | (bound << 16);
 }
 
 void
@@ -100,8 +98,12 @@ lcra_set_disjoint_class(struct lcra_state *l, unsigned c1, unsigned c2)
 void
 lcra_restrict_range(struct lcra_state *l, unsigned node, unsigned len)
 {
-        if (node < l->node_count && l->alignment[node])
-                l->modulus[node] = DIV_ROUND_UP(l->bound - len + 1, 1 << (l->alignment[node] - 1));
+        if (node < l->node_count && l->alignment[node]) {
+                unsigned BA = l->alignment[node];
+                unsigned alignment = (BA & 0xffff) - 1;
+                unsigned bound = BA >> 16;
+                l->modulus[node] = DIV_ROUND_UP(bound - len + 1, 1 << alignment);
+        }
 }
 
 void
@@ -163,9 +165,11 @@ lcra_solve(struct lcra_state *l)
                 unsigned _class = l->class[step];
                 unsigned class_start = l->class_start[_class];
 
-                unsigned shift = l->alignment[step] - 1;
+                unsigned BA = l->alignment[step];
+                unsigned shift = (BA & 0xffff) - 1;
+                unsigned bound = BA >> 16;
 
-                unsigned P = l->bound >> shift;
+                unsigned P = bound >> shift;
                 unsigned Q = l->modulus[step];
                 unsigned r_max = l->class_size[_class];
                 unsigned k_max = r_max >> shift;
index 61908953af9e0a7470a84c6039f0aaa21f62fd4f..fd47fdc35434724b4edfb71d2bc351981abcd230 100644 (file)
 struct lcra_state {
         unsigned node_count;
 
-        /* Word boundary where vectors can't cross */
-        unsigned bound;
-        
         /* Alignment for node in log2(bytes)+1. Since alignment must be
          * non-negative power-of-two, the elements are strictly positive
-         * integers. Zero is the sentinel for a missing node */
+         * integers. Zero is the sentinel for a missing node. In upper word,
+         * bound. */
         unsigned *alignment;
 
         /* Linear constraints imposed. Nested array sized upfront, organized as
@@ -81,8 +79,7 @@ struct lcra_state {
 
 struct lcra_state *
 lcra_alloc_equations(
-                unsigned node_count,
-                unsigned bound, unsigned class_count);
+                unsigned node_count, unsigned class_count);
 
 void
 lcra_free(struct lcra_state *l);
@@ -91,7 +88,7 @@ void
 lcra_set_disjoint_class(struct lcra_state *l, unsigned c1, unsigned c2);
 
 void
-lcra_set_alignment(struct lcra_state *l, unsigned node, unsigned align_log2);
+lcra_set_alignment(struct lcra_state *l, unsigned node, unsigned align_log2, unsigned bound);
 
 void
 lcra_restrict_range(struct lcra_state *l, unsigned node, unsigned len);