Mesa (master): freedreno/a3xx/compiler: make IR heap dyanmic

Rob Clark robclark at kemper.freedesktop.org
Fri Jul 25 17:31:26 UTC 2014


Module: Mesa
Branch: master
Commit: 9613ca569f553666b7397c10321f43bdbb843a13
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=9613ca569f553666b7397c10321f43bdbb843a13

Author: Rob Clark <robclark at freedesktop.org>
Date:   Wed Jul 23 17:21:29 2014 -0400

freedreno/a3xx/compiler: make IR heap dyanmic

The fixed size heap is a remnant of the fdre-a3xx assembler.  Yet it is
convenient for being able to free the entire data structure in one shot
without worrying about leaking nodes.

Change it to dynamically grow the heap size (adding chunks) as needed so
we don't have an artificial upper limit on shader size (other than hw
limits) and don't always have to allocate worst-case size.

Signed-off-by: Rob Clark <robclark at freedesktop.org>

---

 src/gallium/drivers/freedreno/a3xx/ir3.c |   43 +++++++++++++++++++++++++++---
 src/gallium/drivers/freedreno/a3xx/ir3.h |    8 +++---
 2 files changed, 43 insertions(+), 8 deletions(-)

diff --git a/src/gallium/drivers/freedreno/a3xx/ir3.c b/src/gallium/drivers/freedreno/a3xx/ir3.c
index 2a68a8e..5768718 100644
--- a/src/gallium/drivers/freedreno/a3xx/ir3.c
+++ b/src/gallium/drivers/freedreno/a3xx/ir3.c
@@ -33,23 +33,54 @@
 #include "freedreno_util.h"
 #include "instr-a3xx.h"
 
+#define CHUNK_SZ 1020
+
+struct ir3_heap_chunk {
+	struct ir3_heap_chunk *next;
+	uint32_t heap[CHUNK_SZ];
+};
+
+static void grow_heap(struct ir3_shader *shader)
+{
+	struct ir3_heap_chunk *chunk = calloc(1, sizeof(*chunk));
+	chunk->next = shader->chunk;
+	shader->chunk = chunk;
+	shader->heap_idx = 0;
+}
+
 /* simple allocator to carve allocations out of an up-front allocated heap,
  * so that we can free everything easily in one shot.
  */
 void * ir3_alloc(struct ir3_shader *shader, int sz)
 {
-	void *ptr = &shader->heap[shader->heap_idx];
-	shader->heap_idx += align(sz, 4);
+	void *ptr;
+
+	sz = align(sz, 4) / 4;
+
+	if ((shader->heap_idx + sz) > CHUNK_SZ)
+		grow_heap(shader);
+
+	ptr = &shader->chunk->heap[shader->heap_idx];
+	shader->heap_idx += sz;
+
 	return ptr;
 }
 
 struct ir3_shader * ir3_shader_create(void)
 {
-	return calloc(1, sizeof(struct ir3_shader));
+	struct ir3_shader *shader =
+			calloc(1, sizeof(struct ir3_shader));
+	grow_heap(shader);
+	return shader;
 }
 
 void ir3_shader_destroy(struct ir3_shader *shader)
 {
+	while (shader->chunk) {
+		struct ir3_heap_chunk *chunk = shader->chunk;
+		shader->chunk = chunk->next;
+		free(chunk);
+	}
 	free(shader);
 }
 
@@ -559,7 +590,11 @@ static void insert_instr(struct ir3_shader *shader,
 	static uint32_t serialno = 0;
 	instr->serialno = ++serialno;
 #endif
-	assert(shader->instrs_count < ARRAY_SIZE(shader->instrs));
+	if (shader->instrs_count == shader->instrs_sz) {
+		shader->instrs_sz = MAX2(2 * shader->instrs_sz, 16);
+		shader->instrs = realloc(shader->instrs,
+				shader->instrs_sz * sizeof(shader->instrs[0]));
+	}
 	shader->instrs[shader->instrs_count++] = instr;
 }
 
diff --git a/src/gallium/drivers/freedreno/a3xx/ir3.h b/src/gallium/drivers/freedreno/a3xx/ir3.h
index 9ec05da..e6f9a40 100644
--- a/src/gallium/drivers/freedreno/a3xx/ir3.h
+++ b/src/gallium/drivers/freedreno/a3xx/ir3.h
@@ -217,13 +217,13 @@ struct ir3_instruction {
 #endif
 };
 
-#define MAX_INSTRS 1024
+struct ir3_heap_chunk;
 
 struct ir3_shader {
-	unsigned instrs_count;
-	struct ir3_instruction *instrs[MAX_INSTRS];
-	uint32_t heap[128 * MAX_INSTRS];
+	unsigned instrs_count, instrs_sz;
+	struct ir3_instruction **instrs;
 	unsigned heap_idx;
+	struct ir3_heap_chunk *chunk;
 };
 
 struct ir3_block {




More information about the mesa-commit mailing list