nir/print: Add a helper for generating debug info
Prints the shader to a string and assigns source locations based on that. Reviewed-by: Jesse Natalie <jenatali@microsoft.com> Reviewed-by: Alyssa Rosenzweig <alyssa@rosenzweig.io> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18903>
This commit is contained in:
committed by
Marge Bot
parent
4423c50c1b
commit
81e3930ec0
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user