redo IR_IF node, removing IR_ELSE, IR_ENDIF
This commit is contained in:
@@ -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);
|
||||
ifBody = _slang_gen_operation(A, &oper->children[1]);
|
||||
if (haveElseClause)
|
||||
elseBody = _slang_gen_operation(A, &oper->children[2]);
|
||||
else
|
||||
elseBody = NULL;
|
||||
|
||||
trueBody = _slang_gen_operation(A, &oper->children[1]);
|
||||
tree = new_seq(ifNode, trueBody);
|
||||
ifNode = new_if(cond, ifBody, elseBody);
|
||||
|
||||
if (haveElseClause) {
|
||||
elseNode = new_else(ifNode);
|
||||
tree = new_seq(tree, elseNode);
|
||||
|
||||
falseBody = _slang_gen_operation(A, &oper->children[2]);
|
||||
tree = new_seq(tree, falseBody);
|
||||
}
|
||||
|
||||
endifNode = new_endif(haveElseClause ? elseNode : ifNode);
|
||||
tree = new_seq(tree, endifNode);
|
||||
|
||||
return tree;
|
||||
return ifNode;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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:
|
||||
{
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user