[Mesa-dev] [PATCH 10/10] i965/fs: Dump instructions after compaction.

Matt Turner mattst88 at gmail.com
Tue May 13 14:52:14 PDT 2014


Lets us see actual jump targets, instruction locations, and compaction
information.
---
 src/mesa/drivers/dri/i965/Makefile.sources        |   1 +
 src/mesa/drivers/dri/i965/brw_blorp_clear.cpp     |   2 +-
 src/mesa/drivers/dri/i965/brw_clip.c              |   2 +-
 src/mesa/drivers/dri/i965/brw_eu.h                |   3 +-
 src/mesa/drivers/dri/i965/brw_eu_compact.c        |  25 +++-
 src/mesa/drivers/dri/i965/brw_fs.h                |   7 +-
 src/mesa/drivers/dri/i965/brw_fs_generator.cpp    | 135 +++++++++-------------
 src/mesa/drivers/dri/i965/brw_gs.c                |   2 +-
 src/mesa/drivers/dri/i965/brw_sf.c                |   2 +-
 src/mesa/drivers/dri/i965/brw_vec4.h              |   8 +-
 src/mesa/drivers/dri/i965/brw_vec4_generator.cpp  |  92 +++++++--------
 src/mesa/drivers/dri/i965/gen8_fs_generator.cpp   | 122 ++++++++-----------
 src/mesa/drivers/dri/i965/gen8_vec4_generator.cpp |  86 +++++++-------
 src/mesa/drivers/dri/i965/intel_asm_printer.c     |  90 +++++++++++++++
 src/mesa/drivers/dri/i965/intel_asm_printer.h     |  52 +++++++++
 15 files changed, 375 insertions(+), 254 deletions(-)
 create mode 100644 src/mesa/drivers/dri/i965/intel_asm_printer.c
 create mode 100644 src/mesa/drivers/dri/i965/intel_asm_printer.h

diff --git a/src/mesa/drivers/dri/i965/Makefile.sources b/src/mesa/drivers/dri/i965/Makefile.sources
index 9379fd2..1fd97f5 100644
--- a/src/mesa/drivers/dri/i965/Makefile.sources
+++ b/src/mesa/drivers/dri/i965/Makefile.sources
@@ -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 \
diff --git a/src/mesa/drivers/dri/i965/brw_blorp_clear.cpp b/src/mesa/drivers/dri/i965/brw_blorp_clear.cpp
index 2bb08de..4586a17 100644
--- a/src/mesa/drivers/dri/i965/brw_blorp_clear.cpp
+++ b/src/mesa/drivers/dri/i965/brw_blorp_clear.cpp
@@ -490,7 +490,7 @@ brw_blorp_const_color_program::compile(struct brw_context *brw,
       fprintf(stderr, "\n");
    }
 
-   brw_compact_instructions(&func);
+   brw_compact_instructions(&func, NULL);
    return brw_get_program(&func, program_size);
 }
 
diff --git a/src/mesa/drivers/dri/i965/brw_clip.c b/src/mesa/drivers/dri/i965/brw_clip.c
index 1c54b91..e258662 100644
--- a/src/mesa/drivers/dri/i965/brw_clip.c
+++ b/src/mesa/drivers/dri/i965/brw_clip.c
@@ -111,7 +111,7 @@ static void compile_clip_prog( struct brw_context *brw,
       return;
    }
 
-   brw_compact_instructions(&c.func);
+   brw_compact_instructions(&c.func, NULL);
 
    /* get the program
     */
diff --git a/src/mesa/drivers/dri/i965/brw_eu.h b/src/mesa/drivers/dri/i965/brw_eu.h
index 933477d..5aee56f 100644
--- a/src/mesa/drivers/dri/i965/brw_eu.h
+++ b/src/mesa/drivers/dri/i965/brw_eu.h
@@ -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
@@ -415,7 +416,7 @@ 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);
+void brw_compact_instructions(struct brw_compile *p, struct annotation *annotation);
 void brw_uncompact_instruction(struct brw_context *brw,
 			       struct brw_instruction *dst,
 			       struct brw_compact_instruction *src);
diff --git a/src/mesa/drivers/dri/i965/brw_eu_compact.c b/src/mesa/drivers/dri/i965/brw_eu_compact.c
index d8869c0..e18daf5 100644
--- a/src/mesa/drivers/dri/i965/brw_eu_compact.c
+++ b/src/mesa/drivers/dri/i965/brw_eu_compact.c
@@ -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,7 @@ brw_init_compaction_tables(struct brw_context *brw)
 }
 
 void
