From 027ad71b57a0bec882c604027dc83f42eb2eb54c Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Fri, 1 Jul 2016 00:10:15 +0200 Subject: [PATCH] radeonsi: print LLVM IRs to ddebug logs MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Getting LLVM IRs of hanging shaders have never been easier. Reviewed-by: Bas Nieuwenhuizen Reviewed-by: Nicolai Hähnle --- src/gallium/drivers/radeon/r600_pipe_common.c | 1 + src/gallium/drivers/radeon/r600_pipe_common.h | 1 + src/gallium/drivers/radeonsi/si_pipe.c | 3 +++ src/gallium/drivers/radeonsi/si_pipe.h | 1 + src/gallium/drivers/radeonsi/si_shader.c | 12 ++++++++++++ src/gallium/drivers/radeonsi/si_state_shaders.c | 9 ++++++++- 6 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/gallium/drivers/radeon/r600_pipe_common.c b/src/gallium/drivers/radeon/r600_pipe_common.c index 5e981d6..74674e7 100644 --- a/src/gallium/drivers/radeon/r600_pipe_common.c +++ b/src/gallium/drivers/radeon/r600_pipe_common.c @@ -67,6 +67,7 @@ void radeon_shader_binary_clean(struct radeon_shader_binary *b) FREE(b->global_symbol_offsets); FREE(b->relocs); FREE(b->disasm_string); + FREE(b->llvm_ir_string); } /* diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h index c145dc3..1ad69f8 100644 --- a/src/gallium/drivers/radeon/r600_pipe_common.h +++ b/src/gallium/drivers/radeon/r600_pipe_common.h @@ -155,6 +155,7 @@ struct radeon_shader_binary { /** Disassembled shader in a string. */ char *disasm_string; + char *llvm_ir_string; }; void radeon_shader_binary_init(struct radeon_shader_binary *b); diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c index f15e589..ad2a86a 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.c +++ b/src/gallium/drivers/radeonsi/si_pipe.c @@ -139,6 +139,9 @@ static struct pipe_context *si_create_context(struct pipe_screen *screen, if (sscreen->b.debug_flags & DBG_CHECK_VM) flags |= PIPE_CONTEXT_DEBUG; + if (flags & PIPE_CONTEXT_DEBUG) + sscreen->record_llvm_ir = true; /* racy but not critical */ + sctx->b.b.screen = screen; /* this must be set first */ sctx->b.b.priv = priv; sctx->b.b.destroy = si_destroy_context; diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h index 9d15cbf..fc7e73e 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.h +++ b/src/gallium/drivers/radeonsi/si_pipe.h @@ -87,6 +87,7 @@ struct si_screen { /* Whether shaders are monolithic (1-part) or separate (3-part). */ bool use_monolithic_shaders; + bool record_llvm_ir; pipe_mutex shader_parts_mutex; struct si_shader_part *vs_prologs; diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c index 4dcc8c8..77d1a8b 100644 --- a/src/gallium/drivers/radeonsi/si_shader.c +++ b/src/gallium/drivers/radeonsi/si_shader.c @@ -6226,6 +6226,12 @@ void si_shader_dump(struct si_screen *sscreen, struct si_shader *shader, struct pipe_debug_callback *debug, unsigned processor, FILE *file) { + if (file != stderr && shader->binary.llvm_ir_string) { + fprintf(file, "\n%s - main shader part - LLVM IR:\n\n", + si_get_shader_name(shader, processor)); + fprintf(file, "%s\n", shader->binary.llvm_ir_string); + } + if (file != stderr || (r600_can_dump_shader(&sscreen->b, processor) && !(sscreen->b.debug_flags & DBG_NO_ASM))) { @@ -6271,6 +6277,12 @@ int si_compile_llvm(struct si_screen *sscreen, } } + if (sscreen->record_llvm_ir) { + char *ir = LLVMPrintModuleToString(mod); + binary->llvm_ir_string = strdup(ir); + LLVMDisposeMessage(ir); + } + if (!si_replace_shader(count, binary)) { r = radeon_llvm_compile(mod, binary, tm, debug); if (r) diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.c b/src/gallium/drivers/radeonsi/si_state_shaders.c index f78d082..766ef2c 100644 --- a/src/gallium/drivers/radeonsi/si_state_shaders.c +++ b/src/gallium/drivers/radeonsi/si_state_shaders.c @@ -96,6 +96,8 @@ static uint32_t *read_chunk(uint32_t *ptr, void **data, unsigned *size) { *size = *ptr++; assert(*data == NULL); + if (!*size) + return ptr; *data = malloc(*size); return read_data(ptr, *data, *size); } @@ -110,6 +112,8 @@ static void *si_get_shader_binary(struct si_shader *shader) unsigned relocs_size = shader->binary.reloc_count * sizeof(shader->binary.relocs[0]); unsigned disasm_size = strlen(shader->binary.disasm_string) + 1; + unsigned llvm_ir_size = shader->binary.llvm_ir_string ? + strlen(shader->binary.llvm_ir_string) + 1 : 0; unsigned size = 4 + /* total size */ 4 + /* CRC32 of the data below */ @@ -118,7 +122,8 @@ static void *si_get_shader_binary(struct si_shader *shader) 4 + align(shader->binary.code_size, 4) + 4 + align(shader->binary.rodata_size, 4) + 4 + align(relocs_size, 4) + - 4 + align(disasm_size, 4); + 4 + align(disasm_size, 4) + + 4 + align(llvm_ir_size, 4); void *buffer = CALLOC(1, size); uint32_t *ptr = (uint32_t*)buffer; @@ -134,6 +139,7 @@ static void *si_get_shader_binary(struct si_shader *shader) ptr = write_chunk(ptr, shader->binary.rodata, shader->binary.rodata_size); ptr = write_chunk(ptr, shader->binary.relocs, relocs_size); ptr = write_chunk(ptr, shader->binary.disasm_string, disasm_size); + ptr = write_chunk(ptr, shader->binary.llvm_ir_string, llvm_ir_size); assert((char *)ptr - (char *)buffer == size); /* Compute CRC32. */ @@ -165,6 +171,7 @@ static bool si_load_shader_binary(struct si_shader *shader, void *binary) ptr = read_chunk(ptr, (void**)&shader->binary.relocs, &chunk_size); shader->binary.reloc_count = chunk_size / sizeof(shader->binary.relocs[0]); ptr = read_chunk(ptr, (void**)&shader->binary.disasm_string, &chunk_size); + ptr = read_chunk(ptr, (void**)&shader->binary.llvm_ir_string, &chunk_size); return true; } -- 2.7.4