For the series: Reviewed-by: Marek Olšák <[email protected]>
Marek On Tue, Jan 23, 2018 at 11:17 AM, Nicolai Hähnle <[email protected]> wrote: > From: Nicolai Hähnle <[email protected]> > > LLVM now emits labels as part of the disassembly string, which is very > useful but breaks the old parsing approach. > > Use the semicolon to detect the boundary of instructions instead of going > by line breaks. > --- > src/gallium/drivers/radeonsi/si_debug.c | 63 > +++++++++++++++++---------------- > 1 file changed, 32 insertions(+), 31 deletions(-) > > diff --git a/src/gallium/drivers/radeonsi/si_debug.c > b/src/gallium/drivers/radeonsi/si_debug.c > index b24d5e705f5..8334c49a0ee 100644 > --- a/src/gallium/drivers/radeonsi/si_debug.c > +++ b/src/gallium/drivers/radeonsi/si_debug.c > @@ -23,20 +23,21 @@ > > #include "si_pipe.h" > #include "si_compute.h" > #include "sid.h" > #include "gfx9d.h" > #include "sid_tables.h" > #include "ddebug/dd_util.h" > #include "util/u_dump.h" > #include "util/u_log.h" > #include "util/u_memory.h" > +#include "util/u_string.h" > #include "ac_debug.h" > > static void si_dump_bo_list(struct si_context *sctx, > const struct radeon_saved_cs *saved, FILE *f); > > DEBUG_GET_ONCE_OPTION(replace_shaders, "RADEON_REPLACE_SHADERS", NULL) > > static void si_dump_shader(struct si_screen *sscreen, > enum pipe_shader_type processor, > const struct si_shader *shader, FILE *f) > @@ -783,56 +784,54 @@ static void si_dump_gfx_descriptors(struct si_context > *sctx, > static void si_dump_compute_descriptors(struct si_context *sctx, > struct u_log_context *log) > { > if (!sctx->cs_shader_state.program) > return; > > si_dump_descriptors(sctx, PIPE_SHADER_COMPUTE, NULL, log); > } > > struct si_shader_inst { > - char text[160]; /* one disasm line */ > - unsigned offset; /* instruction offset */ > + const char *text; /* start of disassembly for this instruction */ > + unsigned textlen; > unsigned size; /* instruction size = 4 or 8 */ > + uint64_t addr; /* instruction address */ > }; > > -/* Split a disassembly string into lines and add them to the array pointed > - * to by "instructions". */ > +/** > + * Split a disassembly string into instructions and add them to the array > + * pointed to by \p instructions. > + * > + * Labels are considered to be part of the following instruction. > + */ > static void si_add_split_disasm(const char *disasm, > - uint64_t start_addr, > + uint64_t *addr, > unsigned *num, > struct si_shader_inst *instructions) > { > - struct si_shader_inst *last_inst = *num ? &instructions[*num - 1] : > NULL; > - char *next; > + const char *semicolon; > > - while ((next = strchr(disasm, '\n'))) { > - struct si_shader_inst *inst = &instructions[*num]; > - unsigned len = next - disasm; > + while ((semicolon = strchr(disasm, ';'))) { > + struct si_shader_inst *inst = &instructions[(*num)++]; > + const char *end = util_strchrnul(semicolon, '\n'); > > - assert(len < ARRAY_SIZE(inst->text)); > - memcpy(inst->text, disasm, len); > - inst->text[len] = 0; > - inst->offset = last_inst ? last_inst->offset + > last_inst->size : 0; > + inst->text = disasm; > + inst->textlen = end - disasm; > > - const char *semicolon = strchr(disasm, ';'); > - assert(semicolon); > + inst->addr = *addr; > /* More than 16 chars after ";" means the instruction is 8 > bytes long. */ > - inst->size = next - semicolon > 16 ? 8 : 4; > - > - snprintf(inst->text + len, ARRAY_SIZE(inst->text) - len, > - " [PC=0x%"PRIx64", off=%u, size=%u]", > - start_addr + inst->offset, inst->offset, inst->size); > + inst->size = end - semicolon > 16 ? 8 : 4; > + *addr += inst->size; > > - last_inst = inst; > - (*num)++; > - disasm = next + 1; > + if (!(*end)) > + break; > + disasm = end + 1; > } > } > > /* If the shader is being executed, print its asm instructions, and annotate > * those that are being executed right now with information about waves that > * execute them. This is most useful during a GPU hang. > */ > static void si_print_annotated_shader(struct si_shader *shader, > struct ac_wave_info *waves, > unsigned num_waves, > @@ -854,53 +853,55 @@ static void si_print_annotated_shader(struct si_shader > *shader, > return; /* the shader is not being executed */ > > /* Remember the first found wave. The waves are sorted according to > PC. */ > waves = &waves[i]; > num_waves -= i; > > /* Get the list of instructions. > * Buffer size / 4 is the upper bound of the instruction count. > */ > unsigned num_inst = 0; > + uint64_t inst_addr = start_addr; > struct si_shader_inst *instructions = > calloc(shader->bo->b.b.width0 / 4, sizeof(struct > si_shader_inst)); > > if (shader->prolog) { > si_add_split_disasm(shader->prolog->binary.disasm_string, > - start_addr, &num_inst, instructions); > + &inst_addr, &num_inst, instructions); > } > if (shader->previous_stage) { > > si_add_split_disasm(shader->previous_stage->binary.disasm_string, > - start_addr, &num_inst, instructions); > + &inst_addr, &num_inst, instructions); > } > if (shader->prolog2) { > si_add_split_disasm(shader->prolog2->binary.disasm_string, > - start_addr, &num_inst, instructions); > + &inst_addr, &num_inst, instructions); > } > si_add_split_disasm(shader->binary.disasm_string, > - start_addr, &num_inst, instructions); > + &inst_addr, &num_inst, instructions); > if (shader->epilog) { > si_add_split_disasm(shader->epilog->binary.disasm_string, > - start_addr, &num_inst, instructions); > + &inst_addr, &num_inst, instructions); > } > > fprintf(f, COLOR_YELLOW "%s - annotated disassembly:" COLOR_RESET > "\n", > si_get_shader_name(shader, shader->selector->type)); > > /* Print instructions with annotations. */ > for (i = 0; i < num_inst; i++) { > struct si_shader_inst *inst = &instructions[i]; > > - fprintf(f, "%s\n", inst->text); > + fprintf(f, "%.*s [PC=0x%"PRIx64", size=%u]\n", > + inst->textlen, inst->text, inst->addr, inst->size); > > /* Print which waves execute the instruction right now. */ > - while (num_waves && start_addr + inst->offset == waves->pc) { > + while (num_waves && inst->addr == waves->pc) { > fprintf(f, > " " COLOR_GREEN "^ SE%u SH%u CU%u " > "SIMD%u WAVE%u EXEC=%016"PRIx64 " ", > waves->se, waves->sh, waves->cu, waves->simd, > waves->wave, waves->exec); > > if (inst->size == 4) { > fprintf(f, "INST32=%08X" COLOR_RESET "\n", > waves->inst_dw0); > } else { > -- > 2.11.0 > > _______________________________________________ > mesa-dev mailing list > [email protected] > https://lists.freedesktop.org/mailman/listinfo/mesa-dev _______________________________________________ mesa-dev mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/mesa-dev
