ac/radv: move llvm compiler info to struct and init in one place
This ports radv to the shared code, however due to a bug in LLVM
version prior to 7, radv cannot add target info at this stage,
as it would leak one for every shader compile, however I'd prefer
to keep this llvm damage in the shared code, since it isn't the
driver at fault here. We just add a flag to denote if the driver
can support leaking the target info or not, and the common code
does the right thing depending on the llvm version.
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
diff --git a/src/amd/common/ac_llvm_util.c b/src/amd/common/ac_llvm_util.c
index fa85c62..2be2edf 100644
--- a/src/amd/common/ac_llvm_util.c
+++ b/src/amd/common/ac_llvm_util.c
@@ -285,6 +285,7 @@
bool
ac_init_llvm_compiler(struct ac_llvm_compiler *compiler,
+ bool okay_to_leak_target_library_info,
enum radeon_family family,
enum ac_target_machine_options tm_options)
{
@@ -296,10 +297,12 @@
if (!compiler->tm)
return false;
- compiler->target_library_info =
- ac_create_target_library_info(triple);
- if (!compiler->target_library_info)
- goto fail;
+ if (okay_to_leak_target_library_info || (HAVE_LLVM >= 0x0700)) {
+ compiler->target_library_info =
+ ac_create_target_library_info(triple);
+ if (!compiler->target_library_info)
+ goto fail;
+ }
compiler->passmgr = ac_create_passmgr(compiler->target_library_info,
tm_options & AC_TM_CHECK_IR);
diff --git a/src/amd/common/ac_llvm_util.h b/src/amd/common/ac_llvm_util.h
index cd56ff5..ad463c6 100644
--- a/src/amd/common/ac_llvm_util.h
+++ b/src/amd/common/ac_llvm_util.h
@@ -127,6 +127,7 @@
bool ac_init_llvm_compiler(struct ac_llvm_compiler *compiler,
+ bool okay_to_leak_target_library_info,
enum radeon_family family,
enum ac_target_machine_options tm_options);
void ac_destroy_llvm_compiler(struct ac_llvm_compiler *compiler);
diff --git a/src/amd/vulkan/radv_nir_to_llvm.c b/src/amd/vulkan/radv_nir_to_llvm.c
index 9cd29e2..45ac085 100644
--- a/src/amd/vulkan/radv_nir_to_llvm.c
+++ b/src/amd/vulkan/radv_nir_to_llvm.c
@@ -3127,8 +3127,7 @@
static
-LLVMModuleRef ac_translate_nir_to_llvm(LLVMTargetMachineRef tm,
- LLVMPassManagerRef passmgr,
+LLVMModuleRef ac_translate_nir_to_llvm(struct ac_llvm_compiler *ac_llvm,
struct nir_shader *const *shaders,
int shader_count,
struct radv_shader_variant_info *shader_info,
@@ -3142,7 +3141,7 @@
ac_llvm_context_init(&ctx.ac, ctx.context, options->chip_class,
options->family);
- ctx.ac.module = ac_create_module(tm, ctx.context);
+ ctx.ac.module = ac_create_module(ac_llvm->tm, ctx.context);
enum ac_float_mode float_mode =
options->unsafe_math ? AC_FLOAT_MODE_UNSAFE_FP_MATH :
@@ -3297,7 +3296,7 @@
if (options->dump_preoptir)
ac_dump_module(ctx.ac.module);
- ac_llvm_finalize_module(&ctx, passmgr, options);
+ ac_llvm_finalize_module(&ctx, ac_llvm->passmgr, options);
if (shader_count == 1)
ac_nir_eliminate_const_vs_outputs(&ctx);
@@ -3327,7 +3326,7 @@
static unsigned ac_llvm_compile(LLVMModuleRef M,
struct ac_shader_binary *binary,
- LLVMTargetMachineRef tm)
+ struct ac_llvm_compiler *ac_llvm)
{
unsigned retval = 0;
char *err;
@@ -3344,7 +3343,7 @@
&retval);
/* Compile IR*/
- mem_err = LLVMTargetMachineEmitToMemoryBuffer(tm, M, LLVMObjectFile,
+ mem_err = LLVMTargetMachineEmitToMemoryBuffer(ac_llvm->tm, M, LLVMObjectFile,
&err, &out_buffer);
/* Process Errors/Warnings */
@@ -3368,7 +3367,7 @@
return retval;
}
-static void ac_compile_llvm_module(LLVMTargetMachineRef tm,
+static void ac_compile_llvm_module(struct ac_llvm_compiler *ac_llvm,
LLVMModuleRef llvm_module,
struct ac_shader_binary *binary,
struct ac_shader_config *config,
@@ -3387,7 +3386,7 @@
LLVMDisposeMessage(llvm_ir);
}
- int v = ac_llvm_compile(llvm_module, binary, tm);
+ int v = ac_llvm_compile(llvm_module, binary, ac_llvm);
if (v) {
fprintf(stderr, "compile failed\n");
}
@@ -3497,8 +3496,7 @@
}
void
-radv_compile_nir_shader(LLVMTargetMachineRef tm,
- LLVMPassManagerRef passmgr,
+radv_compile_nir_shader(struct ac_llvm_compiler *ac_llvm,
struct ac_shader_binary *binary,
struct ac_shader_config *config,
struct radv_shader_variant_info *shader_info,
@@ -3509,10 +3507,10 @@
LLVMModuleRef llvm_module;
- llvm_module = ac_translate_nir_to_llvm(tm, passmgr, nir, nir_count, shader_info,
+ llvm_module = ac_translate_nir_to_llvm(ac_llvm, nir, nir_count, shader_info,
options);
- ac_compile_llvm_module(tm, llvm_module, binary, config, shader_info,
+ ac_compile_llvm_module(ac_llvm, llvm_module, binary, config, shader_info,
nir[0]->info.stage, options);
for (int i = 0; i < nir_count; ++i)
@@ -3570,8 +3568,7 @@
}
void
-radv_compile_gs_copy_shader(LLVMTargetMachineRef tm,
- LLVMPassManagerRef passmgr,
+radv_compile_gs_copy_shader(struct ac_llvm_compiler *ac_llvm,
struct nir_shader *geom_shader,
struct ac_shader_binary *binary,
struct ac_shader_config *config,
@@ -3585,7 +3582,7 @@
ac_llvm_context_init(&ctx.ac, ctx.context, options->chip_class,
options->family);
- ctx.ac.module = ac_create_module(tm, ctx.context);
+ ctx.ac.module = ac_create_module(ac_llvm->tm, ctx.context);
ctx.is_gs_copy_shader = true;
@@ -3616,8 +3613,8 @@
LLVMBuildRetVoid(ctx.ac.builder);
- ac_llvm_finalize_module(&ctx, passmgr, options);
+ ac_llvm_finalize_module(&ctx, ac_llvm->passmgr, options);
- ac_compile_llvm_module(tm, ctx.ac.module, binary, config, shader_info,
+ ac_compile_llvm_module(ac_llvm, 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 cf416fb..0a34d79 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"
@@ -1795,16 +1796,14 @@
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 *ac_llvm,
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 *ac_llvm,
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 d115f21..5cca761 100644
--- a/src/amd/vulkan/radv_shader.c
+++ b/src/amd/vulkan/radv_shader.c
@@ -541,8 +541,7 @@
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 ac_llvm;
variant = calloc(1, sizeof(struct radv_shader_variant));
if (!variant)
@@ -566,21 +565,19 @@
tm_options |= AC_TM_CHECK_IR;
radv_init_llvm_once();
- tm = ac_create_target_machine(chip_family, tm_options, NULL);
- passmgr = ac_create_passmgr(NULL, tm_options & AC_TM_CHECK_IR);
+ ac_init_llvm_compiler(&ac_llvm, 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(&ac_llvm, *shaders, &binary,
&variant->config, &variant->info,
options);
} else {
- radv_compile_nir_shader(tm, passmgr, &binary, &variant->config,
+ radv_compile_nir_shader(&ac_llvm, &binary, &variant->config,
&variant->info, shaders, shader_count,
options);
}
- LLVMDisposePassManager(passmgr);
- LLVMDisposeTargetMachine(tm);
+ ac_destroy_llvm_compiler(&ac_llvm);
radv_fill_shader_variant(device, variant, &binary, stage);
diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c
index ad0ca7c..d047807 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.c
+++ b/src/gallium/drivers/radeonsi/si_pipe.c
@@ -114,7 +114,7 @@
(!sscreen->llvm_has_working_vgpr_indexing ? AC_TM_PROMOTE_ALLOCA_TO_SCRATCH : 0) |
(sscreen->debug_flags & DBG(CHECK_IR) ? AC_TM_CHECK_IR : 0);
- ac_init_llvm_compiler(compiler, sscreen->info.family, tm_options);
+ ac_init_llvm_compiler(compiler, true, sscreen->info.family, tm_options);
}
static void si_destroy_compiler(struct ac_llvm_compiler *compiler)