-brw_compact_instructions(struct brw_compile *p)
+brw_compact_instructions(struct brw_compile *p, struct annotation *annotation)
 {
    struct brw_context *brw = p->brw;
    void *store = p->store;
@@ -784,6 +785,28 @@ brw_compact_instructions(struct brw_compile *p)
    }
    p->nr_insn = p->next_insn_offset / 16;
 
+   /* Update the instruction offsets for each annotation. */
+   if (annotation) {
+      for (int i = 0, offset = 0; offset < p->next_insn_offset;) {
+         struct brw_instruction *insn = store + offset;
+         int this_old_ip = old_ip[offset / 8];
+
+         while (this_old_ip < annotation[i].offset / 8) {
+            i++;
+         }
+         if (this_old_ip == annotation[i].offset / 8) {
+            annotation[i].offset = offset;
+            i++;
+         }
+
+         if (insn->header.cmpt_control) {
+            offset += 8;
+         } else {
+            offset += 16;
+         }
+      }
+   }
+
    if (0) {
       fprintf(stderr, "dumping compacted program\n");
       brw_dump_compile(brw, p->store, 0, p->next_insn_offset, stderr);
diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h
index 053046b..58897ff 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.h
+++ b/src/mesa/drivers/dri/i965/brw_fs.h
@@ -46,6 +46,7 @@ extern "C" {
 #include "brw_eu.h"
 #include "brw_wm.h"
 #include "brw_shader.h"
+#include "intel_asm_printer.h"
 }
 #include "gen8_generator.h"
 #include "glsl/glsl_types.h"
@@ -587,7 +588,8 @@ public:
                                      FILE *dump_file = NULL);
 
 private:
-   void generate_code(exec_list *instructions, FILE *dump_file);
+   void generate_code(exec_list *instructions, int *num_annotations,
+                      struct annotation **annotation);
    void generate_fb_write(fs_inst *inst);
    void generate_blorp_fb_write(fs_inst *inst);
    void generate_pixel_xy(struct brw_reg dst, bool is_x);
@@ -710,7 +712,8 @@ public:
                                      unsigned *assembly_size);
 
 private:
-   void generate_code(exec_list *instructions);
+   void generate_code(exec_list *instructions, int *num_annotations,
+                      struct annotation **annotation);
    void generate_fb_write(fs_inst *inst);
    void generate_linterp(fs_inst *inst, struct brw_reg dst,
                          struct brw_reg *src);
diff --git a/src/mesa/drivers/dri/i965/brw_fs_generator.cpp b/src/mesa/drivers/dri/i965/brw_fs_generator.cpp
index f8819da..60db219 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_generator.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_generator.cpp
@@ -1318,12 +1318,9 @@ fs_generator::generate_untyped_surface_read(fs_inst *inst, struct brw_reg dst,
 }
 
 void
