mesa: Branch 'glsl-compiler-1' - 8 commits

Brian Paul brianp at kemper.freedesktop.org
Fri Feb 23 17:04:55 UTC 2007


 src/mesa/shader/prog_print.c                    |   34 +++--
 src/mesa/shader/prog_print.h                    |    3 
 src/mesa/shader/slang/slang_builtin.c           |    2 
 src/mesa/shader/slang/slang_codegen.c           |  148 ++++++++----------------
 src/mesa/shader/slang/slang_compile_function.h  |   11 -
 src/mesa/shader/slang/slang_compile_operation.h |    9 -
 src/mesa/shader/slang/slang_emit.c              |   80 +++++++-----
 src/mesa/shader/slang/slang_ir.h                |   13 +-
 src/mesa/shader/slang/slang_label.c             |   77 ++++++++++++
 src/mesa/shader/slang/slang_label.h             |   42 ++++++
 src/mesa/shader/slang/slang_link.c              |   42 ------
 src/mesa/sources                                |    1 
 12 files changed, 257 insertions(+), 205 deletions(-)

New commits:
diff-tree 308be21c2fe8e5d33bd63eca1d3e8250cd80199d (from c2a261f4930f6f73595b6f5df5594d160f3249af)
Author: Brian <brian at yutani.localnet.net>
Date:   Fri Feb 23 10:04:18 2007 -0700

    added slang_label.c

diff --git a/src/mesa/sources b/src/mesa/sources
index 49d8dc9..a7bbc02 100644
--- a/src/mesa/sources
+++ b/src/mesa/sources
@@ -180,6 +180,7 @@ SLANG_SOURCES =	\
 	shader/slang/slang_compile_variable.c	\
 	shader/slang/slang_emit.c	\
 	shader/slang/slang_error.c	\
+	shader/slang/slang_label.c	\
 	shader/slang/slang_library_noise.c	\
 	shader/slang/slang_link.c	\
 	shader/slang/slang_preprocess.c	\
diff-tree c2a261f4930f6f73595b6f5df5594d160f3249af (from 75d4ed968d48d95c274a5965cc19b13a0e47ef9f)
Author: Brian <brian at yutani.localnet.net>
Date:   Fri Feb 23 09:55:21 2007 -0700

    comments, clean-up

diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c
index 6d6b15f..d239a97 100644
--- a/src/mesa/shader/slang/slang_codegen.c
+++ b/src/mesa/shader/slang/slang_codegen.c
@@ -28,6 +28,15 @@
  * \author Brian Paul
  */
 
+
+/***
+ *** NOTES:
+ *** The new_() functions return a new instance of a simple IR node.
+ *** The gen_() functions generate larger IR trees from the simple nodes.
+ ***/
+
+
+
 #include "imports.h"
 #include "macros.h"
 #include "mtypes.h"
