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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev