From 87cdd13324a070aa36424bead9dc2c053da9c301 Mon Sep 17 00:00:00 2001 From: Aaron Watry Date: Thu, 12 Dec 2013 16:34:09 -0600 Subject: radeon/compute: Stop leaking LLVMContexts in radeon_llvm_parse_bitcode 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 CC: "10.0" (cherry picked from commit 8c9a9205d96b5ac0718218bfa952a5b4b6ad939c) --- 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(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/r600/evergreen_compute.c b/src/gallium/drivers/r600/evergreen_compute.c index d668c8e2746..f0f537cd8e2 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 c524da2b84d..0929d8dcf27 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 3ba0acc55bc..cf6d21ed71f 100644 --- a/src/gallium/drivers/radeon/radeon_llvm_util.c +++ b/src/gallium/drivers/radeon/radeon_llvm_util.c @@ -33,11 +33,10 @@ #include #include -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 b85164885dd..733c329e99e 100644 --- a/src/gallium/drivers/radeon/radeon_llvm_util.h +++ b/src/gallium/drivers/radeon/radeon_llvm_util.h @@ -29,10 +29,11 @@ #include -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 2d53f2d9864..214ea3c2552 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); } -- cgit v1.2.3