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 <thomas.stellard@amd.com> CC: "10.0" <mesa-stable@lists.freedesktop.org>
This commit is contained in:
parent
a7653c19a3
commit
8c9a9205d9
|
@ -204,6 +204,8 @@ void *evergreen_create_compute_state(
|
||||||
const unsigned char * code;
|
const unsigned char * code;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
|
shader->llvm_ctx = LLVMContextCreate();
|
||||||
|
|
||||||
COMPUTE_DBG(ctx->screen, "*** evergreen_create_compute_state\n");
|
COMPUTE_DBG(ctx->screen, "*** evergreen_create_compute_state\n");
|
||||||
|
|
||||||
header = cso->prog;
|
header = cso->prog;
|
||||||
|
@ -216,13 +218,14 @@ void *evergreen_create_compute_state(
|
||||||
shader->input_size = cso->req_input_mem;
|
shader->input_size = cso->req_input_mem;
|
||||||
|
|
||||||
#ifdef HAVE_OPENCL
|
#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);
|
shader->kernels = CALLOC(sizeof(struct r600_kernel), shader->num_kernels);
|
||||||
|
|
||||||
for (i = 0; i < shader->num_kernels; i++) {
|
for (i = 0; i < shader->num_kernels; i++) {
|
||||||
struct r600_kernel *kernel = &shader->kernels[i];
|
struct r600_kernel *kernel = &shader->kernels[i];
|
||||||
kernel->llvm_module = radeon_llvm_get_kernel_module(i, code,
|
kernel->llvm_module = radeon_llvm_get_kernel_module(shader->llvm_ctx, i,
|
||||||
header->num_bytes);
|
code, header->num_bytes);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return shader;
|
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;
|
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);
|
free(shader);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,10 @@ struct r600_pipe_compute {
|
||||||
unsigned private_size;
|
unsigned private_size;
|
||||||
unsigned input_size;
|
unsigned input_size;
|
||||||
struct r600_resource *kernel_param;
|
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);
|
struct r600_resource* r600_compute_buffer_alloc_vram(struct r600_screen *screen, unsigned size);
|
||||||
|
|
|
@ -33,11 +33,10 @@
|
||||||
#include <llvm-c/Transforms/IPO.h>
|
#include <llvm-c/Transforms/IPO.h>
|
||||||
#include <llvm-c/Transforms/PassManagerBuilder.h>
|
#include <llvm-c/Transforms/PassManagerBuilder.h>
|
||||||
|
|
||||||
LLVMModuleRef radeon_llvm_parse_bitcode(const unsigned char * bitcode,
|
LLVMModuleRef radeon_llvm_parse_bitcode(LLVMContextRef ctx,
|
||||||
unsigned bitcode_len)
|
const unsigned char * bitcode, unsigned bitcode_len)
|
||||||
{
|
{
|
||||||
LLVMMemoryBufferRef buf;
|
LLVMMemoryBufferRef buf;
|
||||||
LLVMContextRef ctx = LLVMContextCreate();
|
|
||||||
LLVMModuleRef module;
|
LLVMModuleRef module;
|
||||||
|
|
||||||
buf = LLVMCreateMemoryBufferWithMemoryRangeCopy((const char*)bitcode,
|
buf = LLVMCreateMemoryBufferWithMemoryRangeCopy((const char*)bitcode,
|
||||||
|
@ -47,10 +46,10 @@ LLVMModuleRef radeon_llvm_parse_bitcode(const unsigned char * bitcode,
|
||||||
return module;
|
return module;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned radeon_llvm_get_num_kernels(const unsigned char *bitcode,
|
unsigned radeon_llvm_get_num_kernels(LLVMContextRef ctx,
|
||||||
unsigned bitcode_len)
|
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");
|
return LLVMGetNamedMetadataNumOperands(mod, "opencl.kernels");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,7 +86,7 @@ static void radeon_llvm_optimize(LLVMModuleRef mod)
|
||||||
LLVMDisposePassManager(pass_manager);
|
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)
|
const unsigned char *bitcode, unsigned bitcode_len)
|
||||||
{
|
{
|
||||||
LLVMModuleRef mod;
|
LLVMModuleRef mod;
|
||||||
|
@ -95,7 +94,7 @@ LLVMModuleRef radeon_llvm_get_kernel_module(unsigned index,
|
||||||
LLVMValueRef *kernel_metadata;
|
LLVMValueRef *kernel_metadata;
|
||||||
unsigned i;
|
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");
|
num_kernels = LLVMGetNamedMetadataNumOperands(mod, "opencl.kernels");
|
||||||
kernel_metadata = MALLOC(num_kernels * sizeof(LLVMValueRef));
|
kernel_metadata = MALLOC(num_kernels * sizeof(LLVMValueRef));
|
||||||
LLVMGetNamedMetadataOperands(mod, "opencl.kernels", kernel_metadata);
|
LLVMGetNamedMetadataOperands(mod, "opencl.kernels", kernel_metadata);
|
||||||
|
|
|
@ -29,10 +29,11 @@
|
||||||
|
|
||||||
#include <llvm-c/Core.h>
|
#include <llvm-c/Core.h>
|
||||||
|
|
||||||
LLVMModuleRef radeon_llvm_parse_bitcode(const unsigned char * bitcode,
|
LLVMModuleRef radeon_llvm_parse_bitcode(LLVMContextRef ctx,
|
||||||
unsigned bitcode_len);
|
const unsigned char * bitcode, unsigned bitcode_len);
|
||||||
unsigned radeon_llvm_get_num_kernels(const unsigned char *bitcode, unsigned bitcode_len);
|
unsigned radeon_llvm_get_num_kernels(LLVMContextRef ctx,
|
||||||
LLVMModuleRef radeon_llvm_get_kernel_module(unsigned index,
|
const unsigned char *bitcode, unsigned bitcode_len);
|
||||||
|
LLVMModuleRef radeon_llvm_get_kernel_module(LLVMContextRef ctx, unsigned index,
|
||||||
const unsigned char *bitcode, unsigned bitcode_len);
|
const unsigned char *bitcode, unsigned bitcode_len);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -20,6 +20,7 @@ struct si_pipe_compute {
|
||||||
|
|
||||||
struct pipe_resource *global_buffers[MAX_GLOBAL_BUFFERS];
|
struct pipe_resource *global_buffers[MAX_GLOBAL_BUFFERS];
|
||||||
|
|
||||||
|
LLVMContextRef llvm_ctx;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void *radeonsi_create_compute_state(
|
static void *radeonsi_create_compute_state(
|
||||||
|
@ -33,6 +34,8 @@ static void *radeonsi_create_compute_state(
|
||||||
const unsigned char *code;
|
const unsigned char *code;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
|
program->llvm_ctx = LLVMContextCreate();
|
||||||
|
|
||||||
header = cso->prog;
|
header = cso->prog;
|
||||||
code = cso->prog + sizeof(struct pipe_llvm_program_header);
|
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->private_size = cso->req_private_mem;
|
||||||
program->input_size = cso->req_input_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);
|
header->num_bytes);
|
||||||
program->kernels = CALLOC(sizeof(struct si_pipe_shader),
|
program->kernels = CALLOC(sizeof(struct si_pipe_shader),
|
||||||
program->num_kernels);
|
program->num_kernels);
|
||||||
for (i = 0; i < program->num_kernels; i++) {
|
for (i = 0; i < program->num_kernels; i++) {
|
||||||
LLVMModuleRef mod = radeon_llvm_get_kernel_module(i, code,
|
LLVMModuleRef mod = radeon_llvm_get_kernel_module(program->llvm_ctx, i,
|
||||||
header->num_bytes);
|
code, header->num_bytes);
|
||||||
si_compile_llvm(rctx, &program->kernels[i], mod);
|
si_compile_llvm(rctx, &program->kernels[i], mod);
|
||||||
LLVMDisposeModule(mod);
|
LLVMDisposeModule(mod);
|
||||||
}
|
}
|
||||||
|
@ -272,6 +275,10 @@ static void si_delete_compute_state(struct pipe_context *ctx, void* state){
|
||||||
FREE(program->kernels);
|
FREE(program->kernels);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (program->llvm_ctx){
|
||||||
|
LLVMContextDispose(program->llvm_ctx);
|
||||||
|
}
|
||||||
|
|
||||||
//And then free the program itself.
|
//And then free the program itself.
|
||||||
FREE(program);
|
FREE(program);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue