OSDN Git Service

Rework code related to temp register allocation, both for user variables
authorBrian <brian@yutani.localnet.net>
Sat, 13 Jan 2007 21:49:52 +0000 (14:49 -0700)
committerBrian <brian@yutani.localnet.net>
Sat, 13 Jan 2007 21:49:52 +0000 (14:49 -0700)
and expression temporarires.  Much better register utilization now.
Lots of other fixes.
The OpenGL GLSL "orange book" brick shader demo works now.

12 files changed:
src/mesa/shader/slang/slang_codegen.c
src/mesa/shader/slang/slang_compile.c
src/mesa/shader/slang/slang_emit.c
src/mesa/shader/slang/slang_emit.h
src/mesa/shader/slang/slang_ir.h
src/mesa/shader/slang/slang_link2.c
src/mesa/shader/slang/slang_print.c
src/mesa/shader/slang/slang_print.h
src/mesa/shader/slang/slang_storage.c
src/mesa/shader/slang/slang_vartable.c [new file with mode: 0644]
src/mesa/shader/slang/slang_vartable.h [new file with mode: 0644]
src/mesa/sources

index 46a5ecd..aff108d 100644 (file)
@@ -38,6 +38,7 @@
 #include "slang_error.h"
 #include "slang_simplify.h"
 #include "slang_emit.h"
+#include "slang_vartable.h"
 #include "slang_ir.h"
 #include "mtypes.h"
 #include "program.h"
@@ -259,10 +260,10 @@ _slang_sizeof_type_specifier(const slang_type_specifier *spec)
  *   4. other?
  */
 static void
-slang_allocate_storage(slang_gen_context *gc, slang_ir_node *n,
-                      struct gl_program *prog)
+slang_allocate_storage(slang_assemble_ctx *A, slang_ir_node *n)
 {
-   assert(gc);
+   struct gl_program *prog = A->program;
+   assert(A->vartable);
    assert(n);
    assert(n->Opcode == IR_VAR_DECL || n->Opcode == IR_VAR);
    assert(prog);
@@ -285,33 +286,22 @@ slang_allocate_storage(slang_gen_context *gc, slang_ir_node *n,
       /* variable declaration */
       assert(n->Var);
       assert(!is_sampler_type(&n->Var->type));
-      printf("Alloc storage for %p %s:\n", (void*) n->Var, (char*) n->Var->a_name);
-      /*
-      assert(n->Store->Index < 0);
-      */
       n->Store->File = PROGRAM_TEMPORARY;
       n->Store->Size = _slang_sizeof_type_specifier(&n->Var->type.specifier);
       assert(n->Store->Size > 0);
-      if (n->Store->Index < 0)
-      n->Store->Index = _slang_alloc_temporary(gc, n->Store->Size);
-      printf("  Location = %d\n", n->Store->Index);
-      /*
-      printf("alloc var %s storage at %d (size %d)\n",
-             (char *) n->Var->a_name,
-             n->Store->Index,
-             n->Store->Size);
-      */
-      assert(n->Store->Size > 0);
-      n->Var->declared = GL_TRUE;
       return;
    }
 
+#if 00
    if (n->Store->File == PROGRAM_UNDEFINED) {
       printf("*** Var %s  size %d\n", (char*) n->Var->a_name, n->Store->Size);
-
       assert(n->Store->File != PROGRAM_UNDEFINED);
    }
+#endif
 
+   /**
+    ** XXX this all has to be redone
+    **/
    if (n->Store->Index < 0) {
       /* determine storage location for this var */
 
@@ -342,7 +332,6 @@ slang_allocate_storage(slang_gen_context *gc, slang_ir_node *n,
       }
       else {
          /* what's this??? */
-         abort();
       }
    }
 }
@@ -533,54 +522,6 @@ static slang_asm_info AsmInfo[] = {
 };
 
 
-#if 000 /* prototype for future symbol table scheme */
-
-#define MAX_DEPTH 100
-static slang_variable_scope *Stack[MAX_DEPTH];
-static int CurDepth;
-
-static void
-_slang_push_scope(slang_variable_scope *scope)
-{
-   Stack[CurDepth++] = scope;
-   assert(CurDepth < MAX_DEPTH);
-}
-
-static void
-_slang_pop_scope(void)
-{
-   CurDepth--;
-   assert(CurDepth >= 0);
-}
-
-static slang_variable_scope *
-_slang_current_scope(void)
-{
-   if (CurDepth > 0)
-      return Stack[CurDepth - 1];
-   else
-      return NULL;
-}
-
-static slang_variable *
-_slang_find_variable(slang_atom name)
-{
-   int i;
-   for (i = CurDepth - 1; i >= 0; i--) {
-      int j;
-      for (j = 0; j < Stack[i]->num_variables; j++) {
-         if (Stack[i]->variables[j].a_name == name) {
-            return Stack[i]->variables + j;
-         }
-      }
-   }
-   return NULL;
-}
-
-#endif
-
-
-
 /**
  * Recursively free an IR tree.
  */
@@ -675,15 +616,14 @@ new_var(slang_assemble_ctx *A, slang_operation *oper,
       printf("VAR NOT FOUND %s\n", (char *) name);
       assert(v);
    }
-   /** 
-   assert(v->declared);
-   **/
    assert(!oper->var || oper->var == v);
    v->used = GL_TRUE;
-   oper->var = v;
+
    n->Swizzle = swizzle;
    n->Var = v;
-   slang_allocate_storage(A->codegen, n, A->program);
+
+   slang_allocate_storage(A, n);
+
    return n;
 }
 
@@ -725,7 +665,7 @@ slang_is_writemask(const char *field, GLuint *mask)
 
 
 /**
- * Check if the given function is really just a wrapper for an
+ * Check if the given function is really just a wrapper for a
  * basic assembly instruction.
  */
 static GLboolean
