diff options
| author | Brian <brian@yutani.localnet.net> | 2007-03-26 16:56:45 -0600 | 
|---|---|---|
| committer | Brian <brian@yutani.localnet.net> | 2007-03-26 16:56:45 -0600 | 
| commit | c042a91b8b202e4c0623e647bda035c715f7c308 (patch) | |
| tree | 5a3db377e5c55625397757dc56a72d31a93d3754 /src | |
| parent | 813a0e11f1eb903883aef18c5cb5c4702dcb6213 (diff) | |
Get rid of SLANG_OPER_GOTO, start rewrite of 'return' handling.
Diffstat (limited to 'src')
| -rw-r--r-- | src/mesa/shader/slang/slang_codegen.c | 94 | ||||
| -rw-r--r-- | src/mesa/shader/slang/slang_compile_operation.h | 3 | ||||
| -rw-r--r-- | src/mesa/shader/slang/slang_emit.c | 19 | ||||
| -rw-r--r-- | src/mesa/shader/slang/slang_print.c | 5 | 
4 files changed, 65 insertions, 56 deletions
| diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index c2a33778c6..0ca5054ead 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], GLuint size)   * 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 *oper)  /** + * 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 *oper,           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, slang_operation *oper)     }     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, slang_operation *oper)         *   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, slang_operation *oper)        }  #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, slang_operation *oper)        /* 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 * A, slang_operation *oper)                                             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_ctx * A, slang_function * fun)        /* 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 3bed3218a6..b63db04e7e 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 109b2df7aa..92bfb54d80 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, slang_ir_node *n)  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_node *n)     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 c80a6c7e11..90e6fe2a96 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 *op, int indent)           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); | 
