redo IR_IF node, removing IR_ELSE, IR_ENDIF
authorBrian <brian@nostromo.localnet.net>
Wed, 7 Feb 2007 03:45:43 +0000 (20:45 -0700)
committerBrian <brian@nostromo.localnet.net>
Wed, 7 Feb 2007 03:45:43 +0000 (20:45 -0700)
src/mesa/shader/slang/slang_codegen.c
src/mesa/shader/slang/slang_emit.c
src/mesa/shader/slang/slang_ir.h

index a5f033d91231c42ad026b56a3038837f787eb6ac..780c9c1cfed14fe57ee7a3f530ee9a95a7b79023 100644 (file)
@@ -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 * A, const slang_operation *oper)
     *    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 * A, const slang_operation *oper)
    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, const slang_operation *oper)
 
 /**
  * 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, const slang_operation *oper)
     * 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;
 }
 
 
index 3faacdd4cf84731cf3d9b9ae8e97862a9eef6689..82a8f0befb4ea6942331eedbabd86582f54236f0 100644 (file)
@@ -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 *st)
 }
 
 
+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, int indent)
 #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, int indent)
    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_node *n, struct gl_program *prog)
 }
 
 
+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 *n, struct gl_program *prog)
       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:
       {
index df5fc067790d69e4044e4e8b3359344b53db945f..0f2ceb03c07fc5d9076e7cd0f2e790e05563b7e2 100644 (file)
@@ -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 */