diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index 04ddfa25f4c..02d605161ae 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -5149,6 +5149,8 @@ char *nir_shader_as_str(nir_shader *nir, void *mem_ctx); char *nir_shader_as_str_annotated(nir_shader *nir, struct hash_table *annotations, void *mem_ctx); char *nir_instr_as_str(const nir_instr *instr, void *mem_ctx); +char *nir_shader_gather_debug_info(nir_shader *shader, const char *filename); + /** Shallow clone of a single instruction. */ nir_instr *nir_instr_clone(nir_shader *s, const nir_instr *orig); diff --git a/src/compiler/nir/nir_print.c b/src/compiler/nir/nir_print.c index 3e4877e6f80..5320b4e0b9e 100644 --- a/src/compiler/nir/nir_print.c +++ b/src/compiler/nir/nir_print.c @@ -35,6 +35,7 @@ #include "util/mesa-blake3.h" #include "vulkan/vulkan_core.h" #include "nir.h" +#include "nir_builder.h" static void print_indentation(unsigned levels, FILE *fp) @@ -46,6 +47,9 @@ print_indentation(unsigned levels, FILE *fp) typedef struct { FILE *fp; nir_shader *shader; + + const char *def_prefix; + /** map from nir_variable -> printable name */ struct hash_table *ht; @@ -75,6 +79,8 @@ typedef struct { * them align with the `=` for instructions with destination. */ unsigned padding_for_no_dest; + + nir_debug_info_instr **debug_info; } print_state; static void @@ -125,10 +131,10 @@ print_def(nir_def *def, print_state *state) const unsigned padding = (def->bit_size == 1) + 1 + ssa_padding; - fprintf(fp, "%s%u%s%*s%%%u", + fprintf(fp, "%s%u%s%*s%s%u", divergence_status(state, def->divergent), def->bit_size, sizes[def->num_components], - padding, "", def->index); + padding, "", state->def_prefix, def->index); } static unsigned @@ -389,7 +395,7 @@ static void print_src(const nir_src *src, print_state *state, nir_alu_type src_type) { FILE *fp = state->fp; - fprintf(fp, "%%%u", src->ssa->index); + fprintf(fp, "%s%u", state->def_prefix, src->ssa->index); nir_instr *instr = src->ssa->parent_instr; if (instr->type == nir_instr_type_load_const && !NIR_DEBUG(PRINT_NO_INLINE_CONSTS)) { @@ -1994,6 +2000,12 @@ static void print_instr(const nir_instr *instr, print_state *state, unsigned tabs) { FILE *fp = state->fp; + + if (state->debug_info) { + nir_debug_info_instr *di = state->debug_info[instr->index]; + di->src_loc.column = (uint32_t)ftell(fp); + } + print_indentation(tabs, fp); switch (instr->type) { @@ -2654,13 +2666,16 @@ print_shader_info(const struct shader_info *info, FILE *fp) } } -void -nir_print_shader_annotated(nir_shader *shader, FILE *fp, - struct hash_table *annotations) +static void +_nir_print_shader_annotated(nir_shader *shader, FILE *fp, + struct hash_table *annotations, + nir_debug_info_instr **debug_info) { print_state state; init_print_state(&state, shader, fp); + state.def_prefix = debug_info ? "ssa_" : "%"; state.annotations = annotations; + state.debug_info = debug_info; print_shader_info(&shader->info, fp); @@ -2701,6 +2716,13 @@ nir_print_shader_annotated(nir_shader *shader, FILE *fp, destroy_print_state(&state); } +void +nir_print_shader_annotated(nir_shader *shader, FILE *fp, + struct hash_table *annotations) +{ + _nir_print_shader_annotated(shader, fp, annotations, NULL); +} + void nir_print_shader(nir_shader *shader, FILE *fp) { @@ -2708,15 +2730,16 @@ nir_print_shader(nir_shader *shader, FILE *fp) fflush(fp); } -char * -nir_shader_as_str_annotated(nir_shader *nir, struct hash_table *annotations, void *mem_ctx) +static char * +_nir_shader_as_str_annotated(nir_shader *nir, struct hash_table *annotations, void *mem_ctx, + nir_debug_info_instr **debug_info) { char *stream_data = NULL; size_t stream_size = 0; struct u_memstream mem; if (u_memstream_open(&mem, &stream_data, &stream_size)) { FILE *const stream = u_memstream_get(&mem); - nir_print_shader_annotated(nir, stream, annotations); + _nir_print_shader_annotated(nir, stream, annotations, debug_info); u_memstream_close(&mem); } @@ -2729,6 +2752,12 @@ nir_shader_as_str_annotated(nir_shader *nir, struct hash_table *annotations, voi return str; } +char * +nir_shader_as_str_annotated(nir_shader *nir, struct hash_table *annotations, void *mem_ctx) +{ + return _nir_shader_as_str_annotated(nir, annotations, mem_ctx, NULL); +} + char * nir_shader_as_str(nir_shader *nir, void *mem_ctx) { @@ -2740,6 +2769,7 @@ nir_print_instr(const nir_instr *instr, FILE *fp) { print_state state = { .fp = fp, + .def_prefix = "%", }; if (instr->block) { nir_function_impl *impl = nir_cf_node_get_function(&instr->block->cf_node); @@ -2775,6 +2805,7 @@ nir_print_deref(const nir_deref_instr *deref, FILE *fp) { print_state state = { .fp = fp, + .def_prefix = "%", }; print_deref_link(deref, true, &state); } @@ -2787,3 +2818,70 @@ nir_log_shader_annotated_tagged(enum mesa_log_level level, const char *tag, _mesa_log_multiline(level, tag, str); ralloc_free(str); } + +char * +nir_shader_gather_debug_info(nir_shader *shader, const char *filename) +{ + uint32_t instr_count = 0; + nir_foreach_function_impl(impl, shader) { + nir_foreach_block(block, impl) { + nir_foreach_instr(instr, block) { + instr->index = instr_count; + instr_count++; + } + } + } + + if (!instr_count) + return nir_shader_as_str(shader, NULL); + + nir_debug_info_instr **debug_info = rzalloc_array(shader, nir_debug_info_instr *, instr_count); + + instr_count = 0; + nir_foreach_function_impl(impl, shader) { + nir_builder b = nir_builder_at(nir_before_cf_list(&impl->body)); + nir_def *filename_def = nir_build_string(&b, filename); + + nir_foreach_block(block, impl) { + nir_foreach_instr_safe(instr, block) { + if (instr->type == nir_instr_type_debug_info) + continue; + + nir_debug_info_instr *di = nir_debug_info_instr_create(shader, nir_debug_info_src_loc, 0); + di->src_loc.filename = nir_src_for_ssa(filename_def); + di->src_loc.source = nir_debug_info_nir; + debug_info[instr_count++] = di; + } + } + } + + char *str = _nir_shader_as_str_annotated(shader, NULL, NULL, debug_info); + + uint32_t line = 1; + uint32_t character_index = 0; + + for (uint32_t i = 0; i < instr_count; i++) { + nir_debug_info_instr *di = debug_info[i]; + + while (character_index < di->src_loc.column) { + if (str[character_index] == '\n') + line++; + character_index++; + } + + di->src_loc.line = line; + di->src_loc.column = 0; + } + + instr_count = 0; + nir_foreach_function_impl(impl, shader) { + nir_foreach_block(block, impl) { + nir_foreach_instr_safe(instr, block) { + if (instr->type != nir_instr_type_debug_info) + nir_instr_insert_before(instr, &debug_info[instr_count++]->instr); + } + } + } + + return str; +}