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