aco: dump the program if the disassembler failed

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Rhys Perry <pendingchaos02@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6979>
This commit is contained in:
Samuel Pitoiset 2020-10-02 11:06:50 +02:00
parent a7d3be78ce
commit 6db3df5c2f
3 changed files with 16 additions and 13 deletions

View File

@ -172,7 +172,12 @@ void aco_compile_shader(unsigned shader_count,
std::string disasm; std::string disasm;
if (get_disasm) { if (get_disasm) {
std::ostringstream stream; std::ostringstream stream;
aco::print_asm(program.get(), code, exec_size / 4u, stream); if (aco::print_asm(program.get(), code, exec_size / 4u, stream)) {
std::cerr << "Failed to disassemble program:\n";
aco_print_program(program.get(), stderr);
std::cerr << stream.str() << std::endl;
abort();
}
stream << '\0'; stream << '\0';
disasm = stream.str(); disasm = stream.str();
size += disasm.size(); size += disasm.size();

View File

@ -1693,7 +1693,7 @@ void spill(Program* program, live& live_vars, const struct radv_nir_compiler_opt
void insert_wait_states(Program* program); void insert_wait_states(Program* program);
void insert_NOPs(Program* program); void insert_NOPs(Program* program);
unsigned emit_program(Program* program, std::vector<uint32_t>& code); unsigned emit_program(Program* program, std::vector<uint32_t>& code);
void print_asm(Program *program, std::vector<uint32_t>& binary, bool print_asm(Program *program, std::vector<uint32_t>& binary,
unsigned exec_size, std::ostream& out); unsigned exec_size, std::ostream& out);
bool validate_ir(Program* program); bool validate_ir(Program* program);
bool validate_ra(Program* program, const struct radv_nir_compiler_options *options); bool validate_ra(Program* program, const struct radv_nir_compiler_options *options);

View File

@ -14,7 +14,7 @@ namespace aco {
/* LLVM disassembler only supports GFX8+, try to disassemble with CLRXdisasm /* LLVM disassembler only supports GFX8+, try to disassemble with CLRXdisasm
* for GFX6-GFX7 if found on the system, this is better than nothing. * for GFX6-GFX7 if found on the system, this is better than nothing.
*/ */
void print_asm_gfx6_gfx7(Program *program, std::vector<uint32_t>& binary, bool print_asm_gfx6_gfx7(Program *program, std::vector<uint32_t>& binary,
std::ostream& out) std::ostream& out)
{ {
char path[] = "/tmp/fileXXXXXX"; char path[] = "/tmp/fileXXXXXX";
@ -26,7 +26,7 @@ void print_asm_gfx6_gfx7(Program *program, std::vector<uint32_t>& binary,
/* Dump the binary into a temporary file. */ /* Dump the binary into a temporary file. */
fd = mkstemp(path); fd = mkstemp(path);
if (fd < 0) if (fd < 0)
return; return true;
for (uint32_t w : binary) for (uint32_t w : binary)
{ {
@ -83,17 +83,21 @@ void print_asm_gfx6_gfx7(Program *program, std::vector<uint32_t>& binary,
pclose(p); pclose(p);
} }
return false;
fail: fail:
close(fd); close(fd);
unlink(path); unlink(path);
return true;
} }
void print_asm(Program *program, std::vector<uint32_t>& binary, bool print_asm(Program *program, std::vector<uint32_t>& binary,
unsigned exec_size, std::ostream& out) unsigned exec_size, std::ostream& out)
{ {
if (program->chip_class <= GFX7) { if (program->chip_class <= GFX7) {
/* Do not abort if clrxdisasm isn't found. */
print_asm_gfx6_gfx7(program, binary, out); print_asm_gfx6_gfx7(program, binary, out);
return; return false;
} }
std::vector<bool> referenced_blocks(program->blocks.size()); std::vector<bool> referenced_blocks(program->blocks.size());
@ -224,13 +228,7 @@ void print_asm(Program *program, std::vector<uint32_t>& binary,
out << std::setfill(' ') << std::setw(0) << std::dec; out << std::setfill(' ') << std::setw(0) << std::dec;
if (invalid) { return invalid;
/* Invalid instructions usually lead to GPU hangs, which can make
* getting the actual invalid instruction hard. Abort here so that we
* can find the problem.
*/
abort();
}
} }
} }