summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian <brian@yutani.localnet.net>2007-01-17 09:54:31 -0700
committerBrian <brian@yutani.localnet.net>2007-01-17 09:54:31 -0700
commit811f54fa75a557380b34ac97929eaa0190d2d5aa (patch)
tree6241ff5addff4e0d5e92a9808c232ffa7f4ec9fa
parent552a65e4546bd543d60ffe87dc298a41d8a318be (diff)
Fix/clean-up a number of things related to variable/temporary allocation.
-rw-r--r--src/mesa/shader/slang/slang_codegen.c52
-rw-r--r--src/mesa/shader/slang/slang_emit.c9
-rw-r--r--src/mesa/shader/slang/slang_vartable.c22
3 files changed, 54 insertions, 29 deletions
diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c
index 0189b75134..31f2576cb5 100644
--- a/src/mesa/shader/slang/slang_codegen.c
+++ b/src/mesa/shader/slang/slang_codegen.c
@@ -266,6 +266,7 @@ slang_allocate_storage(slang_assemble_ctx *A, slang_ir_node *n)
n->Store = _slang_new_ir_storage(PROGRAM_UNDEFINED, -1, -5);
if (n->Var)
n->Var->aux = n->Store;
+ assert(n->Var->aux);
}
}
@@ -281,7 +282,6 @@ slang_allocate_storage(slang_assemble_ctx *A, slang_ir_node *n)
else {
assert(n->Opcode == IR_VAR);
assert(n->Var);
- assert(n->Store->Size > 0);
if (n->Store->Index < 0) {
const char *varName = (char *) n->Var->a_name;
@@ -1501,6 +1501,29 @@ _slang_gen_temporary(GLint size)
/**
+ * Generate IR node for allocating/declaring a variable.
+ */
+static slang_ir_node *
+_slang_gen_var_decl(slang_assemble_ctx *A, slang_variable *var)
+{
+ slang_ir_node *n;
+ n = new_node(IR_VAR_DECL, NULL, NULL);
+ if (n) {
+ n->Var = var;
+ slang_allocate_storage(A, n);
+ assert(n->Store);
+ assert(n->Store->Index < 0);
+ assert(n->Store->Size > 0);
+ assert(var->aux);
+ assert(n->Store == var->aux);
+ }
+ return n;
+}
+
+
+
+
+/**
* Generate code for a selection expression: b ? x : y
*/
static slang_ir_node *
@@ -1670,13 +1693,7 @@ _slang_gen_declaration(slang_assemble_ctx *A, slang_operation *oper)
v = _slang_locate_variable(oper->locals, oper->a_id, GL_TRUE);
assert(v);
- varDecl = new_node(IR_VAR_DECL, NULL, NULL);
- if (!varDecl)
- return NULL;
-
- varDecl->Var = v;
-
- slang_allocate_storage(A, varDecl);
+ varDecl = _slang_gen_var_decl(A, v);
if (oper->num_children > 0) {
/* child is initializer */
@@ -2314,21 +2331,10 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var,
}
else {
/* ordinary variable (may be const) */
- const GLint size = _slang_sizeof_type_specifier(&var->type.specifier);
- const GLint index = -1;
slang_ir_node *n;
/* IR node to declare the variable */
- n = new_node(IR_VAR_DECL, NULL, NULL);
- if (!n)
- return GL_FALSE;
- n->Var = var;
- store = _slang_new_ir_storage(PROGRAM_TEMPORARY, index, size);
- var->aux = store; /* save var's storage info */
-
- slang_allocate_storage(A, n);
-
- _slang_add_variable(A->vartable, var);
+ n = _slang_gen_var_decl(A, var);
/* IR code for the var's initializer, if present */
if (var->initializer) {
@@ -2338,7 +2344,7 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var,
lhs = new_node(IR_VAR, NULL, NULL);
lhs->Var = var;
lhs->Swizzle = SWIZZLE_NOOP;
- lhs->Store = store;
+ lhs->Store = n->Store;
/* constant folding, etc */
slang_simplify(var->initializer, &A->space, A->atoms);
@@ -2357,8 +2363,8 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var,
if (dbg) printf("GLOBAL VAR %s idx %d\n", (char*) var->a_name,
store ? store->Index : -2);
-
- var->aux = store; /* save var's storage info */
+ if (store)
+ var->aux = store; /* save var's storage info */
return success;
}
diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c
index 1142bc6416..52627486bd 100644
--- a/src/mesa/shader/slang/slang_emit.c
+++ b/src/mesa/shader/slang/slang_emit.c
@@ -618,10 +618,15 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog)
assert(n->Store->File != PROGRAM_UNDEFINED);
assert(n->Store->Size > 0);
assert(n->Store->Index < 0);
- if (!n->Var || n->Var->isTemp)
+ if (!n->Var || n->Var->isTemp) {
+ /* a nameless/temporary variable, will be freed after first use */
n->Store->Index = _slang_alloc_temp(vt, n->Store->Size);
- else
+ }
+ else {
+ /* a regular variable */
+ _slang_add_variable(vt, n->Var);
n->Store->Index = _slang_alloc_var(vt, n->Store->Size);
+ }
assert(n->Store->Index >= 0);
break;
diff --git a/src/mesa/shader/slang/slang_vartable.c b/src/mesa/shader/slang/slang_vartable.c
index cd6a081e04..d4ec848a0a 100644
--- a/src/mesa/shader/slang/slang_vartable.c
+++ b/src/mesa/shader/slang/slang_vartable.c
@@ -3,6 +3,7 @@
#include "slang_compile.h"
#include "slang_compile_variable.h"
#include "slang_vartable.h"
+#include "slang_ir.h"
static int dbg = 0;
@@ -58,16 +59,28 @@ _slang_pop_var_table(slang_var_table *t)
{
slang_var_table *parent = t->parent;
int i;
+
if (dbg) printf("Popping level %d\n", t->level);
+
+ /* free the storage allocated for each variable */
+ for (i = 0; i < t->num_entries; i++) {
+ slang_ir_storage *store = (slang_ir_storage *) t->vars[i]->aux;
+ if (dbg) printf(" Free var %s\n", (char*) t->vars[i]->a_name);
+ assert(t->temps[store->Index] == VAR);
+ t->temps[store->Index] = FREE;
+ store->Index = -1;
+ }
if (t->parent) {
+ /* just verify that any remaining allocations in this scope
+ * were for temps
+ */
for (i = 0; i < MAX_PROGRAM_TEMPS; i++) {
- if (t->temps[i] && !t->parent->temps[i])
+ if (t->temps[i] && !t->parent->temps[i]) {
if (dbg) printf(" Free reg %d\n", i);
+ assert(t->temps[i] == TEMP);
+ }
}
}
- for (i = 0; i < t->num_entries; i++) {
- if (dbg) printf(" Free var %s\n", (char*) t->vars[i]->a_name);
- }
if (t->vars)
free(t->vars);
@@ -84,6 +97,7 @@ void
_slang_add_variable(slang_var_table *t, slang_variable *v)
{
assert(t);
+ if (dbg) printf("Adding var %s\n", (char *) v->a_name);
t->vars = realloc(t->vars, (t->num_entries + 1) * sizeof(slang_variable *));
t->vars[t->num_entries] = v;
t->num_entries++;