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