@@ -1711,7 +1720,6 @@ _slang_gen_return(slang_assemble_ctx * A
       slang_operation gotoOp;
       slang_operation_construct(&gotoOp);
       gotoOp.type = SLANG_OPER_GOTO;
-      /* XXX don't call function? */
       gotoOp.label = A->CurFunction->end_label;
 
       /* assemble the new code */
@@ -2636,7 +2644,7 @@ _slang_codegen_global_variable(slang_ass
 GLboolean
 _slang_codegen_function(slang_assemble_ctx * A, slang_function * fun)
 {
-   slang_ir_node *n, *endLabel;
+   slang_ir_node *n;
    GLboolean success = GL_TRUE;
 
    if (_mesa_strcmp((char *) fun->header.a_name, "main") != 0) {
@@ -2684,8 +2692,7 @@ _slang_codegen_function(slang_assemble_c
    }
 
    /* append an end-of-function-label to IR tree */
-   endLabel = new_label(fun->end_label);
-   n = new_seq(n, endLabel);
+   n = new_seq(n, new_label(fun->end_label));
 
    A->CurFunction = NULL;
 
diff-tree 75d4ed968d48d95c274a5965cc19b13a0e47ef9f (from c18c75b0b78a7a4391d94864fdd3466a0095342f)
Author: Brian <brian at yutani.localnet.net>
Date:   Fri Feb 23 09:42:11 2007 -0700

    Replace slang_ir_node::Target w/ Field.  Remove Comment field.  Clean-up.

diff --git a/src/mesa/shader/slang/slang_builtin.c b/src/mesa/shader/slang/slang_builtin.c
index 7f4290b..2e4687a 100644
--- a/src/mesa/shader/slang/slang_builtin.c
+++ b/src/mesa/shader/slang/slang_builtin.c
@@ -348,7 +348,7 @@ _slang_alloc_statevar(slang_ir_node *n,
    GLuint swizzle;
 
    if (n->Opcode == IR_FIELD) {
-      field = n->Target;
+      field = n->Field;
       n = n->Children[0];
    }
 
diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c
index fb3bab4..6d6b15f 100644
--- a/src/mesa/shader/slang/slang_codegen.c
+++ b/src/mesa/shader/slang/slang_codegen.c
@@ -2077,7 +2077,7 @@ _slang_gen_field(slang_assemble_ctx * A,
 
       n = new_node1(IR_FIELD, base);
       if (n) {
-         n->Target = (char *) oper->a_id;
+         n->Field = (char *) oper->a_id;
          n->Store = _slang_new_ir_storage(base->Store->File,
                                           base->Store->Index,
                                           size);
diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c
index 6b950de..764b5f6 100644
--- a/src/mesa/shader/slang/slang_emit.c
+++ b/src/mesa/shader/slang/slang_emit.c
@@ -285,14 +285,14 @@ slang_print_ir(const slang_ir_node *n, i
       slang_print_ir(n->Children[0], indent + 3);
       break;
    case IR_JUMP:
-      printf("JUMP %s\n", n->Target);
+      printf("JUMP %s\n", n->Label->Name);
       break;
    case IR_CJUMP0:
-      printf("CJUMP0 %s\n", n->Target);
+      printf("CJUMP0 %s\n", n->Label->Name);
       slang_print_ir(n->Children[0], indent+3);
       break;
    case IR_CJUMP1:
-      printf("CJUMP1 %s\n", n->Target);
+      printf("CJUMP1 %s\n", n->Label->Name);
       slang_print_ir(n->Children[0], indent+3);
       break;
 
@@ -365,7 +365,7 @@ slang_print_ir(const slang_ir_node *n, i
              (void*) n->Store);
       break;
    case IR_FIELD:
-      printf("FIELD %s of\n", n->Target);
+      printf("FIELD %s of\n", n->Field);
       slang_print_ir(n->Children[0], indent+3);
       break;
    case IR_FLOAT:
@@ -842,7 +842,6 @@ emit_negation(slang_var_table *vt, slang
    storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask);
    storage_to_src_reg(&inst->SrcReg[0], n->Children[0]->Store);
    inst->SrcReg[0].NegateBase = NEGATE_XYZW;
-   inst->Comment = n->Comment;
    return inst;
 }
 
diff --git a/src/mesa/shader/slang/slang_ir.h b/src/mesa/shader/slang/slang_ir.h
index ba8b613..cd1f606 100644
--- a/src/mesa/shader/slang/slang_ir.h
+++ b/src/mesa/shader/slang/slang_ir.h
@@ -147,13 +147,14 @@ typedef struct slang_ir_node_
 {
    slang_ir_opcode Opcode;
    struct slang_ir_node_ *Children[3];
-   const char *Comment;
-   const char *Target;  /**< Branch target string */
+   slang_ir_storage *Store;  /**< location of result of this operation */
+   GLint InstLocation;  /**< Location of instruction emitted for this node */
+
+   /** special fields depending on Opcode: */
+   const char *Field;  /**< If Opcode == IR_FIELD */
    GLuint Writemask;  /**< If Opcode == IR_MOVE */
    GLfloat Value[4];    /**< If Opcode == IR_FLOAT */
    slang_variable *Var;  /**< If Opcode == IR_VAR or IR_VAR_DECL */
-   slang_ir_storage *Store;  /**< location of result of this operation */
-   GLint InstLocation;  /**< Location of instruction emitted for this node */
    struct slang_ir_node_ *BranchNode;  /**< Used for branching instructions */
    slang_label *Label;  /**< Used for branches */
 } slang_ir_node;
diff-tree c18c75b0b78a7a4391d94864fdd3466a0095342f (from afbf7c7e6b7613d8d219807adaf7d17971ac2e6d)
Author: Brian <brian at yutani.localnet.net>
Date:   Fri Feb 23 09:38:46 2007 -0700

    remove old _slang_gen_if()

diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c
index 3d9b236..fb3bab4 100644
--- a/src/mesa/shader/slang/slang_codegen.c
+++ b/src/mesa/shader/slang/slang_codegen.c
@@ -1439,58 +1439,6 @@ _slang_gen_for(slang_assemble_ctx * A, c
 }
 
 
-#if 0
-/**
- * Generate IR tree for an if/then/else conditional using BRAnch instructions.
- */
-static slang_ir_node *
-_slang_gen_if(slang_assemble_ctx * A, const slang_operation *oper)
-{
-   /*
-    * eval expr (child[0]), updating condcodes
-    * branch if false to _else or _endif
-    * "true" code block
-    * if haveElseClause clause:
-    *    jump "__endif"
-    *    label "__else"
-    *    "false" code block
-    * label "__endif"
-    */
-   const GLboolean haveElseClause = !_slang_is_noop(&oper->children[2]);
-   slang_ir_node *cond, *bra, *trueBody, *endifLab, *tree;
-   slang_atom elseAtom = slang_atom_pool_gen(A->atoms, "__else");
-   slang_atom endifAtom = slang_atom_pool_gen(A->atoms, "__endif");
-
-   cond = _slang_gen_operation(A, &oper->children[0]);
-   cond = new_cond(cond);
-   /*assert(cond->Store);*/
-   bra = new_cjump(haveElseClause ? elseAtom : endifAtom, 0);
-   tree = new_seq(cond, bra);
-
-   trueBody = _slang_gen_operation(A, &oper->children[1]);
-   tree = new_seq(tree, trueBody);
-
-   if (haveElseClause) {
-      /* else clause */
-      slang_ir_node *jump, *elseLab, *falseBody;
-      jump = new_jump(endifAtom);
-      tree = new_seq(tree, jump);
-
-      elseLab = new_label(elseAtom);
-      tree = new_seq(tree, elseLab);
-
-      falseBody = _slang_gen_operation(A, &oper->children[2]);
-      tree = new_seq(tree, falseBody);
-   }
-
-   endifLab = new_label(endifAtom);
-   tree = new_seq(tree, endifLab);
-
-   return tree;
-}
-#endif
-
-
 /**
  * Determine if the given operation is of a specific type.
  */
diff-tree afbf7c7e6b7613d8d219807adaf7d17971ac2e6d (from d8d07b2a8aa5cf9c5ce877b20351983b1aa8d01d)
Author: Brian <brian at yutani.localnet.net>
Date:   Fri Feb 23 09:38:17 2007 -0700

    Re-implement branching with slang_labels.
    
    This eliminates the NOP instructions that had been used as placeholders for
    branch targets.
    Also, fix "return" statement bug.

diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c
index 51c8f27..3d9b236 100644
--- a/src/mesa/shader/slang/slang_codegen.c
+++ b/src/mesa/shader/slang/slang_codegen.c
@@ -39,6 +39,7 @@
 #include "slang_codegen.h"
 #include "slang_compile.h"
 #include "slang_error.h"
+#include "slang_label.h"
 #include "slang_simplify.h"
 #include "slang_emit.h"
 #include "slang_vartable.h"
@@ -425,10 +426,11 @@ new_seq(slang_ir_node *left, slang_ir_no
 }
 
 static slang_ir_node *
-new_label(slang_atom labName)
+new_label(slang_label *label)
 {
    slang_ir_node *n = new_node0(IR_LABEL);
-   n->Target = (char *) labName; /*_mesa_strdup(name);*/
+   if (n)
+      n->Label = label;
    return n;
 }
 
@@ -450,11 +452,11 @@ new_float_literal(const float v[4])
  * XXX maybe pass an IR node as second param to indicate the jump target???
  */
 static slang_ir_node *
-new_cjump(slang_atom target, GLuint zeroOrOne)
+new_cjump(slang_label *dest, GLuint zeroOrOne)
 {
    slang_ir_node *n = new_node0(zeroOrOne ? IR_CJUMP1 : IR_CJUMP0);
    if (n)
-      n->Target = (char *) target;
+      n->Label = dest;
    return n;
 }
 
@@ -463,11 +465,11 @@ new_cjump(slang_atom target, GLuint zero
  * XXX maybe pass an IR node as second param to indicate the jump target???
  */
 static slang_ir_node *
-new_jump(slang_atom target)
+new_jump(slang_label *dest)
 {
    slang_ir_node *n = new_node0(IR_JUMP);
    if (n)
-      n->Target = (char *) target;
+      n->Label = dest;
    return n;
 }
 
@@ -599,6 +601,18 @@ slang_is_asm_function(const slang_functi
 }
 
 
+static GLboolean
+_slang_is_noop(const slang_operation *oper)
+{
+   if (!oper ||
+       oper->type == SLANG_OPER_VOID ||
+       (oper->num_children == 1 && oper->children[0].type == SLANG_OPER_VOID))
+      return GL_TRUE;
+   else
+      return GL_FALSE;
+}
+
+
 /**
  * Produce inline code for a call to an assembly instruction.
  */
@@ -709,11 +723,11 @@ slang_substitute(slang_assemble_ctx *A, 
 	 }
       }
       break;
-#if 1 /* XXX rely on default case below */
+
    case SLANG_OPER_RETURN:
       /* do return replacement here too */
       assert(oper->num_children == 0 || oper->num_children == 1);
-      if (oper->num_children == 1) {
+      if (!_slang_is_noop(oper)) {
          /* replace:
           *   return expr;
           * with:
@@ -751,7 +765,7 @@ slang_substitute(slang_assemble_ctx *A, 
          slang_operation_destruct(blockOper);
       }
       break;
-#endif
+
    case SLANG_OPER_ASSIGN:
    case SLANG_OPER_SUBSCRIPT:
       /* special case:
@@ -992,8 +1006,7 @@ slang_inline_function_call(slang_assembl
                                                     &inlined->children,
                                                     inlined->num_children);
       lab->type = SLANG_OPER_LABEL;
-      lab->a_id = slang_atom_pool_atom(A->atoms,
-                                       (char *) A->CurFunction->end_label);
+      lab->label = A->CurFunction->end_label;
    }
 
    for (i = 0; i < totalArgs; i++) {
@@ -1044,7 +1057,7 @@ _slang_gen_function_call(slang_assemble_
    if (!A->CurFunction->end_label) {
       char name[200];
       sprintf(name, "__endOfFunc_%s_", (char *) A->CurFunction->header.a_name);
-      A->CurFunction->end_label = slang_atom_pool_gen(A->atoms, name);
+      A->CurFunction->end_label = _slang_label_new(name);
    }
 
    if (slang_is_asm_function(fun) && !dest) {
@@ -1075,7 +1088,7 @@ _slang_gen_function_call(slang_assemble_
 
    n = _slang_gen_operation(A, oper);
 
-   A->CurFunction->end_label = NULL;
+   A->CurFunction->end_label = NULL; /* XXX delete/free? */
 
    A->CurFunction = prevFunc;
 
@@ -1198,19 +1211,6 @@ _slang_gen_asm(slang_assemble_ctx *A, sl
 }
 
 
-
-static GLboolean
-_slang_is_noop(const slang_operation *oper)
-{
-   if (!oper ||
-       oper->type == SLANG_OPER_VOID ||
-       (oper->num_children == 1 && oper->children[0].type == SLANG_OPER_VOID))
-      return GL_TRUE;
-   else
-      return GL_FALSE;
-}
-
-
 static void
 print_funcs(struct slang_function_scope_ *scope, const char *name)
 {
@@ -1617,8 +1617,7 @@ _slang_gen_var_decl(slang_assemble_ctx *
 static slang_ir_node *
 _slang_gen_select(slang_assemble_ctx *A, slang_operation *oper)
 {
-   slang_atom altAtom = slang_atom_pool_gen(A->atoms, "__selectAlt");
-   slang_atom endAtom = slang_atom_pool_gen(A->atoms, "__selectEnd");
+   slang_label *altLabel, *endLabel;
    slang_ir_node *altLab, *endLab;
    slang_ir_node *tree, *tmpDecl, *tmpVar, *cond, *cjump, *jump;
    slang_ir_node *bodx, *body, *assignx, *assigny;
@@ -1628,6 +1627,9 @@ _slang_gen_select(slang_assemble_ctx *A,
    assert(oper->type == SLANG_OPER_SELECT);
    assert(oper->num_children == 3);
 
+   altLabel = _slang_label_new("selectAlt");
+   endLabel = _slang_label_new("selectEnd");
+
    /* size of x or y's type */
    slang_typeinfo_construct(&type);
    _slang_typeof_operation(A, &oper->children[1], &type);
@@ -1643,7 +1645,7 @@ _slang_gen_select(slang_assemble_ctx *A,
    tree = new_seq(tmpDecl, cond);
 
    /* jump if false to "alt" label */
-   cjump = new_cjump(altAtom, 0);
+   cjump = new_cjump(altLabel, 0);
    tree = new_seq(tree, cjump);
 
    /* evaluate child 1 (x) and assign to tmp */
@@ -1654,11 +1656,11 @@ _slang_gen_select(slang_assemble_ctx *A,
    tree = new_seq(tree, assigny);
 
    /* jump to "end" label */
-   jump = new_jump(endAtom);
+   jump = new_jump(endLabel);
    tree = new_seq(tree, jump);
 
    /* "alt" label */
-   altLab = new_label(altAtom);
+   altLab = new_label(altLabel);
    tree = new_seq(tree, altLab);
 
    /* evaluate child 2 (y) and assign to tmp */
@@ -1669,7 +1671,7 @@ _slang_gen_select(slang_assemble_ctx *A,
    tree = new_seq(tree, assignx);
 
    /* "end" label */
-   endLab = new_label(endAtom);
+   endLab = new_label(endLabel);
    tree = new_seq(tree, endLab);
    
    /* tmp var value */
@@ -1762,8 +1764,8 @@ _slang_gen_return(slang_assemble_ctx * A
       slang_operation_construct(&gotoOp);
       gotoOp.type = SLANG_OPER_GOTO;
       /* XXX don't call function? */
-      gotoOp.a_id = slang_atom_pool_atom(A->atoms,
-                                         (char *) A->CurFunction->end_label);
+      gotoOp.label = A->CurFunction->end_label;
+
       /* assemble the new code */
       n = _slang_gen_operation(A, &gotoOp);
       /* destroy temp code */
@@ -1819,8 +1821,7 @@ _slang_gen_return(slang_assemble_ctx * A
       jump->type = SLANG_OPER_GOTO;
       assert(A->CurFunction->end_label);
       /* XXX don't call function? */
-      jump->a_id = slang_atom_pool_atom(A->atoms,
-                                        (char *) A->CurFunction->end_label);
+      jump->label = A->CurFunction->end_label;
 
 #if 0 /* debug */
       printf("NEW RETURN:\n");
@@ -2439,9 +2440,9 @@ _slang_gen_operation(slang_assemble_ctx 
    case SLANG_OPER_RETURN:
       return _slang_gen_return(A, oper);
    case SLANG_OPER_GOTO:
-      return new_jump((char*) oper->a_id);
+      return new_jump(oper->label);
    case SLANG_OPER_LABEL:
-      return new_label((char*) oper->a_id);
+      return new_label(oper->label);
    case SLANG_OPER_IDENTIFIER:
       return _slang_gen_variable(A, oper);
    case SLANG_OPER_IF:
@@ -2716,7 +2717,7 @@ _slang_codegen_function(slang_assemble_c
 
    /* Create an end-of-function label */
    if (!A->CurFunction->end_label)
-      A->CurFunction->end_label = slang_atom_pool_gen(A->atoms, "__endOfFunc_main_");
+      A->CurFunction->end_label = _slang_label_new("__endOfFunc__main");
 
    /* push new vartable scope */
    _slang_push_var_table(A->vartable);
diff --git a/src/mesa/shader/slang/slang_compile_function.h b/src/mesa/shader/slang/slang_compile_function.h
index b60b4a2..09fbfd9 100644
--- a/src/mesa/shader/slang/slang_compile_function.h
+++ b/src/mesa/shader/slang/slang_compile_function.h
@@ -25,9 +25,6 @@
 #ifndef SLANG_COMPILE_FUNCTION_H
 #define SLANG_COMPILE_FUNCTION_H
 
-#if defined __cplusplus
-extern "C" {
-#endif
 
 struct slang_code_unit_;
 
@@ -69,7 +66,11 @@ typedef struct slang_function_
    slang_operation *body;      /**< The instruction tree */
    unsigned int address;       /**< Address of this func in memory */
    slang_fixup_table fixups;   /**< Mem locations which need func's address */
+#if 0
    slang_atom end_label;       /**< The end-of-function label */
+#else
+   struct slang_label_ *end_label;
+#endif
 } slang_function;
 
 extern int slang_function_construct(slang_function *);
@@ -102,8 +103,4 @@ slang_function_scope_find_by_name(slang_
 extern slang_function *
 slang_function_scope_find(slang_function_scope *, slang_function *, int);
 
-#ifdef __cplusplus
-}
-#endif
-
 #endif /* SLANG_COMPILE_FUNCTION_H */
diff --git a/src/mesa/shader/slang/slang_compile_operation.h b/src/mesa/shader/slang/slang_compile_operation.h
index a59f968..4adcd2a 100644
--- a/src/mesa/shader/slang/slang_compile_operation.h
+++ b/src/mesa/shader/slang/slang_compile_operation.h
@@ -25,10 +25,6 @@
 #ifndef SLANG_COMPILE_OPERATION_H
 #define SLANG_COMPILE_OPERATION_H
 
-#if defined __cplusplus
-extern "C" {
-#endif
-
 
 /**
  * Types of slang operations.
@@ -122,6 +118,7 @@ typedef struct slang_operation_
    slang_variable_scope *locals; /**< local vars for scope */
    struct slang_function_ *fun;  /**< If type == SLANG_OPER_CALL */
    struct slang_variable_ *var;  /**< If type == slang_oper_identier */
+   struct slang_label_ *label;   /**< If type == SLANG_OPER_LABEL or GOTO */
 } slang_operation;
 
 
@@ -148,8 +145,4 @@ slang_operation_insert(GLuint *numChildr
                        GLuint pos);
 
 
-#ifdef __cplusplus
-}
-#endif
-
 #endif /* SLANG_COMPILE_OPERATION_H */
diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c
index 76b0375..6b950de 100644
--- a/src/mesa/shader/slang/slang_emit.c
+++ b/src/mesa/shader/slang/slang_emit.c
@@ -278,7 +278,7 @@ slang_print_ir(const slang_ir_node *n, i
       slang_print_ir(n->Children[1], indent+3);
       break;
    case IR_LABEL:
-      printf("LABEL: %s\n", n->Target);
+      printf("LABEL: %s\n", n->Label->Name);
       break;
    case IR_COND:
       printf("COND\n");
@@ -848,38 +848,44 @@ emit_negation(slang_var_table *vt, slang
 
 
 static struct prog_instruction *
-emit_label(const char *target, struct gl_program *prog)
+emit_label(const slang_ir_node *n, struct gl_program *prog)
 {
-   struct prog_instruction *inst;
-   inst = new_instruction(prog, OPCODE_NOP);
-   inst->Comment = _mesa_strdup(target);
-   return inst;
+   assert(n->Label);
+   assert(_slang_label_get_location(n->Label) < 0);
+   _slang_label_set_location(n->Label, prog->NumInstructions, prog);
+   return NULL;
 }
 
 
 static struct prog_instruction *
-emit_cjump(const char *target, struct gl_program *prog, GLuint zeroOrOne)
+emit_cjump(slang_ir_node *n, struct gl_program *prog, GLuint zeroOrOne)
 {
    struct prog_instruction *inst;
+   assert(n->Opcode == IR_CJUMP0 || n->Opcode == IR_CJUMP1);
    inst = new_instruction(prog, OPCODE_BRA);
    if (zeroOrOne)
       inst->DstReg.CondMask = COND_NE;  /* branch if non-zero */
    else
       inst->DstReg.CondMask = COND_EQ;  /* branch if equal to zero */
    inst->DstReg.CondSwizzle = SWIZZLE_X;
-   inst->Comment = _mesa_strdup(target);
+   inst->BranchTarget = _slang_label_get_location(n->Label);
+   if (inst->BranchTarget < 0) {
+      _slang_label_add_reference(n->Label, prog->NumInstructions - 1);
+   }
    return inst;
 }
 
 
 static struct prog_instruction *
-emit_jump(const char *target, struct gl_program *prog)
+emit_jump(slang_ir_node *n, struct gl_program *prog)
 {
    struct prog_instruction *inst;
    inst = new_instruction(prog, OPCODE_BRA);
    inst->DstReg.CondMask = COND_TR;  /* always branch */
-   /*inst->DstReg.CondSwizzle = SWIZZLE_X;*/
-   inst->Comment = _mesa_strdup(target);
+   inst->BranchTarget = _slang_label_get_location(n->Label);
+   if (inst->BranchTarget < 0) {
+      _slang_label_add_reference(n->Label, prog->NumInstructions - 1);
+   }
    return inst;
 }
 
@@ -1522,13 +1528,13 @@ emit(slang_var_table *vt, slang_ir_node 
       return emit_not(vt, n, prog);
 
    case IR_LABEL:
-      return emit_label(n->Target, prog);
+      return emit_label(n, prog);
    case IR_JUMP:
-      return emit_jump(n->Target, prog);
+      return emit_jump(n, prog);
    case IR_CJUMP0:
-      return emit_cjump(n->Target, prog, 0);
+      return emit_cjump(n, prog, 0);
    case IR_CJUMP1:
-      return emit_cjump(n->Target, prog, 1);
+      return emit_cjump(n, prog, 1);
    case IR_KILL:
       return emit_kill(prog);
 
@@ -1572,18 +1578,14 @@ _slang_emit_code(slang_ir_node *n, slang
 {
    GLboolean success;
 
-   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);
-      }
-      success = GL_TRUE;
-   }
-   else {
-      /* record an error? */
-      success = GL_FALSE;
+   (void) 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);
    }
+   success = GL_TRUE;
 
    printf("*********** End generate code (%u inst):\n", prog->NumInstructions);
 #if 0
diff --git a/src/mesa/shader/slang/slang_ir.h b/src/mesa/shader/slang/slang_ir.h
index 0c827d9..ba8b613 100644
--- a/src/mesa/shader/slang/slang_ir.h
+++ b/src/mesa/shader/slang/slang_ir.h
@@ -35,6 +35,7 @@
 
 #include "imports.h"
 #include "slang_compile.h"
+#include "slang_label.h"
 #include "mtypes.h"
 
 
@@ -153,7 +154,8 @@ typedef struct slang_ir_node_
    slang_variable *Var;  /**< If Opcode == IR_VAR or IR_VAR_DECL */
    slang_ir_storage *Store;  /**< location of result of this operation */
    GLint InstLocation;  /**< Location of instruction emitted for this node */
-   struct slang_ir_node_ *BranchNode;  /**< Used for branch instructions */
+   struct slang_ir_node_ *BranchNode;  /**< Used for branching instructions */
+   slang_label *Label;  /**< Used for branches */
 } slang_ir_node;
 
 
diff --git a/src/mesa/shader/slang/slang_link.c b/src/mesa/shader/slang/slang_link.c
index 23977b7..e2bb6ee 100644
--- a/src/mesa/shader/slang/slang_link.c
+++ b/src/mesa/shader/slang/slang_link.c
@@ -274,46 +274,6 @@ link_uniform_vars(struct gl_shader_progr
 
 
 /**
- * XXX Temporary
- */
-static void
-_slang_resolve_branches(struct gl_program *prog)
-{
-   struct target {
-      const char *Name;
-      GLuint Pos;
-   };
-   struct target targets[500];
-   GLuint numTargets = 0;
-   GLuint i, j;
-
-   for (i = 0; i < prog->NumInstructions; i++) {
-      struct prog_instruction *inst = prog->Instructions + i;
-      if (inst->Opcode == OPCODE_NOP && inst->Comment) {
-         targets[numTargets].Name = inst->Comment;
-         targets[numTargets].Pos = i;
-         numTargets++;
-      }
-   }
-
-   for (i = 0; i < prog->NumInstructions; i++) {
-      struct prog_instruction *inst = prog->Instructions + i;
-      if (inst->Opcode == OPCODE_BRA && inst->BranchTarget < 0) {
-         for (j = 0; j < numTargets; j++) {
-            if (!strcmp(inst->Comment, targets[j].Name)) {
-               inst->BranchTarget = targets[j].Pos;
-               break;
-            }
-         }
-         if (j == numTargets) {
-            abort();
-         }
-      }
-   }
-}
-
-
-/**
  * Resolve binding of generic vertex attributes.
  * For example, if the vertex shader declared "attribute vec4 foobar" we'll
  * allocate a generic vertex attribute for "foobar" and plug that value into
@@ -574,11 +534,9 @@ _slang_link(GLcontext *ctx,
    }
 
    if (shProg->VertexProgram) {
-      _slang_resolve_branches(&shProg->VertexProgram->Base);
       _slang_resolve_samplers(shProg, &shProg->VertexProgram->Base);
    }
    if (shProg->FragmentProgram) {
-      _slang_resolve_branches(&shProg->FragmentProgram->Base);
       _slang_resolve_samplers(shProg, &shProg->FragmentProgram->Base);
    }
 
diff-tree d8d07b2a8aa5cf9c5ce877b20351983b1aa8d01d (from 0cc941963197fcdf8913462dbb225bc2bfca9d85)
Author: Brian <brian at yutani.localnet.net>
Date:   Fri Feb 23 09:36:29 2007 -0700

    label routines for implementing branches, jumps

diff --git a/src/mesa/shader/slang/slang_label.c b/src/mesa/shader/slang/slang_label.c
new file mode 100644
index 0000000..4d35d2e
--- /dev/null
+++ b/src/mesa/shader/slang/slang_label.c
@@ -0,0 +1,77 @@
+
+
+/**
+ * Functions for managing instruction labels.
+ * Basically, this is used to manage the problem of forward branches where
+ * we have a branch instruciton but don't know the target address yet.
+ */
+
+
+#include "slang_label.h"
+
+
+slang_label *
+_slang_label_new(const char *name)
+{
+   slang_label *l = (slang_label *) _mesa_calloc(sizeof(slang_label));
+   if (l) {
+      l->Name = _mesa_strdup(name);
+      l->Location = -1;
+   }
+   return l;
+}
+
+void
+_slang_label_delete(slang_label *l)
+{
+   if (l->Name)
+      _mesa_free(l->Name);
+   if (l->References)
+      _mesa_free(l->References);
+   _mesa_free(l);
+}
+
+
+void
+_slang_label_add_reference(slang_label *l, GLuint inst)
+{
+   const GLuint oldSize = l->NumReferences * sizeof(GLuint);
+   assert(l->Location < 0);
+   l->References = _mesa_realloc(l->References,
+                                 oldSize, oldSize + sizeof(GLuint));
+   if (l->References) {
+      l->References[l->NumReferences] = inst;
+      l->NumReferences++;
+   }
+}
+
+
+GLint
+_slang_label_get_location(const slang_label *l)
+{
+   return l->Location;
+}
+
+
+void
+_slang_label_set_location(slang_label *l, GLint location,
+                          struct gl_program *prog)
+{
+   GLuint i;
+
+   assert(l->Location < 0);
+   assert(location >= 0);
+
+   l->Location = location;
+
+   /* for the instructions that were waiting to learn the label's location: */
+   for (i = 0; i < l->NumReferences; i++) {
+      const GLuint j = l->References[i];
+      prog->Instructions[j].BranchTarget = location;
+   }
+
+   if (l->References) {
+      _mesa_free(l->References);
+      l->References = NULL;
+   }
+}
diff --git a/src/mesa/shader/slang/slang_label.h b/src/mesa/shader/slang/slang_label.h
new file mode 100644
index 0000000..661624f
--- /dev/null
+++ b/src/mesa/shader/slang/slang_label.h
@@ -0,0 +1,42 @@
+#ifndef SLANG_LABEL_H
+#define SLANG_LABEL_H 1
+
+#include "imports.h"
+#include "mtypes.h"
+#include "prog_instruction.h"
+
+
+struct slang_label_
+{
+   char *Name;
+   GLint Location;
+   /**
+    * List of instruction references (numbered starting at zero) which need
+    * their BranchTarget field filled in with the location eventually
+    * assigned to the label.
+    */
+   GLuint NumReferences;
+   GLuint *References;   /** Array [NumReferences] */
+};
+
+typedef struct slang_label_ slang_label;
+
+
+extern slang_label *
+_slang_label_new(const char *name);
+
+extern void
+_slang_label_delete(slang_label *l);
+
+extern void
+_slang_label_add_reference(slang_label *l, GLuint inst);
+
+extern GLint
+_slang_label_get_location(const slang_label *l);
+
+extern void
+_slang_label_set_location(slang_label *l, GLint location,
+                          struct gl_program *prog);
+
+
+#endif /* SLANG_LABEL_H */
diff-tree 0cc941963197fcdf8913462dbb225bc2bfca9d85 (from 059376c855cbeb160e98f438a35edb8bd88b8bb2)
Author: Brian <brian at yutani.localnet.net>
Date:   Thu Feb 22 17:46:20 2007 -0700

    debug code for emitting variable allocation comments

diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c
index 8ea5441..76b0375 100644
--- a/src/mesa/shader/slang/slang_emit.c
+++ b/src/mesa/shader/slang/slang_emit.c
@@ -1410,7 +1410,22 @@ emit(slang_var_table *vt, slang_ir_node 
          */
          assert(n->Var->aux == n->Store);
       }
-      break;
+#ifdef DEBUG_foo
+      /* emit NOP with comment describing the variable's storage location */
+      {
+         char s[1000];
+         sprintf(s, "TEMP[%d]%s = %s (size %d)",
+                 n->Store->Index,
+                 _mesa_swizzle_string(n->Store->Swizzle, 0, GL_FALSE), 
+                 (char *) n->Var->a_name,
+                 n->Store->Size);
+         inst = new_instruction(prog, OPCODE_NOP);
+         inst->Comment = _mesa_strdup(s);
+         return inst;
+      }
+#else
+      return NULL;
+#endif
 
    case IR_VAR:
       /* Reference to a variable
diff-tree 059376c855cbeb160e98f438a35edb8bd88b8bb2 (from ff0cc92757b59c9343e4fda4d20c32fbfc7586c1)
Author: Brian <brian at yutani.localnet.net>
Date:   Thu Feb 22 17:45:32 2007 -0700

    expose _mesa_swizzle_string()

diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c
index 95b62fc..0d21912 100644
--- a/src/mesa/shader/prog_print.c
+++ b/src/mesa/shader/prog_print.c
@@ -291,8 +291,8 @@ reg_string(enum register_file f, GLint i
  * \param negateBase  4-bit negation vector
  * \param extended  if true, also allow 0, 1 values
  */
-static const char *
-swizzle_string(GLuint swizzle, GLuint negateBase, GLboolean extended)
+const char *
+_mesa_swizzle_string(GLuint swizzle, GLuint negateBase, GLboolean extended)
 {
    static const char swz[] = "xyzw01?!";
    static char s[20];
@@ -403,13 +403,13 @@ print_src_reg(const struct prog_src_regi
    _mesa_printf("%s%s",
                 reg_string((enum register_file) srcReg->File,
                            srcReg->Index, mode, prog),
-                swizzle_string(srcReg->Swizzle,
+                _mesa_swizzle_string(srcReg->Swizzle,
                                srcReg->NegateBase, GL_FALSE));
 #if 0
    _mesa_printf("%s[%d]%s",
                 file_string((enum register_file) srcReg->File, mode),
                 srcReg->Index,
-                swizzle_string(srcReg->Swizzle,
+                _mesa_swizzle_string(srcReg->Swizzle,
                                srcReg->NegateBase, GL_FALSE));
 #endif
 }
@@ -498,8 +498,8 @@ _mesa_print_instruction_opt(const struct
                       file_string((enum register_file) inst->SrcReg[0].File,
                                   mode),
                       inst->SrcReg[0].Index,
-                      swizzle_string(inst->SrcReg[0].Swizzle,
-                                     inst->SrcReg[0].NegateBase, GL_FALSE));
+                      _mesa_swizzle_string(inst->SrcReg[0].Swizzle,
+                                           inst->SrcReg[0].NegateBase, GL_FALSE));
       }
       if (inst->Comment)
          _mesa_printf("  # %s", inst->Comment);
@@ -515,8 +515,8 @@ _mesa_print_instruction_opt(const struct
                    file_string((enum register_file) inst->SrcReg[0].File,
                                mode),
                    inst->SrcReg[0].Index,
-                   swizzle_string(inst->SrcReg[0].Swizzle,
-                                  inst->SrcReg[0].NegateBase, GL_TRUE));
+                   _mesa_swizzle_string(inst->SrcReg[0].Swizzle,
+                                        inst->SrcReg[0].NegateBase, GL_TRUE));
       print_comment(inst);
       break;
    case OPCODE_TEX:
@@ -550,7 +550,7 @@ _mesa_print_instruction_opt(const struct
       _mesa_printf("BRA %u (%s%s)",
                    inst->BranchTarget,
                    condcode_string(inst->DstReg.CondMask),
-                   swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE));
+                   _mesa_swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE));
       print_comment(inst);
       break;
    case OPCODE_CAL:
@@ -560,7 +560,7 @@ _mesa_print_instruction_opt(const struct
    case OPCODE_IF:
       _mesa_printf("IF (%s%s); # (if false, goto %d)",
                    condcode_string(inst->DstReg.CondMask),
-                   swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE),
+                   _mesa_swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE),
                    inst->BranchTarget);
       print_comment(inst);
       return indent + 3;
@@ -579,14 +579,14 @@ _mesa_print_instruction_opt(const struct
    case OPCODE_BRK:
       _mesa_printf("BRK (%s%s); #(goto %d)",
                    condcode_string(inst->DstReg.CondMask),
-                   swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE),
+                   _mesa_swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE),
                    inst->BranchTarget);
       print_comment(inst);
       break;
    case OPCODE_CONT:
       _mesa_printf("CONT (%s%s); #(goto %d)",
                    condcode_string(inst->DstReg.CondMask),
-                   swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE),
+                   _mesa_swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE),
                    inst->BranchTarget);
       print_comment(inst);
       break;
@@ -602,8 +602,14 @@ _mesa_print_instruction_opt(const struct
       _mesa_printf("END\n");
       break;
    case OPCODE_NOP:
-      _mesa_printf("NOP");
-      print_comment(inst);
+      if (mode == PROG_PRINT_DEBUG) {
+         _mesa_printf("NOP");
+         print_comment(inst);
+      }
+      else if (inst->Comment) {
+         /* ARB/NV extensions don't have NOP instruction */
+         _mesa_printf("# %s\n", inst->Comment);
+      }
       break;
    /* XXX may need other special-case instructions */
    default:
diff --git a/src/mesa/shader/prog_print.h b/src/mesa/shader/prog_print.h
index 79c599f..c0101b6 100644
--- a/src/mesa/shader/prog_print.h
+++ b/src/mesa/shader/prog_print.h
@@ -37,6 +37,9 @@ typedef enum {
 } gl_prog_print_mode;
 
 
+extern const char *
+_mesa_swizzle_string(GLuint swizzle, GLuint negateBase, GLboolean extended);
+
 extern void
 _mesa_print_instruction(const struct prog_instruction *inst);
 



More information about the mesa-commit mailing list