[Mesa-dev] [PATCH 07/11] ac/radv: move llvm compiler info to struct and init in one place

Dave Airlie airlied at gmail.com
Wed Jun 27 03:58:41 UTC 2018


From: Dave Airlie <airlied at redhat.com>

This creates a common per-thread compiler info struct, and adds
the init code to it. This is mostly ported from radeonsi.

The common info struct is used in radv first and replaces the
current code.
---
 src/amd/common/ac_llvm_util.c     | 50 +++++++++++++++++++++++++++++++
 src/amd/common/ac_llvm_util.h     | 14 +++++++++
 src/amd/vulkan/radv_nir_to_llvm.c | 39 ++++++++++--------------
 src/amd/vulkan/radv_private.h     |  7 ++---
 src/amd/vulkan/radv_shader.c      | 16 +++++-----
 5 files changed, 91 insertions(+), 35 deletions(-)

diff --git a/src/amd/common/ac_llvm_util.c b/src/amd/common/ac_llvm_util.c
index dd2469d4606..85dc9d72a5c 100644
--- a/src/amd/common/ac_llvm_util.c
+++ b/src/amd/common/ac_llvm_util.c
@@ -188,6 +188,56 @@ LLVMPassManagerRef ac_init_passmgr(LLVMTargetLibraryInfoRef target_library_info,
 	return passmgr;
 }
 
