i965: Print disassembly after compaction.
authorMatt Turner <mattst88@gmail.com>
Mon, 19 May 2014 17:20:37 +0000 (10:20 -0700)
committerMatt Turner <mattst88@gmail.com>
Sun, 25 May 2014 06:03:23 +0000 (23:03 -0700)
Reviewed-by: Eric Anholt <eric@anholt.net>
src/mesa/drivers/dri/i965/brw_fs.h
src/mesa/drivers/dri/i965/brw_fs_generator.cpp
src/mesa/drivers/dri/i965/brw_shader.cpp
src/mesa/drivers/dri/i965/brw_shader.h
src/mesa/drivers/dri/i965/brw_vec4.h
src/mesa/drivers/dri/i965/brw_vec4_generator.cpp
src/mesa/drivers/dri/i965/gen8_fs_generator.cpp
src/mesa/drivers/dri/i965/gen8_vec4_generator.cpp
src/mesa/drivers/dri/i965/intel_asm_printer.h

index 111e994e0d9a9014847e4b0a403c0e6b71d8def1..60a4906cb187f7880e4714e8f780840b282d54b5 100644 (file)
@@ -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"
@@ -209,13 +210,6 @@ public:
    fs_reg dst;
    fs_reg src[3];
 
-   /** @{
-    * Annotation for the generated IR.  One of the two can be set.
-    */
-   const void *ir;
-   const char *annotation;
-   /** @} */
-
    uint32_t texture_offset; /**< Texture offset bitfield */
    uint32_t offset; /* spill/unspill offset */
 
@@ -611,7 +605,8 @@ public:
                                      unsigned *assembly_size);
 
 private:
-   void generate_code(exec_list *instructions);
+   void generate_code(exec_list *instructions,
+                      struct annotation_info *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);
@@ -738,7 +733,8 @@ public:
                                      unsigned *assembly_size);
 
 private:
-   void generate_code(exec_list *instructions);
+   void generate_code(exec_list *instructions,
+                      struct annotation_info *annotation);
    void generate_fb_write(fs_inst *inst);
    void generate_linterp(fs_inst *inst, struct brw_reg dst,
                          struct brw_reg *src);
index 132d5cd6501f0b1bd9d30c84bc23549e0ca8d180..6cff9b34ef93df27b3755735c8731f4e19702c32 100644 (file)
@@ -1322,12 +1322,9 @@ fs_generator::generate_untyped_surface_read(fs_inst *inst, struct brw_reg dst,
 }
 
 void
