Mesa (master): radeonsi: import all TGSI->LLVM code from gallium/radeon

Marek Olšák mareko at kemper.freedesktop.org
Tue Oct 18 17:08:05 UTC 2016


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

Author: Marek Olšák <marek.olsak at amd.com>
Date:   Mon Oct 17 12:30:42 2016 +0200

radeonsi: import all TGSI->LLVM code from gallium/radeon

Acked-by: Nicolai Hähnle <nicolai.haehnle at amd.com>
Reviewed-by: Emil Velikov <emil.velikov at collabora.com>
Acked-by: Edward O'Callaghan <funfunctor at folklore1984.net>

---

 .../drivers/r600/evergreen_compute_internal.h      |   1 -
 src/gallium/drivers/radeon/Makefile.sources        |   6 +-
 src/gallium/drivers/radeon/radeon_llvm.h           | 151 -------------
 src/gallium/drivers/radeon/radeon_llvm_emit.c      | 241 ---------------------
 src/gallium/drivers/radeon/radeon_llvm_emit.h      |  46 ----
 src/gallium/drivers/radeonsi/Makefile.sources      |   1 +
 src/gallium/drivers/radeonsi/si_pipe.c             |   2 +-
 src/gallium/drivers/radeonsi/si_shader.c           |   2 -
 src/gallium/drivers/radeonsi/si_shader_internal.h  | 132 +++++++++++
 src/gallium/drivers/radeonsi/si_shader_tgsi_alu.c  |   1 -
 .../si_shader_tgsi_setup.c}                        | 225 +++++++++++++++++--
 11 files changed, 346 insertions(+), 462 deletions(-)

diff --git a/src/gallium/drivers/r600/evergreen_compute_internal.h b/src/gallium/drivers/r600/evergreen_compute_internal.h
index e6ff760..34d96f6 100644
--- a/src/gallium/drivers/r600/evergreen_compute_internal.h
+++ b/src/gallium/drivers/r600/evergreen_compute_internal.h
@@ -27,7 +27,6 @@
 
 #include "r600_asm.h"
 #ifdef HAVE_OPENCL
-#include "radeon/radeon_llvm.h"
 #include <llvm-c/Core.h>
 #endif
 
diff --git a/src/gallium/drivers/radeon/Makefile.sources b/src/gallium/drivers/radeon/Makefile.sources
index 049da60..3e13dae 100644
--- a/src/gallium/drivers/radeon/Makefile.sources
+++ b/src/gallium/drivers/radeon/Makefile.sources
@@ -25,8 +25,4 @@ C_SOURCES := \
 
 LLVM_C_FILES := \
 	radeon_elf_util.c \
