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:
committed by
Marge Bot
parent
7dd9840128
commit
f8ef1afec8
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.");
|
||||
}
|
||||
|
||||
@@ -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)),
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user