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

Brian Paul brianp at kemper.freedesktop.org
Tue Feb 6 00:25:12 UTC 2007


 src/mesa/shader/prog_print.c          |   13 +++---
 src/mesa/shader/slang/slang_codegen.c |   64 +++++++++++++++++++++++++++-------
 src/mesa/shader/slang/slang_emit.c    |   12 ++++++
 src/mesa/swrast/s_fragprog.c          |   57 +++---------------------------
 4 files changed, 76 insertions(+), 70 deletions(-)

New commits:
diff-tree 86080796471df6a9e126fd536b21c3b10cb5310c (from d9731b26e759671d63e357eee2c921e90448ada2)
Author: Brian <brian at yutani.localnet.net>
Date:   Mon Feb 5 17:18:10 2007 -0700

    Use IR node's BranchNode field for IF/ELSE/ENDIF instructions.
    
    This allows us to back-patch the IF/ELSE instruction's BranchTarget field
    to point to the location of the ELSE/ENDIF instructions.  No longer have to
    search for ELSE/ENDIF in the interpreter.  Also makes it trivial to translate
    IF/ELSE instructions into conditional/unconditional BRA instructions.

diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c
index 208c998..aea11da 100644
--- a/src/mesa/shader/prog_print.c
+++ b/src/mesa/shader/prog_print.c
@@ -319,13 +319,14 @@ _mesa_print_instruction(const struct pro
       print_comment(inst);
       break;
    case OPCODE_IF:
-      _mesa_printf("IF (%s%s)",
+      _mesa_printf("IF (%s%s) (if false, goto %d)",
                    condcode_string(inst->DstReg.CondMask),
-                   swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE));
+                   swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE),
+                   inst->BranchTarget);
       print_comment(inst);
       return indent + 3;
    case OPCODE_ELSE:
-      _mesa_printf("ELSE\n");
+      _mesa_printf("ELSE (goto %d)\n", inst->BranchTarget);
       return indent + 3;
    case OPCODE_ENDIF:
       _mesa_printf("ENDIF\n");
diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c
index c70f73f..7a1881c 100644
--- a/src/mesa/shader/slang/slang_codegen.c
+++ b/src/mesa/shader/slang/slang_codegen.c
@@ -591,6 +591,47 @@ new_end_loop(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)
+{
+   slang_ir_node *n = new_node(IR_IF, NULL, NULL);
+   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;
+   }
+   return n;
+}
+
+
+/**
  * New IR_VAR node - a reference to a previously declared variable.
  */
 static slang_ir_node *
