From 402ab50bedf9fba7654e63a6f2e808714714284d Mon Sep 17 00:00:00 2001 From: =?utf8?q?Michel=20D=C3=A4nzer?= Date: Tue, 28 Oct 2014 11:28:29 +0900 Subject: [PATCH] radeon/llvm: Dynamically allocate branch/loop stack arrays MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This prevents us from silently overflowing the stack arrays, and allows arbitrary stack depths. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=85454 Cc: mesa-stable@lists.freedesktop.org Reported-and-Tested-by: Nick Sarnie Reviewed-by: Marek Olšák --- src/gallium/drivers/radeon/radeon_llvm.h | 10 +++--- .../drivers/radeon/radeon_setup_tgsi_llvm.c | 33 +++++++++++++++++-- 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/src/gallium/drivers/radeon/radeon_llvm.h b/src/gallium/drivers/radeon/radeon_llvm.h index 00714fb6bca..8612ef8daf7 100644 --- a/src/gallium/drivers/radeon/radeon_llvm.h +++ b/src/gallium/drivers/radeon/radeon_llvm.h @@ -33,10 +33,10 @@ #define RADEON_LLVM_MAX_INPUTS 32 * 4 #define RADEON_LLVM_MAX_OUTPUTS 32 * 4 -#define RADEON_LLVM_MAX_BRANCH_DEPTH 16 -#define RADEON_LLVM_MAX_LOOP_DEPTH 16 #define RADEON_LLVM_MAX_ARRAYS 16 +#define RADEON_LLVM_INITIAL_CF_DEPTH 4 + #define RADEON_LLVM_MAX_SYSTEM_VALUES 4 struct radeon_llvm_branch { @@ -122,11 +122,13 @@ struct radeon_llvm_context { /*=== Private Members ===*/ - struct radeon_llvm_branch branch[RADEON_LLVM_MAX_BRANCH_DEPTH]; - struct radeon_llvm_loop loop[RADEON_LLVM_MAX_LOOP_DEPTH]; + struct radeon_llvm_branch *branch; + struct radeon_llvm_loop *loop; unsigned branch_depth; + unsigned branch_depth_max; unsigned loop_depth; + unsigned loop_depth_max; struct tgsi_declaration_range arrays[RADEON_LLVM_MAX_ARRAYS]; unsigned num_arrays; diff --git a/src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c b/src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c index 2fa23ed087c..c30a9d05e3a 100644 --- a/src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c +++ b/src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c @@ -446,7 +446,19 @@ static void bgnloop_emit( endloop_block, "LOOP"); LLVMBuildBr(gallivm->builder, loop_block); LLVMPositionBuilderAtEnd(gallivm->builder, loop_block); - ctx->loop_depth++; + + if (++ctx->loop_depth > ctx->loop_depth_max) { + unsigned new_max = ctx->loop_depth_max << 1; + + if (!new_max) + new_max = RADEON_LLVM_INITIAL_CF_DEPTH; + + ctx->loop = REALLOC(ctx->loop, ctx->loop_depth_max * + sizeof(ctx->loop[0]), + new_max * sizeof(ctx->loop[0])); + ctx->loop_depth_max = new_max; + } + ctx->loop[ctx->loop_depth - 1].loop_block = loop_block; ctx->loop[ctx->loop_depth - 1].endloop_block = endloop_block; } @@ -577,7 +589,18 @@ static void if_cond_emit( LLVMBuildCondBr(gallivm->builder, cond, if_block, else_block); LLVMPositionBuilderAtEnd(gallivm->builder, if_block); - ctx->branch_depth++; + if (++ctx->branch_depth > ctx->branch_depth_max) { + unsigned new_max = ctx->branch_depth_max << 1; + + if (!new_max) + new_max = RADEON_LLVM_INITIAL_CF_DEPTH; + + ctx->branch = REALLOC(ctx->branch, ctx->branch_depth_max * + sizeof(ctx->branch[0]), + new_max * sizeof(ctx->branch[0])); + ctx->branch_depth_max = new_max; + } + ctx->branch[ctx->branch_depth - 1].endif_block = endif_block; ctx->branch[ctx->branch_depth - 1].if_block = if_block; ctx->branch[ctx->branch_depth - 1].else_block = else_block; @@ -1440,4 +1463,10 @@ void radeon_llvm_dispose(struct radeon_llvm_context * ctx) LLVMContextDispose(ctx->soa.bld_base.base.gallivm->context); FREE(ctx->temps); ctx->temps = NULL; + FREE(ctx->loop); + ctx->loop = NULL; + ctx->loop_depth_max = 0; + FREE(ctx->branch); + ctx->branch = NULL; + ctx->branch_depth_max = 0; } -- 2.30.2