diff options
author | Matt Turner <[email protected]> | 2017-11-15 17:08:42 -0800 |
---|---|---|
committer | Matt Turner <[email protected]> | 2017-11-17 12:14:38 -0800 |
commit | 4f82b17287194ca7d10816f6cfe4712a3e0a03fc (patch) | |
tree | 7e2bb056e5c389643e9338e4359e5aae9ab49f92 /src/intel/compiler/intel_asm_annotation.c | |
parent | f80e97346b0da9fab3d60b46bdcf0a0d702f97c9 (diff) |
i965: Rewrite disassembly annotation code
The old code used an array to store each "instruction group" (the new,
better name than the old overloaded "annotation"), and required a
memmove() to shift elements over in the array when we needed to split a
group so that we could add an error message. This was confusing and
difficult to get right, not the least of which was because the array
has a tail sentinel not included in .ann_count.
Instead use a linked list, a data structure made for efficient
insertion.
Acked-by: Samuel Iglesias Gonsálvez <[email protected]>
Reviewed-by: Kenneth Graunke <[email protected]>
Diffstat (limited to 'src/intel/compiler/intel_asm_annotation.c')
-rw-r--r-- | src/intel/compiler/intel_asm_annotation.c | 169 |
1 files changed, 83 insertions, 86 deletions
diff --git a/src/intel/compiler/intel_asm_annotation.c b/src/intel/compiler/intel_asm_annotation.c index 26ab4b98188..2ebe6dd8464 100644 --- a/src/intel/compiler/intel_asm_annotation.c +++ b/src/intel/compiler/intel_asm_annotation.c @@ -30,51 +30,58 @@ __attribute__((weak)) void nir_print_instr(const nir_instr *instr, FILE *fp) {} void -dump_assembly(void *assembly, int num_annotations, struct annotation *annotation, - const struct gen_device_info *devinfo) +dump_assembly(void *assembly, struct disasm_info *disasm) { + const struct gen_device_info *devinfo = disasm->devinfo; 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; + foreach_list_typed(struct inst_group, group, link, &disasm->group_list) { + struct exec_node *next_node = exec_node_get_next(&group->link); + if (exec_node_is_tail_sentinel(next_node)) + break; - if (annotation[i].block_start) { - fprintf(stderr, " START B%d", annotation[i].block_start->num); + struct inst_group *next = + exec_node_data(struct inst_group, next_node, link); + + int start_offset = group->offset; + int end_offset = next->offset; + + if (group->block_start) { + fprintf(stderr, " START B%d", group->block_start->num); foreach_list_typed(struct bblock_link, predecessor_link, link, - &annotation[i].block_start->parents) { + &group->block_start->parents) { struct bblock_t *predecessor_block = predecessor_link->block; fprintf(stderr, " <-B%d", predecessor_block->num); } - fprintf(stderr, " (%u cycles)\n", annotation[i].block_start->cycle_count); + fprintf(stderr, " (%u cycles)\n", group->block_start->cycle_count); } - if (last_annotation_ir != annotation[i].ir) { - last_annotation_ir = annotation[i].ir; + if (last_annotation_ir != group->ir) { + last_annotation_ir = group->ir; if (last_annotation_ir) { fprintf(stderr, " "); - nir_print_instr(annotation[i].ir, stderr); + nir_print_instr(group->ir, stderr); fprintf(stderr, "\n"); } } - if (last_annotation_string != annotation[i].annotation) { - last_annotation_string = annotation[i].annotation; + if (last_annotation_string != group->annotation) { + last_annotation_string = group->annotation; if (last_annotation_string) fprintf(stderr, " %s\n", last_annotation_string); } brw_disassemble(devinfo, assembly, start_offset, end_offset, stderr); - if (annotation[i].error) { - fputs(annotation[i].error, stderr); + if (group->error) { + fputs(group->error, stderr); } - if (annotation[i].block_end) { - fprintf(stderr, " END B%d", annotation[i].block_end->num); + if (group->block_end) { + fprintf(stderr, " END B%d", group->block_end->num); foreach_list_typed(struct bblock_link, successor_link, link, - &annotation[i].block_end->children) { + &group->block_end->children) { struct bblock_t *successor_block = successor_link->block; fprintf(stderr, " ->B%d", successor_block->num); } @@ -84,43 +91,51 @@ dump_assembly(void *assembly, int num_annotations, struct annotation *annotation fprintf(stderr, "\n"); } -static bool -annotation_array_ensure_space(struct annotation_info *annotation) +struct disasm_info * +disasm_initialize(const struct gen_device_info *devinfo, + const struct cfg_t *cfg) { - if (annotation->ann_size <= annotation->ann_count) { - int old_size = annotation->ann_size; - annotation->ann_size = MAX2(1024, annotation->ann_size * 2); - annotation->ann = reralloc(annotation->mem_ctx, annotation->ann, - struct annotation, annotation->ann_size); - if (!annotation->ann) - return false; - - memset(annotation->ann + old_size, 0, - (annotation->ann_size - old_size) * sizeof(struct annotation)); - } - - return true; + struct disasm_info *disasm = ralloc(NULL, struct disasm_info); + exec_list_make_empty(&disasm->group_list); + disasm->devinfo = devinfo; + disasm->cfg = cfg; + disasm->cur_block = 0; + disasm->use_tail = false; + return disasm; } -void annotate(const struct gen_device_info *devinfo, - struct annotation_info *annotation, const struct cfg_t *cfg, - struct backend_instruction *inst, unsigned offset) +struct inst_group * +disasm_new_inst_group(struct disasm_info *disasm, unsigned next_inst_offset) { - if (annotation->mem_ctx == NULL) - annotation->mem_ctx = ralloc_context(NULL); + struct inst_group *tail = rzalloc(disasm, struct inst_group); + tail->offset = next_inst_offset; + exec_list_push_tail(&disasm->group_list, &tail->link); + return tail; +} - if (!annotation_array_ensure_space(annotation)) - return; +void +disasm_annotate(struct disasm_info *disasm, + struct backend_instruction *inst, unsigned offset) +{ + const struct gen_device_info *devinfo = disasm->devinfo; + const struct cfg_t *cfg = disasm->cfg; + + struct inst_group *group; + if (!disasm->use_tail) { + group = disasm_new_inst_group(disasm, offset); + disasm->use_tail = false; + } else { + group = exec_node_data(struct inst_group, + exec_list_get_tail_raw(&disasm->group_list), link); + } - struct annotation *ann = &annotation->ann[annotation->ann_count++]; - ann->offset = offset; if ((INTEL_DEBUG & DEBUG_ANNOTATION) != 0) { - ann->ir = inst->ir; - ann->annotation = inst->annotation; + group->ir = inst->ir; + group->annotation = inst->annotation; } - if (bblock_start(cfg->blocks[annotation->cur_block]) == inst) { - ann->block_start = cfg->blocks[annotation->cur_block]; + if (bblock_start(cfg->blocks[disasm->cur_block]) == inst) { + group->block_start = cfg->blocks[disasm->cur_block]; } /* There is no hardware DO instruction on Gen6+, so since DO always @@ -132,66 +147,48 @@ void annotate(const struct gen_device_info *devinfo, * a corresponding hardware instruction to disassemble. */ if (devinfo->gen >= 6 && inst->opcode == BRW_OPCODE_DO) { - annotation->ann_count--; + disasm->use_tail = true; } - if (bblock_end(cfg->blocks[annotation->cur_block]) == inst) { - ann->block_end = cfg->blocks[annotation->cur_block]; - annotation->cur_block++; - } -} - -void -annotation_finalize(struct annotation_info *annotation, - unsigned next_inst_offset) -{ - if (!annotation->ann_count) - return; - - if (annotation->ann_count == annotation->ann_size) { - annotation->ann = reralloc(annotation->mem_ctx, annotation->ann, - struct annotation, annotation->ann_size + 1); + if (bblock_end(cfg->blocks[disasm->cur_block]) == inst) { + group->block_end = cfg->blocks[disasm->cur_block]; + disasm->cur_block++; } - annotation->ann[annotation->ann_count].offset = next_inst_offset; } void -annotation_insert_error(struct annotation_info *annotation, unsigned offset, - const char *error) +disasm_insert_error(struct disasm_info *disasm, unsigned offset, + const char *error) { - if (!annotation->ann_count) - return; - - /* We may have to split an annotation, so ensure we have enough space - * allocated for that case up front. - */ - if (!annotation_array_ensure_space(annotation)) - return; - - assume(annotation->ann_count > 0); + foreach_list_typed(struct inst_group, cur, link, &disasm->group_list) { + struct exec_node *next_node = exec_node_get_next(&cur->link); + if (exec_node_is_tail_sentinel(next_node)) + break; - for (int i = 0; i < annotation->ann_count; i++) { - struct annotation *cur = &annotation->ann[i]; - struct annotation *next = &annotation->ann[i + 1]; + struct inst_group *next = + exec_node_data(struct inst_group, next_node, link); if (next->offset <= offset) continue; if (offset + sizeof(brw_inst) != next->offset) { - memmove(next, cur, - (annotation->ann_count - i + 2) * sizeof(struct annotation)); + struct inst_group *new = ralloc(disasm, struct inst_group); + memcpy(new, cur, sizeof(struct inst_group)); + cur->error = NULL; cur->error_length = 0; cur->block_end = NULL; - next->offset = offset + sizeof(brw_inst); - next->block_start = NULL; - annotation->ann_count++; + + new->offset = offset + sizeof(brw_inst); + new->block_start = NULL; + + exec_node_insert_after(&cur->link, &new->link); } if (cur->error) ralloc_strcat(&cur->error, error); else - cur->error = ralloc_strdup(annotation->mem_ctx, error); + cur->error = ralloc_strdup(disasm, error); return; } } |