radv,aco: keep track of the prolog disassembly if necessary

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/13376>
This commit is contained in:
Samuel Pitoiset 2021-10-15 10:03:21 +02:00 committed by Marge Bot
parent e836174077
commit 2bf25e6f6e
3 changed files with 63 additions and 36 deletions

View file

@ -73,6 +73,36 @@ validate(aco::Program* program)
assert(is_valid);
}
static std::string
get_disasm_string(aco::Program* program, std::vector<uint32_t>& code,
unsigned exec_size)
{
std::string disasm;
if (check_print_asm_support(program)) {
char* data = NULL;
size_t disasm_size = 0;
struct u_memstream mem;
if (u_memstream_open(&mem, &data, &disasm_size)) {
FILE* const memf = u_memstream_get(&mem);
aco::print_asm(program, code, exec_size / 4u, memf);
fputc(0, memf);
u_memstream_close(&mem);
}
disasm = std::string(data, data + disasm_size);
free(data);
} else {
disasm = "Shader disassembly is not supported in the current configuration"
#ifndef LLVM_AVAILABLE
" (LLVM not available)"
#endif
".\n";
}
return disasm;
}
void
aco_compile_shader(const struct radv_nir_compiler_options* options,
const struct radv_shader_info* info,
@ -201,28 +231,8 @@ aco_compile_shader(const struct radv_nir_compiler_options* options,
std::string disasm;
if (get_disasm) {
if (check_print_asm_support(program.get())) {
char* data = NULL;
size_t disasm_size = 0;
struct u_memstream mem;
if (u_memstream_open(&mem, &data, &disasm_size)) {
FILE* const memf = u_memstream_get(&mem);
aco::print_asm(program.get(), code, exec_size / 4u, memf);
fputc(0, memf);
u_memstream_close(&mem);
}
disasm = std::string(data, data + disasm_size);
size += disasm_size;
free(data);
} else {
disasm = "Shader disassembly is not supported in the current configuration"
#ifndef LLVM_AVAILABLE
" (LLVM not available)"
#endif
".\n";
size += disasm.length();
}
disasm = get_disasm_string(program.get(), code, exec_size);
size += disasm.size();
}
size_t stats_size = 0;
@ -297,21 +307,17 @@ aco_compile_vs_prolog(const struct radv_nir_compiler_options* options,
code.reserve(align(program->blocks[0].instructions.size() * 2, 16));
unsigned exec_size = aco::emit_program(program.get(), code);
if (options->dump_shader) {
if (check_print_asm_support(program.get())) {
aco::print_asm(program.get(), code, exec_size / 4u, stderr);
fprintf(stderr, "\n");
} else {
fprintf(stderr, "Shader disassembly is not supported in the current configuration"
#ifndef LLVM_AVAILABLE
" (LLVM not available)"
#endif
".\n");
}
}
/* copy into binary */
size_t size = code.size() * sizeof(uint32_t) + sizeof(radv_prolog_binary);
bool get_disasm = options->dump_shader || options->record_ir;
std::string disasm;
if (get_disasm) {
disasm = get_disasm_string(program.get(), code, exec_size);
size += disasm.size();
}
radv_prolog_binary* prolog_binary = (radv_prolog_binary*)calloc(size, 1);
prolog_binary->num_sgprs = config.num_sgprs;
@ -320,5 +326,11 @@ aco_compile_vs_prolog(const struct radv_nir_compiler_options* options,
prolog_binary->code_size = code.size() * sizeof(uint32_t);
memcpy(prolog_binary->data, code.data(), prolog_binary->code_size);
if (get_disasm) {
disasm.copy((char*)prolog_binary->data + prolog_binary->code_size,
disasm.size());
prolog_binary->disasm_size = disasm.size();
}
*binary = prolog_binary;
}

View file

@ -1991,6 +1991,7 @@ upload_vs_prolog(struct radv_device *device, struct radv_prolog_binary *bin, uns
prolog->rsrc1 = S_00B848_VGPRS((bin->num_vgprs - 1) / (wave_size == 32 ? 8 : 4)) |
S_00B228_SGPRS((bin->num_sgprs - 1) / 8);
prolog->num_preserved_sgprs = bin->num_preserved_sgprs;
prolog->disasm_string = NULL;
return prolog;
}
@ -2005,6 +2006,7 @@ radv_create_vs_prolog(struct radv_device *device, const struct radv_vs_prolog_ke
options.info = &device->physical_device->rad_info;
options.address32_hi = device->physical_device->rad_info.address32_hi;
options.dump_shader = device->instance->debug_flags & RADV_DEBUG_DUMP_PROLOGS;
options.record_ir = device->instance->debug_flags & RADV_DEBUG_HANG;
struct radv_shader_info info = {0};
info.wave_size = key->wave32 ? 32 : 64;
@ -2024,7 +2026,7 @@ radv_create_vs_prolog(struct radv_device *device, const struct radv_vs_prolog_ke
info.user_sgprs_locs = args.user_sgprs_locs;
#ifdef LLVM_AVAILABLE
if (options.dump_shader)
if (options.dump_shader || options.record_ir)
ac_init_llvm_once();
#endif
@ -2033,9 +2035,17 @@ radv_create_vs_prolog(struct radv_device *device, const struct radv_vs_prolog_ke
struct radv_shader_prolog *prolog = upload_vs_prolog(device, binary, info.wave_size);
if (prolog) {
prolog->nontrivial_divisors = key->state->nontrivial_divisors;
prolog->disasm_string =
binary->disasm_size ? strdup((const char *)(binary->data + binary->code_size)) : NULL;
}
free(binary);
if (prolog && options.dump_shader) {
fprintf(stderr, "Vertex prolog");
fprintf(stderr, "\ndisasm:\n%s\n", prolog->disasm_string);
}
return prolog;
}
@ -2060,6 +2070,7 @@ radv_prolog_destroy(struct radv_device *device, struct radv_shader_prolog *prolo
return;
radv_free_shader_memory(device, prolog->alloc);
free(prolog->disasm_string);
free(prolog);
}

View file

@ -436,6 +436,7 @@ struct radv_prolog_binary {
uint8_t num_vgprs;
uint8_t num_preserved_sgprs;
unsigned code_size;
unsigned disasm_size;
uint8_t data[0];
};
@ -487,6 +488,9 @@ struct radv_shader_prolog {
uint32_t rsrc1;
uint8_t num_preserved_sgprs;
bool nontrivial_divisors;
/* debug only */
char *disasm_string;
};
void radv_optimize_nir(const struct radv_device *device, struct nir_shader *shader,