pan/bi: Dynamically allocate source/dests
authorAlyssa Rosenzweig <alyssa@collabora.com>
Fri, 22 Jul 2022 20:28:46 +0000 (16:28 -0400)
committerMarge Bot <emma+marge@anholt.net>
Fri, 2 Sep 2022 16:03:23 +0000 (16:03 +0000)
Instead store a pointer to the storage. Ideally even these pointer would be
removed but that's quite cumbersome in C...

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

src/panfrost/bifrost/bi_builder.h.py
src/panfrost/bifrost/bi_test.h
src/panfrost/bifrost/bi_validate.c
src/panfrost/bifrost/compiler.h

index 973b15d..4ce47fb 100644 (file)
@@ -92,23 +92,28 @@ def to_suffix(op):
 static inline
 bi_instr * bi_${opcode.replace('.', '_').lower()}${to_suffix(ops[opcode])}(${signature(ops[opcode], modifiers)})
 {
-    bi_instr *I = rzalloc(b->shader, bi_instr);
+<%
+    op = ops[opcode]
+    nr_dests = "nr_dests" if op["variable_dests"] else op["dests"]
+    nr_srcs = "nr_srcs" if op["variable_srcs"] else src_count(op)
+%>
+    size_t size = sizeof(bi_instr) + sizeof(bi_index) * (${nr_dests} + ${nr_srcs});
+    bi_instr *I = (bi_instr *) rzalloc_size(b->shader, size);
+
     I->op = BI_OPCODE_${opcode.replace('.', '_').upper()};
+    I->nr_dests = ${nr_dests};
+    I->nr_srcs = ${nr_srcs};
+    I->dest = (bi_index *) (&I[1]);
+    I->src = I->dest + ${nr_dests};
 
-% if ops[opcode]["variable_dests"]:
-    I->nr_dests = nr_dests;
-% else:
-    I->nr_dests = ${ops[opcode]["dests"]};
-% for dest in range(ops[opcode]["dests"]):
+% if not op["variable_dests"]:
+% for dest in range(op["dests"]):
     I->dest[${dest}] = dest${dest};
 % endfor
 %endif
 
-% if ops[opcode]["variable_srcs"]:
-    I->nr_srcs = nr_srcs;
-% else:
-    I->nr_srcs = ${src_count(ops[opcode])};
-% for src in range(src_count(ops[opcode])):
+% if not op["variable_srcs"]:
+% for src in range(src_count(op)):
     I->src[${src}] = src${src};
 % endfor
 % endif
index f20c0b9..4b54944 100644 (file)
@@ -62,13 +62,23 @@ bit_builder(void *memctx)
 }
 
 /* Helper to compare for logical equality of instructions. Need to skip over
- * the link, guaranteed to be first. After that we can compare raw data. */
+ * the pointers, guaranteed to be first. After that we can compare raw data.
+ */
 static inline bool
 bit_instr_equal(bi_instr *A, bi_instr *B)
 {
-   return memcmp((uint8_t *) A    + sizeof(struct list_head),
-                 (uint8_t *) B    + sizeof(struct list_head),
-                 sizeof(bi_instr) - sizeof(struct list_head)) == 0;
+   size_t skip = sizeof(struct list_head) + 2 * sizeof(bi_index *);
+
+   if (memcmp((uint8_t *) A + skip, (uint8_t *) B + skip, sizeof(bi_instr) - skip))
+           return false;
+
+   if (memcmp(A->dest, B->dest, sizeof(bi_index) * A->nr_dests))
+           return false;
+
+   if (memcmp(A->src, B->src, sizeof(bi_index) * A->nr_srcs))
+           return false;
+
+   return true;
 }
 
 static inline bool
index c0b5d23..1c6e8b3 100644 (file)
@@ -149,33 +149,18 @@ bi_validate_width(bi_context *ctx)
 }
 
 /*
- * Temporary stopgap to check that source/destination counts are correct. This
- * validation pass will go away later this series when we dynamically allocate
- * sources and destinations.
+ * Validate that all destinations of the instruction are present.
  */
 static bool
-bi_validate_src_dest_count(bi_context *ctx)
+bi_validate_dest(bi_context *ctx)
 {
         bool succ = true;
 
         bi_foreach_instr_global(ctx, I) {
-                for (unsigned s = I->nr_srcs; s < ARRAY_SIZE(I->src); ++s) {
-                        if (!bi_is_null(I->src[s])) {
-                                succ = false;
-                                fprintf(stderr,
-                                        "unexpected source %u, expected %u sources\n",
-                                        s, I->nr_srcs);
-                                bi_print_instr(I, stderr);
-                                fprintf(stderr, "\n");
-                        }
-                }
-
-                for (unsigned d = 0; d < ARRAY_SIZE(I->dest); ++d) {
-                        if ((d < I->nr_dests) == bi_is_null(I->dest[d])) {
+                bi_foreach_dest(I, d) {
+                        if (bi_is_null(I->dest[d])) {
                                 succ = false;
-                                fprintf(stderr,
-                                        "unexpected dest %u, expected %u sources\n",
-                                        d, I->nr_dests);
+                                fprintf(stderr, "expected dest %u", d);
                                 bi_print_instr(I, stderr);
                                 fprintf(stderr, "\n");
                         }
@@ -208,8 +193,8 @@ bi_validate(bi_context *ctx, const char *after)
                 fail = true;
         }
 
-        if (!bi_validate_src_dest_count(ctx)) {
-                fprintf(stderr, "Unexpected source/dest count after %s\n", after);
+        if (!bi_validate_dest(ctx)) {
+                fprintf(stderr, "Unexpected source/dest after %s\n", after);
                 fail = true;
         }
 
index 61e19dd..d7c16a8 100644 (file)
@@ -371,15 +371,13 @@ bi_is_value_equiv(bi_index left, bi_index right)
 typedef struct {
         /* Must be first */
         struct list_head link;
+        bi_index *dest;
+        bi_index *src;
 
         enum bi_opcode op;
         uint8_t nr_srcs;
         uint8_t nr_dests;
 
-        /* Data flow */
-        bi_index dest[BI_MAX_DESTS];
-        bi_index src[BI_MAX_SRCS];
-
         /* For a branch */
         struct bi_block *branch_target;