Mesa (master): pan/midgard: Validate tags when branching

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon Nov 4 21:00:31 UTC 2019


Module: Mesa
Branch: master
Commit: 0a77dd32035501d976550928b7c65f7ae28a3e71
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=0a77dd32035501d976550928b7c65f7ae28a3e71

Author: Alyssa Rosenzweig <alyssa.rosenzweig at collabora.com>
Date:   Mon Nov  4 10:09:31 2019 -0500

pan/midgard: Validate tags when branching

Midgard prefetches instructions based on tag (ALU, LD/ST, texture *
size). To do so, the shader descriptor specifies the tag of the first
instruction, all instructions specify the tag of the next linear
instruction is, and all branches explicitly specify the tag of the
branch target.

If you mess this up, you get an INSTR_TYPE_MISMATCH, which unambiguously
refers to this problem, but it's still annoying to try to work out all
the branch targets in your head to debug.

Instead, let's track the tags of various blocks over time, so we can
automatically validate tags of branch targets, to make
INSTR_TYPE_MISMATCH issues immediately obvious in a disassembly.

Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig at collabora.com>

---

 src/panfrost/midgard/disassemble.c | 38 ++++++++++++++++++++++++++++++++------
 1 file changed, 32 insertions(+), 6 deletions(-)

diff --git a/src/panfrost/midgard/disassemble.c b/src/panfrost/midgard/disassemble.c
index 614de3bfd00..df75730a5f9 100644
--- a/src/panfrost/midgard/disassemble.c
+++ b/src/panfrost/midgard/disassemble.c
@@ -26,6 +26,7 @@
 
 #include <stdio.h>
 #include <stdint.h>
+#include <stdlib.h>
 #include <assert.h>
 #include <inttypes.h>
 #include <ctype.h>
@@ -40,6 +41,7 @@
 
 #define DEFINE_CASE(define, str) case define: { printf(str); break; }
 
+static unsigned *midg_tags;
 static bool is_instruction_int = false;
 
 /* Stats */
@@ -770,7 +772,7 @@ print_compact_branch_writeout_field(uint16_t word)
 }
 
 static void
-print_extended_branch_writeout_field(uint8_t *words)
+print_extended_branch_writeout_field(uint8_t *words, unsigned next)
 {
         midgard_branch_extended br;
         memcpy((char *) &br, (char *) words, sizeof(br));
@@ -804,6 +806,18 @@ print_extended_branch_writeout_field(uint8_t *words)
         print_tag_short(br.dest_tag);
         printf("\n");
 
+        unsigned I = next + br.offset * 4;
+
+        if (midg_tags[I] && midg_tags[I] != br.dest_tag) {
+                printf("\t/* XXX TAG ERROR: jumping to ");
+                print_tag_short(br.dest_tag);
+                printf(" but tagged ");
+                print_tag_short(midg_tags[I]);
+                printf(" */\n");
+        }
+
+        midg_tags[I] = br.dest_tag;
+
         midg_stats.instruction_count++;
 }
 
@@ -844,7 +858,7 @@ float_bitcast(uint32_t integer)
 
 static void
 print_alu_word(uint32_t *words, unsigned num_quad_words,
-               unsigned tabs)
+               unsigned tabs, unsigned next)
 {
         uint32_t control_word = words[0];
         uint16_t *beginning_ptr = (uint16_t *)(words + 1);
@@ -908,7 +922,7 @@ print_alu_word(uint32_t *words, unsigned num_quad_words,
         }
 
         if ((control_word >> 27) & 1) {
-                print_extended_branch_writeout_field((uint8_t *) word_ptr);
+                print_extended_branch_writeout_field((uint8_t *) word_ptr, next);
                 word_ptr += 3;
                 num_words += 3;
         }
@@ -1453,6 +1467,8 @@ disassemble_midgard(uint8_t *code, size_t size)
 
         unsigned i = 0;
 
+        midg_tags = calloc(sizeof(midg_tags[0]), num_words);
+
         /* Stats for shader-db */
         memset(&midg_stats, 0, sizeof(midg_stats));
         midg_ever_written = 0;
@@ -1462,14 +1478,24 @@ disassemble_midgard(uint8_t *code, size_t size)
                 unsigned next_tag = (words[i] >> 4) & 0xF;
                 unsigned num_quad_words = midgard_word_size[tag];
 
+                if (midg_tags[i] && midg_tags[i] != tag) {
+                        printf("\t/* XXX: TAG ERROR branch, got ");
+                        print_tag_short(tag);
+                        printf(" expected ");
+                        print_tag_short(midg_tags[i]);
+                        printf(" */\n");
+                }
+
+                midg_tags[i] = tag;
+
                 /* Check the tag */
                 if (last_next_tag > 1) {
                         if (last_next_tag != tag) {
-                                printf("/* TAG ERROR got ");
+                                printf("\t/* XXX: TAG ERROR sequence, got ");
                                 print_tag_short(tag);
                                 printf(" expected ");
                                 print_tag_short(last_next_tag);
-                                printf(" */ ");
+                                printf(" */\n");
                         }
                 } else {
                         /* TODO: Check ALU case */
@@ -1487,7 +1513,7 @@ disassemble_midgard(uint8_t *code, size_t size)
                         break;
 
                 case midgard_word_type_alu:
-                        print_alu_word(&words[i], num_quad_words, tabs);
+                        print_alu_word(&words[i], num_quad_words, tabs, i + 4*num_quad_words);
 
                         /* Reset word static analysis state */
                         is_embedded_constant_half = false;




More information about the mesa-commit mailing list