-	radeon_elf_util.h \
-	radeon_llvm_emit.c \
-	radeon_llvm_emit.h \
-	radeon_llvm.h \
-	radeon_setup_tgsi_llvm.c
+	radeon_elf_util.h
diff --git a/src/gallium/drivers/radeon/radeon_llvm.h b/src/gallium/drivers/radeon/radeon_llvm.h
deleted file mode 100644
index b4b968b..0000000
--- a/src/gallium/drivers/radeon/radeon_llvm.h
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright 2011 Advanced Micro Devices, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Authors: Tom Stellard <thomas.stellard at amd.com>
- *
- */
-
-#ifndef RADEON_LLVM_H
-#define RADEON_LLVM_H
-
-#include <llvm-c/Core.h>
-#include "gallivm/lp_bld_init.h"
-#include "gallivm/lp_bld_tgsi.h"
-#include "tgsi/tgsi_parse.h"
-
-#define RADEON_LLVM_MAX_INPUT_SLOTS 32
-#define RADEON_LLVM_MAX_INPUTS 32 * 4
-#define RADEON_LLVM_MAX_OUTPUTS 32 * 4
-
-#define RADEON_LLVM_INITIAL_CF_DEPTH 4
-
-#define RADEON_LLVM_MAX_SYSTEM_VALUES 4
-
-struct radeon_llvm_flow;
-
-struct radeon_llvm_context {
-	struct lp_build_tgsi_soa_context soa;
-
-	/*=== Front end configuration ===*/
-
-	/* Instructions that are not described by any of the TGSI opcodes. */
-
-	/** This function is responsible for initilizing the inputs array and will be
-	  * called once for each input declared in the TGSI shader.
-	  */
-	void (*load_input)(struct radeon_llvm_context *,
-			   unsigned input_index,
-			   const struct tgsi_full_declaration *decl,
-			   LLVMValueRef out[4]);
-
-	void (*load_system_value)(struct radeon_llvm_context *,
-				  unsigned index,
-				  const struct tgsi_full_declaration *decl);
-
-	void (*declare_memory_region)(struct radeon_llvm_context *,
-				      const struct tgsi_full_declaration *decl);
-
-	/** This array contains the input values for the shader.  Typically these
-	  * values will be in the form of a target intrinsic that will inform the
-	  * backend how to load the actual inputs to the shader. 
-	  */
-	struct tgsi_full_declaration input_decls[RADEON_LLVM_MAX_INPUT_SLOTS];
-	LLVMValueRef inputs[RADEON_LLVM_MAX_INPUTS];
-	LLVMValueRef outputs[RADEON_LLVM_MAX_OUTPUTS][TGSI_NUM_CHANNELS];
-
-	/** This pointer is used to contain the temporary values.
-	  * The amount of temporary used in tgsi can't be bound to a max value and
-	  * thus we must allocate this array at runtime.
-	  */
-	LLVMValueRef *temps;
-	unsigned temps_count;
-	LLVMValueRef system_values[RADEON_LLVM_MAX_SYSTEM_VALUES];
-
-	/*=== Private Members ===*/
-
-	struct radeon_llvm_flow *flow;
-	unsigned flow_depth;
-	unsigned flow_depth_max;
-
-	struct tgsi_array_info *temp_arrays;
-	LLVMValueRef *temp_array_allocas;
-
-	LLVMValueRef undef_alloca;
-
-	LLVMValueRef main_fn;
-	LLVMTypeRef return_type;
-
-	unsigned fpmath_md_kind;
-	LLVMValueRef fpmath_md_2p5_ulp;
-
-	struct gallivm_state gallivm;
-};
-
-LLVMTypeRef tgsi2llvmtype(struct lp_build_tgsi_context *bld_base,
-			  enum tgsi_opcode_type type);
-
-LLVMValueRef bitcast(struct lp_build_tgsi_context *bld_base,
-		     enum tgsi_opcode_type type, LLVMValueRef value);
-
-LLVMValueRef radeon_llvm_bound_index(struct radeon_llvm_context *ctx,
-				     LLVMValueRef index,
-				     unsigned num);
-
-void radeon_llvm_context_init(struct radeon_llvm_context *ctx,
-                              const char *triple,
-			      const struct tgsi_shader_info *info,
-			      const struct tgsi_token *tokens);
-
-void radeon_llvm_create_func(struct radeon_llvm_context *ctx,
-			     LLVMTypeRef *return_types, unsigned num_return_elems,
-			     LLVMTypeRef *ParamTypes, unsigned ParamCount);
-
-void radeon_llvm_dispose(struct radeon_llvm_context *ctx);
-
-void radeon_llvm_finalize_module(struct radeon_llvm_context *ctx,
-				 bool run_verifier);
-
-LLVMValueRef radeon_llvm_emit_fetch_64bit(struct lp_build_tgsi_context *bld_base,
-					  enum tgsi_opcode_type type,
-					  LLVMValueRef ptr,
-					  LLVMValueRef ptr2);
-
-LLVMValueRef radeon_llvm_saturate(struct lp_build_tgsi_context *bld_base,
-                                  LLVMValueRef value);
-
-LLVMValueRef radeon_llvm_emit_fetch(struct lp_build_tgsi_context *bld_base,
-				    const struct tgsi_full_src_register *reg,
-				    enum tgsi_opcode_type type,
-				    unsigned swizzle);
-
-void radeon_llvm_emit_store(struct lp_build_tgsi_context *bld_base,
-			    const struct tgsi_full_instruction *inst,
-			    const struct tgsi_opcode_info *info,
-			    LLVMValueRef dst[4]);
-
-static inline struct radeon_llvm_context *
-radeon_llvm_context(struct lp_build_tgsi_context *bld_base)
-{
-	return (struct radeon_llvm_context*)bld_base;
-}
-
-#endif /* RADEON_LLVM_H */
diff --git a/src/gallium/drivers/radeon/radeon_llvm_emit.c b/src/gallium/drivers/radeon/radeon_llvm_emit.c
deleted file mode 100644
index 9611f15..0000000
--- a/src/gallium/drivers/radeon/radeon_llvm_emit.c
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- * Copyright 2011 Advanced Micro Devices, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Authors: Tom Stellard <thomas.stellard at amd.com>
- *
- */
-
-#include "radeon_llvm_emit.h"
-#include "radeon_elf_util.h"
-#include "c11/threads.h"
-#include "gallivm/lp_bld_misc.h"
-#include "util/u_debug.h"
-#include "util/u_memory.h"
-#include "pipe/p_shader_tokens.h"
-#include "pipe/p_state.h"
-
-#include <llvm-c/Target.h>
-#include <llvm-c/TargetMachine.h>
-#include <llvm-c/Core.h>
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#define CPU_STRING_LEN 30
-#define FS_STRING_LEN 30
-#define TRIPLE_STRING_LEN 7
-
-/**
- * Shader types for the LLVM backend.
- */
-enum radeon_llvm_shader_type {
-	RADEON_LLVM_SHADER_PS = 0,
-	RADEON_LLVM_SHADER_VS = 1,
-	RADEON_LLVM_SHADER_GS = 2,
-	RADEON_LLVM_SHADER_CS = 3,
-};
-
-enum radeon_llvm_calling_convention {
-	RADEON_LLVM_AMDGPU_VS = 87,
-	RADEON_LLVM_AMDGPU_GS = 88,
-	RADEON_LLVM_AMDGPU_PS = 89,
-	RADEON_LLVM_AMDGPU_CS = 90,
-};
-
-void radeon_llvm_add_attribute(LLVMValueRef F, const char *name, int value)
-{
-	char str[16];
-
-	snprintf(str, sizeof(str), "%i", value);
-	LLVMAddTargetDependentFunctionAttr(F, name, str);
-}
-
-/**
- * Set the shader type we want to compile
- *
- * @param type shader type to set
- */
-void radeon_llvm_shader_type(LLVMValueRef F, unsigned type)
-{
-	enum radeon_llvm_shader_type llvm_type;
-	enum radeon_llvm_calling_convention calling_conv;
-
-	switch (type) {
-	case PIPE_SHADER_VERTEX:
-	case PIPE_SHADER_TESS_CTRL:
-	case PIPE_SHADER_TESS_EVAL:
-		llvm_type = RADEON_LLVM_SHADER_VS;
-		calling_conv = RADEON_LLVM_AMDGPU_VS;
-		break;
-	case PIPE_SHADER_GEOMETRY:
-		llvm_type = RADEON_LLVM_SHADER_GS;
-		calling_conv = RADEON_LLVM_AMDGPU_GS;
-		break;
-	case PIPE_SHADER_FRAGMENT:
-		llvm_type = RADEON_LLVM_SHADER_PS;
-		calling_conv = RADEON_LLVM_AMDGPU_PS;
-		break;
-	case PIPE_SHADER_COMPUTE:
-		llvm_type = RADEON_LLVM_SHADER_CS;
-		calling_conv = RADEON_LLVM_AMDGPU_CS;
-		break;
-	default:
-		unreachable("Unhandle shader type");
-	}
-
-	if (HAVE_LLVM >= 0x309)
-		LLVMSetFunctionCallConv(F, calling_conv);
-	else
-		radeon_llvm_add_attribute(F, "ShaderType", llvm_type);
-}
-
-static void init_r600_target()
-{
-	gallivm_init_llvm_targets();
-#if HAVE_LLVM < 0x0307
-	LLVMInitializeR600TargetInfo();
-	LLVMInitializeR600Target();
-	LLVMInitializeR600TargetMC();
-	LLVMInitializeR600AsmPrinter();
-#else
-	LLVMInitializeAMDGPUTargetInfo();
-	LLVMInitializeAMDGPUTarget();
-	LLVMInitializeAMDGPUTargetMC();
-	LLVMInitializeAMDGPUAsmPrinter();
-
-#endif
-}
-
-static once_flag init_r600_target_once_flag = ONCE_FLAG_INIT;
-
-LLVMTargetRef radeon_llvm_get_r600_target(const char *triple)
-{
-	LLVMTargetRef target = NULL;
-	char *err_message = NULL;
-
-	call_once(&init_r600_target_once_flag, init_r600_target);
-
-	if (LLVMGetTargetFromTriple(triple, &target, &err_message)) {
-		fprintf(stderr, "Cannot find target for triple %s ", triple);
-		if (err_message) {
-			fprintf(stderr, "%s\n", err_message);
-		}
-		LLVMDisposeMessage(err_message);
-		return NULL;
-	}
-	return target;
-}
-
-struct radeon_llvm_diagnostics {
-	struct pipe_debug_callback *debug;
-	unsigned retval;
-};
-
-static void radeonDiagnosticHandler(LLVMDiagnosticInfoRef di, void *context)
-{
-	struct radeon_llvm_diagnostics *diag = (struct radeon_llvm_diagnostics *)context;
-	LLVMDiagnosticSeverity severity = LLVMGetDiagInfoSeverity(di);
-	char *description = LLVMGetDiagInfoDescription(di);
-	const char *severity_str = NULL;
-
-	switch (severity) {
-	case LLVMDSError:
-		severity_str = "error";
-		break;
-	case LLVMDSWarning:
-		severity_str = "warning";
-		break;
-	case LLVMDSRemark:
-		severity_str = "remark";
-		break;
-	case LLVMDSNote:
-		severity_str = "note";
-		break;
-	default:
-		severity_str = "unknown";
-	}
-
-	pipe_debug_message(diag->debug, SHADER_INFO,
-			   "LLVM diagnostic (%s): %s", severity_str, description);
-
-	if (severity == LLVMDSError) {
-		diag->retval = 1;
-		fprintf(stderr,"LLVM triggered Diagnostic Handler: %s\n", description);
-	}
-
-	LLVMDisposeMessage(description);
-}
-
-/**
- * Compile an LLVM module to machine code.
- *
- * @returns 0 for success, 1 for failure
- */
-unsigned radeon_llvm_compile(LLVMModuleRef M, struct radeon_shader_binary *binary,
-			     LLVMTargetMachineRef tm,
-			     struct pipe_debug_callback *debug)
-{
-	struct radeon_llvm_diagnostics diag;
-	char *err;
-	LLVMContextRef llvm_ctx;
-	LLVMMemoryBufferRef out_buffer;
-	unsigned buffer_size;
-	const char *buffer_data;
-	LLVMBool mem_err;
-
-	diag.debug = debug;
-	diag.retval = 0;
-
-	/* Setup Diagnostic Handler*/
-	llvm_ctx = LLVMGetModuleContext(M);
-
-	LLVMContextSetDiagnosticHandler(llvm_ctx, radeonDiagnosticHandler, &diag);
-
-	/* Compile IR*/
-	mem_err = LLVMTargetMachineEmitToMemoryBuffer(tm, M, LLVMObjectFile, &err,
-								 &out_buffer);
-
-	/* Process Errors/Warnings */
-	if (mem_err) {
-		fprintf(stderr, "%s: %s", __FUNCTION__, err);
-		pipe_debug_message(debug, SHADER_INFO,
-				   "LLVM emit error: %s", err);
-		FREE(err);
-		diag.retval = 1;
-		goto out;
-	}
-
-	/* Extract Shader Code*/
-	buffer_size = LLVMGetBufferSize(out_buffer);
-	buffer_data = LLVMGetBufferStart(out_buffer);
-
-	radeon_elf_read(buffer_data, buffer_size, binary);
-
-	/* Clean up */
-	LLVMDisposeMemoryBuffer(out_buffer);
-
-out:
-	if (diag.retval != 0)
-		pipe_debug_message(debug, SHADER_INFO, "LLVM compile failed");
-	return diag.retval;
-}
diff --git a/src/gallium/drivers/radeon/radeon_llvm_emit.h b/src/gallium/drivers/radeon/radeon_llvm_emit.h
deleted file mode 100644
index 677978b..0000000
--- a/src/gallium/drivers/radeon/radeon_llvm_emit.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2012 Advanced Micro Devices, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Authors: Tom Stellard <thomas.stellard at amd.com>
- *
- */
-
-#ifndef RADEON_LLVM_EMIT_H
-#define RADEON_LLVM_EMIT_H
-
-#include <llvm-c/Core.h>
-#include <llvm-c/TargetMachine.h>
-#include <stdbool.h>
-
-struct pipe_debug_callback;
-struct radeon_shader_binary;
-
-void radeon_llvm_add_attribute(LLVMValueRef F, const char *name, int value);
-void radeon_llvm_shader_type(LLVMValueRef F, unsigned type);
-
-LLVMTargetRef radeon_llvm_get_r600_target(const char *triple);
-
-unsigned radeon_llvm_compile(LLVMModuleRef M, struct radeon_shader_binary *binary,
-			     LLVMTargetMachineRef tm,
-			     struct pipe_debug_callback *debug);
-
-#endif /* RADEON_LLVM_EMIT_H */
diff --git a/src/gallium/drivers/radeonsi/Makefile.sources b/src/gallium/drivers/radeonsi/Makefile.sources
index a16f19c..727a9cc 100644
--- a/src/gallium/drivers/radeonsi/Makefile.sources
+++ b/src/gallium/drivers/radeonsi/Makefile.sources
@@ -17,6 +17,7 @@ C_SOURCES := \
 	si_shader.h \
 	si_shader_internal.h \
 	si_shader_tgsi_alu.c \
