Fix/clean-up a number of things related to variable/temporary allocation.
authorBrian <brian@yutani.localnet.net>
Wed, 17 Jan 2007 16:54:31 +0000 (09:54 -0700)
committerBrian <brian@yutani.localnet.net>
Wed, 17 Jan 2007 16:54:31 +0000 (09:54 -0700)
src/mesa/shader/slang/slang_codegen.c
src/mesa/shader/slang/slang_emit.c
src/mesa/shader/slang/slang_vartable.c

index 0189b751347e471192a2a8558bbf8f522e2377af..31f2576cb5d1b377a728d4f0dada14426a9b294f 100644 (file)
@@ -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;
@@ -1500,6 +1500,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
  */
@@ -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;
 }
index 1142bc6416b9975b57d217f261a9471844263bb4..52627486bd1744423481ab63122a7498775e3bbc 100644 (file)
@@ -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;
 
index cd6a081e04bfb1bff5a4ab0d5a1c0cfea5f856d2..d4ec848a0a1a8ab3d8dbefef0f519b33b127ecf9 100644 (file)
@@ -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++;