[Mesa-dev] [PATCH 3/8] radeon/compute: Stop leaking LLVMContexts in radeon_llvm_parse_bitcode
Aaron Watry
awatry at gmail.com
Tue Dec 17 14:34:36 PST 2013
Previously we were creating a new LLVMContext every time that we called
radeon_llvm_parse_bitcode, which caused us to leak the context every time
that we compiled a CL program.
Sadly, we can't dispose of the LLVMContext at the point that it was being
created because evergreen_launch_grid (and possibly the SI equivalent) was
assuming that the context used to compile the kernels was still available.
Now, we'll create a new LLVMContext when creating EG/SI compute state, store
it there, and pass it to all of the places that need it.
The LLVM Context gets destroyed when we delete the EG/SI compute state.
Reviewed-by: Tom Stellard <thomas.stellard at amd.com>
CC: "10.0" <mesa-stable at lists.freedesktop.org>
---
src/gallium/drivers/r600/evergreen_compute.c | 18 +++++++++++++++---
src/gallium/drivers/r600/evergreen_compute_internal.h | 4 ++++
src/gallium/drivers/radeon/radeon_llvm_util.c | 15 +++++++--------
src/gallium/drivers/radeon/radeon_llvm_util.h | 9 +++++----
src/gallium/drivers/radeonsi/radeonsi_compute.c | 13 ++++++++++---
5 files changed, 41 insertions(+), 18 deletions(-)
diff --git a/src/gallium/drivers/r600/evergreen_compute.c b/src/gallium/drivers/r600/evergreen_compute.c
index d668c8e..f0f537c 100644
--- a/src/gallium/drivers/r600/evergreen_compute.c
+++ b/src/gallium/drivers/r600/evergreen_compute.c
@@ -204,6 +204,8 @@ void *evergreen_create_compute_state(
const unsigned char * code;
unsigned i;
+ shader->llvm_ctx = LLVMContextCreate();
+
COMPUTE_DBG(ctx->screen, "*** evergreen_create_compute_state\n");
header = cso->prog;
@@ -216,13 +218,14 @@ void *evergreen_create_compute_state(
shader->input_size = cso->req_input_mem;
#ifdef HAVE_OPENCL
- shader->num_kernels = radeon_llvm_get_num_kernels(code, header->num_bytes);
+ shader->num_kernels = radeon_llvm_get_num_kernels(shader->llvm_ctx, code,
+ header->num_bytes);
shader->kernels = CALLOC(sizeof(struct r600_kernel), shader->num_kernels);
for (i = 0; i < shader->num_kernels; i++) {
struct r600_kernel *kernel = &shader->kernels[i];
- kernel->llvm_module = radeon_llvm_get_kernel_module(i, code,
- header->num_bytes);
+ kernel->llvm_module = radeon_llvm_get_kernel_module(shader->llvm_ctx, i,
+ code, header->num_bytes);
}
#endif
return shader;
@@ -232,6 +235,15 @@ void evergreen_delete_compute_state(struct pipe_context *ctx, void* state)
{
struct r600_pipe_compute *shader = (struct r600_pipe_compute *)state;
+ if (!shader)
+ return;
+
+#ifdef HAVE_OPENCL
+ if (shader->llvm_ctx){
+ LLVMContextDispose(shader->llvm_ctx);
+ }
+#endif
+
free(shader);
}
diff --git a/src/gallium/drivers/r600/evergreen_compute_internal.h b/src/gallium/drivers/r600/evergreen_compute_internal.h
index c524da2..0929d8d 100644
--- a/src/gallium/drivers/r600/evergreen_compute_internal.h
+++ b/src/gallium/drivers/r600/evergreen_compute_internal.h
@@ -47,6 +47,10 @@ struct r600_pipe_compute {
unsigned private_size;
unsigned input_size;
struct r600_resource *kernel_param;
+
+#ifdef HAVE_OPENCL
+ LLVMContextRef llvm_ctx;
+#endif
};
struct r600_resource* r600_compute_buffer_alloc_vram(struct r600_screen *screen, unsigned size);
diff --git a/src/gallium/drivers/radeon/radeon_llvm_util.c b/src/gallium/drivers/radeon/radeon_llvm_util.c
index 3ba0acc..cf6d21e 100644
--- a/src/gallium/drivers/radeon/radeon_llvm_util.c
+++ b/src/gallium/drivers/radeon/radeon_llvm_util.c
@@ -33,11 +33,10 @@
#include <llvm-c/Transforms/IPO.h>
#include <llvm-c/Transforms/PassManagerBuilder.h>
-LLVMModuleRef radeon_llvm_parse_bitcode(const unsigned char * bitcode,
- unsigned bitcode_len)
+LLVMModuleRef radeon_llvm_parse_bitcode(LLVMContextRef ctx,
+ const unsigned char * bitcode, unsigned bitcode_len)
{
LLVMMemoryBufferRef buf;
- LLVMContextRef ctx = LLVMContextCreate();
LLVMModuleRef module;
buf = LLVMCreateMemoryBufferWithMemoryRangeCopy((const char*)bitcode,
@@ -47,10 +46,10 @@ LLVMModuleRef radeon_llvm_parse_bitcode(const unsigned char * bitcode,
return module;
}
-unsigned radeon_llvm_get_num_kernels(const unsigned char *bitcode,
- unsigned bitcode_len)
+unsigned radeon_llvm_get_num_kernels(LLVMContextRef ctx,
+ const unsigned char *bitcode, unsigned bitcode_len)
{
- LLVMModuleRef mod = radeon_llvm_parse_bitcode(bitcode, bitcode_len);
+ LLVMModuleRef mod = radeon_llvm_parse_bitcode(ctx, bitcode, bitcode_len);
return LLVMGetNamedMetadataNumOperands(mod, "opencl.kernels");
}
@@ -87,7 +86,7 @@ static void radeon_llvm_optimize(LLVMModuleRef mod)
LLVMDisposePassManager(pass_manager);
}
-LLVMModuleRef radeon_llvm_get_kernel_module(unsigned index,
+LLVMModuleRef radeon_llvm_get_kernel_module(LLVMContextRef ctx, unsigned index,
const unsigned char *bitcode, unsigned bitcode_len)
{
LLVMModuleRef mod;
@@ -95,7 +94,7 @@ LLVMModuleRef radeon_llvm_get_kernel_module(unsigned index,
LLVMValueRef *kernel_metadata;
unsigned i;
- mod = radeon_llvm_parse_bitcode(bitcode, bitcode_len);
+ mod = radeon_llvm_parse_bitcode(ctx, bitcode, bitcode_len);
num_kernels = LLVMGetNamedMetadataNumOperands(mod, "opencl.kernels");
kernel_metadata = MALLOC(num_kernels * sizeof(LLVMValueRef));
LLVMGetNamedMetadataOperands(mod, "opencl.kernels", kernel_metadata);
diff --git a/src/gallium/drivers/radeon/radeon_llvm_util.h b/src/gallium/drivers/radeon/radeon_llvm_util.h
index b851648..733c329 100644
--- a/src/gallium/drivers/radeon/radeon_llvm_util.h
+++ b/src/gallium/drivers/radeon/radeon_llvm_util.h
@@ -29,10 +29,11 @@
#include <llvm-c/Core.h>
-LLVMModuleRef radeon_llvm_parse_bitcode(const unsigned char * bitcode,
- unsigned bitcode_len);
-unsigned radeon_llvm_get_num_kernels(const unsigned char *bitcode, unsigned bitcode_len);
-LLVMModuleRef radeon_llvm_get_kernel_module(unsigned index,
+LLVMModuleRef radeon_llvm_parse_bitcode(LLVMContextRef ctx,
+ const unsigned char * bitcode, unsigned bitcode_len);
+unsigned radeon_llvm_get_num_kernels(LLVMContextRef ctx,
+ const unsigned char *bitcode, unsigned bitcode_len);
+LLVMModuleRef radeon_llvm_get_kernel_module(LLVMContextRef ctx, unsigned index,
const unsigned char *bitcode, unsigned bitcode_len);
#endif
diff --git a/src/gallium/drivers/radeonsi/radeonsi_compute.c b/src/gallium/drivers/radeonsi/radeonsi_compute.c
index 2d53f2d..214ea3c 100644
--- a/src/gallium/drivers/radeonsi/radeonsi_compute.c
+++ b/src/gallium/drivers/radeonsi/radeonsi_compute.c
@@ -20,6 +20,7 @@ struct si_pipe_compute {
struct pipe_resource *global_buffers[MAX_GLOBAL_BUFFERS];
+ LLVMContextRef llvm_ctx;
};
static void *radeonsi_create_compute_state(
@@ -33,6 +34,8 @@ static void *radeonsi_create_compute_state(
const unsigned char *code;
unsigned i;
+ program->llvm_ctx = LLVMContextCreate();
+
header = cso->prog;
code = cso->prog + sizeof(struct pipe_llvm_program_header);
@@ -41,13 +44,13 @@ static void *radeonsi_create_compute_state(
program->private_size = cso->req_private_mem;
program->input_size = cso->req_input_mem;
- program->num_kernels = radeon_llvm_get_num_kernels(code,
+ program->num_kernels = radeon_llvm_get_num_kernels(program->llvm_ctx, code,
header->num_bytes);
program->kernels = CALLOC(sizeof(struct si_pipe_shader),
program->num_kernels);
for (i = 0; i < program->num_kernels; i++) {
- LLVMModuleRef mod = radeon_llvm_get_kernel_module(i, code,
- header->num_bytes);
+ LLVMModuleRef mod = radeon_llvm_get_kernel_module(program->llvm_ctx, i,
+ code, header->num_bytes);
si_compile_llvm(rctx, &program->kernels[i], mod);
LLVMDisposeModule(mod);
}
@@ -272,6 +275,10 @@ static void si_delete_compute_state(struct pipe_context *ctx, void* state){
FREE(program->kernels);
}
+ if (program->llvm_ctx){
+ LLVMContextDispose(program->llvm_ctx);
+ }
+
//And then free the program itself.
FREE(program);
}
--
1.8.3.2
More information about the mesa-dev
mailing list