+	si_shader_tgsi_setup.c \
 	si_state.c \
 	si_state_draw.c \
 	si_state_shaders.c \
diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c
index 5a3f101..7924375 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.c
+++ b/src/gallium/drivers/radeonsi/si_pipe.c
@@ -23,9 +23,9 @@
 
 #include "si_pipe.h"
 #include "si_public.h"
+#include "si_shader_internal.h"
 #include "sid.h"
 
-#include "radeon/radeon_llvm_emit.h"
 #include "radeon/radeon_uvd.h"
 #include "util/u_memory.h"
 #include "util/u_suballoc.h"
diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c
index 37a812a..194da31 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -33,9 +33,7 @@
 #include "gallivm/lp_bld_arit.h"
 #include "gallivm/lp_bld_flow.h"
 #include "gallivm/lp_bld_misc.h"
-#include "radeon/radeon_llvm.h"
 #include "radeon/radeon_elf_util.h"
-#include "radeon/radeon_llvm_emit.h"
 #include "util/u_memory.h"
 #include "util/u_string.h"
 #include "tgsi/tgsi_build.h"
diff --git a/src/gallium/drivers/radeonsi/si_shader_internal.h b/src/gallium/drivers/radeonsi/si_shader_internal.h
index 44dd5fd..b46cc1c 100644
--- a/src/gallium/drivers/radeonsi/si_shader_internal.h
+++ b/src/gallium/drivers/radeonsi/si_shader_internal.h
@@ -27,6 +27,138 @@
 #include "si_shader.h"
 #include "gallivm/lp_bld_init.h"
 #include "gallivm/lp_bld_tgsi.h"