+bool ac_llvm_compiler_init(struct ac_llvm_compiler_info *info,
+			   bool add_target_library_info,
+			   enum radeon_family family,
+			   enum ac_target_machine_options tm_options)
+{
+	memset(info, 0, sizeof(*info));
+	info->tm = ac_create_target_machine(family, tm_options, &info->triple);
+	if (!info->tm)
+		return false;
+
+	/* Get the data layout. */
+	LLVMTargetDataRef data_layout = LLVMCreateTargetDataLayout(info->tm);
+	if (!data_layout)
+		goto fail;
+	info->data_layout = LLVMCopyStringRepOfTargetData(data_layout);
+	LLVMDisposeTargetData(data_layout);
+
+#if HAVE_LLVM < 0x0700
+	if (add_target_library_info)
+#endif
+	{
+		info->target_library_info =
+			ac_create_target_library_info(info->triple);
+		if (!info->target_library_info)
+			goto fail;
+	}
+	info->passmgr = ac_init_passmgr(info->target_library_info, tm_options & AC_TM_CHECK_IR);
+	if (!info->passmgr)
+		goto fail;
+	return true;
+fail:
+	ac_llvm_compiler_dispose(info);
+	return false;
+}
+
+void ac_llvm_compiler_dispose(struct ac_llvm_compiler_info *info)
+{
+	if (info->data_layout)
+		LLVMDisposeMessage((char*)info->data_layout);
+	if (info->passmgr)
+		LLVMDisposePassManager(info->passmgr);
+#if HAVE_LLVM >= 0x0700
+	/* This crashes on LLVM 5.0 and 6.0 and Ubuntu 18.04, so leak it there. */
+	if (info->target_library_info)
+		ac_dispose_target_library_info(info->target_library_info);
+#endif
+	if (info->tm)
+		LLVMDisposeTargetMachine(info->tm);
+}
+
 static const char *attr_to_str(enum ac_func_attr attr)
 {
    switch (attr) {
diff --git a/src/amd/common/ac_llvm_util.h b/src/amd/common/ac_llvm_util.h
index b3d4ccfb2cb..bc91717b5f1 100644
--- a/src/amd/common/ac_llvm_util.h
+++ b/src/amd/common/ac_llvm_util.h
@@ -59,6 +59,7 @@ enum ac_target_machine_options {
 	AC_TM_FORCE_ENABLE_XNACK = (1 << 2),
 	AC_TM_FORCE_DISABLE_XNACK = (1 << 3),
 	AC_TM_PROMOTE_ALLOCA_TO_SCRATCH = (1 << 4),
+	AC_TM_CHECK_IR = (1 << 5),
 };
 
 enum ac_float_mode {
@@ -67,6 +68,14 @@ enum ac_float_mode {
 	AC_FLOAT_MODE_UNSAFE_FP_MATH,
 };
 
+struct ac_llvm_compiler_info {
+	LLVMTargetMachineRef tm;
+	LLVMPassManagerRef passmgr;
+	LLVMTargetLibraryInfoRef target_library_info;
+	const char *triple;
+	const char *data_layout;
+};
+
 const char *ac_get_llvm_processor_name(enum radeon_family family);
 LLVMTargetMachineRef ac_create_target_machine(enum radeon_family family,
 					      enum ac_target_machine_options tm_options,
@@ -110,6 +119,11 @@ ac_get_store_intr_attribs(bool writeonly_memory)
 unsigned
 ac_count_scratch_private_memory(LLVMValueRef function);
 
+bool ac_llvm_compiler_init(struct ac_llvm_compiler_info *info,
+			   bool add_target_library_info, /* crash workaround */
+			   enum radeon_family family,
+			   enum ac_target_machine_options tm_options);
+void ac_llvm_compiler_dispose(struct ac_llvm_compiler_info *info);
 LLVMPassManagerRef ac_init_passmgr(LLVMTargetLibraryInfoRef target_library_info,
 				   bool check_ir);
 LLVMTargetLibraryInfoRef ac_create_target_library_info(const char *triple);
diff --git a/src/amd/vulkan/radv_nir_to_llvm.c b/src/amd/vulkan/radv_nir_to_llvm.c
index ea055881084..115aa773e35 100644
--- a/src/amd/vulkan/radv_nir_to_llvm.c
+++ b/src/amd/vulkan/radv_nir_to_llvm.c
@@ -3127,8 +3127,7 @@ static void prepare_gs_input_vgprs(struct radv_shader_context *ctx)
 
 
 static
-LLVMModuleRef ac_translate_nir_to_llvm(LLVMTargetMachineRef tm,
-                                       LLVMPassManagerRef passmgr,
+LLVMModuleRef ac_translate_nir_to_llvm(struct ac_llvm_compiler_info *llvm_info,
                                        struct nir_shader *const *shaders,
                                        int shader_count,
                                        struct radv_shader_variant_info *shader_info,
@@ -3143,13 +3142,8 @@ LLVMModuleRef ac_translate_nir_to_llvm(LLVMTargetMachineRef tm,
 	ac_llvm_context_init(&ctx.ac, ctx.context, options->chip_class,
 			     options->family);
 	ctx.ac.module = LLVMModuleCreateWithNameInContext("shader", ctx.context);
-	LLVMSetTarget(ctx.ac.module, options->supports_spill ? "amdgcn-mesa-mesa3d" : "amdgcn--");
-
-	LLVMTargetDataRef data_layout = LLVMCreateTargetDataLayout(tm);
-	char *data_layout_str = LLVMCopyStringRepOfTargetData(data_layout);
-	LLVMSetDataLayout(ctx.ac.module, data_layout_str);
-	LLVMDisposeTargetData(data_layout);
-	LLVMDisposeMessage(data_layout_str);
+	LLVMSetTarget(ctx.ac.module, llvm_info->triple);
+	LLVMSetDataLayout(ctx.ac.module, llvm_info->data_layout);
 
 	enum ac_float_mode float_mode =
 		options->unsafe_math ? AC_FLOAT_MODE_UNSAFE_FP_MATH :
@@ -3304,7 +3298,7 @@ LLVMModuleRef ac_translate_nir_to_llvm(LLVMTargetMachineRef tm,
 	if (options->dump_preoptir)
 		ac_dump_module(ctx.ac.module);
 
-	ac_llvm_finalize_module(&ctx, passmgr, options);
+	ac_llvm_finalize_module(&ctx, llvm_info->passmgr, options);
 
 	if (shader_count == 1)
 		ac_nir_eliminate_const_vs_outputs(&ctx);
@@ -3334,7 +3328,7 @@ static void ac_diagnostic_handler(LLVMDiagnosticInfoRef di, void *context)
 
 static unsigned ac_llvm_compile(LLVMModuleRef M,
                                 struct ac_shader_binary *binary,
-                                LLVMTargetMachineRef tm)
+                                struct ac_llvm_compiler_info *llvm_info)
 {
 	unsigned retval = 0;
 	char *err;
@@ -3351,7 +3345,7 @@ static unsigned ac_llvm_compile(LLVMModuleRef M,
 	                                &retval);
 
 	/* Compile IR*/
-	mem_err = LLVMTargetMachineEmitToMemoryBuffer(tm, M, LLVMObjectFile,
+	mem_err = LLVMTargetMachineEmitToMemoryBuffer(llvm_info->tm, M, LLVMObjectFile,
 	                                              &err, &out_buffer);
 
 	/* Process Errors/Warnings */
@@ -3375,7 +3369,7 @@ out:
 	return retval;
 }
 
-static void ac_compile_llvm_module(LLVMTargetMachineRef tm,
+static void ac_compile_llvm_module(struct ac_llvm_compiler_info *llvm_info,
 				   LLVMModuleRef llvm_module,
 				   struct ac_shader_binary *binary,
 				   struct ac_shader_config *config,
@@ -3394,7 +3388,7 @@ static void ac_compile_llvm_module(LLVMTargetMachineRef tm,
 		LLVMDisposeMessage(llvm_ir);
 	}
 
-	int v = ac_llvm_compile(llvm_module, binary, tm);
+	int v = ac_llvm_compile(llvm_module, binary, llvm_info);
 	if (v) {
 		fprintf(stderr, "compile failed\n");
 	}
@@ -3504,8 +3498,7 @@ ac_fill_shader_info(struct radv_shader_variant_info *shader_info, struct nir_sha
 }
 
 void
-radv_compile_nir_shader(LLVMTargetMachineRef tm,
-			LLVMPassManagerRef passmgr,
+radv_compile_nir_shader(struct ac_llvm_compiler_info *llvm_info,
 			struct ac_shader_binary *binary,
 			struct ac_shader_config *config,
 			struct radv_shader_variant_info *shader_info,
@@ -3516,10 +3509,10 @@ radv_compile_nir_shader(LLVMTargetMachineRef tm,
 
 	LLVMModuleRef llvm_module;
 
-	llvm_module = ac_translate_nir_to_llvm(tm, passmgr, nir, nir_count, shader_info,
+	llvm_module = ac_translate_nir_to_llvm(llvm_info, nir, nir_count, shader_info,
 	                                       options);
 
-	ac_compile_llvm_module(tm, llvm_module, binary, config, shader_info,
+	ac_compile_llvm_module(llvm_info, llvm_module, binary, config, shader_info,
 			       nir[0]->info.stage, options);
 
 	for (int i = 0; i < nir_count; ++i)
@@ -3577,8 +3570,7 @@ ac_gs_copy_shader_emit(struct radv_shader_context *ctx)
 }
 
 void
-radv_compile_gs_copy_shader(LLVMTargetMachineRef tm,
-			    LLVMPassManagerRef passmgr,
+radv_compile_gs_copy_shader(struct ac_llvm_compiler_info *llvm_info,
 			    struct nir_shader *geom_shader,
 			    struct ac_shader_binary *binary,
 			    struct ac_shader_config *config,
@@ -3595,7 +3587,8 @@ radv_compile_gs_copy_shader(LLVMTargetMachineRef tm,
 	ctx.ac.module = LLVMModuleCreateWithNameInContext("shader", ctx.context);
 
 	ctx.is_gs_copy_shader = true;
-	LLVMSetTarget(ctx.ac.module, "amdgcn--");
+	LLVMSetTarget(ctx.ac.module, llvm_info->triple);
+	LLVMSetDataLayout(ctx.ac.module, llvm_info->data_layout);
 
 	enum ac_float_mode float_mode =
 		options->unsafe_math ? AC_FLOAT_MODE_UNSAFE_FP_MATH :
@@ -3624,8 +3617,8 @@ radv_compile_gs_copy_shader(LLVMTargetMachineRef tm,
 
 	LLVMBuildRetVoid(ctx.ac.builder);
 
-	ac_llvm_finalize_module(&ctx, passmgr, options);
+	ac_llvm_finalize_module(&ctx, llvm_info->passmgr, options);
 
-	ac_compile_llvm_module(tm, ctx.ac.module, binary, config, shader_info,
+	ac_compile_llvm_module(llvm_info, ctx.ac.module, binary, config, shader_info,
 			       MESA_SHADER_VERTEX, options);
 }
diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h
index 7f741480ac3..24f82e29a98 100644
--- a/src/amd/vulkan/radv_private.h
+++ b/src/amd/vulkan/radv_private.h
@@ -58,6 +58,7 @@
 #include "ac_gpu_info.h"
 #include "ac_surface.h"
 #include "ac_llvm_build.h"
+#include "ac_llvm_util.h"
 #include "radv_descriptor_set.h"
 #include "radv_extensions.h"
 #include "radv_cs.h"
@@ -1797,16 +1798,14 @@ struct radv_fence {
 struct radv_shader_variant_info;
 struct radv_nir_compiler_options;
 
-void radv_compile_gs_copy_shader(LLVMTargetMachineRef tm,
-				 LLVMPassManagerRef passmgr,
+void radv_compile_gs_copy_shader(struct ac_llvm_compiler_info *llvm_info,
 				 struct nir_shader *geom_shader,
 				 struct ac_shader_binary *binary,
 				 struct ac_shader_config *config,
 				 struct radv_shader_variant_info *shader_info,
 				 const struct radv_nir_compiler_options *option);
 
-void radv_compile_nir_shader(LLVMTargetMachineRef tm,
-			     LLVMPassManagerRef passmgr,
+void radv_compile_nir_shader(struct ac_llvm_compiler_info *llvm_info,
 			     struct ac_shader_binary *binary,
 			     struct ac_shader_config *config,
 			     struct radv_shader_variant_info *shader_info,
diff --git a/src/amd/vulkan/radv_shader.c b/src/amd/vulkan/radv_shader.c
index b694300b777..3bbb7867640 100644
--- a/src/amd/vulkan/radv_shader.c
+++ b/src/amd/vulkan/radv_shader.c
@@ -525,8 +525,7 @@ shader_variant_create(struct radv_device *device,
 	enum ac_target_machine_options tm_options = 0;
 	struct radv_shader_variant *variant;
 	struct ac_shader_binary binary;
-	LLVMTargetMachineRef tm;
-	LLVMPassManagerRef passmgr;
+	struct ac_llvm_compiler_info llvm_info;
 
 	variant = calloc(1, sizeof(struct radv_shader_variant));
 	if (!variant)
@@ -546,23 +545,24 @@ shader_variant_create(struct radv_device *device,
 		tm_options |= AC_TM_SUPPORTS_SPILL;
 	if (device->instance->perftest_flags & RADV_PERFTEST_SISCHED)
 		tm_options |= AC_TM_SISCHED;
+	if (options->check_ir)
+		tm_options |= AC_TM_CHECK_IR;
 	
 	radv_init_llvm_once();
-	tm = ac_create_target_machine(chip_family, tm_options, NULL);
-	passmgr = ac_init_passmgr(NULL, options->check_ir);
+
+	ac_llvm_compiler_init(&llvm_info, false, chip_family, tm_options);
 	if (gs_copy_shader) {
 		assert(shader_count == 1);
-		radv_compile_gs_copy_shader(tm, passmgr, *shaders, &binary,
+		radv_compile_gs_copy_shader(&llvm_info, *shaders, &binary,
 					    &variant->config, &variant->info,
 					    options);
 	} else {
-		radv_compile_nir_shader(tm, passmgr, &binary, &variant->config,
+		radv_compile_nir_shader(&llvm_info, &binary, &variant->config,
 					&variant->info, shaders, shader_count,
 					options);
 	}
 
-	LLVMDisposePassManager(passmgr);
-	LLVMDisposeTargetMachine(tm);
+	ac_llvm_compiler_dispose(&llvm_info);
 
 	radv_fill_shader_variant(device, variant, &binary, stage);
 
-- 
2.17.1



More information about the mesa-dev mailing list