Mesa (master): radeonsi: Added Diag Handler to receive LLVM Error messages

Tom Stellard tstellar at kemper.freedesktop.org
Thu Apr 17 15:42:39 UTC 2014


Module: Mesa
Branch: master
Commit: bc86690f137a71a6f1cdcc0393a4b3f181df7240
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=bc86690f137a71a6f1cdcc0393a4b3f181df7240

Author: Darren Powell <darren.powell at amd.com>
Date:   Mon Mar 31 18:00:28 2014 -0400

radeonsi: Added Diag Handler to receive LLVM Error messages

Reviewed-by: Tom Stellard <thomas.stellard at amd.com>

---

 src/gallium/drivers/radeon/radeon_llvm_emit.c |   50 ++++++++++++++++++++++---
 src/gallium/drivers/radeonsi/si_shader.c      |   12 ++++--
 src/gallium/drivers/radeonsi/si_state.c       |    2 +
 3 files changed, 55 insertions(+), 9 deletions(-)

diff --git a/src/gallium/drivers/radeon/radeon_llvm_emit.c b/src/gallium/drivers/radeon/radeon_llvm_emit.c
index 7bcdc27..891781f 100644
--- a/src/gallium/drivers/radeon/radeon_llvm_emit.c
+++ b/src/gallium/drivers/radeon/radeon_llvm_emit.c
@@ -29,6 +29,7 @@
 
 #include <llvm-c/Target.h>
 #include <llvm-c/TargetMachine.h>
+#include <llvm-c/Core.h>
 
 #include <stdlib.h>
 #include <stdio.h>
@@ -79,6 +80,22 @@ static LLVMTargetRef get_r600_target() {
 	return target;
 }
 
+#if HAVE_LLVM >= 0x0305
+
+static void radeonDiagnosticHandler(LLVMDiagnosticInfoRef di, void *context) {
+	unsigned int *diagnosticflag;
+	char *diaginfo_message;
+
+	diaginfo_message = LLVMGetDiagInfoDescription(di);
+	fprintf(stderr,"LLVM triggered Diagnostic Handler: %s\n", diaginfo_message);
+	LLVMDisposeMessage(diaginfo_message);
+
+	diagnosticflag = (unsigned int *)context;
+	*diagnosticflag = ((LLVMDSError == LLVMGetDiagInfoSeverity(di)) ? 1 : 0);
+}
+
+#endif
+
 /**
  * Compile an LLVM module to machine code.
  *
@@ -92,12 +109,15 @@ unsigned radeon_llvm_compile(LLVMModuleRef M, struct radeon_shader_binary *binar
 	char cpu[CPU_STRING_LEN];
 	char fs[FS_STRING_LEN];
 	char *err;
+	LLVMContextRef llvm_ctx;
+	unsigned rval = 0;
 	LLVMMemoryBufferRef out_buffer;
 	unsigned buffer_size;
 	const char *buffer_data;
 	char triple[TRIPLE_STRING_LEN];
-	LLVMBool r;
+	LLVMBool mem_err;
 
+	/* initialise */
 	init_r600_target();
 
 	target = get_r600_target();
@@ -112,24 +132,42 @@ unsigned radeon_llvm_compile(LLVMModuleRef M, struct radeon_shader_binary *binar
 		strncpy(fs, "+DumpCode", FS_STRING_LEN);
 	}
 	strncpy(triple, "r600--", TRIPLE_STRING_LEN);
+
+	/* Setup Diagnostic Handler*/
+	llvm_ctx = LLVMGetModuleContext(M);
+
+#if HAVE_LLVM >= 0x0305
+	LLVMContextSetDiagnosticHandler(llvm_ctx, radeonDiagnosticHandler, &rval);
+#endif
+	rval = 0;
+
+	/* Compile IR*/
 	tm = LLVMCreateTargetMachine(target, triple, cpu, fs,
 				  LLVMCodeGenLevelDefault, LLVMRelocDefault,
 						  LLVMCodeModelDefault);
