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

Brian Paul brianp at kemper.freedesktop.org
Wed Feb 7 05:31:58 UTC 2007


 src/mesa/shader/prog_print.c           |   10 +
 src/mesa/shader/slang/slang_codegen.c  |  261 +++++++++++++++------------------
 src/mesa/shader/slang/slang_emit.c     |  178 +++++++++++++---------
 src/mesa/shader/slang/slang_ir.h       |    7 
 src/mesa/shader/slang/slang_typeinfo.h |    1 
 src/mesa/swrast/s_fragprog.c           |    6 
 6 files changed, 248 insertions(+), 215 deletions(-)

New commits:
diff-tree f22ed0986a743e033d827c78371612c7115ff913 (from 5f7d4668c4b7de1c0d2269809d30aef6d0a089e9)
Author: Brian <brian at nostromo.localnet.net>
Date:   Tue Feb 6 22:31:19 2007 -0700

    Implement CONT, improve BRK.
    
    IR_LOOP's BranchNode ptr is the head of a linked list of CONT and BRK nodes.
    After emitting loop, walk over the linked list, filling in the CONT/BRK
    instruction's BranchTarget field (location of the ENDLOOP instruction, or
    one past).

diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c
index 3d4a474..6c303de 100644
--- a/src/mesa/shader/prog_print.c
+++ b/src/mesa/shader/prog_print.c
@@ -338,8 +338,14 @@ _mesa_print_instruction(const struct pro
       _mesa_printf("ENDLOOP (goto %d)\n", inst->BranchTarget);
       break;
    case OPCODE_BRK:
-      /* XXX just like BRA */
-      _mesa_printf("BRK (%s%s) (for loop beginning at %d)",
+      _mesa_printf("BRK (%s%s) (goto %d)",
+                   condcode_string(inst->DstReg.CondMask),
+                   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),
                    inst->BranchTarget);
diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c
index a4e2935..42c1f08 100644
--- a/src/mesa/shader/slang/slang_codegen.c
+++ b/src/mesa/shader/slang/slang_codegen.c
@@ -608,7 +608,24 @@ new_break(slang_ir_node *loopNode)
    assert(loopNode);
    assert(loopNode->Opcode == IR_LOOP);
    if (n) {
-      n->BranchNode = loopNode;
+      /* insert this node at head of linked list */
+      n->BranchNode = loopNode->BranchNode;
+      loopNode->BranchNode = n;
+   }
+   return n;
+}
+
+
+static slang_ir_node *
+new_cont(slang_ir_node *loopNode)
+{
+   slang_ir_node *n = new_node0(IR_CONT);
+   assert(loopNode);
+   assert(loopNode->Opcode == IR_LOOP);
+   if (n) {
+      /* insert this node at head of linked list */
+      n->BranchNode = loopNode->BranchNode;
+      loopNode->BranchNode = n;
    }
    return n;
 }
@@ -2434,11 +2451,15 @@ _slang_gen_operation(slang_assemble_ctx 
          return new_jump(A->CurLoopBreak);
       }
    case slang_oper_continue:
