aco: Handle nir_debug_info_instr

Propagated debug info using p_debug_info and Program::debug_info.
Offsets into the shader binary are gathered during assembly.
This will be usefull for mapping back the disassembled shader to
nir, glsl or spirv.

Reviewed-by: Timur Kristóf <timur.kristof@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29298>
This commit is contained in:
Konstantin Seurer
2024-10-06 09:38:35 +02:00
committed by Marge Bot
parent 7dd9840128
commit f8ef1afec8
6 changed files with 60 additions and 2 deletions
+5
View File
@@ -1216,6 +1216,11 @@ emit_instruction(asm_context& ctx, std::vector<uint32_t>& out, Instruction* inst
instr->opcode = aco_opcode::s_mov_b32;
/* in case it's an inline constant, make it a literal */
instr->operands[0] = Operand::literal32(0);
} else if (instr->opcode == aco_opcode::p_debug_info) {
assert(instr->operands[0].isConstant());
uint32_t index = instr->operands[0].constantValue();
ctx.program->debug_info[index].offset = (out.size() - 1) * 4;
return;
}
/* Promote VOP12C to VOP3 if necessary. */
@@ -10539,6 +10539,30 @@ visit_jump(isel_context* ctx, nir_jump_instr* instr)
}
}
void
visit_debug_info(isel_context* ctx, nir_debug_info_instr* instr)
{
ac_shader_debug_info info;
memset(&info, 0, sizeof(info));
switch (instr->type) {
case nir_debug_info_src_loc:
info.type = ac_shader_debug_info_src_loc;
info.src_loc.file = strdup(nir_src_as_string(instr->src_loc.filename));
info.src_loc.line = instr->src_loc.line;
info.src_loc.column = instr->src_loc.column;
info.src_loc.spirv_offset = instr->src_loc.spirv_offset;
break;
default:
return;
}
Builder bld(ctx->program, ctx->block);
bld.pseudo(aco_opcode::p_debug_info, Operand::c32(ctx->program->debug_info.size()));
ctx->program->debug_info.push_back(info);
}
void
visit_block(isel_context* ctx, nir_block* block)
{
@@ -10562,6 +10586,7 @@ visit_block(isel_context* ctx, nir_block* block)
case nir_instr_type_undef: visit_undef(ctx, nir_instr_as_undef(instr)); break;
case nir_instr_type_deref: break;
case nir_instr_type_jump: visit_jump(ctx, nir_instr_as_jump(instr)); break;
case nir_instr_type_debug_info: visit_debug_info(ctx, nir_instr_as_debug_info(instr)); break;
default: isel_err(instr, "Unknown NIR instr type");
}
}
+3
View File
@@ -15,6 +15,7 @@
#include "ac_binary.h"
#include "ac_hw_stage.h"
#include "ac_shader_debug_info.h"
#include "ac_shader_util.h"
#include "amd_family.h"
#include <algorithm>
@@ -2131,6 +2132,8 @@ public:
bool is_prolog = false;
bool is_epilog = false;
std::vector<ac_shader_debug_info> debug_info;
std::vector<uint8_t> constant_data;
Temp private_segment_buffer;
Temp scratch_offset;
+3 -2
View File
@@ -2246,7 +2246,8 @@ lower_to_hw_instr(Program* program)
}
aco_ptr<Instruction> mov;
if (instr->isPseudo() && instr->opcode != aco_opcode::p_unit_test) {
if (instr->isPseudo() && instr->opcode != aco_opcode::p_unit_test &&
instr->opcode != aco_opcode::p_debug_info) {
Pseudo_instruction* pi = &instr->pseudo();
switch (instr->opcode) {
@@ -2908,7 +2909,7 @@ lower_to_hw_instr(Program* program)
inst->isLDSDIR()) {
// TODO: GFX6-9 can use vskip
can_remove = prefer_remove;
} else {
} else if (inst->opcode != aco_opcode::p_debug_info) {
can_remove = false;
assert(false && "Pseudo instructions should be lowered by this point.");
}
+2
View File
@@ -439,6 +439,8 @@ insn("p_end_with_regs")
insn("p_shader_cycles_hi_lo_hi")
insn("p_debug_info")
# SOP2 instructions: 2 scalar inputs, 1 scalar output (+optional scc)
SOP2 = {
("s_add_u32", dst(1, SCC), src(1, 1), op(0x00)),
+22
View File
@@ -899,6 +899,24 @@ print_stage(Stage stage, FILE* output)
fprintf(output, ")\n");
}
void
print_debug_info(const Program* program, const Instruction* instr, FILE* output)
{
fprintf(output, "// ");
assert(instr->operands[0].isConstant());
const auto& info = program->debug_info[instr->operands[0].constantValue()];
switch (info.type) {
case ac_shader_debug_info_src_loc:
if (info.src_loc.spirv_offset)
fprintf(output, "0x%x ", info.src_loc.spirv_offset);
fprintf(output, "%s:%u:%u", info.src_loc.file, info.src_loc.line, info.src_loc.column);
break;
}
fprintf(output, "\n");
}
void
aco_print_block(enum amd_gfx_level gfx_level, const Block* block, FILE* output, unsigned flags,
const Program* program)
@@ -926,6 +944,10 @@ aco_print_block(enum amd_gfx_level gfx_level, const Block* block, FILE* output,
for (auto const& instr : block->instructions) {
fprintf(output, "\t");
if (instr->opcode == aco_opcode::p_debug_info) {
print_debug_info(program, instr.get(), output);
continue;
}
if (flags & print_live_vars) {
RegisterDemand demand = instr->register_demand;
fprintf(output, "(%3u vgpr, %3u sgpr) ", demand.vgpr, demand.sgpr);