-fs_generator::generate_code(exec_list *instructions, FILE *dump_file)
+fs_generator::generate_code(exec_list *instructions, int *num_annotations,
+                            struct annotation **annotation)
 {
-   int last_native_insn_offset = p->next_insn_offset;
-   const char *last_annotation_string = NULL;
-   const void *last_annotation_ir = NULL;
-
    if (unlikely(INTEL_DEBUG & DEBUG_WM)) {
       if (prog) {
          fprintf(stderr,
@@ -1340,54 +1337,39 @@ fs_generator::generate_code(exec_list *instructions, FILE *dump_file)
       }
    }
 
+   int block_num = 0;
+   int ann_num = 0;
+   int ann_size = 1024;
    cfg_t *cfg = NULL;
-   if (unlikely(INTEL_DEBUG & DEBUG_WM))
+   struct annotation *ann = NULL;
+
+   if (unlikely(INTEL_DEBUG & DEBUG_WM)) {
       cfg = new(mem_ctx) cfg_t(instructions);
+      ann = rzalloc_array(NULL, struct annotation, ann_size);
+   }
 
    foreach_list(node, instructions) {
       fs_inst *inst = (fs_inst *)node;
       struct brw_reg src[3], dst;
 
       if (unlikely(INTEL_DEBUG & DEBUG_WM)) {
-	 foreach_list(node, &cfg->block_list) {
-	    bblock_link *link = (bblock_link *)node;
-	    bblock_t *block = link->block;
-
-	    if (block->start == inst) {
-	       fprintf(stderr, "   START B%d", block->block_num);
-	       foreach_list(predecessor_node, &block->parents) {
-		  bblock_link *predecessor_link =
-		     (bblock_link *)predecessor_node;
-		  bblock_t *predecessor_block = predecessor_link->block;
-		  fprintf(stderr, " <-B%d", predecessor_block->block_num);
-	       }
-	       fprintf(stderr, "\n");
-	    }
-	 }
+         if (ann_num == ann_size) {
+            ann_size *= 2;
+            ann = reralloc(NULL, ann, struct annotation, ann_size);
+         }
 
-	 if (last_annotation_ir != inst->ir) {
-	    last_annotation_ir = inst->ir;
-	    if (last_annotation_ir) {
-	       fprintf(stderr, "   ");
-               if (prog)
-                  ((ir_instruction *)inst->ir)->fprint(stderr);
-               else {
-                  const prog_instruction *fpi;
-                  fpi = (const prog_instruction *)inst->ir;
-                  fprintf(stderr, "%d: ",
-                          (int)(fpi - (fp ? fp->Base.Instructions : 0)));
-                  _mesa_fprint_instruction_opt(stderr,
-                                               fpi,
-                                               0, PROG_PRINT_DEBUG, NULL);
-               }
-	       fprintf(stderr, "\n");
-	    }
-	 }
-	 if (last_annotation_string != inst->annotation) {
-	    last_annotation_string = inst->annotation;
-	    if (last_annotation_string)
-	       fprintf(stderr, "   %s\n", last_annotation_string);
-	 }
+         ann[ann_num].offset = p->next_insn_offset;
+         ann[ann_num].ir = inst->ir;
+         ann[ann_num].annotation = inst->annotation;
+
+         if (cfg->blocks[block_num]->start == inst) {
+            ann[ann_num].block_start = cfg->blocks[block_num];
+         }
+         if (cfg->blocks[block_num]->end == inst) {
+            ann[ann_num].block_end = cfg->blocks[block_num];
+            block_num++;
+         }
+         ann_num++;
       }
 
       for (unsigned int i = 0; i < 3; i++) {
@@ -1800,44 +1782,15 @@ fs_generator::generate_code(exec_list *instructions, FILE *dump_file)
 	 }
 	 abort();
       }
-
-      if (unlikely(INTEL_DEBUG & DEBUG_WM)) {
-	 brw_dump_compile(brw, p->store, last_native_insn_offset, p->next_insn_offset, stderr);
-
-	 foreach_list(node, &cfg->block_list) {
-	    bblock_link *link = (bblock_link *)node;
-	    bblock_t *block = link->block;
-
-	    if (block->end == inst) {
-	       fprintf(stderr, "   END B%d", block->block_num);
-	       foreach_list(successor_node, &block->children) {
-		  bblock_link *successor_link =
-		     (bblock_link *)successor_node;
-		  bblock_t *successor_block = successor_link->block;
-		  fprintf(stderr, " ->B%d", successor_block->block_num);
-	       }
-	       fprintf(stderr, "\n");
-	    }
-	 }
-      }
-
-      last_native_insn_offset = p->next_insn_offset;
-   }
-
-   if (unlikely(INTEL_DEBUG & DEBUG_WM)) {
-      fprintf(stderr, "\n");
    }
 
    brw_set_uip_jip(p);
 
-   /* OK, while the INTEL_DEBUG=wm above is very nice for debugging FS
-    * emit issues, it doesn't get the jump distances into the output,
-    * which is often something we want to debug.  So this is here in
-    * case you're doing that.
-    */
-   if (dump_file) {
-      brw_dump_compile(brw, p->store, 0, p->next_insn_offset, dump_file);
+   if (unlikely(INTEL_DEBUG & DEBUG_WM)) {
+      ann[ann_num].offset = p->next_insn_offset;
    }
+   *num_annotations = ann_num;
+   *annotation = ann;
 }
 
 const unsigned *
@@ -1848,10 +1801,21 @@ fs_generator::generate_assembly(exec_list *simd8_instructions,
 {
    assert(simd8_instructions || simd16_instructions);
 
+   const struct gl_program *prog = fp ? &fp->Base : NULL;
+
    if (simd8_instructions) {
+      struct annotation *annotation;
+      int num_annotations;
+
       dispatch_width = 8;
-      generate_code(simd8_instructions, dump_file);
-      brw_compact_instructions(p);
+      generate_code(simd8_instructions, &num_annotations, &annotation);
+      brw_compact_instructions(p, annotation);
+
+      if (unlikely(INTEL_DEBUG & DEBUG_WM)) {
+         dump_assembly(p->store, num_annotations, annotation, brw, prog,
+                       brw_dump_compile, dump_file);
+         ralloc_free(annotation);
+      }
    }
 
    if (simd16_instructions) {
@@ -1865,9 +1829,18 @@ fs_generator::generate_assembly(exec_list *simd8_instructions,
 
       brw_set_compression_control(p, BRW_COMPRESSION_COMPRESSED);
 
+      struct annotation *annotation;
+      int num_annotations;
+
       dispatch_width = 16;
-      generate_code(simd16_instructions, dump_file);
-      brw_compact_instructions(p);
+      generate_code(simd16_instructions, &num_annotations, &annotation);
+      brw_compact_instructions(p, annotation);
+
+      if (unlikely(INTEL_DEBUG & DEBUG_WM)) {
+         dump_assembly(p->store, num_annotations, annotation, brw, prog,
+                       brw_dump_compile, dump_file);
+         ralloc_free(annotation);
+      }
    }
 
    return brw_get_program(p, assembly_size);
diff --git a/src/mesa/drivers/dri/i965/brw_gs.c b/src/mesa/drivers/dri/i965/brw_gs.c
index eaa527f..b0df524 100644
--- a/src/mesa/drivers/dri/i965/brw_gs.c
+++ b/src/mesa/drivers/dri/i965/brw_gs.c
@@ -128,7 +128,7 @@ static void compile_ff_gs_prog(struct brw_context *brw,
       }
    }
 
-   brw_compact_instructions(&c.func);
+   brw_compact_instructions(&c.func, NULL);
 
    /* get the program
     */
diff --git a/src/mesa/drivers/dri/i965/brw_sf.c b/src/mesa/drivers/dri/i965/brw_sf.c
index 401fa7b..fec396e 100644
--- a/src/mesa/drivers/dri/i965/brw_sf.c
+++ b/src/mesa/drivers/dri/i965/brw_sf.c
@@ -110,7 +110,7 @@ static void compile_sf_prog( struct brw_context *brw,
       return;
    }
 
-   brw_compact_instructions(&c.func);
+   brw_compact_instructions(&c.func, NULL);
 
    /* get the program
     */
diff --git a/src/mesa/drivers/dri/i965/brw_vec4.h b/src/mesa/drivers/dri/i965/brw_vec4.h
index a86972a..14d114c 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4.h
+++ b/src/mesa/drivers/dri/i965/brw_vec4.h
@@ -36,10 +36,12 @@ extern "C" {
 
 #include "brw_context.h"
 #include "brw_eu.h"
+#include "intel_asm_printer.h"
 
 #ifdef __cplusplus
 }; /* extern "C" */
 #include "gen8_generator.h"
+#include "brw_cfg.h"
 #endif
 
 #include "glsl/ir.h"
@@ -650,7 +652,8 @@ public:
    const unsigned *generate_assembly(exec_list *insts, unsigned *asm_size);
 
 private:
-   void generate_code(exec_list *instructions);
+   void generate_code(exec_list *instructions, int *num_annotations,
+                      struct annotation **annotation);
    void generate_vec4_instruction(vec4_instruction *inst,
                                   struct brw_reg dst,
                                   struct brw_reg *src);
@@ -751,7 +754,8 @@ public:
    const unsigned *generate_assembly(exec_list *insts, unsigned *asm_size);
 
 private:
-   void generate_code(exec_list *instructions);
+   void generate_code(exec_list *instructions, int *num_annotations,
+                      struct annotation **annotation);
    void generate_vec4_instruction(vec4_instruction *inst,
                                   struct brw_reg dst,
                                   struct brw_reg *src);
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp b/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp
index cd9c562..9e3bc7f 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp
@@ -1260,12 +1260,9 @@ vec4_generator::generate_vec4_instruction(vec4_instruction *instruction,
 }
 
 void
-vec4_generator::generate_code(exec_list *instructions)
+vec4_generator::generate_code(exec_list *instructions, int *num_annotations,
+                              annotation **annotation)
 {
-   int last_native_insn_offset = 0;
-   const char *last_annotation_string = NULL;
-   const void *last_annotation_ir = NULL;
-
    if (unlikely(debug_flag)) {
       if (shader_prog) {
          fprintf(stderr, "Native code for %s vertex shader %d:\n",
@@ -1276,32 +1273,39 @@ vec4_generator::generate_code(exec_list *instructions)
       }
    }
 
+   int block_num = 0;
+   int ann_num = 0;
+   int ann_size = 1024;
+   cfg_t *cfg = NULL;
+   struct annotation *ann = NULL;
+
+   if (unlikely(debug_flag)) {
+      cfg = new(mem_ctx) cfg_t(instructions);
+      ann = rzalloc_array(NULL, struct annotation, ann_size);
+   }
+
    foreach_list(node, instructions) {
       vec4_instruction *inst = (vec4_instruction *)node;
       struct brw_reg src[3], dst;
 
       if (unlikely(debug_flag)) {
-	 if (last_annotation_ir != inst->ir) {
-	    last_annotation_ir = inst->ir;
-	    if (last_annotation_ir) {
-	       fprintf(stderr, "   ");
-               if (shader_prog) {
-                  ((ir_instruction *) last_annotation_ir)->fprint(stderr);
-               } else {
-                  const prog_instruction *vpi;
-                  vpi = (const prog_instruction *) inst->ir;
-                  fprintf(stderr, "%d: ", (int)(vpi - prog->Instructions));
-                  _mesa_fprint_instruction_opt(stderr, vpi, 0,
-                                               PROG_PRINT_DEBUG, NULL);
-               }
-	       fprintf(stderr, "\n");
-	    }
-	 }
-	 if (last_annotation_string != inst->annotation) {
-	    last_annotation_string = inst->annotation;
-	    if (last_annotation_string)
-	       fprintf(stderr, "   %s\n", last_annotation_string);
-	 }
+         if (ann_num == ann_size) {
+            ann_size *= 2;
+            ann = reralloc(NULL, ann, struct annotation, ann_size);
+         }
+
+         ann[ann_num].offset = p->next_insn_offset;
+         ann[ann_num].ir = inst->ir;
+         ann[ann_num].annotation = inst->annotation;
+
+         if (cfg->blocks[block_num]->start == inst) {
+            ann[ann_num].block_start = cfg->blocks[block_num];
+         }
+         if (cfg->blocks[block_num]->end == inst) {
+            ann[ann_num].block_end = cfg->blocks[block_num];
+            block_num++;
+         }
+         ann_num++;
       }
 
       for (unsigned int i = 0; i < 3; i++) {
@@ -1332,38 +1336,34 @@ vec4_generator::generate_code(exec_list *instructions)
          if (inst->no_dd_check)
             last->header.dependency_control |= BRW_DEPENDENCY_NOTCHECKED;
       }
-
-      if (unlikely(debug_flag)) {
-	 brw_dump_compile(brw, p->store,
-			  last_native_insn_offset, p->next_insn_offset, stderr);
-      }
-
-      last_native_insn_offset = p->next_insn_offset;
-   }
-
-   if (unlikely(debug_flag)) {
-      fprintf(stderr, "\n");
    }
 
    brw_set_uip_jip(p);
 
-   /* OK, while the INTEL_DEBUG=vs above is very nice for debugging VS
-    * emit issues, it doesn't get the jump distances into the output,
-    * which is often something we want to debug.  So this is here in
-    * case you're doing that.
-    */
-   if (0 && unlikely(debug_flag)) {
-      brw_dump_compile(brw, p->store, 0, p->next_insn_offset, stderr);
+   if (unlikely(debug_flag)) {
+      ann[ann_num].offset = p->next_insn_offset;
    }
+   *num_annotations = ann_num;
+   *annotation = ann;
 }
 
 const unsigned *
 vec4_generator::generate_assembly(exec_list *instructions,
                                   unsigned *assembly_size)
 {
+   struct annotation *annotation;
+   int num_annotations;
+
    brw_set_access_mode(p, BRW_ALIGN_16);
-   generate_code(instructions);
-   brw_compact_instructions(p);
+   generate_code(instructions, &num_annotations, &annotation);
+   brw_compact_instructions(p, annotation);
+
+   if (unlikely(debug_flag)) {
+      dump_assembly(p->store, num_annotations, annotation, brw, prog,
+                    brw_dump_compile, stderr);
+      ralloc_free(annotation);
+   }
+
    return brw_get_program(p, assembly_size);
 }
 
diff --git a/src/mesa/drivers/dri/i965/gen8_fs_generator.cpp b/src/mesa/drivers/dri/i965/gen8_fs_generator.cpp
index d25da81..7ca68b2 100644
--- a/src/mesa/drivers/dri/i965/gen8_fs_generator.cpp
+++ b/src/mesa/drivers/dri/i965/gen8_fs_generator.cpp
@@ -879,12 +879,9 @@ gen8_fs_generator::generate_untyped_surface_read(fs_inst *ir,
 }
 
 void
-gen8_fs_generator::generate_code(exec_list *instructions)
+gen8_fs_generator::generate_code(exec_list *instructions, int *num_annotations,
+                                 struct annotation **annotation)
 {
-   int last_native_inst_offset = next_inst_offset;
-   const char *last_annotation_string = NULL;
-   const void *last_annotation_ir = NULL;
-
    if (unlikely(INTEL_DEBUG & DEBUG_WM)) {
       if (prog) {
          fprintf(stderr,
@@ -901,53 +898,39 @@ gen8_fs_generator::generate_code(exec_list *instructions)
       }
    }
 
+   int block_num = 0;
+   int ann_num = 0;
+   int ann_size = 1024;
    cfg_t *cfg = NULL;
-   if (unlikely(INTEL_DEBUG & DEBUG_WM))
+   struct annotation *ann = NULL;
+
+   if (unlikely(INTEL_DEBUG & DEBUG_WM)) {
       cfg = new(mem_ctx) cfg_t(instructions);
+      ann = rzalloc_array(NULL, struct annotation, ann_size);
+   }
 
    foreach_list(node, instructions) {
       fs_inst *ir = (fs_inst *) node;
       struct brw_reg src[3], dst;
 
       if (unlikely(INTEL_DEBUG & DEBUG_WM)) {
-         foreach_list(node, &cfg->block_list) {
-            bblock_link *link = (bblock_link *)node;
-            bblock_t *block = link->block;
-
-            if (block->start == ir) {
-               fprintf(stderr, "   START B%d", block->block_num);
-               foreach_list(predecessor_node, &block->parents) {
-                  bblock_link *predecessor_link =
-                     (bblock_link *)predecessor_node;
-                  bblock_t *predecessor_block = predecessor_link->block;
-                  fprintf(stderr, " <-B%d", predecessor_block->block_num);
-               }
-               fprintf(stderr, "\n");
-            }
+         if (ann_num == ann_size) {
+            ann_size *= 2;
+            ann = reralloc(NULL, ann, struct annotation, ann_size);
          }
 
-         if (last_annotation_ir != ir->ir) {
-            last_annotation_ir = ir->ir;
-            if (last_annotation_ir) {
-               fprintf(stderr, "   ");
-               if (prog) {
-                  ((ir_instruction *) ir->ir)->fprint(stderr);
-               } else if (prog) {
-                  const prog_instruction *fpi;
-                  fpi = (const prog_instruction *) ir->ir;
-                  fprintf(stderr, "%d: ", (int)(fpi - prog->Instructions));
-                  _mesa_fprint_instruction_opt(stderr,
-                                               fpi,
-                                               0, PROG_PRINT_DEBUG, NULL);
-               }
-               fprintf(stderr, "\n");
-            }
+         ann[ann_num].offset = next_inst_offset;
+         ann[ann_num].ir = ir->ir;
+         ann[ann_num].annotation = ir->annotation;
+
+         if (cfg->blocks[block_num]->start == ir) {
+            ann[ann_num].block_start = cfg->blocks[block_num];
          }
-         if (last_annotation_string != ir->annotation) {
-            last_annotation_string = ir->annotation;
-            if (last_annotation_string)
-               fprintf(stderr, "   %s\n", last_annotation_string);
+         if (cfg->blocks[block_num]->end == ir) {
+            ann[ann_num].block_end = cfg->blocks[block_num];
+            block_num++;
          }
+         ann_num++;
       }
 
       for (unsigned int i = 0; i < 3; i++) {
@@ -1291,44 +1274,15 @@ gen8_fs_generator::generate_code(exec_list *instructions)
          }
          abort();
       }
-
-      if (unlikely(INTEL_DEBUG & DEBUG_WM)) {
-         gen8_dump_compile(brw, store, last_native_inst_offset, next_inst_offset, stderr);
-
-         foreach_list(node, &cfg->block_list) {
-            bblock_link *link = (bblock_link *)node;
-            bblock_t *block = link->block;
-
-            if (block->end == ir) {
-               fprintf(stderr, "   END B%d", block->block_num);
-               foreach_list(successor_node, &block->children) {
-                  bblock_link *successor_link =
-                     (bblock_link *)successor_node;
-                  bblock_t *successor_block = successor_link->block;
-                  fprintf(stderr, " ->B%d", successor_block->block_num);
-               }
-               fprintf(stderr, "\n");
-            }
-         }
-      }
-
-      last_native_inst_offset = next_inst_offset;
-   }
-
-   if (unlikely(INTEL_DEBUG & DEBUG_WM)) {
-      fprintf(stderr, "\n");
    }
 
    patch_jump_targets();
 
-   /* OK, while the INTEL_DEBUG=fs above is very nice for debugging FS
-    * emit issues, it doesn't get the jump distances into the output,
-    * which is often something we want to debug.  So this is here in
-    * case you're doing that.
-    */
-   if (0 && unlikely(INTEL_DEBUG & DEBUG_WM)) {
-      gen8_dump_compile(brw, store, 0, next_inst_offset, stderr);
+   if (unlikely(INTEL_DEBUG & DEBUG_WM)) {
+      ann[ann_num].offset = next_inst_offset;
    }
+   *num_annotations = ann_num;
+   *annotation = ann;
 }
 
 const unsigned *
@@ -1339,8 +1293,17 @@ gen8_fs_generator::generate_assembly(exec_list *simd8_instructions,
    assert(simd8_instructions || simd16_instructions);
 
    if (simd8_instructions) {
+      struct annotation *annotation;
+      int num_annotations;
+
       dispatch_width = 8;
-      generate_code(simd8_instructions);
+      generate_code(simd8_instructions, &num_annotations, &annotation);
+
+      if (unlikely(INTEL_DEBUG & DEBUG_WM)) {
+         dump_assembly(store, num_annotations, annotation, brw, prog,
+                       gen8_dump_compile, stderr);
+         ralloc_free(annotation);
+      }
    }
 
    if (simd16_instructions) {
@@ -1351,8 +1314,17 @@ gen8_fs_generator::generate_assembly(exec_list *simd8_instructions,
       /* Save off the start of this SIMD16 program */
       c->prog_data.prog_offset_16 = nr_inst * sizeof(gen8_instruction);
 
+      struct annotation *annotation;
+      int num_annotations;
+
       dispatch_width = 16;
-      generate_code(simd16_instructions);
+      generate_code(simd16_instructions, &num_annotations, &annotation);
+
+      if (unlikely(INTEL_DEBUG & DEBUG_WM)) {
+         dump_assembly(store, num_annotations, annotation, brw, prog,
+                       gen8_dump_compile, stderr);
+         ralloc_free(annotation);
+      }
    }
 
    *assembly_size = next_inst_offset;
diff --git a/src/mesa/drivers/dri/i965/gen8_vec4_generator.cpp b/src/mesa/drivers/dri/i965/gen8_vec4_generator.cpp
index 0c54e6d..026e677 100644
--- a/src/mesa/drivers/dri/i965/gen8_vec4_generator.cpp
+++ b/src/mesa/drivers/dri/i965/gen8_vec4_generator.cpp
@@ -841,12 +841,10 @@ gen8_vec4_generator::generate_vec4_instruction(vec4_instruction *instruction,
 }
 
 void
-gen8_vec4_generator::generate_code(exec_list *instructions)
+gen8_vec4_generator::generate_code(exec_list *instructions,
+                                   int *num_annotations,
+                                   annotation **annotation)
 {
-   int last_native_inst_offset = 0;
-   const char *last_annotation_string = NULL;
-   const void *last_annotation_ir = NULL;
-
    if (unlikely(debug_flag)) {
       if (shader_prog) {
          fprintf(stderr, "Native code for %s vertex shader %d:\n",
@@ -857,32 +855,39 @@ gen8_vec4_generator::generate_code(exec_list *instructions)
       }
    }
 
+   int block_num = 0;
+   int ann_num = 0;
+   int ann_size = 1024;
+   cfg_t *cfg = NULL;
+   struct annotation *ann = NULL;
+
+   if (unlikely(debug_flag)) {
+      cfg = new(mem_ctx) cfg_t(instructions);
+      ann = rzalloc_array(NULL, struct annotation, ann_size);
+   }
+
    foreach_list(node, instructions) {
       vec4_instruction *ir = (vec4_instruction *) node;
       struct brw_reg src[3], dst;
 
       if (unlikely(debug_flag)) {
-         if (last_annotation_ir != ir->ir) {
-            last_annotation_ir = ir->ir;
-            if (last_annotation_ir) {
-               fprintf(stderr, "   ");
-               if (shader_prog) {
-                  ((ir_instruction *) last_annotation_ir)->fprint(stderr);
-               } else {
-                  const prog_instruction *vpi;
-                  vpi = (const prog_instruction *) ir->ir;
-                  fprintf(stderr, "%d: ", (int)(vpi - prog->Instructions));
-                  _mesa_fprint_instruction_opt(stderr, vpi, 0,
-                                               PROG_PRINT_DEBUG, NULL);
-               }
-               fprintf(stderr, "\n");
-            }
+         if (ann_num == ann_size) {
+            ann_size *= 2;
+            ann = reralloc(NULL, ann, struct annotation, ann_size);
          }
-         if (last_annotation_string != ir->annotation) {
-            last_annotation_string = ir->annotation;
-            if (last_annotation_string)
-               fprintf(stderr, "   %s\n", last_annotation_string);
+
+         ann[ann_num].offset = next_inst_offset;
+         ann[ann_num].ir = ir->ir;
+         ann[ann_num].annotation = ir->annotation;
+
+         if (cfg->blocks[block_num]->start == ir) {
+            ann[ann_num].block_start = cfg->blocks[block_num];
+         }
+         if (cfg->blocks[block_num]->end == ir) {
+            ann[ann_num].block_end = cfg->blocks[block_num];
+            block_num++;
          }
+         ann_num++;
       }
 
       for (unsigned int i = 0; i < 3; i++) {
@@ -908,37 +913,34 @@ gen8_vec4_generator::generate_code(exec_list *instructions)
          gen8_set_no_dd_clear(last, ir->no_dd_clear);
          gen8_set_no_dd_check(last, ir->no_dd_check);
       }
-
-      if (unlikely(debug_flag)) {
-         gen8_dump_compile(brw, store, last_native_inst_offset, next_inst_offset, stderr);
-      }
-
-      last_native_inst_offset = next_inst_offset;
-   }
-
-   if (unlikely(debug_flag)) {
-      fprintf(stderr, "\n");
    }
 
    patch_jump_targets();
 
-   /* OK, while the INTEL_DEBUG=vs above is very nice for debugging VS
-    * emit issues, it doesn't get the jump distances into the output,
-    * which is often something we want to debug.  So this is here in
-    * case you're doing that.
-    */
-   if (0 && unlikely(debug_flag)) {
-      gen8_dump_compile(brw, store, 0, next_inst_offset, stderr);
+   if (unlikely(debug_flag)) {
+      ann[ann_num].offset = next_inst_offset;
    }
+   *num_annotations = ann_num;
+   *annotation = ann;
 }
 
 const unsigned *
 gen8_vec4_generator::generate_assembly(exec_list *instructions,
                                        unsigned *assembly_size)
 {
+   struct annotation *annotation;
+   int num_annotations;
+
    default_state.access_mode = BRW_ALIGN_16;
    default_state.exec_size = BRW_EXECUTE_8;
-   generate_code(instructions);
+   generate_code(instructions, &num_annotations, &annotation);
+
+   if (unlikely(debug_flag)) {
+      dump_assembly(store, num_annotations, annotation, brw, prog,
+                    gen8_dump_compile, stderr);
+      ralloc_free(annotation);
+   }
+
    *assembly_size = next_inst_offset;
    return (const unsigned *) store;
 }
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
index 0000000..6ccdfdb
--- /dev/null
+++ b/src/mesa/drivers/dri/i965/intel_asm_printer.c
@@ -0,0 +1,90 @@
+/*
+ * 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 "glsl/ir.h"
+#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, FILE *dump_file)
+{
+   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)
+               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
index 0000000..47eb75d
--- /dev/null
+++ b/src/mesa/drivers/dri/i965/intel_asm_printer.h
@@ -0,0 +1,52 @@
+/*
+ * 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 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, FILE *dump_file);
+
+#endif /* _INTEL_ASM_ANNOTATION_H */
-- 
1.8.3.2



More information about the mesa-dev mailing list