-
-	r = LLVMTargetMachineEmitToMemoryBuffer(tm, M, LLVMObjectFile, &err,
+	mem_err = LLVMTargetMachineEmitToMemoryBuffer(tm, M, LLVMObjectFile, &err,
 								 &out_buffer);
-	if (r) {
-		fprintf(stderr, "%s", err);
+
+	/* Process Errors/Warnings */
+	if (mem_err) {
+		fprintf(stderr, "%s: %s", __FUNCTION__, err);
 		FREE(err);
+		LLVMDisposeTargetMachine(tm);
 		return 1;
 	}
 
+	if (0 != rval) {
+		fprintf(stderr, "%s: Processing Diag Flag\n", __FUNCTION__);
+	}
+
+	/* Extract Shader Code*/
 	buffer_size = LLVMGetBufferSize(out_buffer);
 	buffer_data = LLVMGetBufferStart(out_buffer);
 
 	radeon_elf_read(buffer_data, buffer_size, binary, dump);
 
+	/* Clean up */
 	LLVMDisposeMemoryBuffer(out_buffer);
 	LLVMDisposeTargetMachine(tm);
-	return 0;
+	return rval;
 }
diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c
index e4390ee..0d070d3 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -2293,14 +2293,19 @@ static void preload_streamout_buffers(struct si_shader_context *si_shader_ctx)
 int si_compile_llvm(struct si_context *sctx, struct si_pipe_shader *shader,
 							LLVMModuleRef mod)
 {
+	unsigned r; /* llvm_compile result */
 	unsigned i;
 	uint32_t *ptr;
 	struct radeon_shader_binary binary;
 	bool dump = r600_can_dump_shader(&sctx->screen->b,
 			shader->selector ? shader->selector->tokens : NULL);
+	const char * gpu_family = r600_get_llvm_processor_name(sctx->screen->b.family);
+
+	/* Use LLVM to compile shader */
 	memset(&binary, 0, sizeof(binary));
-	radeon_llvm_compile(mod, &binary,
-		r600_get_llvm_processor_name(sctx->screen->b.family), dump);
+	r = radeon_llvm_compile(mod, &binary, gpu_family, dump);
+
+	/* Output binary dump if rscreen->debug_flags are set */
 	if (dump && ! binary.disassembled) {
 		fprintf(stderr, "SI CODE:\n");
 		for (i = 0; i < binary.code_size; i+=4 ) {
@@ -2313,6 +2318,7 @@ int si_compile_llvm(struct si_context *sctx, struct si_pipe_shader *shader,
 	/* XXX: We may be able to emit some of these values directly rather than
 	 * extracting fields to be emitted later.
 	 */
+	/* Parse config data in compiled binary */
 	for (i = 0; i < binary.config_size; i+= 8) {
 		unsigned reg = util_le32_to_cpu(*(uint32_t*)(binary.config + i));
 		unsigned value = util_le32_to_cpu(*(uint32_t*)(binary.config + i + 4));
@@ -2361,7 +2367,7 @@ int si_compile_llvm(struct si_context *sctx, struct si_pipe_shader *shader,
 	free(binary.code);
 	free(binary.config);
 
-	return 0;
+	return r;
 }
 
 /* Generate code for the hardware VS shader stage to go with a geometry shader */
diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c
index d81354e..ab9c4cc 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -2208,9 +2208,11 @@ static void si_bind_ps_shader(struct pipe_context *ctx, void *state)
 	struct si_context *sctx = (struct si_context *)ctx;
 	struct si_pipe_shader_selector *sel = state;
 
+	/* skip if supplied shader is one already in use */
 	if (sctx->ps_shader == sel)
 		return;
 
+	/* use dummy shader if supplied shader is corrupt */
 	if (!sel || !sel->current)
 		sel = sctx->dummy_pixel_shader;
 




More information about the mesa-commit mailing list