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.stell...@amd.com>

CC: "10.0" <mesa-sta...@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

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to