summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMarek Olšák <marek.olsak@amd.com>2016-07-01 00:10:15 +0200
committerMarek Olšák <marek.olsak@amd.com>2016-07-05 00:47:13 +0200
commit027ad71b57a0bec882c604027dc83f42eb2eb54c (patch)
tree75437fa7e38855d3ab68738ac8d5d98d52ea5915 /src
parent28a03be06b183caa433de03c9bf35ba5dbd8c77a (diff)
downloadexternal_mesa3d-027ad71b57a0bec882c604027dc83f42eb2eb54c.zip
external_mesa3d-027ad71b57a0bec882c604027dc83f42eb2eb54c.tar.gz
external_mesa3d-027ad71b57a0bec882c604027dc83f42eb2eb54c.tar.bz2
radeonsi: print LLVM IRs to ddebug logs
Getting LLVM IRs of hanging shaders have never been easier. Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl> Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
Diffstat (limited to 'src')
-rw-r--r--src/gallium/drivers/radeon/r600_pipe_common.c1
-rw-r--r--src/gallium/drivers/radeon/r600_pipe_common.h1
-rw-r--r--src/gallium/drivers/radeonsi/si_pipe.c3
-rw-r--r--src/gallium/drivers/radeonsi/si_pipe.h1
-rw-r--r--src/gallium/drivers/radeonsi/si_shader.c12
-rw-r--r--src/gallium/drivers/radeonsi/si_state_shaders.c9
6 files changed, 26 insertions, 1 deletions
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;
}