+#include "tgsi/tgsi_parse.h"
+
+#include <llvm-c/Core.h>
+#include <llvm-c/TargetMachine.h>
+
+struct pipe_debug_callback;
+struct radeon_shader_binary;
+
+#define RADEON_LLVM_MAX_INPUT_SLOTS 32
+#define RADEON_LLVM_MAX_INPUTS 32 * 4
+#define RADEON_LLVM_MAX_OUTPUTS 32 * 4
+
+#define RADEON_LLVM_INITIAL_CF_DEPTH 4
+
+#define RADEON_LLVM_MAX_SYSTEM_VALUES 4
+
+struct radeon_llvm_flow;
+
+struct radeon_llvm_context {
+	struct lp_build_tgsi_soa_context soa;
+
+	/*=== Front end configuration ===*/
+
+	/* Instructions that are not described by any of the TGSI opcodes. */
+
+	/** This function is responsible for initilizing the inputs array and will be
+	  * called once for each input declared in the TGSI shader.
+	  */
+	void (*load_input)(struct radeon_llvm_context *,
+			   unsigned input_index,
+			   const struct tgsi_full_declaration *decl,
+			   LLVMValueRef out[4]);
+
+	void (*load_system_value)(struct radeon_llvm_context *,
+				  unsigned index,
+				  const struct tgsi_full_declaration *decl);
+
+	void (*declare_memory_region)(struct radeon_llvm_context *,
+				      const struct tgsi_full_declaration *decl);
+
+	/** This array contains the input values for the shader.  Typically these
+	  * values will be in the form of a target intrinsic that will inform the
+	  * backend how to load the actual inputs to the shader.
+	  */
+	struct tgsi_full_declaration input_decls[RADEON_LLVM_MAX_INPUT_SLOTS];
+	LLVMValueRef inputs[RADEON_LLVM_MAX_INPUTS];
+	LLVMValueRef outputs[RADEON_LLVM_MAX_OUTPUTS][TGSI_NUM_CHANNELS];
+
+	/** This pointer is used to contain the temporary values.
+	  * The amount of temporary used in tgsi can't be bound to a max value and
+	  * thus we must allocate this array at runtime.
+	  */
+	LLVMValueRef *temps;
+	unsigned temps_count;
+	LLVMValueRef system_values[RADEON_LLVM_MAX_SYSTEM_VALUES];
+
+	/*=== Private Members ===*/
+
+	struct radeon_llvm_flow *flow;
+	unsigned flow_depth;
+	unsigned flow_depth_max;
+
+	struct tgsi_array_info *temp_arrays;
+	LLVMValueRef *temp_array_allocas;
+
+	LLVMValueRef undef_alloca;
+
+	LLVMValueRef main_fn;
+	LLVMTypeRef return_type;
+
+	unsigned fpmath_md_kind;
+	LLVMValueRef fpmath_md_2p5_ulp;
+
+	struct gallivm_state gallivm;
+};
+
+static inline struct radeon_llvm_context *
+radeon_llvm_context(struct lp_build_tgsi_context *bld_base)
+{
+	return (struct radeon_llvm_context*)bld_base;
+}
+
+void radeon_llvm_add_attribute(LLVMValueRef F, const char *name, int value);
+void radeon_llvm_shader_type(LLVMValueRef F, unsigned type);
+
+LLVMTargetRef radeon_llvm_get_r600_target(const char *triple);
+
+unsigned radeon_llvm_compile(LLVMModuleRef M, struct radeon_shader_binary *binary,
+			     LLVMTargetMachineRef tm,
+			     struct pipe_debug_callback *debug);
+
+LLVMTypeRef tgsi2llvmtype(struct lp_build_tgsi_context *bld_base,
+			  enum tgsi_opcode_type type);
+
+LLVMValueRef bitcast(struct lp_build_tgsi_context *bld_base,
+		     enum tgsi_opcode_type type, LLVMValueRef value);
+
+LLVMValueRef radeon_llvm_bound_index(struct radeon_llvm_context *ctx,
+				     LLVMValueRef index,
+				     unsigned num);
+
+void radeon_llvm_context_init(struct radeon_llvm_context *ctx,
+                              const char *triple,
+			      const struct tgsi_shader_info *info,
+			      const struct tgsi_token *tokens);
+
+void radeon_llvm_create_func(struct radeon_llvm_context *ctx,
+			     LLVMTypeRef *return_types, unsigned num_return_elems,
+			     LLVMTypeRef *ParamTypes, unsigned ParamCount);
+
+void radeon_llvm_dispose(struct radeon_llvm_context *ctx);
+
+void radeon_llvm_finalize_module(struct radeon_llvm_context *ctx,
+				 bool run_verifier);
+
+LLVMValueRef radeon_llvm_emit_fetch_64bit(struct lp_build_tgsi_context *bld_base,
+					  enum tgsi_opcode_type type,
+					  LLVMValueRef ptr,
+					  LLVMValueRef ptr2);
+
+LLVMValueRef radeon_llvm_saturate(struct lp_build_tgsi_context *bld_base,
+                                  LLVMValueRef value);
+
+LLVMValueRef radeon_llvm_emit_fetch(struct lp_build_tgsi_context *bld_base,
+				    const struct tgsi_full_src_register *reg,
+				    enum tgsi_opcode_type type,
+				    unsigned swizzle);
+
+void radeon_llvm_emit_store(struct lp_build_tgsi_context *bld_base,
+			    const struct tgsi_full_instruction *inst,
+			    const struct tgsi_opcode_info *info,
+			    LLVMValueRef dst[4]);
 
 void si_shader_context_init_alu(struct lp_build_tgsi_context *bld_base);
 void si_prepare_cube_coords(struct lp_build_tgsi_context *bld_base,
diff --git a/src/gallium/drivers/radeonsi/si_shader_tgsi_alu.c b/src/gallium/drivers/radeonsi/si_shader_tgsi_alu.c
index 192a2cb..75ceb57 100644
--- a/src/gallium/drivers/radeonsi/si_shader_tgsi_alu.c
+++ b/src/gallium/drivers/radeonsi/si_shader_tgsi_alu.c
@@ -26,7 +26,6 @@
 #include "gallivm/lp_bld_intr.h"
 #include "gallivm/lp_bld_gather.h"
 #include "tgsi/tgsi_parse.h"
-#include "radeon/radeon_llvm.h"
 
 static void kill_if_fetch_args(struct lp_build_tgsi_context *bld_base,
 			       struct lp_build_emit_data *emit_data)
diff --git a/src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c b/src/gallium/drivers/radeonsi/si_shader_tgsi_setup.c
similarity index 87%
rename from src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c
rename to src/gallium/drivers/radeonsi/si_shader_tgsi_setup.c
index c06eb3e..e1534c7 100644
--- a/src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c
+++ b/src/gallium/drivers/radeonsi/si_shader_tgsi_setup.c
@@ -1,12 +1,12 @@
 /*
- * Copyright 2011 Advanced Micro Devices, Inc.
+ * Copyright 2016 Advanced Micro Devices, Inc.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
  * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
  *
  * The above copyright notice and this permission notice (including the next
  * paragraph) shall be included in all copies or substantial portions of the
@@ -14,16 +14,15 @@
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Authors: Tom Stellard <thomas.stellard at amd.com>
- *
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
-#include "radeon_llvm.h"
+
+#include "si_shader_internal.h"
+#include "radeon/radeon_elf_util.h"
 
 #include "gallivm/lp_bld_const.h"
 #include "gallivm/lp_bld_gather.h"
@@ -39,7 +38,6 @@
 #include "util/u_debug.h"
 
 #include <stdio.h>
-#include <llvm-c/Core.h>
 #include <llvm-c/Transforms/Scalar.h>
 
 /* Data for if/else/endif and bgnloop/endloop control flow structures.
@@ -50,6 +48,205 @@ struct radeon_llvm_flow {
 	LLVMBasicBlockRef loop_entry_block;
 };
 
+#define CPU_STRING_LEN 30
+#define FS_STRING_LEN 30
+#define TRIPLE_STRING_LEN 7
+
+/**
+ * Shader types for the LLVM backend.
+ */
+enum radeon_llvm_shader_type {
+	RADEON_LLVM_SHADER_PS = 0,
+	RADEON_LLVM_SHADER_VS = 1,
+	RADEON_LLVM_SHADER_GS = 2,
+	RADEON_LLVM_SHADER_CS = 3,
+};
+
+enum radeon_llvm_calling_convention {
+	RADEON_LLVM_AMDGPU_VS = 87,
+	RADEON_LLVM_AMDGPU_GS = 88,
+	RADEON_LLVM_AMDGPU_PS = 89,
+	RADEON_LLVM_AMDGPU_CS = 90,
+};
+
+void radeon_llvm_add_attribute(LLVMValueRef F, const char *name, int value)
+{
+	char str[16];
+
+	snprintf(str, sizeof(str), "%i", value);
+	LLVMAddTargetDependentFunctionAttr(F, name, str);
+}
+
+/**
+ * Set the shader type we want to compile
+ *
+ * @param type shader type to set
+ */
+void radeon_llvm_shader_type(LLVMValueRef F, unsigned type)
+{
+	enum radeon_llvm_shader_type llvm_type;
+	enum radeon_llvm_calling_convention calling_conv;
+
+	switch (type) {
+	case PIPE_SHADER_VERTEX:
+	case PIPE_SHADER_TESS_CTRL:
+	case PIPE_SHADER_TESS_EVAL:
+		llvm_type = RADEON_LLVM_SHADER_VS;
+		calling_conv = RADEON_LLVM_AMDGPU_VS;
+		break;
+	case PIPE_SHADER_GEOMETRY:
+		llvm_type = RADEON_LLVM_SHADER_GS;
+		calling_conv = RADEON_LLVM_AMDGPU_GS;
+		break;
+	case PIPE_SHADER_FRAGMENT:
+		llvm_type = RADEON_LLVM_SHADER_PS;
+		calling_conv = RADEON_LLVM_AMDGPU_PS;
+		break;
+	case PIPE_SHADER_COMPUTE:
+		llvm_type = RADEON_LLVM_SHADER_CS;
+		calling_conv = RADEON_LLVM_AMDGPU_CS;
+		break;
+	default:
+		unreachable("Unhandle shader type");
+	}
+
+	if (HAVE_LLVM >= 0x309)
+		LLVMSetFunctionCallConv(F, calling_conv);
+	else
+		radeon_llvm_add_attribute(F, "ShaderType", llvm_type);
+}
+
+static void init_r600_target()
+{
+	gallivm_init_llvm_targets();
+#if HAVE_LLVM < 0x0307
+	LLVMInitializeR600TargetInfo();
+	LLVMInitializeR600Target();
+	LLVMInitializeR600TargetMC();
+	LLVMInitializeR600AsmPrinter();
+#else
+	LLVMInitializeAMDGPUTargetInfo();
+	LLVMInitializeAMDGPUTarget();
+	LLVMInitializeAMDGPUTargetMC();
+	LLVMInitializeAMDGPUAsmPrinter();
+
+#endif
+}
+
+static once_flag init_r600_target_once_flag = ONCE_FLAG_INIT;
+
+LLVMTargetRef radeon_llvm_get_r600_target(const char *triple)
+{
+	LLVMTargetRef target = NULL;
+	char *err_message = NULL;
+
+	call_once(&init_r600_target_once_flag, init_r600_target);
+
+	if (LLVMGetTargetFromTriple(triple, &target, &err_message)) {
+		fprintf(stderr, "Cannot find target for triple %s ", triple);
+		if (err_message) {
+			fprintf(stderr, "%s\n", err_message);
+		}
+		LLVMDisposeMessage(err_message);
+		return NULL;
+	}
+	return target;
+}
+
+struct radeon_llvm_diagnostics {
+	struct pipe_debug_callback *debug;
+	unsigned retval;
+};
+
+static void radeonDiagnosticHandler(LLVMDiagnosticInfoRef di, void *context)
+{
+	struct radeon_llvm_diagnostics *diag = (struct radeon_llvm_diagnostics *)context;
+	LLVMDiagnosticSeverity severity = LLVMGetDiagInfoSeverity(di);
+	char *description = LLVMGetDiagInfoDescription(di);
+	const char *severity_str = NULL;
+
+	switch (severity) {
+	case LLVMDSError:
+		severity_str = "error";
+		break;
+	case LLVMDSWarning:
+		severity_str = "warning";
+		break;
+	case LLVMDSRemark:
+		severity_str = "remark";
+		break;
+	case LLVMDSNote:
+		severity_str = "note";
+		break;
+	default:
+		severity_str = "unknown";
+	}
+
+	pipe_debug_message(diag->debug, SHADER_INFO,
+			   "LLVM diagnostic (%s): %s", severity_str, description);
+
+	if (severity == LLVMDSError) {
+		diag->retval = 1;
+		fprintf(stderr,"LLVM triggered Diagnostic Handler: %s\n", description);
+	}
+
+	LLVMDisposeMessage(description);
+}
+
+/**
+ * Compile an LLVM module to machine code.
+ *
+ * @returns 0 for success, 1 for failure
+ */
+unsigned radeon_llvm_compile(LLVMModuleRef M, struct radeon_shader_binary *binary,
+			     LLVMTargetMachineRef tm,
+			     struct pipe_debug_callback *debug)
+{
+	struct radeon_llvm_diagnostics diag;
+	char *err;
+	LLVMContextRef llvm_ctx;
+	LLVMMemoryBufferRef out_buffer;
+	unsigned buffer_size;
+	const char *buffer_data;
+	LLVMBool mem_err;
+
+	diag.debug = debug;
+	diag.retval = 0;
+
+	/* Setup Diagnostic Handler*/
+	llvm_ctx = LLVMGetModuleContext(M);
+
+	LLVMContextSetDiagnosticHandler(llvm_ctx, radeonDiagnosticHandler, &diag);
+
+	/* Compile IR*/
+	mem_err = LLVMTargetMachineEmitToMemoryBuffer(tm, M, LLVMObjectFile, &err,
+								 &out_buffer);
+
+	/* Process Errors/Warnings */
+	if (mem_err) {
+		fprintf(stderr, "%s: %s", __FUNCTION__, err);
+		pipe_debug_message(debug, SHADER_INFO,
+				   "LLVM emit error: %s", err);
+		FREE(err);
+		diag.retval = 1;
+		goto out;
+	}
+
+	/* Extract Shader Code*/
+	buffer_size = LLVMGetBufferSize(out_buffer);
+	buffer_data = LLVMGetBufferStart(out_buffer);
+
+	radeon_elf_read(buffer_data, buffer_size, binary);
+
+	/* Clean up */
+	LLVMDisposeMemoryBuffer(out_buffer);
+
+out:
+	if (diag.retval != 0)
+		pipe_debug_message(debug, SHADER_INFO, "LLVM compile failed");
+	return diag.retval;
+}
+
 LLVMTypeRef tgsi2llvmtype(struct lp_build_tgsi_context *bld_base,
 			  enum tgsi_opcode_type type)
 {




More information about the mesa-commit mailing list