i965: Add annotation data structure and support code.
authorMatt Turner <mattst88@gmail.com>
Mon, 19 May 2014 17:17:51 +0000 (10:17 -0700)
committerMatt Turner <mattst88@gmail.com>
Sun, 25 May 2014 06:03:23 +0000 (23:03 -0700)
Will be used to print disassembly after jump targets are set and
instructions are compacted, while still retaining higher-level IR
annotations and basic block information.

An array of 'struct annotation' will live along side the generated
assembly. The generators will populate the array with their IR
annotations, and basic block pointers if the instructions began or ended
a basic block pointer.

We'll then update the instruction offset when we compact instructions
and then using the annotations print the disassembly.

Reviewed-by: Eric Anholt <eric@anholt.net>
src/mesa/drivers/dri/i965/Makefile.sources
src/mesa/drivers/dri/i965/brw_blorp_clear.cpp
src/mesa/drivers/dri/i965/brw_clip.c
src/mesa/drivers/dri/i965/brw_eu.h
src/mesa/drivers/dri/i965/brw_eu_compact.c
src/mesa/drivers/dri/i965/brw_fs_generator.cpp
src/mesa/drivers/dri/i965/brw_gs.c
src/mesa/drivers/dri/i965/brw_sf.c
src/mesa/drivers/dri/i965/brw_vec4_generator.cpp
src/mesa/drivers/dri/i965/intel_asm_printer.c [new file with mode: 0644]
src/mesa/drivers/dri/i965/intel_asm_printer.h [new file with mode: 0644]

index 5fc90b54a754e64fc65787a18adba84d2149e126..25700593d368a5dacef4811f86b9a57d158216a1 100644 (file)
@@ -3,6 +3,7 @@ i965_INCLUDES = \
        $(MESA_TOP)/src/mesa/drivers/dri/intel
 
 i965_FILES = \
+       intel_asm_printer.c \
        intel_batchbuffer.c \
        intel_blit.c \
        intel_buffer_objects.c \
index 4b2c6672e0aad572d619700825648021700aca57..ea0065a678272beb4839ff5e8669048980cc31b0 100644 (file)
@@ -490,7 +490,7 @@ brw_blorp_const_color_program::compile(struct brw_context *brw,
       fprintf(stderr, "\n");
    }
 
-   brw_compact_instructions(&func, 0);
+   brw_compact_instructions(&func, 0, 0, NULL);
    return brw_get_program(&func, program_size);
 }
 
index 57c49f0235d02764ac1740bc5d9a53bd429b2c4a..536c0859da6fd6fe24311daa7c653780f492f7bc 100644 (file)
@@ -110,7 +110,7 @@ static void compile_clip_prog( struct brw_context *brw,
       return;
    }
 
-   brw_compact_instructions(&c.func, 0);
+   brw_compact_instructions(&c.func, 0, 0, NULL);
 
    /* get the program
     */
index 65008a0513b47672d039a38b4652b05f1a8b7057..8ce31a1d3b97ed27817a79399ac43bbf684825b1 100644 (file)
@@ -37,6 +37,7 @@
 #include "brw_structs.h"
 #include "brw_defines.h"
 #include "brw_reg.h"
+#include "intel_asm_printer.h"
 #include "program/prog_instruction.h"
 
 #ifdef __cplusplus
@@ -410,7 +411,8 @@ uint32_t brw_swap_cmod(uint32_t cmod);
 
 /* brw_eu_compact.c */
 void brw_init_compaction_tables(struct brw_context *brw);
-void brw_compact_instructions(struct brw_compile *p, int start_offset);
+void brw_compact_instructions(struct brw_compile *p, int start_offset,
+                              int num_annotations, struct annotation *annotation);
 void brw_uncompact_instruction(struct brw_context *brw,
                               struct brw_instruction *dst,
                               struct brw_compact_instruction *src);
index c3a2ec31c748a805ef8356070fae577fbab38015..40d1fc23ec855c625507dd4c3d5ef08e5172bb54 100644 (file)
@@ -39,6 +39,7 @@
 
 #include "brw_context.h"
 #include "brw_eu.h"