-fs_generator::generate_code(exec_list *instructions)
+fs_generator::generate_code(exec_list *instructions,
+                            struct annotation_info *annotation)
 {
-   int last_native_insn_offset = p->next_insn_offset;
-   const char *last_annotation_string = NULL;
-   const void *last_annotation_ir = NULL;
-
    if (unlikely(debug_flag)) {
       if (prog) {
          fprintf(stderr,
@@ -1352,47 +1349,8 @@ fs_generator::generate_code(exec_list *instructions)
       fs_inst *inst = (fs_inst *)node;
       struct brw_reg src[3], dst;
 
-      if (unlikely(debug_flag)) {
-        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 (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);
-        }
-      }
+      if (unlikely(debug_flag))
+         annotate(brw, annotation, cfg, inst, p->next_insn_offset);
 
       for (unsigned int i = 0; i < 3; i++) {
         src[i] = brw_reg_from_fs_reg(&inst->src[i]);
@@ -1792,7 +1750,9 @@ fs_generator::generate_code(exec_list *instructions)
          /* This is the place where the final HALT needs to be inserted if
           * we've emitted any discards.  If not, this will emit no code.
           */
-         patch_discard_jumps_to_fb_writes();
+         if (!patch_discard_jumps_to_fb_writes()) {
+            annotation->ann_count--;
+         }
          break;
 
       default:
@@ -1804,44 +1764,10 @@ fs_generator::generate_code(exec_list *instructions)
         }
         abort();
       }
-
-      if (unlikely(debug_flag)) {
-        brw_disassemble(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(debug_flag)) {
-      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 (0) {
-      brw_disassemble(brw, p->store, 0, p->next_insn_offset, stderr);
-   }
+   annotation_finalize(annotation, p->next_insn_offset);
 }
 
 const unsigned *
@@ -1851,10 +1777,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_info annotation;
+      memset(&annotation, 0, sizeof(annotation));
+
       dispatch_width = 8;
-      generate_code(simd8_instructions);
-      brw_compact_instructions(p, 0, 0, NULL);
+      generate_code(simd8_instructions, &annotation);
+      brw_compact_instructions(p, 0, annotation.ann_count, annotation.ann);
+
+      if (unlikely(debug_flag)) {
+         dump_assembly(p->store, annotation.ann_count, annotation.ann,
+                       brw, prog, brw_disassemble);
+         ralloc_free(annotation.ann);
+      }
    }
 
    if (simd16_instructions) {
@@ -1868,9 +1805,19 @@ fs_generator::generate_assembly(exec_list *simd8_instructions,
 
       brw_set_compression_control(p, BRW_COMPRESSION_COMPRESSED);
 
+      struct annotation_info annotation;
+      memset(&annotation, 0, sizeof(annotation));
+
       dispatch_width = 16;
-      generate_code(simd16_instructions);
-      brw_compact_instructions(p, prog_data->prog_offset_16, 0, NULL);
+      generate_code(simd16_instructions, &annotation);
+      brw_compact_instructions(p, prog_data->prog_offset_16,
+                               annotation.ann_count, annotation.ann);
+
+      if (unlikely(debug_flag)) {
+         dump_assembly(p->store, annotation.ann_count, annotation.ann,
+                       brw, prog, brw_disassemble);
+         ralloc_free(annotation.ann);
+      }
    }
 
    return brw_get_program(p, assembly_size);
index 714c603f26367c0711632d9a88dd5c669c0c37df..f4f1334d9ef56d6c7e03f4f03eae77c8e98241a6 100644 (file)
@@ -28,6 +28,7 @@ extern "C" {
 #include "brw_vs.h"
 #include "brw_vec4_gs.h"
 #include "brw_fs.h"
+#include "brw_cfg.h"
 #include "glsl/ir_optimization.h"
 #include "glsl/glsl_parser_extras.h"
 #include "main/shaderapi.h"
@@ -760,3 +761,56 @@ backend_visitor::assign_common_binding_table_offsets(uint32_t next_binding_table
 
    /* prog_data->base.binding_table.size will be set by brw_mark_surface_used. */
 }
+
+void annotate(struct brw_context *brw,
+              struct annotation_info *annotation, cfg_t *cfg,
+              backend_instruction *inst, unsigned offset)
+{
+   if (annotation->ann_size <= annotation->ann_count) {
+      annotation->ann_size = MAX2(1024, annotation->ann_size * 2);
+      annotation->ann = reralloc(annotation->mem_ctx, annotation->ann,
+                                 struct annotation, annotation->ann_size);
+      if (!annotation->ann)
+         return;
+   }
+
+   struct annotation *ann = &annotation->ann[annotation->ann_count++];
+   ann->offset = offset;
+   ann->ir = inst->ir;
+   ann->annotation = inst->annotation;
+
+   if (cfg->blocks[annotation->cur_block]->start == inst) {
+      ann->block_start = cfg->blocks[annotation->cur_block];
+   }
+
+   /* There is no hardware DO instruction on Gen6+, so since DO always
+    * starts a basic block, we need to set the .block_start of the next
+    * instruction's annotation with a pointer to the bblock started by
+    * the DO.
+    *
+    * There's also only complication from emitting an annotation without
+    * a corresponding hardware instruction to disassemble.
+    */
+   if (brw->gen >= 6 && inst->opcode == BRW_OPCODE_DO) {
+      annotation->ann_count--;
+   }
+
+   if (cfg->blocks[annotation->cur_block]->end == inst) {
+      ann->block_end = cfg->blocks[annotation->cur_block];
+      annotation->cur_block++;
+   }
+}
+
+void
+annotation_finalize(struct annotation_info *annotation,
+                    unsigned next_inst_offset)
+{
+   if (!annotation->ann_count)
+      return;
+
+   if (annotation->ann_count == annotation->ann_size) {
+      annotation->ann = reralloc(annotation->mem_ctx, annotation->ann,
+                                 struct annotation, annotation->ann_size + 1);
+   }
+   annotation->ann[annotation->ann_count].offset = next_inst_offset;
+}
index 5ae4092ac872bff696d34c75714358515c44e9d5..5af6e082df28e339c56cddfe69dcf2bdfdd6c9bd 100644 (file)
@@ -25,6 +25,7 @@
 #include "brw_defines.h"
 #include "main/compiler.h"
 #include "glsl/ir.h"
+#include "intel_asm_printer.h"
 
 #pragma once
 
@@ -40,6 +41,8 @@ enum PACKED register_file {
 
 #ifdef __cplusplus
 
+class cfg_t;
+
 class backend_instruction : public exec_node {
 public:
    bool is_tex() const;
@@ -62,6 +65,13 @@ public:
    uint8_t predicate;
    bool predicate_inverse;
    bool writes_accumulator; /**< instruction implicitly writes accumulator */
+
+   /** @{
+    * Annotation for the generated IR.  One of the two can be set.
+    */
+   const void *ir;
+   const char *annotation;
+   /** @} */
 };
 
 enum instruction_scheduler_mode {
@@ -108,6 +118,11 @@ public:
 
 uint32_t brw_texture_offset(struct gl_context *ctx, ir_constant *offset);
 
+void annotate(struct brw_context *brw,
+              struct annotation_info *annotation, cfg_t *cfg,
+              backend_instruction *inst, unsigned offset);
+void annotation_finalize(struct annotation_info *annotation, unsigned offset);
+
 #endif /* __cplusplus */
 
 int brw_type_for_base_type(const struct glsl_type *type);
index a86972a8d452654ecb417b2d06ac7b0bedffb935..4b2b01942b472243c20c79d41f41cf99728ce1b6 100644 (file)
@@ -36,6 +36,7 @@ extern "C" {
 
 #include "brw_context.h"
 #include "brw_eu.h"
+#include "intel_asm_printer.h"
 
 #ifdef __cplusplus
 }; /* extern "C" */
@@ -260,12 +261,6 @@ public:
    int base_mrf; /**< First MRF in the SEND message, if mlen is nonzero. */
 
    uint32_t offset; /* spill/unspill offset */
-   /** @{
-    * Annotation for the generated IR.  One of the two can be set.
-    */
-   const void *ir;
-   const char *annotation;
-   /** @} */
 
    bool is_send_from_grf();
    bool can_reswizzle_dst(int dst_writemask, int swizzle, int swizzle_mask);
@@ -650,7 +645,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,
+                      struct annotation_info *annotation);
    void generate_vec4_instruction(vec4_instruction *inst,
                                   struct brw_reg dst,
                                   struct brw_reg *src);
@@ -751,7 +747,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,
+                      struct annotation_info *annotation);
    void generate_vec4_instruction(vec4_instruction *inst,
                                   struct brw_reg dst,
                                   struct brw_reg *src);
index a91bfe7948f246c04a25e7f4b6b9be8960050590..29ca7602e0b14399fc0d3f1324ceea744a5759c2 100644 (file)
@@ -21,6 +21,7 @@
  */
 
 #include "brw_vec4.h"
+#include "brw_cfg.h"
 
 extern "C" {
 #include "brw_eu.h"
@@ -1260,12 +1261,9 @@ vec4_generator::generate_vec4_instruction(vec4_instruction *instruction,
 }
 
 void
-vec4_generator::generate_code(exec_list *instructions)
+vec4_generator::generate_code(exec_list *instructions,
+                              struct annotation_info *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,33 +1274,16 @@ vec4_generator::generate_code(exec_list *instructions)
       }
    }
 
+   cfg_t *cfg = NULL;
+   if (unlikely(debug_flag))
+      cfg = new(mem_ctx) cfg_t(instructions);
+
    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 (unlikely(debug_flag))
+         annotate(brw, annotation, cfg, inst, p->next_insn_offset);
 
       for (unsigned int i = 0; i < 3; i++) {
         src[i] = inst->get_src(this->prog_data, i);
@@ -1332,38 +1313,29 @@ vec4_generator::generate_code(exec_list *instructions)
          if (inst->no_dd_check)
             last->header.dependency_control |= BRW_DEPENDENCY_NOTCHECKED;
       }
-
-      if (unlikely(debug_flag)) {
-        brw_disassemble(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_disassemble(brw, p->store, 0, p->next_insn_offset, stderr);
-   }
+   annotation_finalize(annotation, p->next_insn_offset);
 }
 
 const unsigned *
 vec4_generator::generate_assembly(exec_list *instructions,
                                   unsigned *assembly_size)
 {
+   struct annotation_info annotation;
+   memset(&annotation, 0, sizeof(annotation));
+
    brw_set_access_mode(p, BRW_ALIGN_16);
-   generate_code(instructions);
-   brw_compact_instructions(p, 0, 0, NULL);
+   generate_code(instructions, &annotation);
+   brw_compact_instructions(p, 0, annotation.ann_count, annotation.ann);
+
+   if (unlikely(debug_flag)) {
+      dump_assembly(p->store, annotation.ann_count, annotation.ann,
+                    brw, prog, brw_disassemble);
+      ralloc_free(annotation.ann);
+   }
+
    return brw_get_program(p, assembly_size);
 }
 
index d01b4d8a3ca0ab404ab68d9f2e87970150f693be..aec9421e853575ff70808d3239ba6189d70fe952 100644 (file)
@@ -884,12 +884,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,
+                                 struct annotation_info *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,
@@ -914,46 +911,8 @@ gen8_fs_generator::generate_code(exec_list *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 (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");
-            }
-         }
-         if (last_annotation_string != ir->annotation) {
-            last_annotation_string = ir->annotation;
-            if (last_annotation_string)
-               fprintf(stderr, "   %s\n", last_annotation_string);
-         }
-      }
+      if (unlikely(INTEL_DEBUG & DEBUG_WM))
+         annotate(brw, annotation, cfg, ir, next_inst_offset);
 
       for (unsigned int i = 0; i < 3; i++) {
          src[i] = brw_reg_from_fs_reg(&ir->src[i]);
@@ -1296,44 +1255,10 @@ gen8_fs_generator::generate_code(exec_list *instructions)
          }
          abort();
       }
-
-      if (unlikely(INTEL_DEBUG & DEBUG_WM)) {
-         gen8_disassemble(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_disassemble(brw, store, 0, next_inst_offset, stderr);
-   }
+   annotation_finalize(annotation, next_inst_offset);
 }
 
 const unsigned *
@@ -1344,8 +1269,17 @@ gen8_fs_generator::generate_assembly(exec_list *simd8_instructions,
    assert(simd8_instructions || simd16_instructions);
 
    if (simd8_instructions) {
+      struct annotation_info annotation;
+      memset(&annotation, 0, sizeof(annotation));
+
       dispatch_width = 8;
-      generate_code(simd8_instructions);
+      generate_code(simd8_instructions, &annotation);
+
+      if (unlikely(INTEL_DEBUG & DEBUG_WM)) {
+         dump_assembly(store, annotation.ann_count, annotation.ann, brw, prog,
+                       gen8_disassemble);
+         ralloc_free(annotation.ann);
+      }
    }
 
    if (simd16_instructions) {
@@ -1356,8 +1290,17 @@ gen8_fs_generator::generate_assembly(exec_list *simd8_instructions,
       /* Save off the start of this SIMD16 program */
       prog_data->prog_offset_16 = nr_inst * sizeof(gen8_instruction);
 
+      struct annotation_info annotation;
+      memset(&annotation, 0, sizeof(annotation));
+
       dispatch_width = 16;
-      generate_code(simd16_instructions);
+      generate_code(simd16_instructions, &annotation);
+
+      if (unlikely(INTEL_DEBUG & DEBUG_WM)) {
+         dump_assembly(store, annotation.ann_count, annotation.ann,
+                       brw, prog, gen8_disassemble);
+         ralloc_free(annotation.ann);
+      }
    }
 
    *assembly_size = next_inst_offset;
index e53fd35fb607c7d800d54c67b55cbc6a97d93263..c291a9d64bb15e837547e4083be23e9022eed9ca 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 #include "brw_vec4.h"
+#include "brw_cfg.h"
 
 extern "C" {
 #include "brw_eu.h"
@@ -841,12 +842,9 @@ 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,
+                                   struct annotation_info *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,33 +855,16 @@ gen8_vec4_generator::generate_code(exec_list *instructions)
       }
    }
 
+   cfg_t *cfg = NULL;
+   if (unlikely(debug_flag))
+      cfg = new(mem_ctx) cfg_t(instructions);
+
    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 (last_annotation_string != ir->annotation) {
-            last_annotation_string = ir->annotation;
-            if (last_annotation_string)
-               fprintf(stderr, "   %s\n", last_annotation_string);
-         }
-      }
+      if (unlikely(debug_flag))
+         annotate(brw, annotation, cfg, ir, next_inst_offset);
 
       for (unsigned int i = 0; i < 3; i++) {
          src[i] = ir->get_src(prog_data, i);
@@ -908,37 +889,29 @@ 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_disassemble(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_disassemble(brw, store, 0, next_inst_offset, stderr);
-   }
+   annotation_finalize(annotation, next_inst_offset);
 }
 
 const unsigned *
 gen8_vec4_generator::generate_assembly(exec_list *instructions,
                                        unsigned *assembly_size)
 {
+   struct annotation_info annotation;
+   memset(&annotation, 0, sizeof(annotation));
+
    default_state.access_mode = BRW_ALIGN_16;
    default_state.exec_size = BRW_EXECUTE_8;
-   generate_code(instructions);
+   generate_code(instructions, &annotation);
+
+   if (unlikely(debug_flag)) {
+      dump_assembly(store, annotation.ann_count, annotation.ann,
+                    brw, prog, gen8_disassemble);
+      ralloc_free(annotation.ann);
+   }
+
    *assembly_size = next_inst_offset;
    return (const unsigned *) store;
 }
index 893c76bde4fe7e2f1e23f6f48d6783375f7309cc..dfe64d6c2fa0ed5b29b8e2684039a6667d19f8c2 100644 (file)
 #ifndef _INTEL_ASM_ANNOTATION_H
 #define _INTEL_ASM_ANNOTATION_H
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 struct bblock_t;
 struct brw_context;
 struct gl_program;
@@ -42,6 +46,16 @@ struct annotation {
    const char *annotation;
 };
 
+struct annotation_info {
+   void *mem_ctx;
+   struct annotation *ann;
+   int ann_count;
+   int ann_size;
+
+   /** Block index in the cfg. */
+   int cur_block;
+};
+
 typedef void (*disassemble_func)(struct brw_context *brw, void *assembly,
                                  int start, int end, FILE *out);
 
@@ -50,4 +64,8 @@ dump_assembly(void *assembly, int num_annotations, struct annotation *annotation
               struct brw_context *brw, const struct gl_program *prog,
               disassemble_func disassemble);
 
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
 #endif /* _INTEL_ASM_ANNOTATION_H */