From a35b9cb625495e51a42b56cd1d8d2cb019abe243 Mon Sep 17 00:00:00 2001 From: Matt Turner Date: Mon, 19 May 2014 10:17:51 -0700 Subject: [PATCH] i965: Add annotation data structure and support code. 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. Reviewed-by: Eric Anholt --- 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 ++++++- .../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 +- .../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 5fc90b54a75..25700593d36 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 4b2c6672e0a..ea0065a6782 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 57c49f0235d..536c0859da6 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 65008a0513b..8ce31a1d3b9 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 c3a2ec31c74..40d1fc23ec8 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 bf3f32cb069..0fcf5271c21 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 18b09560c2c..97a2ee39bf3 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 e11de264f2e..aad0310ccec 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 e4bc6823ec9..a91bfe7948f 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 00000000000..f533e7cf284 --- /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->Instructions) + 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 00000000000..893c76bde4f --- /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 */ -- 2.30.2