+#include "intel_asm_printer.h"
 
 static const uint32_t gen6_control_index_table[32] = {
    0b00000000000000000,
@@ -661,7 +662,8 @@ brw_init_compaction_tables(struct brw_context *brw)
 }
 
 void
-brw_compact_instructions(struct brw_compile *p, int start_offset)
+brw_compact_instructions(struct brw_compile *p, int start_offset,
+                         int num_annotations, struct annotation *annotation)
 {
    struct brw_context *brw = p->brw;
    void *store = p->store + start_offset / 16;
@@ -784,6 +786,33 @@ brw_compact_instructions(struct brw_compile *p, int start_offset)
    }
    p->nr_insn = p->next_insn_offset / 16;
 
+   /* Update the instruction offsets for each annotation. */
+   if (annotation) {
+      for (int offset = 0, i = 0; i < num_annotations; i++) {
+         while (start_offset + old_ip[offset / 8] * 8 != annotation[i].offset) {
+            assert(start_offset + old_ip[offset / 8] * 8 <
+                   annotation[i].offset);
+            struct brw_instruction *insn = store + offset;
+            if (insn->header.cmpt_control) {
+               offset += 8;
+            } else {
+               offset += 16;
+            }
+         }
+
+         annotation[i].offset = start_offset + offset;
+
+         struct brw_instruction *insn = store + offset;
+         if (insn->header.cmpt_control) {
+            offset += 8;
+         } else {
+            offset += 16;
+         }
+      }
+
+      annotation[num_annotations].offset = p->next_insn_offset;
+   }
+
    if (0) {
       fprintf(stderr, "dumping compacted program\n");
       brw_disassemble(brw, store, 0, p->next_insn_offset - start_offset, stderr);
index bf3f32cb069c2a2d938ae12d37ccd1be10ed3d32..0fcf5271c217f385ebffcc123647b33f1d5a8923 100644 (file)
@@ -1853,7 +1853,7 @@ fs_generator::generate_assembly(exec_list *simd8_instructions,
    if (simd8_instructions) {
       dispatch_width = 8;
       generate_code(simd8_instructions);
-      brw_compact_instructions(p, 0);
+      brw_compact_instructions(p, 0, 0, NULL);
    }
 
    if (simd16_instructions) {
@@ -1869,7 +1869,7 @@ fs_generator::generate_assembly(exec_list *simd8_instructions,
 
       dispatch_width = 16;
       generate_code(simd16_instructions);
-      brw_compact_instructions(p, prog_data->prog_offset_16);
+      brw_compact_instructions(p, prog_data->prog_offset_16, 0, NULL);
    }
 
    return brw_get_program(p, assembly_size);
index 18b09560c2c55481bae1656b2fa7380b0b7912e7..97a2ee39bf3fd67eefe2c6ed0fd2ea1d0bf69ef2 100644 (file)
@@ -128,7 +128,7 @@ static void compile_ff_gs_prog(struct brw_context *brw,
       }
    }
 
-   brw_compact_instructions(&c.func, 0);
+   brw_compact_instructions(&c.func, 0, 0, NULL);
 
    /* get the program
     */
index e11de264f2eebf2a8a4ef16ad2f1547419677342..aad0310ccecac948dfcacfa351e7b078db58edcb 100644 (file)
@@ -109,7 +109,7 @@ static void compile_sf_prog( struct brw_context *brw,
       return;
    }
 
-   brw_compact_instructions(&c.func, 0);
+   brw_compact_instructions(&c.func, 0, 0, NULL);
 
    /* get the program
     */
index e4bc6823ec9fe81cc7a58db4610a5a5c267992bb..a91bfe7948f246c04a25e7f4b6b9be8960050590 100644 (file)
@@ -1363,7 +1363,7 @@ vec4_generator::generate_assembly(exec_list *instructions,
 {
    brw_set_access_mode(p, BRW_ALIGN_16);
    generate_code(instructions);
-   brw_compact_instructions(p, 0);
+   brw_compact_instructions(p, 0, 0, NULL);
    return brw_get_program(p, assembly_size);
 }
 
diff --git a/src/mesa/drivers/dri/i965/intel_asm_printer.c b/src/mesa/drivers/dri/i965/intel_asm_printer.c
new file mode 100644 (file)
index 0000000..f533e7c
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * Copyright © 2014 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "brw_cfg.h"
+#include "intel_asm_printer.h"
+#include "program/prog_print.h"
+#include "program/prog_instruction.h"
+
+void
+dump_assembly(void *assembly, int num_annotations, struct annotation *annotation,
+              struct brw_context *brw, const struct gl_program *prog,
+              disassemble_func disassemble)
+{
+   const char *last_annotation_string = NULL;
+   const void *last_annotation_ir = NULL;
+
+   for (int i = 0; i < num_annotations; i++) {
+      int start_offset = annotation[i].offset;
+      int end_offset = annotation[i + 1].offset;
+
+      if (annotation[i].block_start) {
+         fprintf(stderr, "   START B%d", annotation[i].block_start->block_num);
+         foreach_list_typed(struct bblock_link, predecessor_link, link,
+                            &annotation[i].block_start->parents) {
+            struct bblock_t *predecessor_block = predecessor_link->block;
+            fprintf(stderr, " <-B%d", predecessor_block->block_num);
+         }
+         fprintf(stderr, "\n");
+      }
+
+      if (last_annotation_ir != annotation[i].ir) {
+         last_annotation_ir = annotation[i].ir;
+         if (last_annotation_ir) {
+            fprintf(stderr, "   ");
+            if (!prog->Instructions)
+               fprint_ir(stderr, annotation[i].ir);
+            else {
+               const struct prog_instruction *pi =
+                  (const struct prog_instruction *)annotation[i].ir;
+               fprintf(stderr, "%d: ",
+                       (int)(pi - prog->Instructions));
+               _mesa_fprint_instruction_opt(stderr,
+                                            pi,
+                                            0, PROG_PRINT_DEBUG, NULL);
+            }
+            fprintf(stderr, "\n");
+         }
+      }
+
+      if (last_annotation_string != annotation[i].annotation) {
+         last_annotation_string = annotation[i].annotation;
+         if (last_annotation_string)
+            fprintf(stderr, "   %s\n", last_annotation_string);
+      }
+
+      disassemble(brw, assembly, start_offset, end_offset, stderr);
+
+      if (annotation[i].block_end) {
+         fprintf(stderr, "   END B%d", annotation[i].block_end->block_num);
+         foreach_list_typed(struct bblock_link, successor_link, link,
+                            &annotation[i].block_end->children) {
+            struct bblock_t *successor_block = successor_link->block;
+            fprintf(stderr, " ->B%d", successor_block->block_num);
+         }
+         fprintf(stderr, "\n");
+      }
+   }
+   fprintf(stderr, "\n");
+}
diff --git a/src/mesa/drivers/dri/i965/intel_asm_printer.h b/src/mesa/drivers/dri/i965/intel_asm_printer.h
new file mode 100644 (file)
index 0000000..893c76b
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright © 2014 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef _INTEL_ASM_ANNOTATION_H
+#define _INTEL_ASM_ANNOTATION_H
+
+struct bblock_t;
+struct brw_context;
+struct gl_program;
+
+struct annotation {
+   int offset;
+
+   /* Pointers to the basic block in the CFG if the instruction group starts
+    * or ends a basic block.
+    */
+   struct bblock_t *block_start;
+   struct bblock_t *block_end;
+
+   /* Annotation for the generated IR.  One of the two can be set. */
+   const void *ir;
+   const char *annotation;
+};
+
+typedef void (*disassemble_func)(struct brw_context *brw, void *assembly,
+                                 int start, int end, FILE *out);
+
+void
+dump_assembly(void *assembly, int num_annotations, struct annotation *annotation,
+              struct brw_context *brw, const struct gl_program *prog,
+              disassemble_func disassemble);
+
+#endif /* _INTEL_ASM_ANNOTATION_H */