summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichel Dänzer <michel.daenzer@amd.com>2014-10-28 11:28:29 +0900
committerEmil Velikov <emil.l.velikov@gmail.com>2014-10-29 18:18:54 +0000
commit894ac63c34413d1ee0c7269c58a9d10451a28646 (patch)
treea6eb3c5fae85f1d2aefdd5a9fdbfc7f9fd3830f5
parentd26258166ca056da62536bebdf107e21d9ce92fb (diff)
radeon/llvm: Dynamically allocate branch/loop stack arrays
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 <commendsarnex@gmail.com> Reviewed-by: Marek Olšák <marek.olsak@amd.com> (cherry picked from commit 402ab50bedf9fba7654e63a6f2e808714714284d)
-rw-r--r--src/gallium/drivers/radeon/radeon_llvm.h10
-rw-r--r--src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c33
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 119e613c5e5..be679a1727a 100644
--- a/src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c
+++ b/src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c
@@ -445,7 +445,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;
}
@@ -576,7 +588,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;
@@ -1439,4 +1462,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;
}