@@ -753,7 +693,7 @@ slang_inline_asm_function(slang_assemble_ctx *A,
    slang_operation *inlined = slang_operation_new(1);
 
    /*assert(oper->type == slang_oper_call);  or vec4_add, etc */
-
+   printf("Inline asm %s\n", (char*) fun->header.a_name);
    inlined->type = fun->body->children[0].type;
    inlined->a_id = fun->body->children[0].a_id;
    inlined->num_children = numArgs;
@@ -833,9 +773,7 @@ slang_substitute(slang_assemble_ctx *A, slang_operation *oper,
         for (i = 0; i < substCount; i++) {
            if (v == substOld[i]) {
                /* OK, replace this slang_oper_identifier with a new expr */
-              assert(substNew[i]->type == slang_oper_identifier ||
-                      substNew[i]->type == slang_oper_literal_float);
-#if 1 /* DEBUG only */
+#if 0 /* DEBUG only */
               if (substNew[i]->type == slang_oper_identifier) {
                   assert(substNew[i]->var);
                   assert(substNew[i]->var->a_name);
@@ -843,7 +781,7 @@ slang_substitute(slang_assemble_ctx *A, slang_operation *oper,
                         (char*)v->a_name, (char*) substNew[i]->var->a_name,
                         (void*) oper);
                }
-              else
+              else {
                  printf("Substitute %s with %f in id node %p\n",
                         (char*)v->a_name, substNew[i]->literal[0],
                         (void*) oper);
@@ -958,15 +896,15 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun,
    substNew = (slang_operation **)
       _mesa_calloc(totalArgs * sizeof(slang_operation *));
 
-   printf("\nInline call to %s  (total vars=%d  nparams=%d)\n",
+   printf("Inline call to %s  (total vars=%d  nparams=%d)\n",
          (char *) fun->header.a_name,
          fun->parameters->num_variables, numArgs);
 
-
    if (haveRetValue && !returnOper) {
-      /* Create comma sequence for inlined code, the left child will be the
-       * function body and the right child will be a variable (__retVal)
-       * that will get the return value.
+      /* Create 3-child comma sequence for inlined code:
+       * child[0]:  declare __resultTmp
+       * child[1]:  inlined function body
+       * child[2]:  __resultTmp
        */
       slang_operation *commaSeq;
       slang_operation *declOper = NULL;
@@ -981,13 +919,13 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun,
       /* allocate the return var */
       resultVar = slang_variable_scope_grow(commaSeq->locals);
       /*
-      printf("Alloc __resultTemp in scope %p for retval of calling %s\n",
+      printf("Alloc __resultTmp in scope %p for retval of calling %s\n",
              (void*)commaSeq->locals, (char *) fun->header.a_name);
       */
 
       resultVar->a_name = slang_atom_pool_atom(A->atoms, "__resultTmp");
       resultVar->type = fun->header.type; /* XXX copy? */
-      /*resultVar->type.qualifier = slang_qual_out;*/
+      resultVar->isTemp = GL_TRUE;
 
       /* child[0] = __resultTmp declaration */
       declOper = &commaSeq->children[0];
@@ -1027,12 +965,12 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun,
     */
    substCount = 0;
    for (i = 0; i < totalArgs; i++) {
-      slang_variable *p = &fun->parameters->variables[i];
-
+      slang_variable *p = fun->parameters->variables[i];
+      /*
       printf("Param %d: %s %s \n", i,
              slang_type_qual_string(p->type.qualifier),
             (char *) p->a_name);
-
+      */
       if (p->type.qualifier == slang_qual_inout ||
          p->type.qualifier == slang_qual_out) {
         /* an output param */
@@ -1042,9 +980,10 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun,
          else
             arg = returnOper;
         paramMode[i] = SUBST;
-        assert(arg->type == slang_oper_identifier
-               /*||arg->type == slang_oper_variable_decl*/);
-         slang_resolve_variable(arg);
+
+        if (arg->type == slang_oper_identifier)
+            slang_resolve_variable(arg);
+
          /* replace parameter 'p' with argument 'arg' */
         substOld[substCount] = p;
         substNew[substCount] = arg; /* will get copied */
@@ -1073,15 +1012,14 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun,
       assert(paramMode[i]);
    }
 
-#if 00
-   printf("ABOUT to inline body %p with checksum %d\n",
-          (char *) fun->body, slang_checksum_tree(fun->body));
-#endif
-
    /* actual code inlining: */
    slang_operation_copy(inlined, fun->body);
 
-#if 000
+   /*** XXX review this */
+   assert(inlined->type = slang_oper_block_no_new_scope);
+   inlined->type = slang_oper_block_new_scope;
+
+#if 0
    printf("======================= orig body code ======================\n");
    printf("=== params scope = %p\n", (void*) fun->parameters);
    slang_print_tree(fun->body, 8);
@@ -1092,7 +1030,7 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun,
    /* do parameter substitution in inlined code: */
    slang_substitute(A, inlined, substCount, substOld, substNew, GL_FALSE);
 
-#if 000
+#if 0
    printf("======================= subst code ==========================\n");
    slang_print_tree(inlined, 8);
    printf("=============================================================\n");
@@ -1104,7 +1042,7 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun,
    numCopyIn = 0;
    for (i = 0; i < numArgs; i++) {
       if (paramMode[i] == COPY_IN) {
-        slang_variable *p = &fun->parameters->variables[i];
+        slang_variable *p = fun->parameters->variables[i];
         /* declare parameter 'p' */
         slang_operation *decl = slang_operation_insert(&inlined->num_children,
                                                        &inlined->children,
@@ -1138,7 +1076,7 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun,
 
    for (i = 0; i < totalArgs; i++) {
       if (paramMode[i] == COPY_OUT) {
-        const slang_variable *p = &fun->parameters->variables[i];
+        const slang_variable *p = fun->parameters->variables[i];
         /* actualCallVar = outParam */
         /*if (i > 0 || !haveRetValue)*/
         slang_operation *ass = slang_operation_insert(&inlined->num_children,
@@ -1215,7 +1153,6 @@ _slang_gen_function_call(slang_assemble_ctx *A, slang_function *fun,
    printf("\n");
 #endif
 
-   /* assemble what we just made XXX here??? */
    n = _slang_gen_operation(A, oper);
 
    CurFunction->end_label = NULL;
@@ -1323,7 +1260,6 @@ _slang_gen_asm(slang_assemble_ctx *A, slang_operation *oper,
          dest_oper = &dest_oper->children[0];
       }
 
-      assert(dest_oper->type == slang_oper_identifier);
       n0 = _slang_gen_operation(A, dest_oper);
       assert(n0->Var);
       assert(n0->Store);
@@ -1676,9 +1612,8 @@ _slang_gen_declaration(slang_assemble_ctx *A, slang_operation *oper)
       return NULL;
 
    varDecl->Var = v;
-   v->declared = GL_TRUE;
 
-   slang_allocate_storage(A->codegen, varDecl, A->program);
+   slang_allocate_storage(A, varDecl);
 
    if (oper->num_children > 0) {
       /* child is initializer */
@@ -1728,7 +1663,9 @@ _slang_gen_variable(slang_assemble_ctx * A, slang_operation *oper)
     */
    slang_atom aVar = oper->var ? oper->var->a_name : oper->a_id;
    slang_ir_node *n = new_var(A, oper, aVar, SWIZZLE_NOOP);
+   /*
    assert(oper->var);
+   */
    return n;
 }
 
@@ -1856,7 +1793,7 @@ _slang_gen_subscript(slang_assemble_ctx * A, slang_operation *oper)
       /* new storage info since we don't want to change the original */
       base->Store = _slang_clone_ir_storage(base->Store);
       if (_slang_type_is_vector(array_ti.spec.type)) {
-         /* scalar element (float) of a basic vector (vec3) */
+         /* scalar element (float) of a basic vector (ex: vec3) */
          const GLuint max = _slang_type_dim(array_ti.spec.type);
          if (index >= max) {
             RETURN_ERROR("array index out of bounds", 0);
@@ -1888,39 +1825,60 @@ static slang_ir_node *
 _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper)
 {
    switch (oper->type) {
-   case slang_oper_block_no_new_scope:
    case slang_oper_block_new_scope:
+      {
+         slang_ir_node *n;
+
+         A->vartable = _slang_push_var_table(A->vartable);
+
+         oper->type = slang_oper_block_no_new_scope; /* temp change */
+         n = _slang_gen_operation(A, oper);
+         oper->type = slang_oper_block_new_scope; /* restore */
+
+         A->vartable = _slang_pop_var_table(A->vartable);
+
+         if (n)
+            n = new_node(IR_SCOPE, n, NULL);
+         return n;
+      }
+      break;
+
+   case slang_oper_block_no_new_scope:
       /* list of operations */
       assert(oper->num_children > 0);
       {
          slang_ir_node *n, *tree = NULL;
          GLuint i;
+
          for (i = 0; i < oper->num_children; i++) {
             n = _slang_gen_operation(A, &oper->children[i]);
-            if (!n)
+            if (!n) {
+               _slang_free_ir_tree(tree);
                return NULL; /* error must have occured */
+            }
             tree = tree ? new_seq(tree, n) : n;
          }
 
-      if (oper->locals->num_variables > 0) {
-         int i;
-         /*
-         printf("\n****** Deallocate vars in scope!\n");
-         */
-         for (i = 0; i < oper->locals->num_variables; i++) {
-            slang_variable *v = oper->locals->variables + i;
-            if (v->aux) {
-               slang_ir_storage *store = (slang_ir_storage *) v->aux;
-               /*
-               printf("  Deallocate var %s\n", (char*) v->a_name);
-               */
-               assert(store->File == PROGRAM_TEMPORARY);
-               assert(store->Index >= 0);
-               _slang_free_temporary(A->codegen, store->Index, store->Size);
+#if 00
+         if (oper->locals->num_variables > 0) {
+            int i;
+            /*
+            printf("\n****** Deallocate vars in scope!\n");
+            */
+            for (i = 0; i < oper->locals->num_variables; i++) {
+               slang_variable *v = oper->locals->variables + i;
+               if (v->aux) {
+                  slang_ir_storage *store = (slang_ir_storage *) v->aux;
+                  /*
+                  printf("  Deallocate var %s\n", (char*) v->a_name);
+                  */
+                  assert(store->File == PROGRAM_TEMPORARY);
+                  assert(store->Index >= 0);
+                  _slang_free_temp(A->vartable, store->Index, store->Size);
+               }
             }
          }
-      }
-
+#endif
          return tree;
       }
       break;
@@ -2022,12 +1980,10 @@ _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper)
       return _slang_gen_assignment(A, oper);
    case slang_oper_addassign:
       {
+         /* XXX this is broken */
         slang_ir_node *n;
          assert(oper->num_children == 2);
-        n = _slang_gen_function_call_name(A, "+=", oper, NULL);
-         /* The result of this operation should be stored back into child[0] */
-         assert(n->Children[0]->Store);
-         n->Store = n->Children[0]->Store;
+        n = _slang_gen_function_call_name(A, "+=", oper, &oper->children[0]);
         return n;
       }
    case slang_oper_subassign:
@@ -2171,9 +2127,7 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var,
          /* We know it's a uniform, but don't allocate storage unless
           * it's really used.
           */
-
          store = _slang_new_ir_storage(PROGRAM_STATE_VAR, -1, size);
-
       }
       if (dbg) printf("UNIFORM ");
    }
@@ -2260,10 +2214,12 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var,
       if (!n)
          return GL_FALSE;
       n->Var = var;
-      var->declared = GL_TRUE;
       store = _slang_new_ir_storage(PROGRAM_TEMPORARY, index, size);
       var->aux = store;  /* save var's storage info */
-      slang_allocate_storage(A->codegen, n, A->program);
+
+      slang_allocate_storage(A, n);
+
+      _slang_add_variable(A->vartable, var);
 
       /* IR code for the var's initializer, if present */
       if (var->initializer) {
@@ -2284,7 +2240,7 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var,
          n = new_seq(n, init);
       }
 
-      success = _slang_emit_code(n, A->codegen, A->program, GL_FALSE);
+      success = _slang_emit_code(n, A->vartable, A->program, GL_FALSE);
 
       _slang_free_ir_tree(n);
    }
@@ -2328,8 +2284,7 @@ _slang_codegen_function(slang_assemble_ctx * A, slang_function * fun)
    assert(A->program->Parameters );
    assert(A->program->Varying);
 
-   assert(A->codegen);
-   /*   A->codegen = _slang_new_codegen_context();*/
+   assert(A->vartable);
 
    /* fold constant expressions, etc. */
    slang_simplify(fun->body, &A->space, A->atoms);
@@ -2340,8 +2295,16 @@ _slang_codegen_function(slang_assemble_ctx * A, slang_function * fun)
    if (!CurFunction->end_label)
       CurFunction->end_label = slang_atom_pool_gen(A->atoms, "__endOfFunc_main_");
 
+   /* push new vartable scope */
+   A->vartable = _slang_push_var_table(A->vartable);
+
    /* Generate IR tree for the function body code */
    n = _slang_gen_operation(A, fun->body);
+   if (n)
+      n = new_node(IR_SCOPE, n, NULL);
+
+   /* pop vartable, restore previous */
+   A->vartable = _slang_pop_var_table(A->vartable);
 
    if (!n) {
       /* XXX record error */
@@ -2361,11 +2324,13 @@ _slang_codegen_function(slang_assemble_ctx * A, slang_function * fun)
 #if 0
    printf("************* IR for %s *******\n", (char*)fun->header.a_name);
    slang_print_ir(n, 0);
+#endif
+#if 1
    printf("************* End codegen function ************\n\n");
 #endif
 
    /* Emit program instructions */
-   success = _slang_emit_code(n, A->codegen, A->program, GL_TRUE);
+   success = _slang_emit_code(n, A->vartable, A->program, GL_TRUE);
    _slang_free_ir_tree(n);
 
    /* free codegen context */
index 9a77c5a..c459eb2 100644 (file)
@@ -39,6 +39,7 @@
 #include "slang_storage.h"
 #include "slang_error.h"
 #include "slang_emit.h"
+#include "slang_vartable.h"
 
 #include "slang_print.h"
 
@@ -98,7 +99,9 @@ _slang_code_object_ctr(slang_code_object * self)
    for (i = 0; i < SLANG_BUILTIN_TOTAL; i++)
       _slang_code_unit_ctr(&self->builtin[i], self);
    _slang_code_unit_ctr(&self->unit, self);
+#if 01
    _slang_assembly_file_ctr(&self->assembly);
+#endif
    slang_machine_ctr(&self->machine);
    self->varpool.next_addr = 0;
    slang_atom_pool_construct(&self->atompool);
@@ -116,7 +119,9 @@ _slang_code_object_dtr(slang_code_object * self)
    for (i = 0; i < SLANG_BUILTIN_TOTAL; i++)
       _slang_code_unit_dtr(&self->builtin[i]);
    _slang_code_unit_dtr(&self->unit);
+#if 01
    slang_assembly_file_destruct(&self->assembly);
+#endif
    slang_machine_dtr(&self->machine);
    slang_atom_pool_destruct(&self->atompool);
    slang_export_data_table_dtr(&self->expdata);
@@ -248,7 +253,7 @@ typedef struct slang_output_ctx_
    slang_var_pool *global_pool;
    slang_machine *machine;
    struct gl_program *program;
-   slang_gen_context *codegen;
+   slang_var_table *vartable;
 } slang_output_ctx;
 
 /* _slang_compile() */
@@ -868,7 +873,7 @@ parse_statement(slang_parse_ctx * C, slang_output_ctx * O,
                slang_operation *o = &oper->children[i - first_var];
                o->type = slang_oper_variable_decl;
                o->locals->outer_scope = O->vars;
-               o->a_id = O->vars->variables[i].a_name;
+               o->a_id = O->vars->variables[i]->a_name;
             }
          }
       }
@@ -879,9 +884,6 @@ parse_statement(slang_parse_ctx * C, slang_output_ctx * O,
        */
       oper->type = slang_oper_asm;
       oper->a_id = parse_identifier(C);
-      if (strcmp((char*)oper->a_id, "dot") == 0) {
-         printf("Assemble dot! **************************\n");
-      }
       if (oper->a_id == SLANG_ATOM_NULL)
          return 0;
       while (*C->I != OP_END) {
@@ -1547,15 +1549,19 @@ parse_function_definition(slang_parse_ctx * C, slang_output_ctx * O,
 static GLboolean
 initialize_global(slang_assemble_ctx * A, slang_variable * var)
 {
+#if 01
    slang_assembly_file_restore_point point;
+#endif
    slang_machine mach;
    slang_assembly_local_info save_local = A->local;
    slang_operation op_id, op_assign;
    GLboolean result;
 
+#if 01
    /* save the current assembly */
    if (!slang_assembly_file_restore_point_save(A->file, &point))
       return GL_FALSE;
+#endif
 
    /* setup the machine */
    mach = *A->mach;
@@ -1578,13 +1584,13 @@ initialize_global(slang_assemble_ctx * A, slang_variable * var)
 
    /* put the variable into operation's scope */
    op_id.locals->variables =
-      (slang_variable *) slang_alloc_malloc(sizeof(slang_variable));
+      (slang_variable **) slang_alloc_malloc(sizeof(slang_variable *));
    if (op_id.locals->variables == NULL) {
       slang_operation_destruct(&op_id);
       return GL_FALSE;
    }
    op_id.locals->num_variables = 1;
-   op_id.locals->variables[0] = *var;
+   op_id.locals->variables[0] = var;
 
    /* construct the assignment expression */
    if (!slang_operation_construct(&op_assign)) {
@@ -1605,8 +1611,12 @@ initialize_global(slang_assemble_ctx * A, slang_variable * var)
    op_assign.children[0] = op_id;
    op_assign.children[1] = *var->initializer;
 
+#if 0 /* this should go away */
    /* insert the actual expression */
    result = _slang_assemble_operation(A, &op_assign, slang_ref_forbid);
+#else
+   result = 1;
+#endif
 
    /* carefully destroy the operations */
    op_assign.num_children = 0;
@@ -1627,9 +1637,11 @@ initialize_global(slang_assemble_ctx * A, slang_variable * var)
       return GL_FALSE;
 #endif
 
+#if 01
    /* restore the old assembly */
    if (!slang_assembly_file_restore_point_load(A->file, &point))
       return GL_FALSE;
+#endif
    A->local = save_local;
 
    /* now we copy the contents of the initialized variable back to the original machine */
@@ -1732,8 +1744,11 @@ parse_init_declarator(slang_parse_ctx * C, slang_output_ctx * O,
       A.space.funcs = O->funs;
       A.space.structs = O->structs;
       A.space.vars = O->vars;
-      A.codegen = O->codegen;
       A.program = O->program;
+#if 0
+      A.codegen = O->codegen;
+#endif
+      A.vartable = O->vartable;
 
       _slang_codegen_global_variable(&A, var, C->type);
    }
@@ -1896,7 +1911,10 @@ parse_function(slang_parse_ctx * C, slang_output_ctx * O, int definition,
       A.space.structs = O->structs;
       A.space.vars = O->vars;
       A.program = O->program;
+#if 0
       A.codegen = O->codegen;
+#endif
+      A.vartable = O->vartable;
 
       _slang_reset_error();
 
@@ -1906,14 +1924,14 @@ parse_function(slang_parse_ctx * C, slang_output_ctx * O, int definition,
                             (*parsed_func_ret)->param_count);
 #endif
 
-
+#if 0
       if (!_slang_assemble_function(&A, *parsed_func_ret)) {
          /* propogate the error message back through the info log */
          C->L->text = _mesa_strdup(_slang_error_text());
          C->L->dont_free_text = GL_FALSE;
          return GL_FALSE;
       }
-
+#endif
 
 #if 0
       printf("**************************************\n");
@@ -1961,6 +1979,7 @@ parse_code_unit(slang_parse_ctx * C, slang_code_unit * unit,
                 struct gl_program *program)
 {
    slang_output_ctx o;
+   GLboolean success;
 
    /* setup output context */
    o.funs = &unit->funs;
@@ -1970,7 +1989,7 @@ parse_code_unit(slang_parse_ctx * C, slang_code_unit * unit,
    o.global_pool = &unit->object->varpool;
    o.machine = &unit->object->machine;
    o.program = program;
-   o.codegen = _slang_new_codegen_context();
+   o.vartable = _slang_push_var_table(NULL);
 
    /* parse individual functions and declarations */
    while (*C->I != EXTERNAL_NULL) {
@@ -1978,20 +1997,25 @@ parse_code_unit(slang_parse_ctx * C, slang_code_unit * unit,
       case EXTERNAL_FUNCTION_DEFINITION:
          {
             slang_function *func;
-
-            if (!parse_function(C, &o, 1, &func))
-               return GL_FALSE;
+            success = parse_function(C, &o, 1, &func);
          }
          break;
       case EXTERNAL_DECLARATION:
-         if (!parse_declaration(C, &o))
-            return GL_FALSE;
+         success = parse_declaration(C, &o);
          break;
       default:
+         success = GL_FALSE;
+      }
+
+      if (!success) {
+         /* xxx free codegen */
+         _slang_pop_var_table(o.vartable);
          return GL_FALSE;
       }
    }
    C->I++;
+
+   _slang_pop_var_table(o.vartable);
    return GL_TRUE;
 }
 
index 2670134..81f8565 100644 (file)
@@ -34,6 +34,7 @@
 #include "program.h"
 #include "prog_instruction.h"
 #include "prog_parameter.h"
+#include "prog_print.h"
 #include "slang_emit.h"
 
 
@@ -83,6 +84,7 @@ static slang_ir_info IrInfo[] = {
    { IR_COS, "IR_COS", OPCODE_COS, 1, 1 },
    /* other */
    { IR_SEQ, "IR_SEQ", 0, 0, 0 },
+   { IR_SCOPE, "IR_SCOPE", 0, 0, 0 },
    { IR_LABEL, "IR_LABEL", 0, 0, 0 },
    { IR_JUMP, "IR_JUMP", 0, 0, 0 },
    { IR_CJUMP, "IR_CJUMP", 0, 0, 0 },
@@ -227,6 +229,11 @@ slang_print_ir(const slang_ir_node *n, int indent)
       slang_print_ir(n->Children[0], indent + IND);
       slang_print_ir(n->Children[1], indent + IND);
       break;
+   case IR_SCOPE:
+      printf("NEW SCOPE\n");
+      assert(!n->Children[1]);
+      slang_print_ir(n->Children[0], indent + 3);
+      break;
    case IR_MOVE:
       printf("MOVE (writemask = %s)\n", writemask_string(n->Writemask));
       slang_print_ir(n->Children[0], indent+3);
@@ -279,71 +286,36 @@ slang_print_ir(const slang_ir_node *n, int indent)
 }
 
 
-GLint
-_slang_alloc_temporary(slang_gen_context *gc, GLint size)
-{
-   const GLuint sz4 = (size + 3) / 4;
-   GLuint i, j;
-   ASSERT(size > 0); /* number of floats */
-
-   for (i = 0; i < MAX_PROGRAM_TEMPS; i++) {
-      GLuint found = 0;
-      for (j = 0; j < sz4; j++) {
-         if (!gc->TempUsed[i + j]) {
-            found++;
-         }
-      }
-      if (found == sz4) {
-         /* found block of size/4 free regs */
-         for (j = 0; j < sz4; j++)
-            gc->TempUsed[i + j] = GL_TRUE;
-         return i;
-      }
-   }
-   return -1;
-}
-
-
-
-static GLboolean
-is_temporary(const slang_gen_context *gc, const slang_ir_storage *st)
-{
-   if (st->File == PROGRAM_TEMPORARY && gc->TempUsed[st->Index])
-      return gc->TempUsed[st->Index];
-   else
-      return GL_FALSE;
-}
-
-
-void
-_slang_free_temporary(slang_gen_context *gc, GLuint r, GLint size)
-{
-   const GLuint sz4 = (size + 3) / 4;
-   GLuint i;
-   for (i = 0; i < sz4; i++) {
-      if (gc->TempUsed[r + i])
-         gc->TempUsed[r + i] = GL_FALSE;
-   }
-}
-
-
 /**
  * Allocate temporary storage for an intermediate result (such as for
  * a multiply or add, etc.
  */
 static void
-slang_alloc_temp_storage(slang_gen_context *gc, slang_ir_node *n, GLint size)
+alloc_temp_storage(slang_var_table *vt, slang_ir_node *n, GLint size)
 {
    GLint indx;
    assert(!n->Var);
    assert(!n->Store);
    assert(size > 0);
-   printf("Allocate binop temp:\n");
-   indx = _slang_alloc_temporary(gc, size);
+   indx = _slang_alloc_temp(vt, size);
    n->Store = _slang_new_ir_storage(PROGRAM_TEMPORARY, indx, size);
 }
 
 
+static void
+free_temp_storage(slang_var_table *vt, slang_ir_node *n)
+{
+   if (n->Store->File == PROGRAM_TEMPORARY && n->Store->Index >= 0) {
+      if (_slang_is_temp(vt, n->Store->Index)) {
+         _slang_free_temp(vt, n->Store->Index, n->Store->Size);
+         /* XXX free(store)? */
+         n->Store->Index = -1;
+         n->Store->Size = -1;
+      }
+   }
+}
+
+
 static slang_ir_storage *
 alloc_constant(const GLfloat v[], GLuint size, struct gl_program *prog)
 {
@@ -445,14 +417,14 @@ new_instruction(struct gl_program *prog, gl_inst_opcode opcode)
 
 
 static struct prog_instruction *
-emit(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog);
+emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog);
 
 
 /**
  * Generate code for a simple binary-op instruction.
  */
 static struct prog_instruction *
-emit_binop(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog)
+emit_binop(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog)
 {
    struct prog_instruction *inst;
    const slang_ir_info *info = slang_find_ir_info(n->Opcode);
@@ -460,25 +432,32 @@ emit_binop(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog)
 
    assert(info->InstOpcode != OPCODE_NOP);
 
-   emit(gc, n->Children[0], prog);
-   emit(gc, n->Children[1], prog);
+   /* gen code for children */
+   emit(vt, n->Children[0], prog);
+   emit(vt, n->Children[1], prog);
+
+   /* gen this instruction */
    inst = new_instruction(prog, info->InstOpcode);
-   /* alloc temp storage for the result: */
-   if (!n->Store || n->Store->File == PROGRAM_UNDEFINED) {
-      slang_alloc_temp_storage(gc, n, info->ResultSize);
-   }
-   storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask);
    storage_to_src_reg(&inst->SrcReg[0], n->Children[0]->Store,
                       n->Children[0]->Swizzle);
    storage_to_src_reg(&inst->SrcReg[1], n->Children[1]->Store,
                       n->Children[1]->Swizzle);
+   free_temp_storage(vt, n->Children[0]);
+   free_temp_storage(vt, n->Children[1]);
+
+   if (!n->Store) {
+      alloc_temp_storage(vt, n, info->ResultSize);
+   }
+   storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask);
+
    inst->Comment = n->Comment;
+   /*_mesa_print_instruction(inst);*/
    return inst;
 }
 
 
 static struct prog_instruction *
-emit_unop(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog)
+emit_unop(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog)
 {
    struct prog_instruction *inst;
    const slang_ir_info *info = slang_find_ir_info(n->Opcode);
@@ -486,26 +465,28 @@ emit_unop(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog)
 
    assert(info->NumParams == 1);
 
-   emit(gc, n->Children[0], prog);
+   /* gen code for child */
+   emit(vt, n->Children[0], prog);
 
+   /* gen this instruction */
    inst = new_instruction(prog, info->InstOpcode);
-
-   if (!n->Store)
-      slang_alloc_temp_storage(gc, n, info->ResultSize);
-
-   storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask);
-
    storage_to_src_reg(&inst->SrcReg[0], n->Children[0]->Store,
                       n->Children[0]->Swizzle);
+   free_temp_storage(vt, n->Children[0]);
 
-   inst->Comment = n->Comment;
+   if (!n->Store) {
+      alloc_temp_storage(vt, n, info->ResultSize);
+   }
+   storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask);
 
+   inst->Comment = n->Comment;
+   /*_mesa_print_instruction(inst);*/
    return inst;
 }
 
 
 static struct prog_instruction *
-emit_negation(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog)
+emit_negation(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog)
 {
    /* Implement as MOV dst, -src; */
    /* XXX we could look at the previous instruction and in some circumstances
@@ -513,10 +494,10 @@ emit_negation(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog)
     */
    struct prog_instruction *inst;
 
-   emit(gc, n->Children[0], prog);
+   emit(vt, n->Children[0], prog);
 
    if (!n->Store)
-      slang_alloc_temp_storage(gc, n, n->Children[0]->Store->Size);
+      alloc_temp_storage(vt, n, n->Children[0]->Store->Size);
 
    inst = new_instruction(prog, OPCODE_MOV);
    storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask);
@@ -563,7 +544,7 @@ emit_jump(const char *target, struct gl_program *prog)
 
 
 static struct prog_instruction *
-emit_tex(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog)
+emit_tex(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog)
 {
    struct prog_instruction *inst;
    if (n->Opcode == IR_TEX) {
@@ -578,7 +559,7 @@ emit_tex(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog)
    }
 
    if (!n->Store)
-      slang_alloc_temp_storage(gc, n, 4);
+      alloc_temp_storage(vt, n, 4);
 
    storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask);
 
@@ -600,7 +581,7 @@ emit_tex(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog)
 
 
 static struct prog_instruction *
-emit(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog)
+emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog)
 {
    struct prog_instruction *inst;
    if (!n)
@@ -610,34 +591,54 @@ emit(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog)
    case IR_SEQ:
       assert(n->Children[0]);
       assert(n->Children[1]);
-      emit(gc, n->Children[0], prog);
-      inst = emit(gc, n->Children[1], prog);
+      emit(vt, n->Children[0], prog);
+      inst = emit(vt, n->Children[1], prog);
       n->Store = n->Children[1]->Store;
       return inst;
-      break;
+
+   case IR_SCOPE:
+      /* new variable scope */
+      vt = _slang_push_var_table(vt);
+      inst = emit(vt, n->Children[0], prog);
+      vt = _slang_pop_var_table(vt);
+      return inst;
+
    case IR_VAR_DECL:
+      /* Variable declaration - allocate a register for it */
+      assert(n->Store);
+      assert(n->Store->File != PROGRAM_UNDEFINED);
+      assert(n->Store->Size > 0);
+      if (n->Var->isTemp)
+         n->Store->Index = _slang_alloc_temp(vt, n->Store->Size);
+      else
+         n->Store->Index = _slang_alloc_var(vt, n->Store->Size);
+      break;
+
    case IR_VAR:
-      /* Storage should have already been resolved/allocated */
+      /* Reference to a variable
+       * Storage should have already been resolved/allocated.
+       */
       assert(n->Store);
       assert(n->Store->File != PROGRAM_UNDEFINED);
       assert(n->Store->Index >= 0);
       assert(n->Store->Size > 0);
       break;
+
    case IR_MOVE:
       /* rhs */
       assert(n->Children[1]);
-      inst = emit(gc, n->Children[1], prog);
+      inst = emit(vt, n->Children[1], prog);
       /* lhs */
-      emit(gc, n->Children[0], prog);
+      emit(vt, n->Children[0], prog);
 
 #if 1
-      if (inst && is_temporary(gc, n->Children[1]->Store)) {
+      if (inst && _slang_is_temp(vt, n->Children[1]->Store->Index)) {
          /* Peephole optimization:
           * Just modify the RHS to put its result into the dest of this
           * MOVE operation.  Then, this MOVE is a no-op.
           */
-         _slang_free_temporary(gc, n->Children[1]->Store->Index,
-                               n->Children[1]->Store->Size);
+         _slang_free_temp(vt, n->Children[1]->Store->Index,
+                          n->Children[1]->Store->Size);
          *n->Children[1]->Store = *n->Children[0]->Store;
          /* fixup the prev (RHS) instruction */
          storage_to_dst_reg(&inst->DstReg, n->Children[0]->Store, n->Writemask);
@@ -673,9 +674,9 @@ emit(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog)
                                n->Children[1]->Swizzle);
          }
          /* XXX is this test correct? */
-         if (n->Children[1]->Store->File == PROGRAM_TEMPORARY) {
-            _slang_free_temporary(gc, n->Children[1]->Store->Index,
-                                  n->Children[1]->Store->Size);
+         if (_slang_is_temp(vt, n->Children[1]->Store->Index)) {
+            _slang_free_temp(vt, n->Children[1]->Store->Index,
+                             n->Children[1]->Store->Size);
          }
          /*inst->Comment = _mesa_strdup("IR_MOVE");*/
          n->Store = n->Children[0]->Store; /*XXX new */
@@ -697,7 +698,7 @@ emit(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog)
    case IR_POW:
    case IR_EXP:
    case IR_EXP2:
-      return emit_binop(gc, n, prog);
+      return emit_binop(vt, n, prog);
    case IR_RSQ:
    case IR_RCP:
    case IR_FLOOR:
@@ -707,13 +708,13 @@ emit(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog)
    case IR_COS:
    case IR_DDX:
    case IR_DDY:
-      return emit_unop(gc, n, prog);
+      return emit_unop(vt, n, prog);
    case IR_TEX:
    case IR_TEXB:
    case IR_TEXP:
-      return emit_tex(gc, n, prog);
+      return emit_tex(vt, n, prog);
    case IR_NEG:
-      return emit_negation(gc, n, prog);
+      return emit_negation(vt, n, prog);
    case IR_LABEL:
       return emit_label(n->Target, prog);
    case IR_FLOAT:
@@ -726,7 +727,7 @@ emit(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog)
           * Next instruction is typically an IR_CJUMP.
           */
          /* last child expr instruction: */
-         struct prog_instruction *inst = emit(gc, n->Children[0], prog);
+         struct prog_instruction *inst = emit(vt, n->Children[0], prog);
          if (inst) {
             /* set inst's CondUpdate flag */
             inst->CondUpdate = GL_TRUE;
@@ -737,13 +738,13 @@ emit(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog)
              * is normally generated for the expression "i".
              * Generate a move instruction just to set condition codes.
              */
-            slang_alloc_temp_storage(gc, n, 1);
+            alloc_temp_storage(vt, n, 1);
             inst = new_instruction(prog, OPCODE_MOV);
             inst->CondUpdate = GL_TRUE;
             storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask);
             storage_to_src_reg(&inst->SrcReg[0], n->Children[0]->Store,
                                n->Children[0]->Swizzle);
-            _slang_free_temporary(gc, n->Store->Index, n->Store->Size);
+            _slang_free_temp(vt, n->Store->Index, n->Store->Size);
             return inst; /* XXX or null? */
          }
       }
@@ -760,23 +761,14 @@ emit(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog)
 }
 
 
-slang_gen_context *
-_slang_new_codegen_context(void)
-{
-   slang_gen_context *gc = (slang_gen_context *) _mesa_calloc(sizeof(*gc));
-   return gc;
-}
-
-
-
 GLboolean
-_slang_emit_code(slang_ir_node *n, slang_gen_context *gc,
+_slang_emit_code(slang_ir_node *n, slang_var_table *vt,
                  struct gl_program *prog, GLboolean withEnd)
 {
    GLboolean success;
 
-   if (emit(gc, n, prog)) {
-      /* finish up by addeing the END opcode to program */
+   if (emit(vt, n, prog)) {
+      /* finish up by adding the END opcode to program */
       if (withEnd) {
          struct prog_instruction *inst;
          inst = new_instruction(prog, OPCODE_END);
@@ -788,8 +780,8 @@ _slang_emit_code(slang_ir_node *n, slang_gen_context *gc,
       success = GL_FALSE;
    }
 
-#if 0
    printf("*********** End generate code (%u inst):\n", prog->NumInstructions);
+#if 0
    _mesa_print_program(prog);
    _mesa_print_program_parameters(ctx,prog);
 #endif
index 73ae082..7a845fe 100644 (file)
 #include "mtypes.h"
 
 
-extern slang_gen_context *
-_slang_new_codegen_context(void);
-
-
 extern void
 slang_print_ir(const slang_ir_node *n, int indent);
 
@@ -48,15 +44,8 @@ extern slang_ir_storage *
 _slang_clone_ir_storage(slang_ir_storage *store);
 
 
-extern GLint
-_slang_alloc_temporary(slang_gen_context *gc, GLint size);
-
-extern void
-_slang_free_temporary(slang_gen_context *gc, GLuint r, GLint size);
-
-
 extern GLboolean
-_slang_emit_code(slang_ir_node *n, slang_gen_context *gc,
+_slang_emit_code(slang_ir_node *n, slang_var_table *vartable,
                  struct gl_program *prog, GLboolean withEnd);
 
 
index b106e85..baf1137 100644 (file)
@@ -45,6 +45,7 @@ typedef enum
 {
    IR_NOP = 0,
    IR_SEQ,     /* sequence (eval left, then right) */
+   IR_SCOPE,   /* new variable scope (one child) */
    IR_LABEL,   /* target of a jump or cjump */
    IR_JUMP,    /* unconditional jump */
    IR_CJUMP,   /* conditional jump */
index 7dfdd28..3ea7954 100644 (file)
@@ -259,8 +259,10 @@ link_uniform_vars(struct gl_shader_program *shProg, struct gl_program *prog)
       if (inst->Opcode == OPCODE_TEX ||
           inst->Opcode == OPCODE_TXB ||
           inst->Opcode == OPCODE_TXP) {
+         /*
          printf("====== remap sampler from %d to %d\n",
                 inst->Sampler, map[ inst->Sampler ]);
+         */
          inst->Sampler = map[ inst->Sampler ];
       }
    }
index 020f30a..07509cd 100644 (file)
@@ -188,7 +188,7 @@ find_scope(const slang_variable_scope *s, slang_atom name)
 {
    GLuint i;
    for (i = 0; i < s->num_variables; i++) {
-      if (s->variables[i].a_name == name)
+      if (s->variables[i]->a_name == name)
          return s;
    }
    if (s->outer_scope)
@@ -202,8 +202,8 @@ find_var(const slang_variable_scope *s, slang_atom name)
 {
    GLuint i;
    for (i = 0; i < s->num_variables; i++) {
-      if (s->variables[i].a_name == name)
-         return &s->variables[i];
+      if (s->variables[i]->a_name == name)
+         return s->variables[i];
    }
    if (s->outer_scope)
       return find_var(s->outer_scope, name);
@@ -621,7 +621,7 @@ slang_print_function(const slang_function *f, GLboolean body)
           (char *) f->header.a_name);
 
    for (i = 0; i < f->param_count; i++) {
-      print_variable(&f->parameters->variables[i], 3);
+      print_variable(f->parameters->variables[i], 3);
    }
 
    printf(")\n");
@@ -632,199 +632,6 @@ slang_print_function(const slang_function *f, GLboolean body)
 
 
 
-/* operation */
-#define OP_END 0
-#define OP_BLOCK_BEGIN_NO_NEW_SCOPE 1
-#define OP_BLOCK_BEGIN_NEW_SCOPE 2
-#define OP_DECLARE 3
-#define OP_ASM 4
-#define OP_BREAK 5
-#define OP_CONTINUE 6
-#define OP_DISCARD 7
-#define OP_RETURN 8
-#define OP_EXPRESSION 9
-#define OP_IF 10
-#define OP_WHILE 11
-#define OP_DO 12
-#define OP_FOR 13
-#define OP_PUSH_VOID 14
-#define OP_PUSH_BOOL 15
-#define OP_PUSH_INT 16
-#define OP_PUSH_FLOAT 17
-#define OP_PUSH_IDENTIFIER 18
-#define OP_SEQUENCE 19
-#define OP_ASSIGN 20
-#define OP_ADDASSIGN 21
-#define OP_SUBASSIGN 22
-#define OP_MULASSIGN 23
-#define OP_DIVASSIGN 24
-/*#define OP_MODASSIGN 25*/
-/*#define OP_LSHASSIGN 26*/
-/*#define OP_RSHASSIGN 27*/
-/*#define OP_ORASSIGN 28*/
-/*#define OP_XORASSIGN 29*/
-/*#define OP_ANDASSIGN 30*/
-#define OP_SELECT 31
-#define OP_LOGICALOR 32
-#define OP_LOGICALXOR 33
-#define OP_LOGICALAND 34
-/*#define OP_BITOR 35*/
-/*#define OP_BITXOR 36*/
-/*#define OP_BITAND 37*/
-#define OP_EQUAL 38
-#define OP_NOTEQUAL 39
-#define OP_LESS 40
-#define OP_GREATER 41
-#define OP_LESSEQUAL 42
-#define OP_GREATEREQUAL 43
-/*#define OP_LSHIFT 44*/
-/*#define OP_RSHIFT 45*/
-#define OP_ADD 46
-#define OP_SUBTRACT 47
-#define OP_MULTIPLY 48
-#define OP_DIVIDE 49
-/*#define OP_MODULUS 50*/
-#define OP_PREINCREMENT 51
-#define OP_PREDECREMENT 52
-#define OP_PLUS 53
-#define OP_MINUS 54
-/*#define OP_COMPLEMENT 55*/
-#define OP_NOT 56
-#define OP_SUBSCRIPT 57
-#define OP_CALL 58
-#define OP_FIELD 59
-#define OP_POSTINCREMENT 60
-#define OP_POSTDECREMENT 61
-
-
-void
-slang_print_opcode(unsigned int opcode)
-{
-   switch (opcode) {
-   case OP_PUSH_VOID:
-      printf("OP_PUSH_VOID\n");
-      break;
-   case OP_PUSH_BOOL:
-      printf("OP_PUSH_BOOL\n");
-      break;
-   case OP_PUSH_INT:
-      printf("OP_PUSH_INT\n");
-      break;
-   case OP_PUSH_FLOAT:
-      printf("OP_PUSH_FLOAT\n");
-      break;
-   case OP_PUSH_IDENTIFIER:
-      printf("OP_PUSH_IDENTIFIER\n");
-      break;
-   case OP_SEQUENCE:
-      printf("OP_SEQUENCE\n");
-      break;
-   case OP_ASSIGN:
-      printf("OP_ASSIGN\n");
-      break;
-   case OP_ADDASSIGN:
-      printf("OP_ADDASSIGN\n");
-      break;
-   case OP_SUBASSIGN:
-      printf("OP_SUBASSIGN\n");
-      break;
-   case OP_MULASSIGN:
-      printf("OP_MULASSIGN\n");
-      break;
-   case OP_DIVASSIGN:
-      printf("OP_DIVASSIGN\n");
-      break;
-   /*case OP_MODASSIGN:*/
-   /*case OP_LSHASSIGN:*/
-   /*case OP_RSHASSIGN:*/
-   /*case OP_ORASSIGN:*/
-   /*case OP_XORASSIGN:*/
-   /*case OP_ANDASSIGN:*/
-   case OP_SELECT:
-      printf("OP_SELECT\n");
-      break;
-   case OP_LOGICALOR:
-      printf("OP_LOGICALOR\n");
-      break;
-   case OP_LOGICALXOR:
-      printf("OP_LOGICALXOR\n");
-      break;
-   case OP_LOGICALAND:
-      printf("OP_LOGICALAND\n");
-      break;
-   /*case OP_BITOR:*/
-   /*case OP_BITXOR:*/
-   /*case OP_BITAND:*/
-   case OP_EQUAL:
-      printf("OP_EQUAL\n");
-      break;
-   case OP_NOTEQUAL:
-      printf("OP_NOTEQUAL\n");
-      break;
-   case OP_LESS:
-      printf("OP_LESS\n");
-      break;
-   case OP_GREATER:
-      printf("OP_GREATER\n");
-      break;
-   case OP_LESSEQUAL:
-      printf("OP_LESSEQUAL\n");
-      break;
-   case OP_GREATEREQUAL:
-      printf("OP_GREATEREQUAL\n");
-      break;
-   /*case OP_LSHIFT:*/
-   /*case OP_RSHIFT:*/
-   case OP_ADD:
-      printf("OP_ADD\n");
-      break;
-   case OP_SUBTRACT:
-      printf("OP_SUBTRACT\n");
-      break;
-   case OP_MULTIPLY:
-      printf("OP_MULTIPLY\n");
-      break;
-   case OP_DIVIDE:
-      printf("OP_DIVIDE\n");
-      break;
-   /*case OP_MODULUS:*/
-   case OP_PREINCREMENT:
-      printf("OP_PREINCREMENT\n");
-      break;
-   case OP_PREDECREMENT:
-      printf("OP_PREDECREMENT\n");
-      break;
-   case OP_PLUS:
-      printf("OP_PLUS\n");
-      break;
-   case OP_MINUS:
-      printf("OP_MINUS\n");
-      break;
-   case OP_NOT:
-      printf("OP_NOT\n");
-      break;
-   /*case OP_COMPLEMENT:*/
-   case OP_SUBSCRIPT:
-      printf("OP_SUBSCRIPT\n");
-      break;
-   case OP_CALL:
-      printf("OP_CALL\n");
-      break;
-   case OP_FIELD:
-      printf("OP_FIELD\n");
-      break;
-   case OP_POSTINCREMENT:
-      printf("OP_POSTINCREMENT\n");
-      break;
-   case OP_POSTDECREMENT:
-      printf("OP_POSTDECREMENT\n");
-      break;
-   default:
-      printf("UNKNOWN OP %d\n", opcode);
-   }
-}
-
-
 
 const char *
 slang_asm_string(slang_assembly_type t)
@@ -1083,6 +890,7 @@ slang_print_type(const slang_fully_specified_type *t)
 }
 
 
+#if 0
 static char *
 slang_var_string(const slang_variable *v)
 {
@@ -1092,6 +900,7 @@ slang_var_string(const slang_variable *v)
            slang_fq_type_string(&v->type));
    return str;
 }
+#endif
 
 
 void
@@ -1111,13 +920,13 @@ _slang_print_var_scope(const slang_variable_scope *vars, int indent)
    printf("Var scope %p  %d vars:\n", (void *) vars, vars->num_variables);
    for (i = 0; i < vars->num_variables; i++) {
       spaces(indent + 3);
-      printf("%s\n", (char *) vars->variables[i].a_name);
+      printf("%s (at %p)\n", (char *) vars->variables[i]->a_name, (void*) (vars->variables + i));
    }
    spaces(indent + 3);
    printf("outer_scope = %p\n", (void*) vars->outer_scope);
 
    if (vars->outer_scope) {
-      spaces(indent + 3);
+      /*spaces(indent + 3);*/
       _slang_print_var_scope(vars->outer_scope, indent + 3);
    }
 }
index a98607a..ae39be6 100644 (file)
@@ -10,10 +10,6 @@ extern void
 slang_print_tree(const slang_operation *op, int indent);
 
 
-extern void
-slang_print_opcode(unsigned int opcode);
-
-
 extern const char *
 slang_asm_string(slang_assembly_type t);
 
index 6220b7c..71ac069 100644 (file)
@@ -126,8 +126,8 @@ static GLboolean aggregate_variables (slang_storage_aggregate *agg, slang_variab
        GLuint i;
 
        for (i = 0; i < vars->num_variables; i++)
-               if (!_slang_aggregate_variable (agg, &vars->variables[i].type.specifier,
-                               vars->variables[i].array_len, funcs, structs, globals, mach, file, atoms))
+               if (!_slang_aggregate_variable (agg, &vars->variables[i]->type.specifier,
+                               vars->variables[i]->array_len, funcs, structs, globals, mach, file, atoms))
                        return GL_FALSE;
        return GL_TRUE;
 }
diff --git a/src/mesa/shader/slang/slang_vartable.c b/src/mesa/shader/slang/slang_vartable.c
new file mode 100644 (file)
index 0000000..cd6a081
--- /dev/null
@@ -0,0 +1,202 @@
+
+#include "imports.h"
+#include "slang_compile.h"
+#include "slang_compile_variable.h"
+#include "slang_vartable.h"
+
+
+static int dbg = 0;
+
+
+typedef enum {
+   FREE,
+   VAR,
+   TEMP
+} TempState;
+
+static int Level = 0;
+
+struct slang_var_table_
+{
+   int level;
+   int num_entries;
+   slang_variable **vars;  /* array [num_entries] */
+
+   TempState temps[MAX_PROGRAM_TEMPS];
+
+   struct slang_var_table_ *parent;
+};
+
+
+
+/**
+ * Create new table, put at head, return ptr to it.
+ */
+slang_var_table *
+_slang_push_var_table(slang_var_table *parent)
+{
+   slang_var_table *t
+      = (slang_var_table *) _mesa_calloc(sizeof(slang_var_table));
+   if (t) {
+      t->level = Level++;
+      t->parent = parent;
+      if (parent) {
+         /* copy the info indicating which temp regs are in use */
+         memcpy(t->temps, parent->temps, sizeof(t->temps));
+      }
+      if (dbg) printf("Pushing level %d\n", t->level);
+   }
+   return t;
+}
+
+
+/**
+ * Destroy given table, return ptr to parent
+ */
+slang_var_table *
+_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);
+   if (t->parent) {
+      for (i = 0; i < MAX_PROGRAM_TEMPS; i++) {
+         if (t->temps[i] && !t->parent->temps[i])
+            if (dbg) printf("  Free reg %d\n", i);
+      }
+   }
+   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);
+   free(t);
+   Level--;
+   return parent;
+}
+
+
+/**
+ * Add a new variable to the given symbol table.
+ */
+void
+_slang_add_variable(slang_var_table *t, slang_variable *v)
+{
+   assert(t);
+   t->vars = realloc(t->vars, (t->num_entries + 1) * sizeof(slang_variable *));
+   t->vars[t->num_entries] = v;
+   t->num_entries++;
+}
+
+
+/**
+ * Look for variable by name in given table.
+ * If not found, parent table will be searched.
+ */
+slang_variable *
+_slang_find_variable(const slang_var_table *t, slang_atom name)
+{
+   while (1) {
+      int i;
+      for (i = 0; i < t->num_entries; i++) {
+         if (t->vars[i]->a_name == name)
+            return t->vars[i];
+      }
+      if (t->parent)
+         t = t->parent;
+      else
+         return NULL;
+   }
+}
+
+
+static GLint
+alloc_reg(slang_var_table *t, GLint size, GLboolean isTemp)
+{
+   const GLuint sz4 = (size + 3) / 4;
+   GLuint i, j;
+   assert(size > 0); /* number of floats */
+
+   for (i = 0; i < MAX_PROGRAM_TEMPS; i++) {
+      GLuint found = 0;
+      for (j = 0; j < sz4; j++) {
+         if (!t->temps[i + j]) {
+            found++;
+         }
+         else {
+            break;
+         }
+      }
+      if (found == sz4) {
+         /* found block of size/4 free regs */
+         for (j = 0; j < sz4; j++)
+            t->temps[i + j] = isTemp ? TEMP : VAR;
+         return i;
+      }
+   }
+   return -1;
+}
+
+
+/**
+ * Allocate temp register(s) for storing a variable.
+ */
+GLint
+_slang_alloc_var(slang_var_table *t, GLint size)
+{
+   int i = alloc_reg(t, size, GL_FALSE);
+   if (dbg) printf("Alloc var %d (level %d)\n", i, t->level);
+   return i;
+}
+
+
+void
+_slang_reserve_var(slang_var_table *t, GLint r, GLint size)
+{
+   const GLint sz4 = (size + 3) / 4;
+   GLint i;
+   for (i = 0; i < sz4; i++) {
+      t->temps[r + i] = VAR;
+   }
+}
+
+
+/**
+ * Allocate temp register(s) for storing an unnamed intermediate value.
+ */
+GLint
+_slang_alloc_temp(slang_var_table *t, GLint size)
+{
+   int i = alloc_reg(t, size, GL_TRUE);
+   if (dbg) printf("Alloc temp %d (level %d)\n", i, t->level);
+   return i;
+}
+
+
+void
+_slang_free_temp(slang_var_table *t, GLint r, GLint size)
+{
+   const GLuint sz4 = (size + 3) / 4;
+   GLuint i;
+   assert(size > 0);
+   assert(r >= 0);
+   assert(r < MAX_PROGRAM_TEMPS);
+   if (dbg) printf("Free temp %d (level %d)\n", r, t->level);
+   for (i = 0; i < sz4; i++) {
+      assert(t->temps[r + i] == TEMP);
+      t->temps[r + i] = FREE;
+   }
+}
+
+
+GLboolean
+_slang_is_temp(slang_var_table *t, GLint r)
+{
+   assert(r >= 0);
+   assert(r < MAX_PROGRAM_TEMPS);
+   if (t->temps[r] == TEMP)
+      return GL_TRUE;
+   else
+      return GL_FALSE;
+}
diff --git a/src/mesa/shader/slang/slang_vartable.h b/src/mesa/shader/slang/slang_vartable.h
new file mode 100644 (file)
index 0000000..c8e37c9
--- /dev/null
@@ -0,0 +1,38 @@
+
+#ifndef SLANG_VARTABLE_H
+#define SLANG_VARTABLE_H
+
+
+typedef struct slang_var_table_ slang_var_table;
+
+struct slang_variable_;
+
+extern slang_var_table *
+_slang_push_var_table(slang_var_table *parent);
+
+extern slang_var_table *
+_slang_pop_var_table(slang_var_table *t);
+
+extern void
+_slang_add_variable(slang_var_table *t, struct slang_variable_ *v);
+
+extern struct slang_variable_ *
+_slang_find_variable(const slang_var_table *t, slang_atom name);
+
+extern GLint
+_slang_alloc_var(slang_var_table *t, GLint size);
+
+extern void
+_slang_reserve_var(slang_var_table *t, GLint r, GLint size);
+
+extern GLint
+_slang_alloc_temp(slang_var_table *t, GLint size);
+
+extern void
+_slang_free_temp(slang_var_table *t, GLint r, GLint size);
+
+extern GLboolean
+_slang_is_temp(slang_var_table *t, GLint r);
+
+
+#endif /* SLANG_VARTABLE_H */
index 19f4338..1b0474c 100644 (file)
@@ -189,6 +189,7 @@ SLANG_SOURCES =     \
        shader/slang/slang_preprocess.c \
        shader/slang/slang_simplify.c   \
        shader/slang/slang_storage.c    \
+       shader/slang/slang_vartable.c   \
        shader/slang/slang_print.c      \
        shader/slang/slang_utility.c