@@ -1401,13 +1442,13 @@ _slang_gen_hl_while(slang_assemble_ctx *
    cond = new_node(IR_NOT, cond, NULL);
    cond = _slang_gen_cond(cond);
 
-   ifThen = new_node(IR_IF, cond, NULL);
+   ifThen = new_if(cond);
    tree = new_seq(beginLoop, ifThen);
 
    brk = new_node(IR_BREAK, NULL, NULL);
    tree = new_seq(tree, brk);
 
-   endif = new_node(IR_ENDIF, NULL, NULL);
+   endif = new_endif(ifThen);
    tree = new_seq(tree, endif);
 
    body = _slang_gen_operation(A, &oper->children[1]);
@@ -1589,13 +1630,11 @@ _slang_gen_hl_if(slang_assemble_ctx * A,
 {
    /*
     * eval expr (child[0]), updating condcodes
-    * branch if false to _else or _endif
-    * "true" code block
-    * if haveElseClause clause:
-    *    jump "__endif"
-    *    label "__else"
-    *    "false" code block
-    * label "__endif"
+    * IF expr THEN
+    *    if-body code
+    * ELSE
+    *    else-body code
+    * ENDIF
     */
    /* XXX special cases to check for:
     * if body of conditiona is just a "break", emit a conditional break
@@ -1608,21 +1647,20 @@ _slang_gen_hl_if(slang_assemble_ctx * A,
    cond = _slang_gen_operation(A, &oper->children[0]);
    cond = _slang_gen_cond(cond);
    /*assert(cond->Store);*/
-   ifNode = new_node(IR_IF, cond, NULL);
+   ifNode = new_if(cond);
 
    trueBody = _slang_gen_operation(A, &oper->children[1]);
    tree = new_seq(ifNode, trueBody);
 
    if (haveElseClause) {
-      /* else clause */
-      elseNode = new_node(IR_ELSE, NULL, NULL);
+      elseNode = new_else(ifNode);
       tree = new_seq(tree, elseNode);
 
       falseBody = _slang_gen_operation(A, &oper->children[2]);
       tree = new_seq(tree, falseBody);
    }
 
-   endifNode = new_node(IR_ENDIF, NULL, NULL);
+   endifNode = new_endif(haveElseClause ? elseNode : ifNode);
    tree = new_seq(tree, endifNode);
 
    return tree;
diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c
index 311eea1..b890a6d 100644
--- a/src/mesa/shader/slang/slang_emit.c
+++ b/src/mesa/shader/slang/slang_emit.c
@@ -1036,6 +1036,7 @@ emit_not(slang_var_table *vt, slang_ir_n
 
    free_temp_storage(vt, n->Children[0]);
 
+   inst->Comment = _mesa_strdup("NOT");
    return inst;
 }
 
@@ -1259,18 +1260,29 @@ emit(slang_var_table *vt, slang_ir_node 
          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;
+         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);
+         prog->Instructions[n->BranchNode->InstLocation].BranchTarget = prog->NumInstructions;
          return inst;
       }
    case IR_ENDIF:
       {
          struct prog_instruction *inst;
+         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);
+         prog->Instructions[n->BranchNode->InstLocation].BranchTarget = prog->NumInstructions;
          return inst;
       }
 
diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c
index 287dd9b..fbd25c0 100644
--- a/src/mesa/swrast/s_fragprog.c
+++ b/src/mesa/swrast/s_fragprog.c
@@ -897,62 +897,17 @@ execute_program( GLcontext *ctx,
                   /* do if-clause (just continue execution) */
                }
                else {
-                  /* search for else-clause or endif */
-                  /* XXX could encode location of the else/endif statement
-                   * in the IF instruction to avoid searching...
-                   */
-                  GLint ifDepth = 1;
-                  do {
-                     pc++;
-                     inst = program->Base.Instructions + pc;
-                     if (inst->Opcode == OPCODE_END) {
-                        /* mal-formed program! */
-                        _mesa_problem(ctx, "END found before ELSE/ENDIF");
-                        return GL_FALSE;
-                     }
-                     else if (inst->Opcode == OPCODE_IF) {
-                        /* nested if */
-                        ifDepth++;
-                     }
-                     else if (inst->Opcode == OPCODE_ELSE) {
-                        if (ifDepth == 1) {
-                           /* ok, continue normal execution */
-                           break;
-                        }
-                     }
-                     else if (inst->Opcode == OPCODE_ENDIF) {
-                        ifDepth--;
-                        if (ifDepth == 0) {
-                           /* ok, continue normal execution */
-                           break;
-                        }
-                     }
-                     assert(ifDepth >= 0);
-                  } while (pc < maxInst);
+                  /* go to the instruction after ELSE or ENDIF */
+                  assert(inst->BranchTarget >= 0);
+                  pc = inst->BranchTarget - 1;
                }
             }
             break;
          case OPCODE_ELSE:
             {
-               /* find/goto ENDIF */
-               GLint ifDepth = 1;
-               do {
-                  pc++;
-                  inst = program->Base.Instructions + pc;
-                  if (inst->Opcode == OPCODE_END) {
-                     /* mal-formed program! */
-                     abort();
-                  }
-                  else if (inst->Opcode == OPCODE_IF) {
-                     ifDepth++;
-                  }
-                  else if (inst->Opcode == OPCODE_ENDIF) {
-                     ifDepth--;
-                     if (ifDepth == 0)
-                        break;
-                  }
-                  assert(ifDepth >= 0);
-               } while (pc < maxInst);
+               /* goto ENDIF */
+               assert(inst->BranchTarget >= 0);
+               pc = inst->BranchTarget - 1;
             }
             break;
          case OPCODE_ENDIF:
diff-tree d9731b26e759671d63e357eee2c921e90448ada2 (from 5e73284cee882bc3463e013c9b468a9b84c6dbc1)
Author: Brian <brian at yutani.localnet.net>
Date:   Mon Feb 5 15:17:06 2007 -0700

    minor formatting changes

diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c
index 9474fe9..208c998 100644
--- a/src/mesa/shader/prog_print.c
+++ b/src/mesa/shader/prog_print.c
@@ -325,16 +325,16 @@ _mesa_print_instruction(const struct pro
       print_comment(inst);
       return indent + 3;
    case OPCODE_ELSE:
-      _mesa_printf("ELSE;\n");
+      _mesa_printf("ELSE\n");
       return indent + 3;
    case OPCODE_ENDIF:
-      _mesa_printf("ENDIF;\n");
+      _mesa_printf("ENDIF\n");
       break;
    case OPCODE_BGNLOOP:
-      _mesa_printf("LOOP;\n");
+      _mesa_printf("BGNLOOP\n");
       return indent + 3;
    case OPCODE_ENDLOOP:
-      _mesa_printf("ENDLOOP;\n");
+      _mesa_printf("ENDLOOP (goto %d)\n", inst->BranchTarget);
       break;
    case OPCODE_BRK:
       /* XXX just like BRA */



More information about the mesa-commit mailing list