Will be used to print disassembly after jump targets are set and instructions are compacted, while still retaining higher-level IR annotations and basic block information.
An array of 'struct annotation' will live along side the generated assembly. The generators will populate the array with their IR annotations, and basic block pointers if the instructions began or ended a basic block pointer. We'll then update the instruction offset when we compact instructions and then using the annotations print the disassembly. --- 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 | 4 +- src/mesa/drivers/dri/i965/brw_eu_compact.c | 31 ++++++++- src/mesa/drivers/dri/i965/brw_fs_generator.cpp | 4 +- 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_generator.cpp | 2 +- src/mesa/drivers/dri/i965/intel_asm_printer.c | 89 ++++++++++++++++++++++++ src/mesa/drivers/dri/i965/intel_asm_printer.h | 53 ++++++++++++++ 11 files changed, 183 insertions(+), 9 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 5fc90b5..2570059 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 4b2c667..ea0065a 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, 0); + brw_compact_instructions(&func, 0, 0, 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 57c49f0..536c085 100644 --- a/src/mesa/drivers/dri/i965/brw_clip.c +++ b/src/mesa/drivers/dri/i965/brw_clip.c @@ -110,7 +110,7 @@ static void compile_clip_prog( struct brw_context *brw, return; } - brw_compact_instructions(&c.func, 0); + brw_compact_instructions(&c.func, 0, 0, NULL); /* get the program */ diff --git a/src/mesa/drivers/dri/i965/brw_eu.h b/src/mesa/drivers/dri/i965/brw_eu.h index 65008a0..8ce31a1 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 @@ -410,7 +411,8 @@ uint32_t brw_swap_cmod(uint32_t cmod); /* brw_eu_compact.c */ void brw_init_compaction_tables(struct brw_context *brw); -void brw_compact_instructions(struct brw_compile *p, int start_offset); +void brw_compact_instructions(struct brw_compile *p, int start_offset, + int num_annotations, struct annotation *annotation); void brw_uncompact_instruction(struct brw_context *brw, struct brw_instruction *dst, struct brw_compact_instruction *src); diff --git a/src/mesa/drivers/dri/i965/brw_eu_compact.c b/src/mesa/drivers/dri/i965/brw_eu_compact.c index c3a2ec3..40d1fc2 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,8 @@ brw_init_compaction_tables(struct brw_context *brw) } void -brw_compact_instructions(struct brw_compile *p, int start_offset) +brw_compact_instructions(struct brw_compile *p, int start_offset, + int num_annotations, struct annotation *annotation) { struct brw_context *brw = p->brw; void *store = p->store + start_offset / 16; @@ -784,6 +786,33 @@ brw_compact_instructions(struct brw_compile *p, int start_offset) } p->nr_insn = p->next_insn_offset / 16; + /* Update the instruction offsets for each annotation. */ + if (annotation) { + for (int offset = 0, i = 0; i < num_annotations; i++) { + while (start_offset + old_ip[offset / 8] * 8 != annotation[i].offset) { + assert(start_offset + old_ip[offset / 8] * 8 < + annotation[i].offset); + struct brw_instruction *insn = store + offset; + if (insn->header.cmpt_control) { + offset += 8; + } else { + offset += 16; + } + } + + annotation[i].offset = start_offset + offset; + + struct brw_instruction *insn = store + offset; + if (insn->header.cmpt_control) { + offset += 8; + } else { + offset += 16; + } + } + + annotation[num_annotations].offset = p->next_insn_offset; + } + if (0) { fprintf(stderr, "dumping compacted program\n"); brw_disassemble(brw, store, 0, p->next_insn_offset - start_offset, stderr); diff --git a/src/mesa/drivers/dri/i965/brw_fs_generator.cpp b/src/mesa/drivers/dri/i965/brw_fs_generator.cpp index bf3f32c..0fcf527 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_generator.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_generator.cpp @@ -1853,7 +1853,7 @@ fs_generator::generate_assembly(exec_list *simd8_instructions, if (simd8_instructions) { dispatch_width = 8; generate_code(simd8_instructions); - brw_compact_instructions(p, 0); + brw_compact_instructions(p, 0, 0, NULL); } if (simd16_instructions) { @@ -1869,7 +1869,7 @@ fs_generator::generate_assembly(exec_list *simd8_instructions, dispatch_width = 16; generate_code(simd16_instructions); - brw_compact_instructions(p, prog_data->prog_offset_16); + brw_compact_instructions(p, prog_data->prog_offset_16, 0, NULL); } return brw_get_program(p, assembly_size); diff --git a/src/mesa/drivers/dri/i965/brw_gs.c b/src/mesa/drivers/dri/i965/brw_gs.c index 18b0956..97a2ee3 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, 0); + brw_compact_instructions(&c.func, 0, 0, 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 e11de26..aad0310 100644 --- a/src/mesa/drivers/dri/i965/brw_sf.c +++ b/src/mesa/drivers/dri/i965/brw_sf.c @@ -109,7 +109,7 @@ static void compile_sf_prog( struct brw_context *brw, return; } - brw_compact_instructions(&c.func, 0); + brw_compact_instructions(&c.func, 0, 0, NULL); /* get the program */ diff --git a/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp b/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp index e4bc682..a91bfe7 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp @@ -1363,7 +1363,7 @@ vec4_generator::generate_assembly(exec_list *instructions, { brw_set_access_mode(p, BRW_ALIGN_16); generate_code(instructions); - brw_compact_instructions(p, 0); + brw_compact_instructions(p, 0, 0, NULL); return brw_get_program(p, assembly_size); } diff --git a/src/mesa/drivers/dri/i965/intel_asm_printer.c b/src/mesa/drivers/dri/i965/intel_asm_printer.c new file mode 100644 index 0000000..7904dfc --- /dev/null +++ b/src/mesa/drivers/dri/i965/intel_asm_printer.c @@ -0,0 +1,89 @@ +/* + * Copyright © 2014 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "brw_cfg.h" +#include "intel_asm_printer.h" +#include "program/prog_print.h" +#include "program/prog_instruction.h" + +void +dump_assembly(void *assembly, int num_annotations, struct annotation *annotation, + struct brw_context *brw, const struct gl_program *prog, + disassemble_func disassemble) +{ + const char *last_annotation_string = NULL; + const void *last_annotation_ir = NULL; + + for (int i = 0; i < num_annotations; i++) { + int start_offset = annotation[i].offset; + int end_offset = annotation[i + 1].offset; + + if (annotation[i].block_start) { + fprintf(stderr, " START B%d", annotation[i].block_start->block_num); + foreach_list_typed(struct bblock_link, predecessor_link, link, + &annotation[i].block_start->parents) { + struct bblock_t *predecessor_block = predecessor_link->block; + fprintf(stderr, " <-B%d", predecessor_block->block_num); + } + fprintf(stderr, "\n"); + } + + if (last_annotation_ir != annotation[i].ir) { + last_annotation_ir = annotation[i].ir; + if (last_annotation_ir) { + fprintf(stderr, " "); + if (prog) + 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..893c76b --- /dev/null +++ b/src/mesa/drivers/dri/i965/intel_asm_printer.h @@ -0,0 +1,53 @@ +/* + * Copyright © 2014 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef _INTEL_ASM_ANNOTATION_H +#define _INTEL_ASM_ANNOTATION_H + +struct bblock_t; +struct brw_context; +struct gl_program; + +struct annotation { + int offset; + + /* Pointers to the basic block in the CFG if the instruction group starts + * or ends a basic block. + */ + struct bblock_t *block_start; + struct bblock_t *block_end; + + /* Annotation for the generated IR. One of the two can be set. */ + const void *ir; + const char *annotation; +}; + +typedef void (*disassemble_func)(struct brw_context *brw, void *assembly, + int start, int end, FILE *out); + +void +dump_assembly(void *assembly, int num_annotations, struct annotation *annotation, + struct brw_context *brw, const struct gl_program *prog, + disassemble_func disassemble); + +#endif /* _INTEL_ASM_ANNOTATION_H */ -- 1.8.3.2 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev