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 <eric@anholt.net>
This commit is contained in:
Matt Turner 2014-05-19 10:17:51 -07:00
parent 59f4e80d53
commit a35b9cb625
11 changed files with 183 additions and 9 deletions

View file

@ -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 \

View file

@ -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);
}

View file

@ -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
*/

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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
*/

View file

@ -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
*/

View file

@ -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);
}

View file

@ -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");
}

View file

@ -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 */