mesa: Branch 'master' - 7 commits

Brian Paul brianp at kemper.freedesktop.org
Tue Mar 27 00:47:23 UTC 2007


 src/mesa/shader/prog_print.c                    |    9 -
 src/mesa/shader/slang/slang_codegen.c           |  194 ++++++++++++++++--------
 src/mesa/shader/slang/slang_compile_operation.h |    4 
 src/mesa/shader/slang/slang_emit.c              |   93 ++++++++---
 src/mesa/shader/slang/slang_ir.c                |    4 
 src/mesa/shader/slang/slang_ir.h                |    4 
 src/mesa/shader/slang/slang_link.c              |    7 
 src/mesa/shader/slang/slang_print.c             |    7 
 src/mesa/shader/slang/slang_typeinfo.h          |    1 
 9 files changed, 220 insertions(+), 103 deletions(-)

New commits:
diff-tree ae36cfc65eac19281b5ad338e4095008dc69ab21 (from 9878e8ff516486900228429f26b37cb01cd7313f)
Author: Brian <brian at yutani.localnet.net>
Date:   Mon Mar 26 18:47:19 2007 -0600

    s/SUB/BGNSUB/

diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c
index 3ab0041..8fa7ef3 100644
--- a/src/mesa/shader/prog_print.c
+++ b/src/mesa/shader/prog_print.c
@@ -629,7 +629,7 @@ _mesa_print_instruction_opt(const struct
       break;
 
    case OPCODE_BGNSUB:
-      _mesa_printf("SUB");
+      _mesa_printf("BGNSUB");
       print_comment(inst);
       return indent + 3;
    case OPCODE_ENDSUB:
diff-tree 9878e8ff516486900228429f26b37cb01cd7313f (from 6583429f89df1b6838c5405bd32e5ef30bdf163f)
Author: Brian <brian at yutani.localnet.net>
Date:   Mon Mar 26 18:46:07 2007 -0600

    Checkpoint: implementing true CAL/RET instructions for subroutine calls.
    
    Also, found/fixed a code generation regression:  the emit_swizzle() function
    was always returning NULL.  This caused emit_move() to miss its chance at peephole
    optimization.

diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c
index 0ca5054..93b6d9f 100644
--- a/src/mesa/shader/slang/slang_codegen.c
+++ b/src/mesa/shader/slang/slang_codegen.c
@@ -468,6 +468,21 @@ new_float_literal(const float v[4], GLui
    return n;
 }
 
+
+/**
+ * Inlined subroutine.
+ */
+static slang_ir_node *
+new_inlined_function_call(slang_ir_node *code, slang_label *name)
+{
+   slang_ir_node *n = new_node1(IR_FUNC, code);
+   assert(name);
+   if (n)
+      n->Label = name;
+   return n;
+}
+
+
 /**
  * Unconditional jump.
  */
@@ -1092,8 +1107,18 @@ _slang_gen_function_call(slang_assemble_
    else {
       /* non-assembly function */
       inlined = slang_inline_function_call(A, fun, oper, dest);
+      if (inlined) {
+         assert(inlined->type == SLANG_OPER_BLOCK_NEW_SCOPE ||
+                inlined->type == SLANG_OPER_SEQUENCE);
+         inlined->type = SLANG_OPER_INLINED_CALL;
+         inlined->fun = fun;
+         inlined->label = _slang_label_new((char*) fun->header.a_name);
+      }
    }
 
+   if (!inlined)
+      return NULL;
+
    /* Replace the function call with the inlined block */
    slang_operation_destruct(oper);
    *oper = *inlined;
@@ -2581,6 +2606,7 @@ _slang_gen_operation(slang_assemble_ctx 
 	 return n;
       }
 
+   case SLANG_OPER_INLINED_CALL:
    case SLANG_OPER_SEQUENCE:
       {
          slang_ir_node *tree = NULL;
@@ -2589,6 +2615,9 @@ _slang_gen_operation(slang_assemble_ctx 
             slang_ir_node *n = _slang_gen_operation(A, &oper->children[i]);
             tree = tree ? new_seq(tree, n) : n;
          }
+         if (oper->type == SLANG_OPER_INLINED_CALL) {
+            tree = new_inlined_function_call(tree, oper->label);
+         }
          return tree;
       }
 
diff --git a/src/mesa/shader/slang/slang_compile_operation.h b/src/mesa/shader/slang/slang_compile_operation.h
index b63db04..d497b6f 100644
--- a/src/mesa/shader/slang/slang_compile_operation.h
+++ b/src/mesa/shader/slang/slang_compile_operation.h
@@ -93,6 +93,7 @@ typedef enum slang_operation_type_
    SLANG_OPER_NOT,              /* "!" [expr] */
    SLANG_OPER_SUBSCRIPT,        /* [expr] "[" [expr] "]" */
    SLANG_OPER_CALL,             /* [func name] [param] [param] [...] */
+   SLANG_OPER_INLINED_CALL,     /* inlined function call */
    SLANG_OPER_FIELD,            /* i.e.: ".next" or ".xzy" or ".xxx" etc */
    SLANG_OPER_POSTINCREMENT,    /* [var] "++" */
    SLANG_OPER_POSTDECREMENT     /* [var] "--" */
diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c
index e747a6e..21b73c2 100644
--- a/src/mesa/shader/slang/slang_emit.c
+++ b/src/mesa/shader/slang/slang_emit.c
@@ -62,6 +62,7 @@ typedef struct
    /* code-gen options */
    GLboolean EmitHighLevelInstructions;
    GLboolean EmitCondCodes;
+   GLboolean EmitBeginEndSub;
    GLboolean EmitComments;
 } slang_emit_info;
 
@@ -203,6 +204,13 @@ new_instruction(slang_emit_info *emitInf
 {
    struct gl_program *prog = emitInfo->prog;
    struct prog_instruction *inst;
+
+#if 0
+   /* print prev inst */
+   if (prog->NumInstructions > 0) {
+      _mesa_print_instruction(prog->Instructions + prog->NumInstructions - 1);
+   }
+#endif
    prog->Instructions = _mesa_realloc_instructions(prog->Instructions,
                                                    prog->NumInstructions,
                                                    prog->NumInstructions + 1);
@@ -710,6 +718,28 @@ emit_label(slang_emit_info *emitInfo, co
 }
 
 
+/**
+ * Emit code for an inlined function call.
+ */
+static struct prog_instruction *
+emit_func(slang_emit_info *emitInfo, slang_ir_node *n)
+{
+   struct prog_instruction *inst;
+   assert(n->Label);
+   if (emitInfo->EmitBeginEndSub) {
+      inst = new_instruction(emitInfo, OPCODE_BGNSUB);
+      inst->Comment = _mesa_strdup(n->Label->Name);
+   }
+   inst = emit(emitInfo, n->Children[0]);
+   if (emitInfo->EmitBeginEndSub) {
+      inst = new_instruction(emitInfo, OPCODE_ENDSUB);
+      inst->Comment = _mesa_strdup(n->Label->Name);
+   }
+   n->Store = n->Children[0]->Store;
+   return inst;
+}
+
+
 static struct prog_instruction *
 emit_return(slang_emit_info *emitInfo, slang_ir_node *n)
 {
@@ -803,14 +833,20 @@ emit_move(slang_emit_info *emitInfo, sla
    n->Store = n->Children[0]->Store;
 
 #if PEEPHOLE_OPTIMIZATIONS
-   if (inst && _slang_is_temp(emitInfo->vt, n->Children[1]->Store)) {
+   if (inst &&
+       _slang_is_temp(emitInfo->vt, n->Children[1]->Store) &&
+       (inst->DstReg.File == n->Children[1]->Store->File) &&
+       (inst->DstReg.Index == 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.
+       * The Right-Hand-Side has its results in a temporary place.
+       * Modify the RHS (and the prev instruction) to store its results
+       * in the destination specified by n->Children[0].
+       * Then, this MOVE is a no-op.
        */
-      _slang_free_temp(emitInfo->vt, n->Children[1]->Store);
+      if (n->Children[1]->Opcode != IR_SWIZZLE)
+         _slang_free_temp(emitInfo->vt, n->Children[1]->Store);
       *n->Children[1]->Store = *n->Children[0]->Store;
-      /* fixup the prev (RHS) instruction */
+      /* fixup the previous instruction (which stored the RHS result) */
       assert(n->Children[0]->Store->Index >= 0);
       storage_to_dst_reg(&inst->DstReg, n->Children[0]->Store, n->Writemask);
       return inst;
@@ -870,11 +906,17 @@ emit_cond(slang_emit_info *emitInfo, sla
        * Need to update condition code register.
        * Next instruction is typically an IR_IF.
        */
-      if (inst) {
-         /* set inst's CondUpdate flag */
+      if (inst &&
+          n->Children[0]->Store &&
+          inst->DstReg.File == n->Children[0]->Store->File &&
+          inst->DstReg.Index == n->Children[0]->Store->Index) {
+         /* The previous instruction wrote to the register who's value
+          * we're testing.  Just update that instruction so that the
+          * condition codes are updated.
+          */
          inst->CondUpdate = GL_TRUE;
          n->Store = n->Children[0]->Store;
-         return inst; /* XXX or null? */
+         return inst;
       }
       else {
          /* This'll happen for things like "if (i) ..." where no code
@@ -1227,8 +1269,9 @@ static struct prog_instruction *
 emit_swizzle(slang_emit_info *emitInfo, slang_ir_node *n)
 {
    GLuint swizzle;
+   struct prog_instruction *inst;
 
-   (void) emit(emitInfo, n->Children[0]);
+   inst = emit(emitInfo, n->Children[0]);
 
 #ifdef DEBUG
    {
@@ -1246,10 +1289,10 @@ emit_swizzle(slang_emit_info *emitInfo, 
    n->Store->Index = n->Children[0]->Store->Index;
    n->Store->Size = swizzle_size(n->Store->Swizzle);
 #if 0
-   printf("Emit Swizzle reg %d  chSize %d  size %d  swz %s\n",
+   printf("Emit Swizzle %s  reg %d  chSize %d  mySize %d\n",
+          _mesa_swizzle_string(n->Store->Swizzle, 0, 0),
           n->Store->Index, n->Children[0]->Store->Size,
-          n->Store->Size,
-          _mesa_swizzle_string(n->Store->Swizzle, 0, 0));
+          n->Store->Size);
 #endif
 
    /* apply this swizzle to child's swizzle to get composed swizzle */
@@ -1257,7 +1300,7 @@ emit_swizzle(slang_emit_info *emitInfo, 
    n->Store->Swizzle = swizzle_swizzle(n->Children[0]->Store->Swizzle,
                                        swizzle);
 
-   return NULL;
+   return inst;
 }
 
 
@@ -1505,6 +1548,9 @@ emit(slang_emit_info *emitInfo, slang_ir
    case IR_KILL:
       return emit_kill(emitInfo);
 
+   case IR_FUNC:
+      return emit_func(emitInfo, n);
+
    case IR_IF:
       return emit_if(emitInfo, n);
 
@@ -1553,6 +1599,7 @@ _slang_emit_code(slang_ir_node *n, slang
 
    emitInfo.EmitHighLevelInstructions = ctx->Shader.EmitHighLevelInstructions;
    emitInfo.EmitCondCodes = ctx->Shader.EmitCondCodes;
+   emitInfo.EmitBeginEndSub = 0;  /* XXX temporary */
    emitInfo.EmitComments = ctx->Shader.EmitComments;
 
    (void) emit(&emitInfo, n);
diff --git a/src/mesa/shader/slang/slang_ir.h b/src/mesa/shader/slang/slang_ir.h
index a617a7e..a9a530a 100644
--- a/src/mesa/shader/slang/slang_ir.h
+++ b/src/mesa/shader/slang/slang_ir.h
@@ -62,6 +62,8 @@ typedef enum
    IR_RETURN,    /* return from subroutine */
    IR_CALL,      /* call subroutine */
 
+   IR_FUNC,      /* inlined function code */
+
    IR_LOOP,      /* high-level loop-begin / loop-end */
                  /* Children[0] = loop body */
                  /* Children[1] = loop tail code, or NULL */
diff-tree 6583429f89df1b6838c5405bd32e5ef30bdf163f (from 037c06846041877fb03890864520daa33b5fa4a9)
Author: Brian <brian at yutani.localnet.net>
Date:   Mon Mar 26 17:16:26 2007 -0600

    Get rid of IR_JUMP and related code.

diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c
index 92bfb54..e747a6e 100644
--- a/src/mesa/shader/slang/slang_emit.c
+++ b/src/mesa/shader/slang/slang_emit.c
@@ -711,22 +711,6 @@ emit_label(slang_emit_info *emitInfo, co
 
 
 static struct prog_instruction *
-emit_jump(slang_emit_info *emitInfo, slang_ir_node *n)
-{
-   struct prog_instruction *inst;
-   assert(n);
-   assert(n->Label);
-   inst = new_instruction(emitInfo, OPCODE_BRA);
-   inst->DstReg.CondMask = COND_TR;  /* always branch */
-   inst->BranchTarget = _slang_label_get_location(n->Label);
-   if (inst->BranchTarget < 0) {
-      _slang_label_add_reference(n->Label, emitInfo->prog->NumInstructions - 1);
-   }
-   return inst;
-}
-
-
-static struct prog_instruction *
 emit_return(slang_emit_info *emitInfo, slang_ir_node *n)
 {
    struct prog_instruction *inst;
@@ -1517,10 +1501,7 @@ emit(slang_emit_info *emitInfo, slang_ir
 
    case IR_LABEL:
       return emit_label(emitInfo, n);
-   case IR_JUMP:
-      assert(n);
-      assert(n->Label);
-      return emit_jump(emitInfo, n);
+
    case IR_KILL:
       return emit_kill(emitInfo);
 
diff --git a/src/mesa/shader/slang/slang_ir.c b/src/mesa/shader/slang/slang_ir.c
index 14a7b69..95b154d 100644
--- a/src/mesa/shader/slang/slang_ir.c
+++ b/src/mesa/shader/slang/slang_ir.c
@@ -74,7 +74,6 @@ static const slang_ir_info IrInfo[] = {
    { IR_SEQ, "IR_SEQ", OPCODE_NOP, 0, 0 },
    { IR_SCOPE, "IR_SCOPE", OPCODE_NOP, 0, 0 },
    { IR_LABEL, "IR_LABEL", OPCODE_NOP, 0, 0 },
-   { IR_JUMP, "IR_JUMP", OPCODE_NOP, 0, 0 },
    { IR_IF, "IR_IF", OPCODE_NOP, 0, 0 },
    { IR_KILL, "IR_KILL", OPCODE_NOP, 0, 0 },
    { IR_COND, "IR_COND", OPCODE_NOP, 0, 0 },
@@ -281,9 +280,6 @@ _slang_print_ir_tree(const slang_ir_node
       printf("COND\n");
       _slang_print_ir_tree(n->Children[0], indent + 3);
       break;
-   case IR_JUMP:
-      printf("JUMP %s\n", n->Label->Name);
-      break;
 
    case IR_IF:
       printf("IF \n");
diff --git a/src/mesa/shader/slang/slang_ir.h b/src/mesa/shader/slang/slang_ir.h
index 2e90409..a617a7e 100644
--- a/src/mesa/shader/slang/slang_ir.h
+++ b/src/mesa/shader/slang/slang_ir.h
@@ -49,7 +49,7 @@ typedef enum
    IR_SCOPE,   /* new variable scope (one child) */
 
    IR_LABEL,   /* target of a jump or cjump */
-   IR_JUMP,    /* unconditional jump */
+
    IR_COND,    /* conditional expression/predicate */
 
    IR_IF,      /* high-level IF/then/else */
diff-tree 037c06846041877fb03890864520daa33b5fa4a9 (from c042a91b8b202e4c0623e647bda035c715f7c308)
Author: Brian <brian at yutani.localnet.net>
Date:   Mon Mar 26 16:58:50 2007 -0600

    special case RET

diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c
index 3f7ad47..3ab0041 100644
--- a/src/mesa/shader/prog_print.c
+++ b/src/mesa/shader/prog_print.c
@@ -571,6 +571,13 @@ _mesa_print_instruction_opt(const struct
       _mesa_printf("CAL %u", inst->BranchTarget);
       print_comment(inst);
       break;
+   case OPCODE_RET:
+      _mesa_printf("RET (%s%s); # (goto %d)",
+                   condcode_string(inst->DstReg.CondMask),
+                   _mesa_swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE),
+                   inst->BranchTarget);
+      print_comment(inst);
+      break;
    case OPCODE_IF:
       if (inst->SrcReg[0].File != PROGRAM_UNDEFINED) {
          /* Use ordinary register */
diff-tree c042a91b8b202e4c0623e647bda035c715f7c308 (from 813a0e11f1eb903883aef18c5cb5c4702dcb6213)
Author: Brian <brian at yutani.localnet.net>
Date:   Mon Mar 26 16:56:45 2007 -0600

    Get rid of SLANG_OPER_GOTO, start rewrite of 'return' handling.

diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c
index c2a3377..0ca5054 100644
--- a/src/mesa/shader/slang/slang_codegen.c
+++ b/src/mesa/shader/slang/slang_codegen.c
@@ -472,9 +472,9 @@ new_float_literal(const float v[4], GLui
  * Unconditional jump.
  */
 static slang_ir_node *
-new_jump(slang_label *dest)
+new_return(slang_label *dest)
 {
-   slang_ir_node *n = new_node0(IR_JUMP);
+   slang_ir_node *n = new_node0(IR_RETURN);
    assert(dest);
    if (n)
       n->Label = dest;
@@ -607,6 +607,24 @@ _slang_is_noop(const slang_operation *op
 
 
 /**
+ * Recursively search tree for a node of the given type.
+ */
+static slang_operation *
+_slang_find_node_type(slang_operation *oper, slang_operation_type type)
+{
+   GLuint i;
+   if (oper->type == type)
+      return oper;
+   for (i = 0; i < oper->num_children; i++) {
+      slang_operation *p = _slang_find_node_type(&oper->children[i], type);
+      if (p)
+         return p;
+   }
+   return NULL;
+}
+
+
+/**
  * Produce inline code for a call to an assembly instruction.
  * XXX Note: children are passed as asm args in-order, not by name!
  */
@@ -749,7 +767,7 @@ slang_substitute(slang_assemble_ctx *A, 
          slang_operation_copy(&assignOper->children[1],
                               &oper->children[0]);
 
-         returnOper->type = SLANG_OPER_RETURN;
+         returnOper->type = SLANG_OPER_RETURN; /* return w/ no value */
          assert(returnOper->num_children == 0);
 
          /* do substitutions on the "__retVal = expr" sub-tree */
@@ -1744,22 +1762,7 @@ _slang_gen_return(slang_assemble_ctx * A
    }
 
    if (!haveReturnValue) {
-      /* Convert from:
-       *   return;
-       * To:
-       *   goto __endOfFunction;
-       */
-      slang_ir_node *n;
-      slang_operation gotoOp;
-      slang_operation_construct(&gotoOp);
-      gotoOp.type = SLANG_OPER_GOTO;
-      gotoOp.label = A->curFuncEndLabel;
-      assert(gotoOp.label);
-
-      n = _slang_gen_operation(A, &gotoOp);
-      /* destroy temp code */
-      slang_operation_destruct(&gotoOp);
-      return n;
+      return new_return(A->curFuncEndLabel);
    }
    else {
       /*
@@ -1767,9 +1770,9 @@ _slang_gen_return(slang_assemble_ctx * A
        *   return expr;
        * To:
        *   __retVal = expr;
-       *   goto __endOfFunction;
+       *   return;  // goto __endOfFunction
        */
-      slang_operation *block, *assign, *jump;
+      slang_operation *assign;
       slang_atom a_retVal;
       slang_ir_node *n;
 
@@ -1787,17 +1790,8 @@ _slang_gen_return(slang_assemble_ctx * A
       }
 #endif
 
-      block = slang_operation_new(1);
-      block->type = SLANG_OPER_BLOCK_NO_NEW_SCOPE;
-      assert(block->locals);
-      block->locals->outer_scope = oper->locals->outer_scope;
-      block->num_children = 2;
-      block->children = slang_operation_new(2);
-
-      /* child[0]: __retVal = expr; */
-      assign = &block->children[0];
+      assign = slang_operation_new(1);
       assign->type = SLANG_OPER_ASSIGN;
-      assign->locals->outer_scope = block->locals;
       assign->num_children = 2;
       assign->children = slang_operation_new(2);
       /* lhs (__retVal) */
@@ -1808,22 +1802,11 @@ _slang_gen_return(slang_assemble_ctx * A
       /* XXX we might be able to avoid this copy someday */
       slang_operation_copy(&assign->children[1], &oper->children[0]);
 
-      /* child[1]: goto __endOfFunction */
-      jump = &block->children[1];
-      jump->type = SLANG_OPER_GOTO;
-      assert(A->curFuncEndLabel);
-      /* XXX don't call function? */
-      jump->label = A->curFuncEndLabel;
-      assert(jump->label);
-
-#if 0 /* debug */
-      printf("NEW RETURN:\n");
-      slang_print_tree(block, 0);
-#endif
-
       /* assemble the new code */
-      n = _slang_gen_operation(A, block);
-      slang_operation_delete(block);
+      n = new_seq(_slang_gen_operation(A, assign),
+                  new_return(A->curFuncEndLabel));
+
+      slang_operation_delete(assign);
       return n;
    }
 }
@@ -2552,8 +2535,6 @@ _slang_gen_operation(slang_assemble_ctx 
                                            oper, NULL);
    case SLANG_OPER_RETURN:
       return _slang_gen_return(A, oper);
-   case SLANG_OPER_GOTO:
-      return new_jump(oper->label);
    case SLANG_OPER_LABEL:
       return new_label(oper->label);
    case SLANG_OPER_IDENTIFIER:
@@ -2817,6 +2798,23 @@ _slang_codegen_function(slang_assemble_c
       /* we only really generate code for main, all other functions get
        * inlined.
        */
+#if 0
+      /* do some basic error checking though */
+      if (fun->header.type.specifier.type != SLANG_SPEC_VOID) {
+         /* check that non-void functions actually return something */
+         slang_operation *op
+            = _slang_find_node_type(fun->body, SLANG_OPER_RETURN);
+         if (!op) {
+            slang_info_log_error(A->log,
+                                 "function \"%s\" has no return statement",
+                                 (char *) fun->header.a_name);
+            printf(
+                   "function \"%s\" has no return statement\n",
+                   (char *) fun->header.a_name);
+            return GL_FALSE;
+         }
+      }
+#endif
       return GL_TRUE;  /* not an error */
    }
 
diff --git a/src/mesa/shader/slang/slang_compile_operation.h b/src/mesa/shader/slang/slang_compile_operation.h
index 3bed321..b63db04 100644
--- a/src/mesa/shader/slang/slang_compile_operation.h
+++ b/src/mesa/shader/slang/slang_compile_operation.h
@@ -42,7 +42,6 @@ typedef enum slang_operation_type_
    SLANG_OPER_CONTINUE,         /* "continue" statement */
    SLANG_OPER_DISCARD,          /* "discard" (kill fragment) statement */
    SLANG_OPER_RETURN,           /* "return" [expr]  */
-   SLANG_OPER_GOTO,             /* jump to label */
    SLANG_OPER_LABEL,            /* a jump target */
    SLANG_OPER_EXPRESSION,       /* [expr] */
    SLANG_OPER_IF,               /* "if" [0] then [1] else [2] */
@@ -118,7 +117,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 */
+   struct slang_label_ *label;   /**< If type == SLANG_OPER_LABEL */
 } slang_operation;
 
 
diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c
index 109b2df..92bfb54 100644
--- a/src/mesa/shader/slang/slang_emit.c
+++ b/src/mesa/shader/slang/slang_emit.c
@@ -727,6 +727,23 @@ emit_jump(slang_emit_info *emitInfo, sla
 
 
 static struct prog_instruction *
+emit_return(slang_emit_info *emitInfo, slang_ir_node *n)
+{
+   struct prog_instruction *inst;
+   assert(n);
+   assert(n->Opcode == IR_RETURN);
+   assert(n->Label);
+   inst = new_instruction(emitInfo, OPCODE_BRA /*RET*/); /*XXX TEMPORARY*/
+   inst->DstReg.CondMask = COND_TR;  /* always branch */
+   inst->BranchTarget = _slang_label_get_location(n->Label);
+   if (inst->BranchTarget < 0) {
+      _slang_label_add_reference(n->Label, emitInfo->prog->NumInstructions - 1);
+   }
+   return inst;
+}
+
+
+static struct prog_instruction *
 emit_kill(slang_emit_info *emitInfo)
 {
    struct prog_instruction *inst;
@@ -1528,7 +1545,7 @@ emit(slang_emit_info *emitInfo, slang_ir
    case IR_END_SUB:
       return new_instruction(emitInfo, OPCODE_ENDSUB);
    case IR_RETURN:
-      return new_instruction(emitInfo, OPCODE_RET);
+      return emit_return(emitInfo, n);
 
    case IR_NOP:
       return NULL;
diff --git a/src/mesa/shader/slang/slang_print.c b/src/mesa/shader/slang/slang_print.c
index c80a6c7..90e6fe2 100644
--- a/src/mesa/shader/slang/slang_print.c
+++ b/src/mesa/shader/slang/slang_print.c
@@ -308,11 +308,6 @@ slang_print_tree(const slang_operation *
          slang_print_tree(&op->children[0], indent + 3);
       break;
 
-   case SLANG_OPER_GOTO:
-      spaces(indent);
-      printf("GOTO %s\n", (char *) op->a_id);
-      break;
-
    case SLANG_OPER_LABEL:
       spaces(indent);
       printf("LABEL %s\n", (char *) op->a_id);
diff-tree 813a0e11f1eb903883aef18c5cb5c4702dcb6213 (from 52cc32378c541261d045f160a14ab0cfd27009ad)
Author: Brian <brian at yutani.localnet.net>
Date:   Mon Mar 26 16:01:58 2007 -0600

    remove debug abort() calls

diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c
index 9859628..c2a3377 100644
--- a/src/mesa/shader/slang/slang_codegen.c
+++ b/src/mesa/shader/slang/slang_codegen.c
@@ -681,11 +681,8 @@ slang_substitute(slang_assemble_ctx *A, 
 	 GLuint i;
          v = _slang_locate_variable(oper->locals, id, GL_TRUE);
 	 if (!v) {
-	    printf("var %s not found!\n", (char *) oper->a_id);
-            _slang_print_var_scope(oper->locals, 6);
-
-            abort();
-	    break;
+            _mesa_problem(NULL, "var %s not found!\n", (char *) oper->a_id);
+            return;
 	 }
 
 	 /* look for a substitution */
@@ -1134,7 +1131,8 @@ make_writemask(const char *field)
          mask |= WRITEMASK_W;
          break;
       default:
-         abort();
+         _mesa_problem(NULL, "invalid writemask in make_writemask()");
+         return 0;
       }
       field++;
    }
@@ -2619,8 +2617,8 @@ _slang_gen_operation(slang_assemble_ctx 
       return new_node0(IR_NOP);
 
    default:
-      printf("Unhandled node type %d\n", oper->type);
-      abort();
+      _mesa_problem(NULL, "bad node type %d in _slang_gen_operation",
+                    oper->type);
       return new_node0(IR_NOP);
    }
 
diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c
index 6507cde..109b2df 100644
--- a/src/mesa/shader/slang/slang_emit.c
+++ b/src/mesa/shader/slang/slang_emit.c
@@ -1535,7 +1535,6 @@ emit(slang_emit_info *emitInfo, slang_ir
 
    default:
       _mesa_problem(NULL, "Unexpected IR opcode in emit()\n");
-      abort();
    }
    return NULL;
 }
diff --git a/src/mesa/shader/slang/slang_link.c b/src/mesa/shader/slang/slang_link.c
index 39df256..0cad69d 100644
--- a/src/mesa/shader/slang/slang_link.c
+++ b/src/mesa/shader/slang/slang_link.c
@@ -208,10 +208,11 @@ link_uniform_vars(struct gl_shader_progr
             j = _mesa_add_sampler(shProg->Uniforms, p->Name);
             break;
          default:
-            abort();
+            _mesa_problem(NULL, "bad parameter type in link_uniform_vars()");
+            return GL_FALSE;
          }
-
       }
+
       ASSERT(j >= 0);
 
       size = p->Size;
@@ -544,7 +545,7 @@ _slang_link(GLcontext *ctx,
       if (!_slang_resolve_attributes(shProg, &shProg->VertexProgram->Base)) {
          /*goto cleanup;*/
          _mesa_problem(ctx, "_slang_resolve_attributes() failed");
-         abort(); /* XXX fix */
+         return;
       }
    }
 
diff --git a/src/mesa/shader/slang/slang_print.c b/src/mesa/shader/slang/slang_print.c
index 4be9041..c80a6c7 100644
--- a/src/mesa/shader/slang/slang_print.c
+++ b/src/mesa/shader/slang/slang_print.c
@@ -274,10 +274,8 @@ slang_print_tree(const slang_operation *
             */
          }
          else {
-            abort();
             spaces(indent);
             printf("DECL %s (anonymous variable!!!!)\n", (char *) op->a_id);
-            /*abort();*/
          }
       }
       break;
diff-tree 52cc32378c541261d045f160a14ab0cfd27009ad (from c3da0bd7dde9febf206efac88bb67e98dfc90baa)
Author: Brian <brian at yutani.localnet.net>
Date:   Mon Mar 26 15:46:35 2007 -0600

    Additional error checking for 'return' statements.

diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c
index f9dae9f..9859628 100644
--- a/src/mesa/shader/slang/slang_codegen.c
+++ b/src/mesa/shader/slang/slang_codegen.c
@@ -716,7 +716,7 @@ slang_substitute(slang_assemble_ctx *A, 
    case SLANG_OPER_RETURN:
       /* do return replacement here too */
       assert(oper->num_children == 0 || oper->num_children == 1);
-      if (!_slang_is_noop(oper)) {
+      if (oper->num_children == 1 && !_slang_is_noop(&oper->children[0])) {
          /* replace:
           *   return expr;
           * with:
@@ -725,6 +725,14 @@ slang_substitute(slang_assemble_ctx *A, 
           * then do substitutions on the assignment.
           */
          slang_operation *blockOper, *assignOper, *returnOper;
+
+         /* check if function actually has a return type */
+         assert(A->CurFunction);
+         if (A->CurFunction->header.type.specifier.type == SLANG_SPEC_VOID) {
+            slang_info_log_error(A->log, "illegal return expression");
+            return;
+         }
+
          blockOper = slang_operation_new(1);
          blockOper->type = SLANG_OPER_BLOCK_NO_NEW_SCOPE;
          blockOper->num_children = 2;
@@ -755,6 +763,14 @@ slang_substitute(slang_assemble_ctx *A, 
          slang_operation_copy(oper, blockOper);
          slang_operation_destruct(blockOper);
       }
+      else {
+         /* check if return value was expected */
+         assert(A->CurFunction);
+         if (A->CurFunction->header.type.specifier.type != SLANG_SPEC_VOID) {
+            slang_info_log_error(A->log, "return statement requires an expression");
+            return;
+         }
+      }
       break;
 
    case SLANG_OPER_ASSIGN:
@@ -806,6 +822,11 @@ slang_inline_function_call(slang_assembl
    slang_variable **substOld;
    slang_operation **substNew;
    GLuint substCount, numCopyIn, i;
+   slang_function *prevFunction;
+
+   /* save / push */
+   prevFunction = A->CurFunction;
+   A->CurFunction = fun;
 
    /*assert(oper->type == SLANG_OPER_CALL); (or (matrix) multiply, etc) */
    assert(fun->param_count == totalArgs);
@@ -1027,6 +1048,10 @@ slang_inline_function_call(slang_assembl
 	  fun->parameters->num_variables, numArgs);
    slang_print_tree(top, 0);
 #endif
+
+   /* pop */
+   A->CurFunction = prevFunction;
+
    return top;
 }
 
@@ -1703,9 +1728,24 @@ _slang_gen_logical_or(slang_assemble_ctx
 static slang_ir_node *
 _slang_gen_return(slang_assemble_ctx * A, slang_operation *oper)
 {
-   if (oper->num_children == 0 ||
-       (oper->num_children == 1 &&
-        oper->children[0].type == SLANG_OPER_VOID)) {
+   const GLboolean haveReturnValue
+      = (oper->num_children == 1 &&
+         oper->children[0].type != SLANG_OPER_VOID);
+
+   /* error checking */
+   assert(A->CurFunction);
+   if (haveReturnValue &&
+       A->CurFunction->header.type.specifier.type == SLANG_SPEC_VOID) {
+      slang_info_log_error(A->log, "illegal return expression");
+      return NULL;
+   }
+   else if (!haveReturnValue &&
+       A->CurFunction->header.type.specifier.type != SLANG_SPEC_VOID) {
+      slang_info_log_error(A->log, "return statement requires an expression");
+      return NULL;
+   }
+
+   if (!haveReturnValue) {
       /* Convert from:
        *   return;
        * To:
@@ -1718,7 +1758,6 @@ _slang_gen_return(slang_assemble_ctx * A
       gotoOp.label = A->curFuncEndLabel;
       assert(gotoOp.label);
 
-      /* assemble the new code */
       n = _slang_gen_operation(A, &gotoOp);
       /* destroy temp code */
       slang_operation_destruct(&gotoOp);
@@ -1743,7 +1782,10 @@ _slang_gen_return(slang_assemble_ctx * A
       {
          slang_variable *v
             = _slang_locate_variable(oper->locals, a_retVal, GL_TRUE);
-         assert(v);
+         if (!v) {
+            /* trying to return a value in a void-valued function */
+            return NULL;
+         }
       }
 #endif
 
@@ -1843,6 +1885,9 @@ _slang_gen_declaration(slang_assemble_ct
       _slang_simplify(v->initializer, &A->space, A->atoms); 
       rhs = _slang_gen_operation(A, v->initializer);
 #endif
+      if (!rhs)
+         return NULL;
+
       assert(rhs);
       init = new_node2(IR_MOVE, var, rhs);
       /*
@@ -2786,6 +2831,8 @@ _slang_codegen_function(slang_assemble_c
    assert(A->program->Parameters );
    assert(A->program->Varying);
    assert(A->vartable);
+   A->CurLoop = NULL;
+   A->CurFunction = fun;
 
    /* fold constant expressions, etc. */
    _slang_simplify(fun->body, &A->space, A->atoms);
diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c
index 77470ac..6507cde 100644
--- a/src/mesa/shader/slang/slang_emit.c
+++ b/src/mesa/shader/slang/slang_emit.c
@@ -793,11 +793,12 @@ emit_move(slang_emit_info *emitInfo, sla
    assert(n->Children[1]);
    inst = emit(emitInfo, n->Children[1]);
 
+   if (!n->Children[1]->Store) {
+      slang_info_log_error(emitInfo->log, "invalid assignment");
+      return NULL;
+   }
    assert(n->Children[1]->Store->Index >= 0);
 
-#if 0
-   assert(!n->Store);
-#endif
    n->Store = n->Children[0]->Store;
 
 #if PEEPHOLE_OPTIMIZATIONS
diff --git a/src/mesa/shader/slang/slang_typeinfo.h b/src/mesa/shader/slang/slang_typeinfo.h
index be2e229..c815c99 100644
--- a/src/mesa/shader/slang/slang_typeinfo.h
+++ b/src/mesa/shader/slang/slang_typeinfo.h
@@ -64,6 +64,7 @@ typedef struct slang_assemble_ctx_
    slang_info_log *log;
    struct slang_label_ *curFuncEndLabel;
    struct slang_ir_node_ *CurLoop;
+   struct slang_function_ *CurFunction;
 } slang_assemble_ctx;
 
 



More information about the mesa-commit mailing list