summaryrefslogtreecommitdiffstats
path: root/src/mesa
diff options
context:
space:
mode:
authorBrian Paul <[email protected]>2009-06-24 17:02:34 -0600
committerBrian Paul <[email protected]>2009-06-26 13:16:34 -0600
commit2f1c5c58b33dc616a3744cd40fcae20971309b3c (patch)
treedc4e625a8dfae9d6f31393e22279b1ef175c2b88 /src/mesa
parent65eaafee250bdcc8e82104e45dcc152735cf8b85 (diff)
glsl: checkpoint: predicate __retVal = expr with __returnFlag
The glean "function with early return (1)" test passes now.
Diffstat (limited to 'src/mesa')
-rw-r--r--src/mesa/shader/slang/slang_codegen.c86
1 files changed, 60 insertions, 26 deletions
diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c
index c4550bbd9ba..f182ae6e06a 100644
--- a/src/mesa/shader/slang/slang_codegen.c
+++ b/src/mesa/shader/slang/slang_codegen.c
@@ -951,7 +951,7 @@ slang_substitute(slang_assemble_ctx *A, slang_operation *oper,
* return;
* then do substitutions on the assignment.
*/
- slang_operation *blockOper, *assignOper, *returnOper;
+ slang_operation *blockOper;
/* check if function actually has a return type */
assert(A->CurFunction);
@@ -962,31 +962,64 @@ slang_substitute(slang_assemble_ctx *A, slang_operation *oper,
blockOper = slang_operation_new(1);
blockOper->type = SLANG_OPER_BLOCK_NO_NEW_SCOPE;
- blockOper->num_children = 2;
blockOper->locals->outer_scope = oper->locals->outer_scope;
- blockOper->children = slang_operation_new(2);
- assignOper = blockOper->children + 0;
- returnOper = blockOper->children + 1;
-
- assignOper->type = SLANG_OPER_ASSIGN;
- assignOper->num_children = 2;
- assignOper->locals->outer_scope = blockOper->locals;
- assignOper->children = slang_operation_new(2);
- assignOper->children[0].type = SLANG_OPER_IDENTIFIER;
- assignOper->children[0].a_id = slang_atom_pool_atom(A->atoms, "__retVal");
- assignOper->children[0].locals->outer_scope = assignOper->locals;
+ slang_operation_add_children(blockOper, 2);
+
+ /* if EmitContReturn:
+ * if (!__returnFlag) {
+ * build: __retVal = expr;
+ * }
+ * otherwise:
+ * build: __retVal = expr;
+ */
+ {
+ slang_operation *assignOper;
- slang_operation_copy(&assignOper->children[1],
- &oper->children[0]);
+ if (!A->EmitContReturn) {
+ slang_operation *ifOper = slang_oper_child(blockOper, 0);
+ ifOper->type = SLANG_OPER_IF;
+ slang_operation_add_children(ifOper, 3);
+
+ {
+ slang_operation *cond = slang_oper_child(ifOper, 0);
+ cond->type = SLANG_OPER_IDENTIFIER;
+ cond->a_id = slang_atom_pool_atom(A->atoms, "__returnFlag");
+ }
+ {
+ assignOper = slang_oper_child(ifOper, 1);
+ }
+ {
+ slang_operation *elseOper = slang_oper_child(ifOper, 2);
+ elseOper->type = SLANG_OPER_VOID;
+ }
+ }
+ else {
+ assignOper = slang_oper_child(blockOper, 0);
+ }
- returnOper->type = SLANG_OPER_RETURN; /* return w/ no value */
- returnOper->locals->outer_scope = blockOper->locals;
+ assignOper->type = SLANG_OPER_ASSIGN;
+ slang_operation_add_children(assignOper, 2);
+ {
+ slang_operation *lhs = slang_oper_child(assignOper, 0);
+ lhs->type = SLANG_OPER_IDENTIFIER;
+ lhs->a_id = slang_atom_pool_atom(A->atoms, "__retVal");
+ }
+ {
+ slang_operation *rhs = slang_oper_child(assignOper, 1);
+ slang_operation_copy(rhs, &oper->children[0]);
+ }
- assert(returnOper->num_children == 0);
+ /* do substitutions on the "__retVal = expr" sub-tree */
+ slang_substitute(A, assignOper,
+ substCount, substOld, substNew, GL_FALSE);
+ }
- /* do substitutions on the "__retVal = expr" sub-tree */
- slang_substitute(A, assignOper,
- substCount, substOld, substNew, GL_FALSE);
+ /* build: return; */
+ {
+ slang_operation *returnOper = slang_oper_child(blockOper, 1);
+ returnOper->type = SLANG_OPER_RETURN; /* return w/ no value */
+ assert(returnOper->num_children == 0);
+ }
/* install new code */
slang_operation_copy(oper, blockOper);
@@ -1408,14 +1441,14 @@ declare_return_flag(slang_assemble_ctx *A, slang_operation *oper)
decl = slang_operation_insert_child(oper, 1);
slang_generate_declaration(A, oper->locals, decl,
- SLANG_SPEC_BOOL, "__returnFlag", GL_FALSE);
+ SLANG_SPEC_BOOL, "__returnFlag", GL_TRUE);
slang_print_tree(oper, 0);
}
/**
- * Replace 'return' with '__returnFlag = true'.
+ * Replace 'return' with '__returnFlag = false'.
* This is used to remove 'early returns' from functions.
*/
static void
@@ -1424,7 +1457,7 @@ replace_return_with_flag_set(slang_assemble_ctx *A, slang_operation *oper)
slang_atom id = slang_atom_pool_atom(A->atoms, "__returnFlag");
assert(oper->type == SLANG_OPER_RETURN);
- /* replace 'return' with __returnFlag = true' */
+ /* replace 'return' with __returnFlag = false' */
slang_operation_free_children(oper);
oper->type = SLANG_OPER_ASSIGN;
slang_operation_add_children(oper, 2);
@@ -1435,7 +1468,7 @@ replace_return_with_flag_set(slang_assemble_ctx *A, slang_operation *oper)
}
{
slang_operation *rhs = slang_oper_child(oper, 1);
- slang_operation_literal_bool(rhs, GL_TRUE);
+ slang_operation_literal_bool(rhs, GL_FALSE);
}
{
@@ -3966,6 +3999,7 @@ _slang_gen_return(slang_assemble_ctx * A, slang_operation *oper)
new_return(A->curFuncEndLabel));
}
else {
+ /* set __returnFlag = false; */
slang_operation *setFlag = slang_operation_new(1);
setFlag->type = SLANG_OPER_ASSIGN;
setFlag->locals->outer_scope = oper->locals;
@@ -3977,7 +4011,7 @@ _slang_gen_return(slang_assemble_ctx * A, slang_operation *oper)
}
{
slang_operation *rhs = slang_oper_child(setFlag, 1);
- slang_operation_literal_bool(rhs, GL_TRUE);
+ slang_operation_literal_bool(rhs, GL_FALSE);
}
n = new_seq(_slang_gen_operation(A, assign),
_slang_gen_operation(A, setFlag));