[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