-      if (!A->CurLoopCont) {
+      if (!A->CurLoop && !A->CurLoopCont) {
          RETURN_ERROR("'continue' not in loop", 0);
       }
-      /* XXX emit IR_CONT instruction */
-      return new_jump(A->CurLoopCont);
+      if (UseHighLevelInstructions) {
+         return new_cont(A->CurLoop);
+      }
+      else {
+         return new_jump(A->CurLoopCont);
+      }
    case slang_oper_discard:
       return new_node0(IR_KILL);
 
diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c
index c18f1e3..2d5a7cf 100644
--- a/src/mesa/shader/slang/slang_emit.c
+++ b/src/mesa/shader/slang/slang_emit.c
@@ -1303,7 +1303,9 @@ emit(slang_var_table *vt, slang_ir_node 
 
    case IR_LOOP:
       {
-         struct prog_instruction *beginInst;
+         struct prog_instruction *beginInst, *endInst;
+         GLuint endInstLoc;
+         slang_ir_node *p;
 
          /* save location of this instruction, used by OPCODE_ENDLOOP */
          n->InstLocation = prog->NumInstructions;
@@ -1312,27 +1314,48 @@ emit(slang_var_table *vt, slang_ir_node 
          /* body */
          emit(vt, n->Children[0], prog);
 
-         inst = new_instruction(prog, OPCODE_ENDLOOP);
-         /* The instruction BranchTarget points to top of loop */
-         inst->BranchTarget = n->InstLocation;
+         endInstLoc = prog->NumInstructions;
+         endInst = new_instruction(prog, OPCODE_ENDLOOP);
+         /* The ENDLOOP's BranchTarget points to top of loop */
+         endInst->BranchTarget = n->InstLocation;
          /* Update BGNLOOP's BranchTarget to point to this instruction */
          beginInst = prog->Instructions + n->InstLocation;
          beginInst->BranchTarget = prog->NumInstructions - 1;
-         return inst;
+
+         /* Done emitting loop code.  Now walk over the loop's linked list
+          * of BREAK and CONT nodes, filling in their BranchTarget fields.
+          */
+         for (p = n->BranchNode; p; p = p->BranchNode) {
+            if (p->Opcode == IR_BREAK) {
+               struct prog_instruction *brkInst
+                  = prog->Instructions + p->InstLocation;
+               assert(brkInst->Opcode == OPCODE_BRK);
+               brkInst->BranchTarget = endInstLoc + 1;
+            }
+            else {
+               assert(p->Opcode == IR_CONT);
+               struct prog_instruction *contInst
+                  = prog->Instructions + p->InstLocation;
+               assert(contInst->Opcode == OPCODE_CONT);
+               contInst->BranchTarget = endInstLoc;
+            }
+         }
+         return NULL;
       }
    case IR_CONT:
-      return new_instruction(prog, OPCODE_CONT);
+      {
+         struct prog_instruction *inst;
+         n->InstLocation = prog->NumInstructions;
+         inst = new_instruction(prog, OPCODE_CONT);
+         inst->DstReg.CondMask = COND_TR;  /* always true */
+         return inst;
+      }
    case IR_BREAK:
       {
          struct prog_instruction *inst;
+         n->InstLocation = prog->NumInstructions;
          inst = new_instruction(prog, OPCODE_BRK);
          inst->DstReg.CondMask = COND_TR;  /* always true */
-         /* This instruction's branch target is top of loop, not bottom of
-          * loop because we don't know where it is yet!
-          */
-         assert(n->BranchNode);
-         assert(n->BranchNode->InstLocation >= 0);
-         inst->BranchTarget = n->BranchNode->InstLocation;
          return inst;
       }
 
diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c
index 12c8aee..63974b3 100644
--- a/src/mesa/swrast/s_fragprog.c
+++ b/src/mesa/swrast/s_fragprog.c
@@ -704,6 +704,7 @@ execute_program( GLcontext *ctx,
             break;
          case OPCODE_BRK: /* break out of loop */
             {
+#if 0
                /* The location of the ENDLOOP instruction is saved in the
                 * BGNLOOP instruction.  Get that instruction and jump to
                 * its BranchTarget + 1.
@@ -714,6 +715,9 @@ execute_program( GLcontext *ctx,
                ASSERT(loopBeginInst->BranchTarget >= 0);
                /* we'll add one at bottom of for-loop */
                pc = loopBeginInst->BranchTarget;
+#else
+               pc = inst->BranchTarget - 1;
+#endif
             }
             break;
          case OPCODE_CAL: /* Call subroutine */
@@ -747,6 +751,8 @@ execute_program( GLcontext *ctx,
             }
             break;
          case OPCODE_CONT: /* continue loop */
+            /* Subtract 1 here since we'll do pc++ at end of for-loop */
+            pc = inst->BranchTarget - 1;
             break;
          case OPCODE_COS:
             {
diff-tree 5f7d4668c4b7de1c0d2269809d30aef6d0a089e9 (from 7e73bc32f565b3d07e9a5cfbe0736d1d6bd6a2c1)
Author: Brian <brian at nostromo.localnet.net>
Date:   Tue Feb 6 21:33:29 2007 -0700

    replace IR_BEGIN_LOOP/IR_END_LOOP with IR_LOOP

diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c
index 88d61a5..a4e2935 100644
--- a/src/mesa/shader/slang/slang_codegen.c
+++ b/src/mesa/shader/slang/slang_codegen.c
@@ -490,10 +490,12 @@ static void
 _slang_free_ir_tree(slang_ir_node *n)
 {
 #if 0
+   GLuint i;
    if (!n)
       return;
-   _slang_free_ir_tree(n->Children[0]);
-   _slang_free_ir_tree(n->Children[1]);
+   for (i = 0; i < 3; i++)
+      _slang_free_ir_tree(n->Children[i]);
+   /* Do not free n->BranchNode since it's a child elsewhere */
    free(n);
 #endif
 }
@@ -537,9 +539,10 @@ new_node0(slang_ir_opcode op)
 static slang_ir_node *
 new_seq(slang_ir_node *left, slang_ir_node *right)
 {
-   /* XXX if either left or right is null, just return pointer to other?? */
-   assert(left);
-   assert(right);
+   if (!left)
+      return right;
+   if (!right)
+      return left;
    return new_node2(IR_SEQ, left, right);
 }
 
@@ -592,32 +595,20 @@ new_jump(slang_atom target)
 
 
 static slang_ir_node *
-new_begin_loop(void)
-{
-   slang_ir_node *n = new_node0(IR_BEGIN_LOOP);
-   return n;
-}
-
-
-static slang_ir_node *
-new_end_loop(slang_ir_node *beginNode)
+new_loop(slang_ir_node *body)
 {
-   slang_ir_node *n = new_node0(IR_END_LOOP);
-   assert(beginNode);
-   if (n) {
-      n->BranchNode = beginNode;
-   }
-   return n;
+   return new_node1(IR_LOOP, body);
 }
 
 
 static slang_ir_node *
-new_break(slang_ir_node *beginNode)
+new_break(slang_ir_node *loopNode)
 {
    slang_ir_node *n = new_node0(IR_BREAK);
-   assert(beginNode);
+   assert(loopNode);
+   assert(loopNode->Opcode == IR_LOOP);
    if (n) {
-      n->BranchNode = beginNode;
+      n->BranchNode = loopNode;
    }
    return n;
 }
@@ -1415,43 +1406,43 @@ _slang_gen_while(slang_assemble_ctx * A,
 
 
 /**
- * Generate IR tree for a while-loop using high-level BGNLOOP/ENDLOOP,
- * IF/ENDIF instructions.
+ * Generate IR tree for a while-loop using high-level LOOP, IF instructions.
  */
 static slang_ir_node *
 _slang_gen_hl_while(slang_assemble_ctx * A, const slang_operation *oper)
 {
+   slang_ir_node *prevLoop;
    /*
-    * BGNLOOP
+    * LOOP:
     *    eval expr (child[0]), updating condcodes
-    *    IF !expr THEN
+    *    IF !expr:
     *       BRK
-    *    ENDIF
     *    body code (child[1])
-    * ENDLOOP
     */
-   slang_ir_node *beginLoop, *endLoop, *ifThen;
-   slang_ir_node *cond, *body, *tree;
+   slang_ir_node *ifThen, *cond, *body, *loop;
 
-   beginLoop = new_begin_loop();
+   loop = new_loop(NULL);
+
+   /* save old, push new loop */
+   prevLoop = A->CurLoop;
+   A->CurLoop = loop;
 
    cond = _slang_gen_operation(A, &oper->children[0]);
    cond = new_node1(IR_NOT, cond);
    cond = _slang_gen_cond(cond);
 
    ifThen = new_if(cond,
-                   new_break(beginLoop),
+                   new_break(A->CurLoop),
                    NULL);
-   tree = new_seq(beginLoop, ifThen);
 
    body = _slang_gen_operation(A, &oper->children[1]);
-   if (body)
-      tree = new_seq(tree, body);
 
-   endLoop = new_end_loop(beginLoop);
-   tree = new_seq(tree, endLoop);
+   loop->Children[0] = new_seq(ifThen, body);
 
-   return tree;
+
+   A->CurLoop = prevLoop; /* pop loop, restore prev */
+
+   return loop;
 }
 
 
@@ -2433,11 +2424,15 @@ _slang_gen_operation(slang_assemble_ctx 
       else
          return _slang_gen_for(A, oper);
    case slang_oper_break:
-      if (!A->CurLoopBreak) {
+      if (!A->CurLoop && !A->CurLoopBreak) {
          RETURN_ERROR("'break' not in loop", 0);
       }
-      /* XXX emit IR_BREAK instruction */
-      return new_jump(A->CurLoopBreak);
+      if (UseHighLevelInstructions) {
+         return new_break(A->CurLoop);
+      }
+      else {
+         return new_jump(A->CurLoopBreak);
+      }
    case slang_oper_continue:
       if (!A->CurLoopCont) {
          RETURN_ERROR("'continue' not in loop", 0);
diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c
index 82a8f0b..c18f1e3 100644
--- a/src/mesa/shader/slang/slang_emit.c
+++ b/src/mesa/shader/slang/slang_emit.c
@@ -317,11 +317,11 @@ slang_print_ir(const slang_ir_node *n, i
       printf("CALL\n");
       break;
 
-   case IR_BEGIN_LOOP:
-      printf("BEGIN_LOOP\n");
-      break;
-   case IR_END_LOOP:
-      printf("END_LOOP\n");
+   case IR_LOOP:
+      printf("LOOP\n");
+      slang_print_ir(n->Children[0], indent+3);
+      spaces(indent);
+      printf("ENDLOOP\n");
       break;
    case IR_CONT:
       printf("CONT\n");
@@ -1301,23 +1301,22 @@ emit(slang_var_table *vt, slang_ir_node 
    case IR_IF:
       return emit_if(vt, n, prog);
 
-   case IR_BEGIN_LOOP:
+   case IR_LOOP:
       {
+         struct prog_instruction *beginInst;
+
          /* save location of this instruction, used by OPCODE_ENDLOOP */
          n->InstLocation = prog->NumInstructions;
          (void) new_instruction(prog, OPCODE_BGNLOOP);
-      }
-      break;
-   case IR_END_LOOP:
-      {
-         struct prog_instruction *inst, *beginInst;
+
+         /* body */
+         emit(vt, n->Children[0], prog);
+
          inst = new_instruction(prog, OPCODE_ENDLOOP);
-         assert(n->BranchNode);
-         assert(n->BranchNode->InstLocation >= 0);
          /* The instruction BranchTarget points to top of loop */
-         inst->BranchTarget = n->BranchNode->InstLocation;
-         /* Update BEGIN_LOOP's BranchTarget to point to this instruction */
-         beginInst = prog->Instructions + n->BranchNode->InstLocation;
+         inst->BranchTarget = n->InstLocation;
+         /* Update BGNLOOP's BranchTarget to point to this instruction */
+         beginInst = prog->Instructions + n->InstLocation;
          beginInst->BranchTarget = prog->NumInstructions - 1;
          return inst;
       }
@@ -1336,6 +1335,7 @@ emit(slang_var_table *vt, slang_ir_node 
          inst->BranchTarget = n->BranchNode->InstLocation;
          return inst;
       }
+
    case IR_BEGIN_SUB:
       return new_instruction(prog, OPCODE_BGNSUB);
    case IR_END_SUB:
@@ -1343,6 +1343,9 @@ emit(slang_var_table *vt, slang_ir_node 
    case IR_RETURN:
       return new_instruction(prog, OPCODE_RET);
 
+   case IR_NOP:
+      return NULL;
+
    default:
       _mesa_problem(NULL, "Unexpected IR opcode in emit()\n");
       abort();
diff --git a/src/mesa/shader/slang/slang_ir.h b/src/mesa/shader/slang/slang_ir.h
index 0f2ceb0..a7c858c 100644
--- a/src/mesa/shader/slang/slang_ir.h
+++ b/src/mesa/shader/slang/slang_ir.h
@@ -60,8 +60,7 @@ typedef enum
    IR_RETURN,    /* return from subroutine */
    IR_CALL,      /* call subroutine */
 
-   IR_BEGIN_LOOP,/* begin loop */
-   IR_END_LOOP,  /* end loop */
+   IR_LOOP,      /* high-level loop-begin / loop-end */
    IR_CONT,      /* continue loop */
    IR_BREAK,     /* break loop */
 
diff --git a/src/mesa/shader/slang/slang_typeinfo.h b/src/mesa/shader/slang/slang_typeinfo.h
index 6e27079..d23bb6b 100644
--- a/src/mesa/shader/slang/slang_typeinfo.h
+++ b/src/mesa/shader/slang/slang_typeinfo.h
@@ -63,6 +63,7 @@ typedef struct slang_assemble_ctx_
    struct slang_function_ *CurFunction;
    slang_atom CurLoopBreak;
    slang_atom CurLoopCont;
+   struct slang_ir_node_ *CurLoop;
 } slang_assemble_ctx;
 
 
diff-tree 7e73bc32f565b3d07e9a5cfbe0736d1d6bd6a2c1 (from 204336451678ba8710756111e6cf4867d6adb40e)
Author: Brian <brian at nostromo.localnet.net>
Date:   Tue Feb 6 20:53:09 2007 -0700

    new_node[0123]() functions

diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c
index 780c9c1..88d61a5 100644
--- a/src/mesa/shader/slang/slang_codegen.c
+++ b/src/mesa/shader/slang/slang_codegen.c
@@ -500,13 +500,15 @@ _slang_free_ir_tree(slang_ir_node *n)
 
 
 static slang_ir_node *
-new_node(slang_ir_opcode op, slang_ir_node *left, slang_ir_node *right)
+new_node3(slang_ir_opcode op,
+          slang_ir_node *c0, slang_ir_node *c1, slang_ir_node *c2)
 {
    slang_ir_node *n = (slang_ir_node *) calloc(1, sizeof(slang_ir_node));
    if (n) {
       n->Opcode = op;
-      n->Children[0] = left;
-      n->Children[1] = right;
+      n->Children[0] = c0;
+      n->Children[1] = c1;
+      n->Children[2] = c2;
       n->Writemask = WRITEMASK_XYZW;
       n->InstLocation = -1;
    }
@@ -514,18 +516,37 @@ new_node(slang_ir_opcode op, slang_ir_no
 }
 
 static slang_ir_node *
+new_node2(slang_ir_opcode op, slang_ir_node *c0, slang_ir_node *c1)
+{
+   return new_node3(op, c0, c1, NULL);
+}
+
+static slang_ir_node *
+new_node1(slang_ir_opcode op, slang_ir_node *c0)
+{
+   return new_node3(op, c0, NULL, NULL);
+}
+
+static slang_ir_node *
+new_node0(slang_ir_opcode op)
+{
+   return new_node3(op, NULL, NULL, NULL);
+}
+
+
+static slang_ir_node *
 new_seq(slang_ir_node *left, slang_ir_node *right)
 {
    /* XXX if either left or right is null, just return pointer to other?? */
    assert(left);
    assert(right);
-   return new_node(IR_SEQ, left, right);
+   return new_node2(IR_SEQ, left, right);
 }
 
 static slang_ir_node *
 new_label(slang_atom labName)
 {
-   slang_ir_node *n = new_node(IR_LABEL, NULL, NULL);
+   slang_ir_node *n = new_node0(IR_LABEL);
    n->Target = (char *) labName; /*_mesa_strdup(name);*/
    return n;
 }
@@ -534,7 +555,7 @@ static slang_ir_node *
 new_float_literal(const float v[4])
 {
    const GLuint size = (v[0] == v[1] && v[0] == v[2] && v[0] == v[3]) ? 1 : 4;
-   slang_ir_node *n = new_node(IR_FLOAT, NULL, NULL);
+   slang_ir_node *n = new_node0(IR_FLOAT);
    COPY_4V(n->Value, v);
    /* allocate a storage object, but compute actual location (Index) later */
    n->Store = _slang_new_ir_storage(PROGRAM_CONSTANT, -1, size);
@@ -550,7 +571,7 @@ new_float_literal(const float v[4])
 static slang_ir_node *
 new_cjump(slang_atom target, GLuint zeroOrOne)
 {
-   slang_ir_node *n = new_node(zeroOrOne ? IR_CJUMP1 : IR_CJUMP0, NULL, NULL);
+   slang_ir_node *n = new_node0(zeroOrOne ? IR_CJUMP1 : IR_CJUMP0);
    if (n)
       n->Target = (char *) target;
    return n;
@@ -563,7 +584,7 @@ new_cjump(slang_atom target, GLuint zero
 static slang_ir_node *
 new_jump(slang_atom target)
 {
-   slang_ir_node *n = new_node(IR_JUMP, NULL, NULL);
+   slang_ir_node *n = new_node0(IR_JUMP);
    if (n)
       n->Target = (char *) target;
    return n;
@@ -573,7 +594,7 @@ new_jump(slang_atom target)
 static slang_ir_node *
 new_begin_loop(void)
 {
-   slang_ir_node *n = new_node(IR_BEGIN_LOOP, NULL, NULL);
+   slang_ir_node *n = new_node0(IR_BEGIN_LOOP);
    return n;
 }
 
@@ -581,7 +602,7 @@ new_begin_loop(void)
 static slang_ir_node *
 new_end_loop(slang_ir_node *beginNode)
 {
-   slang_ir_node *n = new_node(IR_END_LOOP, NULL, NULL);
+   slang_ir_node *n = new_node0(IR_END_LOOP);
    assert(beginNode);
    if (n) {
       n->BranchNode = beginNode;
@@ -593,7 +614,7 @@ new_end_loop(slang_ir_node *beginNode)
 static slang_ir_node *
 new_break(slang_ir_node *beginNode)
 {
-   slang_ir_node *n = new_node(IR_BREAK, NULL, NULL);
+   slang_ir_node *n = new_node0(IR_BREAK);
    assert(beginNode);
    if (n) {
       n->BranchNode = beginNode;
@@ -605,12 +626,7 @@ new_break(slang_ir_node *beginNode)
 static slang_ir_node *
 new_if(slang_ir_node *cond, slang_ir_node *ifPart, slang_ir_node *elsePart)
 {
-   slang_ir_node *n = new_node(IR_IF, cond, ifPart);
-   assert(cond);
-   if (n) {
-      n->Children[2] = elsePart;
-   }
-   return n;
+   return new_node3(IR_IF, cond, ifPart, elsePart);
 }
 
 
@@ -621,7 +637,7 @@ static slang_ir_node *
 new_var(slang_assemble_ctx *A, slang_operation *oper, slang_atom name)
 {
    slang_variable *v = _slang_locate_variable(oper->locals, name, GL_TRUE);
-   slang_ir_node *n = new_node(IR_VAR, NULL, NULL);
+   slang_ir_node *n = new_node0(IR_VAR);
    if (!v)
       return NULL;
    assert(!oper->var || oper->var == v);
@@ -1222,9 +1238,7 @@ _slang_gen_asm(slang_assemble_ctx *A, sl
       kids[j] = _slang_gen_operation(A, &oper->children[firstOperand + j]);
    }
 
-   n = new_node(info->Opcode, kids[0], kids[1]);
-   if (kids[2])
-      n->Children[2] = kids[2];
+   n = new_node3(info->Opcode, kids[0], kids[1], kids[2]);
 
    if (firstOperand) {
       /* Setup n->Store to be a particular location.  Otherwise, storage
@@ -1271,7 +1285,7 @@ _slang_is_noop(const slang_operation *op
 static slang_ir_node *
 _slang_gen_cond(slang_ir_node *n)
 {
-   slang_ir_node *c = new_node(IR_COND, n, NULL);
+   slang_ir_node *c = new_node1(IR_COND, n);
    return c;
 }
 
@@ -1422,7 +1436,7 @@ _slang_gen_hl_while(slang_assemble_ctx *
    beginLoop = new_begin_loop();
 
    cond = _slang_gen_operation(A, &oper->children[0]);
-   cond = new_node(IR_NOT, cond, NULL);
+   cond = new_node1(IR_NOT, cond);
    cond = _slang_gen_cond(cond);
 
    ifThen = new_if(cond,
@@ -1715,7 +1729,7 @@ _slang_gen_temporary(GLint size)
 
    store = _slang_new_ir_storage(PROGRAM_TEMPORARY, -1, size);
    if (store) {
-      n = new_node(IR_VAR_DECL, NULL, NULL);
+      n = new_node0(IR_VAR_DECL);
       if (n) {
          n->Store = store;
       }
@@ -1734,7 +1748,7 @@ static slang_ir_node *
 _slang_gen_var_decl(slang_assemble_ctx *A, slang_variable *var)
 {
    slang_ir_node *n;
-   n = new_node(IR_VAR_DECL, NULL, NULL);
+   n = new_node0(IR_VAR_DECL);
    if (n) {
       n->Var = var;
       slang_allocate_storage(A, n);
@@ -1788,10 +1802,10 @@ _slang_gen_select(slang_assemble_ctx *A,
    tree = new_seq(tree, cjump);
 
    /* evaluate child 1 (x) and assign to tmp */
-   tmpVar = new_node(IR_VAR, NULL, NULL);
+   tmpVar = new_node0(IR_VAR);
    tmpVar->Store = tmpDecl->Store;
    body = _slang_gen_operation(A, &oper->children[1]);
-   assigny = new_node(IR_MOVE, tmpVar, body);
+   assigny = new_node2(IR_MOVE, tmpVar, body);
    tree = new_seq(tree, assigny);
 
    /* jump to "end" label */
@@ -1803,10 +1817,10 @@ _slang_gen_select(slang_assemble_ctx *A,
    tree = new_seq(tree, altLab);
 
    /* evaluate child 2 (y) and assign to tmp */
-   tmpVar = new_node(IR_VAR, NULL, NULL);
+   tmpVar = new_node0(IR_VAR);
    tmpVar->Store = tmpDecl->Store;
    bodx = _slang_gen_operation(A, &oper->children[2]);
-   assignx = new_node(IR_MOVE, tmpVar, bodx);
+   assignx = new_node2(IR_MOVE, tmpVar, bodx);
    tree = new_seq(tree, assignx);
 
    /* "end" label */
@@ -1814,7 +1828,7 @@ _slang_gen_select(slang_assemble_ctx *A,
    tree = new_seq(tree, endLab);
    
    /* tmp var value */
-   tmpVar = new_node(IR_VAR, NULL, NULL);
+   tmpVar = new_node0(IR_VAR);
    tmpVar->Store = tmpDecl->Store;
    tree = new_seq(tree, tmpVar);
 
@@ -2006,7 +2020,7 @@ _slang_gen_declaration(slang_assemble_ct
       /* XXX make copy of this initializer? */
       rhs = _slang_gen_operation(A, &oper->children[0]);
       assert(rhs);
-      init = new_node(IR_MOVE, var, rhs);
+      init = new_node2(IR_MOVE, var, rhs);
       /*assert(rhs->Opcode != IR_SEQ);*/
       n = new_seq(varDecl, init);
    }
@@ -2030,7 +2044,7 @@ _slang_gen_declaration(slang_assemble_ct
       rhs = _slang_gen_operation(A, v->initializer);
 #endif
       assert(rhs);
-      init = new_node(IR_MOVE, var, rhs);
+      init = new_node2(IR_MOVE, var, rhs);
       /*
         assert(rhs->Opcode != IR_SEQ);
       */
@@ -2157,7 +2171,7 @@ swizzle_to_writemask(GLuint swizzle,
 static slang_ir_node *
 _slang_gen_swizzle(slang_ir_node *child, GLuint swizzle)
 {
-   slang_ir_node *n = new_node(IR_SWIZZLE, child, NULL);
+   slang_ir_node *n = new_node1(IR_SWIZZLE, child);
    if (n) {
       n->Store = _slang_new_ir_storage(PROGRAM_UNDEFINED, -1, -1);
       n->Store->Swizzle = swizzle;
@@ -2201,7 +2215,7 @@ _slang_gen_assignment(slang_assemble_ctx
              */
             rhs = _slang_gen_swizzle(rhs, newSwizzle);
          }
-         n = new_node(IR_MOVE, lhs, rhs);
+         n = new_node2(IR_MOVE, lhs, rhs);
          n->Writemask = writemask;
          return n;
       }
@@ -2322,7 +2336,7 @@ _slang_gen_subscript(slang_assemble_ctx 
       array = _slang_gen_operation(A, &oper->children[0]);
       index = _slang_gen_operation(A, &oper->children[1]);
       if (array && index) {
-         elem = new_node(IR_ELEMENT, array, index);
+         elem = new_node2(IR_ELEMENT, array, index);
          elem->Store = _slang_new_ir_storage(array->Store->File,
                                              array->Store->Index,
                                              elemSize);
@@ -2356,7 +2370,7 @@ _slang_gen_operation(slang_assemble_ctx 
          _slang_pop_var_table(A->vartable);
 
          if (n)
-            n = new_node(IR_SCOPE, n, NULL);
+            n = new_node1(IR_SCOPE, n);
          return n;
       }
       break;
@@ -2431,32 +2445,32 @@ _slang_gen_operation(slang_assemble_ctx 
       /* XXX emit IR_CONT instruction */
       return new_jump(A->CurLoopCont);
    case slang_oper_discard:
-      return new_node(IR_KILL, NULL, NULL);
+      return new_node0(IR_KILL);
 
    case slang_oper_equal:
-      return new_node(IR_SEQUAL,
+      return new_node2(IR_SEQUAL,
                       _slang_gen_operation(A, &oper->children[0]),
                       _slang_gen_operation(A, &oper->children[1]));
    case slang_oper_notequal:
-      return new_node(IR_SNEQUAL,
+      return new_node2(IR_SNEQUAL,
                       _slang_gen_operation(A, &oper->children[0]),
                       _slang_gen_operation(A, &oper->children[1]));
    case slang_oper_greater:
-      return new_node(IR_SGT,
+      return new_node2(IR_SGT,
                       _slang_gen_operation(A, &oper->children[0]),
                       _slang_gen_operation(A, &oper->children[1]));
    case slang_oper_less:
       /* child[0] < child[1]  ---->   child[1] > child[0] */
-      return new_node(IR_SGT,
+      return new_node2(IR_SGT,
                       _slang_gen_operation(A, &oper->children[1]),
                       _slang_gen_operation(A, &oper->children[0]));
    case slang_oper_greaterequal:
-      return new_node(IR_SGE,
+      return new_node2(IR_SGE,
                       _slang_gen_operation(A, &oper->children[0]),
                       _slang_gen_operation(A, &oper->children[1]));
    case slang_oper_lessequal:
       /* child[0] <= child[1]  ---->   child[1] >= child[0] */
-      return new_node(IR_SGE,
+      return new_node2(IR_SGE,
                       _slang_gen_operation(A, &oper->children[1]),
                       _slang_gen_operation(A, &oper->children[0]));
    case slang_oper_add:
@@ -2648,7 +2662,7 @@ _slang_gen_operation(slang_assemble_ctx 
    default:
       printf("Unhandled node type %d\n", oper->type);
       abort();
-      return new_node(IR_NOP, NULL, NULL);
+      return new_node0(IR_NOP);
    }
       abort();
    return NULL;
@@ -2793,7 +2807,7 @@ _slang_codegen_global_variable(slang_ass
          slang_ir_node *lhs, *rhs, *init;
 
          /* Generate IR_MOVE instruction to initialize the variable */
-         lhs = new_node(IR_VAR, NULL, NULL);
+         lhs = new_node0(IR_VAR);
          lhs->Var = var;
          lhs->Store = n->Store;
 
@@ -2802,7 +2816,7 @@ _slang_codegen_global_variable(slang_ass
 
          rhs = _slang_gen_operation(A, var->initializer);
          assert(rhs);
-         init = new_node(IR_MOVE, lhs, rhs);
+         init = new_node2(IR_MOVE, lhs, rhs);
          n = new_seq(n, init);
       }
 
@@ -2866,7 +2880,7 @@ _slang_codegen_function(slang_assemble_c
    /* Generate IR tree for the function body code */
    n = _slang_gen_operation(A, fun->body);
    if (n)
-      n = new_node(IR_SCOPE, n, NULL);
+      n = new_node1(IR_SCOPE, n);
 
    /* pop vartable, restore previous */
    _slang_pop_var_table(A->vartable);
diff-tree 204336451678ba8710756111e6cf4867d6adb40e (from 2755c798f3cb89fcd4ece16cd740af1cd86a6b99)
Author: Brian <brian at nostromo.localnet.net>
Date:   Tue Feb 6 20:45:43 2007 -0700

    redo IR_IF node, removing IR_ELSE, IR_ENDIF

diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c
index a5f033d..780c9c1 100644
--- a/src/mesa/shader/slang/slang_codegen.c
+++ b/src/mesa/shader/slang/slang_codegen.c
@@ -47,7 +47,7 @@
 #include "slang_print.h"
 
 
-static GLboolean UseHighLevelInstructions = GL_FALSE;
+static GLboolean UseHighLevelInstructions = GL_TRUE;
 
 static slang_ir_node *
 _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper);
@@ -602,42 +602,13 @@ new_break(slang_ir_node *beginNode)
 }
 
 
-/**
- * Child[0] is the condition.
- * XXX we might re-design IR_IF so Children[1] is the "then" body and
- * Children[0] is the "else" body.
- */
 static slang_ir_node *
-new_if(slang_ir_node *cond)
+new_if(slang_ir_node *cond, slang_ir_node *ifPart, slang_ir_node *elsePart)
 {
-   slang_ir_node *n = new_node(IR_IF, NULL, NULL);
+   slang_ir_node *n = new_node(IR_IF, cond, ifPart);
    assert(cond);
    if (n) {
-      n->Children[0] = cond;
-   }
-   return n;
-}
-
-
-static slang_ir_node *
-new_else(slang_ir_node *ifNode)
-{
-   slang_ir_node *n = new_node(IR_ELSE, NULL, NULL);
-   assert(ifNode);
-   if (n) {
-      n->BranchNode = ifNode;
-   }
-   return n;
-}
-
-
-static slang_ir_node *
-new_endif(slang_ir_node *elseOrIfNode)
-{
-   slang_ir_node *n = new_node(IR_ENDIF, NULL, NULL);
-   assert(elseOrIfNode);
-   if (n) {
-      n->BranchNode = elseOrIfNode;
+      n->Children[2] = elsePart;
    }
    return n;
 }
@@ -1445,8 +1416,8 @@ _slang_gen_hl_while(slang_assemble_ctx *
     *    body code (child[1])
     * ENDLOOP
     */
-   slang_ir_node *beginLoop, *endLoop, *ifThen, *endif;
-   slang_ir_node *brk, *cond, *body, *tree;
+   slang_ir_node *beginLoop, *endLoop, *ifThen;
+   slang_ir_node *cond, *body, *tree;
 
    beginLoop = new_begin_loop();
 
@@ -1454,15 +1425,11 @@ _slang_gen_hl_while(slang_assemble_ctx *
    cond = new_node(IR_NOT, cond, NULL);
    cond = _slang_gen_cond(cond);
 
-   ifThen = new_if(cond);
+   ifThen = new_if(cond,
+                   new_break(beginLoop),
+                   NULL);
    tree = new_seq(beginLoop, ifThen);
 
-   brk = new_break(beginLoop);
-   tree = new_seq(tree, brk);
-
-   endif = new_endif(ifThen);
-   tree = new_seq(tree, endif);
-
    body = _slang_gen_operation(A, &oper->children[1]);
    if (body)
       tree = new_seq(tree, body);
@@ -1702,7 +1669,7 @@ _slang_gen_if(slang_assemble_ctx * A, co
 
 /**
  * Generate IR tree for an if/then/else conditional using high-level
- * IF/ELSE/ENDIF instructions
+ * IR_IF instruction.
  */
 static slang_ir_node *
 _slang_gen_hl_if(slang_assemble_ctx * A, const slang_operation *oper)
@@ -1720,29 +1687,19 @@ _slang_gen_hl_if(slang_assemble_ctx * A,
     * instruction.
     */
    const GLboolean haveElseClause = !_slang_is_noop(&oper->children[2]);
-   slang_ir_node *ifNode, *cond, *trueBody, *elseNode, *falseBody, *endifNode;
-   slang_ir_node *tree;
+   slang_ir_node *ifNode, *cond, *ifBody, *elseBody;
 
    cond = _slang_gen_operation(A, &oper->children[0]);
    cond = _slang_gen_cond(cond);
-   /*assert(cond->Store);*/
-   ifNode = new_if(cond);
-
-   trueBody = _slang_gen_operation(A, &oper->children[1]);
-   tree = new_seq(ifNode, trueBody);
-
-   if (haveElseClause) {
-      elseNode = new_else(ifNode);
-      tree = new_seq(tree, elseNode);
-
-      falseBody = _slang_gen_operation(A, &oper->children[2]);
-      tree = new_seq(tree, falseBody);
-   }
+   ifBody = _slang_gen_operation(A, &oper->children[1]);
+   if (haveElseClause)
+      elseBody = _slang_gen_operation(A, &oper->children[2]);
+   else
+      elseBody = NULL;
 
-   endifNode = new_endif(haveElseClause ? elseNode : ifNode);
-   tree = new_seq(tree, endifNode);
+   ifNode = new_if(cond, ifBody, elseBody);
 
-   return tree;
+   return ifNode;
 }
 
 
diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c
index 3faacdd..82a8f0b 100644
--- a/src/mesa/shader/slang/slang_emit.c
+++ b/src/mesa/shader/slang/slang_emit.c
@@ -103,8 +103,6 @@ static slang_ir_info IrInfo[] = {
    { IR_CJUMP0, "IR_CJUMP0", OPCODE_NOP, 0, 0 },
    { IR_CJUMP1, "IR_CJUMP1", OPCODE_NOP, 0, 0 },
    { IR_IF, "IR_IF", OPCODE_NOP, 0, 0 },
-   { IR_ELSE, "IR_ELSE", OPCODE_NOP, 0, 0 },
-   { IR_ENDIF, "IR_ENDIF", OPCODE_NOP, 0, 0 },
    { IR_KILL, "IR_KILL", OPCODE_NOP, 0, 0 },
    { IR_COND, "IR_COND", OPCODE_NOP, 0, 0 },
    { IR_CALL, "IR_CALL", OPCODE_NOP, 0, 0 },
@@ -232,11 +230,18 @@ storage_string(const slang_ir_storage *s
 }
 
 
+static void
+spaces(int n)
+{
+   while (n-- > 0) {
+      printf(" ");
+   }
+}
+
 #define IND 0
 void
 slang_print_ir(const slang_ir_node *n, int indent)
 {
-   int i;
    if (!n)
       return;
 #if !IND
@@ -244,8 +249,7 @@ slang_print_ir(const slang_ir_node *n, i
 #else
       printf("%3d:", indent);
 #endif
-      for (i = 0; i < indent; i++)
-	 printf(" ");
+      spaces(indent);
 
    switch (n->Opcode) {
    case IR_SEQ:
@@ -289,11 +293,14 @@ slang_print_ir(const slang_ir_node *n, i
    case IR_IF:
       printf("IF \n");
       slang_print_ir(n->Children[0], indent+3);
-      break;
-   case IR_ELSE:
-      printf("ELSE\n");
-      break;
-   case IR_ENDIF:
+      spaces(indent);
+      printf("THEN\n");
+      slang_print_ir(n->Children[1], indent+3);
+      if (n->Children[2]) {
+         spaces(indent);
+         printf("ELSE\n");
+         slang_print_ir(n->Children[2], indent+3);
+      }
       printf("ENDIF\n");
       break;
 
@@ -1041,6 +1048,44 @@ emit_not(slang_var_table *vt, slang_ir_n
 }
 
 
+static struct prog_instruction *
+emit_if(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog)
+{
+   struct prog_instruction *ifInst;
+   GLuint ifInstLoc, elseInstLoc;
+
+   emit(vt, n->Children[0], prog);  /* the condition */
+   ifInstLoc = prog->NumInstructions;
+   ifInst = new_instruction(prog, OPCODE_IF);
+   ifInst->DstReg.CondMask = COND_NE;  /* if cond is non-zero */
+   ifInst->DstReg.CondSwizzle = SWIZZLE_X;
+
+   /* if body */
+   emit(vt, n->Children[1], prog);
+
+   if (n->Children[2]) {
+      /* else body */
+      elseInstLoc = prog->NumInstructions;
+      (void) new_instruction(prog, OPCODE_ELSE);
+      ifInst = prog->Instructions + ifInstLoc;
+      ifInst->BranchTarget = prog->NumInstructions;
+
+      emit(vt, n->Children[2], prog);
+   }
+   else {
+      ifInst = prog->Instructions + ifInstLoc;
+      ifInst->BranchTarget = prog->NumInstructions + 1;
+   }
+
+   (void) new_instruction(prog, OPCODE_ENDIF);
+   if (n->Children[2]) {
+      struct prog_instruction *elseInst;
+      elseInst = prog->Instructions + elseInstLoc;
+      elseInst->BranchTarget = prog->NumInstructions;
+   }
+   return NULL;
+}
+
 
 /**
  * Remove any SWIZZLE_NIL terms from given swizzle mask (smear prev term).
@@ -1254,42 +1299,7 @@ emit(slang_var_table *vt, slang_ir_node 
       return emit_kill(prog);
 
    case IR_IF:
-      {
-         struct prog_instruction *inst;
-         emit(vt, n->Children[0], prog);  /* the condition */
-         inst = new_instruction(prog, OPCODE_IF);
-         inst->DstReg.CondMask = COND_NE;  /* if cond is non-zero */
-         inst->DstReg.CondSwizzle = SWIZZLE_X;
-         n->InstLocation = prog->NumInstructions - 1;
-         return inst;
-      }
-   case IR_ELSE:
-      {
-         struct prog_instruction *inst, *ifInst;
-         n->InstLocation = prog->NumInstructions;
-         inst = new_instruction(prog, OPCODE_ELSE);
-         /* point IF's BranchTarget just after this instruction */
-         assert(n->BranchNode);
-         assert(n->BranchNode->InstLocation >= 0);
-         ifInst = prog->Instructions + n->BranchNode->InstLocation;
-         assert(ifInst->Opcode == OPCODE_IF);
-         ifInst->BranchTarget = prog->NumInstructions;
-         return inst;
-      }
-   case IR_ENDIF:
-      {
-         struct prog_instruction *inst, *elseInst;
-         n->InstLocation = prog->NumInstructions;
-         inst = new_instruction(prog, OPCODE_ENDIF);
-         /* point ELSE's BranchTarget to just after this inst */
-         assert(n->BranchNode);
-         assert(n->BranchNode->InstLocation >= 0);
-         elseInst = prog->Instructions + n->BranchNode->InstLocation;
-         assert(elseInst->Opcode == OPCODE_ELSE ||
-                elseInst->Opcode == OPCODE_IF);
-         elseInst->BranchTarget = prog->NumInstructions;
-         return inst;
-      }
+      return emit_if(vt, n, prog);
 
    case IR_BEGIN_LOOP:
       {
diff --git a/src/mesa/shader/slang/slang_ir.h b/src/mesa/shader/slang/slang_ir.h
index df5fc06..0f2ceb0 100644
--- a/src/mesa/shader/slang/slang_ir.h
+++ b/src/mesa/shader/slang/slang_ir.h
@@ -53,9 +53,7 @@ typedef enum
    IR_CJUMP1,  /* conditional jump if one (or non-zero) */
    IR_COND,    /* conditional expression/predicate */
 
-   IR_IF,      /* high-level IF */
-   IR_ELSE,    /* high-level ELSE */
-   IR_ENDIF,   /* high-level ENDIF */
+   IR_IF,      /* high-level IF/then/else */
 
    IR_BEGIN_SUB, /* begin subroutine */
    IR_END_SUB,   /* end subroutine */



More information about the mesa-commit mailing list