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

Brian Paul brianp at kemper.freedesktop.org
Thu Feb 8 20:23:50 UTC 2007


 src/mesa/shader/slang/slang_codegen.c |  106 ++++++++++++----------------
 src/mesa/shader/slang/slang_emit.c    |   44 +++++++++++
 src/mesa/swrast/s_fragprog.c          |  125 +++++++++++++++-------------------
 3 files changed, 144 insertions(+), 131 deletions(-)

New commits:
diff-tree b768c485474baefdde63098776e9d32c17b859ab (from 97125fb370faa6aee0967254fad69f27189b9325)
Author: Brian <brian at nostromo.localnet.net>
Date:   Thu Feb 8 13:23:17 2007 -0700

    Use conditional break in for/do/while loops.

diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c
index bd7b30c..6671f31 100644
--- a/src/mesa/shader/slang/slang_codegen.c
+++ b/src/mesa/shader/slang/slang_codegen.c
@@ -617,6 +617,21 @@ new_break(slang_ir_node *loopNode)
 
 
 static slang_ir_node *
+new_break_if_false(slang_ir_node *loopNode, slang_ir_node *cond)
+{
+   slang_ir_node *n = new_node1(IR_BREAK_IF_FALSE, cond);
+   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;
+}
+
+
+static slang_ir_node *
 new_cont(slang_ir_node *loopNode)
 {
    slang_ir_node *n = new_node0(IR_CONT);
@@ -632,6 +647,14 @@ new_cont(slang_ir_node *loopNode)
 
 
 static slang_ir_node *
+new_cond(slang_ir_node *n)
+{
+   slang_ir_node *c = new_node1(IR_COND, n);
+   return c;
+}
+
+
+static slang_ir_node *
 new_if(slang_ir_node *cond, slang_ir_node *ifPart, slang_ir_node *elsePart)
 {
    return new_node3(IR_IF, cond, ifPart, elsePart);
@@ -1290,14 +1313,6 @@ _slang_is_noop(const slang_operation *op
 }
 
 
-static slang_ir_node *
-_slang_gen_cond(slang_ir_node *n)
-{
-   slang_ir_node *c = new_node1(IR_COND, n);
-   return c;
-}
-
-
 static void
 print_funcs(struct slang_function_scope_ *scope, const char *name)
 {
@@ -1381,12 +1396,10 @@ _slang_gen_while(slang_assemble_ctx * A,
    slang_ir_node *prevLoop;
    /*
     * LOOP:
-    *    eval expr (child[0]), updating condcodes
-    *    IF !expr:
-    *       BRK
+    *    BREAK if !expr (child[0])
     *    body code (child[1])
     */
-   slang_ir_node *ifThen, *cond, *body, *loop;
+   slang_ir_node *loop, *cond, *breakIf, *body;
 
    loop = new_loop(NULL);
 
@@ -1395,19 +1408,12 @@ _slang_gen_while(slang_assemble_ctx * A,
    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(A->CurLoop),
-                   NULL);
-
+   breakIf = new_break_if_false(A->CurLoop, cond);
    body = _slang_gen_operation(A, &oper->children[1]);
+   loop->Children[0] = new_seq(breakIf, body);
 
-   loop->Children[0] = new_seq(ifThen, body);
-
-
-   A->CurLoop = prevLoop; /* pop loop, restore prev */
+   /* pop loop, restore prev */
+   A->CurLoop = prevLoop;
 
    return loop;
 }
@@ -1423,11 +1429,9 @@ _slang_gen_do(slang_assemble_ctx * A, co
    /*
     * LOOP:
     *    body code (child[0])
-    *    eval expr (child[1]), updating condcodes
-    *    IF !expr:
-    *       BRK
+    *    BREAK if !expr (child[1])
     */
-   slang_ir_node *ifThen, *cond, *body, *loop;
+   slang_ir_node *loop, *cond, *breakIf, *body;
 
    loop = new_loop(NULL);
 
@@ -1436,18 +1440,12 @@ _slang_gen_do(slang_assemble_ctx * A, co
    A->CurLoop = loop;
 
    body = _slang_gen_operation(A, &oper->children[0]);
-
    cond = _slang_gen_operation(A, &oper->children[1]);
-   cond = new_node1(IR_NOT, cond);
-   cond = _slang_gen_cond(cond);
+   breakIf = new_break_if_false(A->CurLoop, cond);
+   loop->Children[0] = new_seq(body, breakIf);
 
-   ifThen = new_if(cond,
-                   new_break(A->CurLoop),
-                   NULL);
-
-   loop->Children[0] = new_seq(body, ifThen);
-
-   A->CurLoop = prevLoop; /* pop loop, restore prev */
+   /* pop loop, restore prev */
+   A->CurLoop = prevLoop;
 
    return loop;
 }
@@ -1463,13 +1461,11 @@ _slang_gen_for(slang_assemble_ctx * A, c
    /*
     * init (child[0])
     * LOOP:
-    *    eval expr (child[1]), updating condcodes
-    *    IF !expr:
-    *       BRK
+    *    BREAK if !expr (child[1])
     *    body code (child[3])
     *    incr code (child[2])   // XXX continue here
     */
-   slang_ir_node *init, *ifThen, *cond, *body, *loop, *incr;
+   slang_ir_node *loop, *cond, *breakIf, *body, *init, *incr;
 
    init = _slang_gen_operation(A, &oper->children[0]);
    loop = new_loop(NULL);
@@ -1479,21 +1475,14 @@ _slang_gen_for(slang_assemble_ctx * A, c
    A->CurLoop = loop;
 
    cond = _slang_gen_operation(A, &oper->children[1]);
-   cond = new_node1(IR_NOT, cond);
-   cond = _slang_gen_cond(cond);
-
-   ifThen = new_if(cond,
-                   new_break(A->CurLoop),
-                   NULL);
-
+   breakIf = new_break_if_false(A->CurLoop, cond);
    body = _slang_gen_operation(A, &oper->children[3]);
-
    incr = _slang_gen_operation(A, &oper->children[2]);
+   loop->Children[0] = new_seq(breakIf,
+                               new_seq(body, incr));
 
-   loop->Children[0] = new_seq(ifThen,
-                               new_seq(body,incr));
-
-   A->CurLoop = prevLoop; /* pop loop, restore prev */
+   /* pop loop, restore prev */
+   A->CurLoop = prevLoop;
 
    return new_seq(init, loop);
 }
@@ -1521,7 +1510,7 @@ _slang_gen_if(slang_assemble_ctx * A, co
    slang_atom endifAtom = slang_atom_pool_gen(A->atoms, "__endif");
 
    cond = _slang_gen_operation(A, &oper->children[0]);
-   cond = _slang_gen_cond(cond);
+   cond = new_cond(cond);
    /*assert(cond->Store);*/
    bra = new_cjump(haveElseClause ? elseAtom : endifAtom, 0);
    tree = new_seq(cond, bra);
@@ -1572,7 +1561,7 @@ _slang_gen_hl_if(slang_assemble_ctx * A,
    slang_ir_node *ifNode, *cond, *ifBody, *elseBody;
 
    cond = _slang_gen_operation(A, &oper->children[0]);
-   cond = _slang_gen_cond(cond);
+   cond = new_cond(cond);
    ifBody = _slang_gen_operation(A, &oper->children[1]);
    if (haveElseClause)
       elseBody = _slang_gen_operation(A, &oper->children[2]);
@@ -1662,7 +1651,7 @@ _slang_gen_select(slang_assemble_ctx *A,
 
    /* eval condition */
    cond = _slang_gen_operation(A, &oper->children[0]);
-   cond = _slang_gen_cond(cond);
+   cond = new_cond(cond);
    tree = new_seq(tmpDecl, cond);
 
    /* jump if false to "alt" label */
@@ -2245,9 +2234,6 @@ _slang_gen_operation(slang_assemble_ctx 
 
    case slang_oper_block_no_new_scope:
       /* list of operations */
-      /*
-      assert(oper->num_children > 0);
-      */
       if (oper->num_children > 0)
       {
          slang_ir_node *n, *tree = NULL;
@@ -2287,7 +2273,7 @@ _slang_gen_operation(slang_assemble_ctx 
       break;
    case slang_oper_expression:
       return _slang_gen_operation(A, &oper->children[0]);
-      break;
+
    case slang_oper_for:
       return _slang_gen_for(A, oper);
    case slang_oper_do:
diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c
index 6e2394f..d83880a 100644
--- a/src/mesa/shader/slang/slang_emit.c
+++ b/src/mesa/shader/slang/slang_emit.c
@@ -332,6 +332,9 @@ slang_print_ir(const slang_ir_node *n, i
    case IR_BREAK:
       printf("BREAK\n");
       break;
+   case IR_BREAK_IF_FALSE:
+      printf("BREAK_IF_FALSE\n");
+      break;
 
    case IR_VAR:
       printf("VAR %s%s at %s  store %p\n",
@@ -1153,13 +1156,17 @@ emit_loop(slang_var_table *vt, slang_ir_
     */
    for (ir = n->BranchNode; ir; ir = ir->BranchNode) {
       struct prog_instruction *inst = prog->Instructions + ir->InstLocation;
-      if (ir->Opcode == IR_BREAK) {
+      if (ir->Opcode == IR_BREAK ||
+          ir->Opcode == IR_BREAK_IF_FALSE ||
+          ir->Opcode == IR_BREAK_IF_TRUE) {
          assert(inst->Opcode == OPCODE_BRK ||
                 inst->Opcode == OPCODE_BRA);
          inst->BranchTarget = endInstLoc + 1;
       }
       else {
-         assert(ir->Opcode == IR_CONT);
+         assert(ir->Opcode == IR_CONT ||
+                ir->Opcode == IR_CONT_IF_FALSE ||
+                ir->Opcode == IR_CONT_IF_TRUE);
          assert(inst->Opcode == OPCODE_CONT ||
                 inst->Opcode == OPCODE_BRA);
          /* XXX goto top of loop instead! */
@@ -1192,6 +1199,35 @@ emit_cont_break(slang_var_table *vt, sla
 
 
 /**
+ * Conditional loop continue/break.
+ */
+static struct prog_instruction *
+emit_cont_break_if(slang_var_table *vt, slang_ir_node *n,
+                   struct gl_program *prog, GLboolean breakTrue)
+{
+   gl_inst_opcode opcode;
+   struct prog_instruction *inst;
+
+   /* evaluate condition expr, setting cond codes */
+   inst = emit(vt, n->Children[0], prog);
+   assert(inst);
+   inst->CondUpdate = GL_TRUE;
+
+   n->InstLocation = prog->NumInstructions;
+   if (EmitHighLevelInstructions) {
+      opcode = (n->Opcode == IR_CONT) ? OPCODE_CONT : OPCODE_BRK;
+   }
+   else {
+      opcode = OPCODE_BRA;
+   }
+   inst = new_instruction(prog, opcode);
+   inst->DstReg.CondMask = breakTrue ? COND_NE : COND_EQ;
+   return inst;
+}
+
+
+
+/**
  * Remove any SWIZZLE_NIL terms from given swizzle mask (smear prev term).
  * Ex: fix_swizzle("zyNN") -> "zyyy"
  */
@@ -1407,6 +1443,10 @@ emit(slang_var_table *vt, slang_ir_node 
 
    case IR_LOOP:
       return emit_loop(vt, n, prog);
+   case IR_BREAK_IF_FALSE:
+      return emit_cont_break_if(vt, n, prog, GL_FALSE);
+   case IR_BREAK_IF_TRUE:
+      return emit_cont_break_if(vt, n, prog, GL_TRUE);
    case IR_BREAK:
       /* fall-through */
    case IR_CONT:
diff-tree 97125fb370faa6aee0967254fad69f27189b9325 (from 2c75ef62ea8dfd690aab6fa4f2c85afba569a21f)
Author: Brian <brian at nostromo.localnet.net>
Date:   Thu Feb 8 13:22:31 2007 -0700

    Simplify code with eval_condition().  Implement conditional BRK.

diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c
index ace10a9..ce028f7 100644
--- a/src/mesa/swrast/s_fragprog.c
+++ b/src/mesa/swrast/s_fragprog.c
@@ -418,6 +418,29 @@ test_cc(GLuint condCode, GLuint ccMaskRu
 
 
 /**
+ * Evaluate the 4 condition codes against a predicate and return GL_TRUE
+ * or GL_FALSE to indicate result.
+ */
+static INLINE GLboolean
+eval_condition(const struct fp_machine *machine,
+               const struct prog_instruction *inst)
+{
+   const GLuint swizzle = inst->DstReg.CondSwizzle;
+   const GLuint condMask = inst->DstReg.CondMask;
+   if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) ||
+       test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) ||
+       test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) ||
+       test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) {
+      return GL_TRUE;
+   }
+   else {
+      return GL_FALSE;
+   }
+}
+
+
+
+/**
  * Store 4 floats into a register.  Observe the instructions saturate and
  * set-condition-code flags.
  */
@@ -687,40 +710,28 @@ execute_program( GLcontext *ctx,
          case OPCODE_ENDSUB: /* end subroutine */
             break;
          case OPCODE_BRA: /* conditional branch */
-            {
-               /* NOTE: The branch is conditional! */
-               const GLuint swizzle = inst->DstReg.CondSwizzle;
-               const GLuint condMask = inst->DstReg.CondMask;
-               if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) ||
-                   test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) ||
-                   test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) ||
-                   test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) {
-                  /* take branch */
-                  pc = inst->BranchTarget - 1;
-               }
+            if (eval_condition(machine, inst)) {
+               /* take branch */
+               pc = inst->BranchTarget - 1;
             }
             break;
-         case OPCODE_BRK: /* break out of loop */
+         case OPCODE_BRK: /* break out of loop (conditional) */
             /* fall-through */
-         case OPCODE_CONT: /* continue loop */
+         case OPCODE_CONT: /* continue loop (conditional) */
             /* Subtract 1 here since we'll do pc++ at end of for-loop */
-            pc = inst->BranchTarget - 1;
+            if (eval_condition(machine, inst)) {
+               /* take branch */
+               pc = inst->BranchTarget - 1;
+            }
             break;
-         case OPCODE_CAL: /* Call subroutine */
-            {
-               /* NOTE: The call is conditional! */
-               const GLuint swizzle = inst->DstReg.CondSwizzle;
-               const GLuint condMask = inst->DstReg.CondMask;
-               if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) ||
-                   test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) ||
-                   test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) ||
-                   test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) {
-                  if (machine->StackDepth >= MAX_PROGRAM_CALL_DEPTH) {
-                     return GL_TRUE; /* Per GL_NV_vertex_program2 spec */
-                  }
-                  machine->CallStack[machine->StackDepth++] = pc + 1;
-                  pc = inst->BranchTarget; /* XXX - 1 ??? */
+         case OPCODE_CAL: /* Call subroutine (conditional) */
+            if (eval_condition(machine, inst)) {
+               /* call the subroutine */
+               if (machine->StackDepth >= MAX_PROGRAM_CALL_DEPTH) {
+                  return GL_TRUE; /* Per GL_NV_vertex_program2 spec */
                }
+               machine->CallStack[machine->StackDepth++] = pc + 1;
+               pc = inst->BranchTarget; /* XXX - 1 ??? */
             }
             break;
          case OPCODE_CMP:
@@ -871,29 +882,20 @@ execute_program( GLcontext *ctx,
             }
             break;
          case OPCODE_IF:
-            {
-               const GLuint swizzle = inst->DstReg.CondSwizzle;
-               const GLuint condMask = inst->DstReg.CondMask;
-               if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) ||
-                   test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) ||
-                   test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) ||
-                   test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) {
-                  /* do if-clause (just continue execution) */
-               }
-               else {
-                  /* go to the instruction after ELSE or ENDIF */
-                  assert(inst->BranchTarget >= 0);
-                  pc = inst->BranchTarget - 1;
-               }
+            if (eval_condition(machine, inst)) {
+               /* do if-clause (just continue execution) */
             }
-            break;
-         case OPCODE_ELSE:
-            {
-               /* goto ENDIF */
+            else {
+               /* go to the instruction after ELSE or ENDIF */
                assert(inst->BranchTarget >= 0);
                pc = inst->BranchTarget - 1;
             }
             break;
+         case OPCODE_ELSE:
+            /* goto ENDIF */
+            assert(inst->BranchTarget >= 0);
+            pc = inst->BranchTarget - 1;
+            break;
          case OPCODE_ENDIF:
             /* nothing */
             break;
@@ -908,16 +910,9 @@ execute_program( GLcontext *ctx,
                store_vector4( inst, machine, result );
             }
             break;
-         case OPCODE_KIL_NV: /* NV_f_p only */
-            {
-               const GLuint swizzle = inst->DstReg.CondSwizzle;
-               const GLuint condMask = inst->DstReg.CondMask;
-               if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) ||
-                   test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) ||
-                   test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) ||
-                   test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) {
-                  return GL_FALSE;
-               }
+         case OPCODE_KIL_NV: /* NV_f_p only (conditional) */
+            if (eval_condition(machine, inst)) {
+               return GL_FALSE;
             }
             break;
          case OPCODE_KIL: /* ARB_f_p only */
@@ -1203,20 +1198,12 @@ execute_program( GLcontext *ctx,
                store_vector4( inst, machine, result );
             }
             break;
-         case OPCODE_RET: /* return from subroutine */
-            {
-               /* NOTE: The return is conditional! */
-               const GLuint swizzle = inst->DstReg.CondSwizzle;
-               const GLuint condMask = inst->DstReg.CondMask;
-               if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) ||
-                   test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) ||
-                   test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) ||
-                   test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) {
-                  if (machine->StackDepth == 0) {
-                     return GL_TRUE; /* Per GL_NV_vertex_program2 spec */
-                  }
-                  pc = machine->CallStack[--machine->StackDepth];
+         case OPCODE_RET: /* return from subroutine (conditional) */
+            if (eval_condition(machine, inst)) {
+               if (machine->StackDepth == 0) {
+                  return GL_TRUE; /* Per GL_NV_vertex_program2 spec */
                }
+               pc = machine->CallStack[--machine->StackDepth];
             }
             break;
          case OPCODE_RFL: /* reflection vector */



More information about the mesa-commit mailing list