summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Paul <brian.paul@tungstengraphics.com>2008-07-15 13:25:57 -0600
committerBrian Paul <brian.paul@tungstengraphics.com>2008-07-15 13:29:25 -0600
commitf6152c35101311c2b128eb23b25b3f38d9e8b5be (patch)
tree5954adf19ff894e7225e997bc1c9535ef5eb63bc
parentbc4b1ca5636e68a6e6b0e3f88e9ff6b888837656 (diff)
mesa: fix some function inlining bugs
Need to add local vars of original function to the new scope's variable list (though the DECLs were already present). In slang_operation_copy() call slang_replace_scope() for SLANG_OPER_BLOCK_NEW_SCOPE opers.
-rw-r--r--src/mesa/shader/slang/slang_codegen.c41
-rw-r--r--src/mesa/shader/slang/slang_compile_operation.c31
-rw-r--r--src/mesa/shader/slang/slang_compile_operation.h5
-rw-r--r--src/mesa/shader/slang/slang_compile_variable.h1
4 files changed, 53 insertions, 25 deletions
diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c
index 425beefe85..9d5721214f 100644
--- a/src/mesa/shader/slang/slang_codegen.c
+++ b/src/mesa/shader/slang/slang_codegen.c
@@ -651,6 +651,8 @@ new_var(slang_assemble_ctx *A, slang_operation *oper, slang_atom name)
if (!var)
return NULL;
+ assert(var->declared);
+
assert(!oper->var || oper->var == var);
n = new_node0(IR_VAR);
@@ -925,31 +927,6 @@ slang_substitute(slang_assemble_ctx *A, slang_operation *oper,
/**
- * Recursively traverse 'oper', replacing occurances of 'oldScope' with
- * 'newScope' in the oper->locals->outer_scope filed.
- *
- * This is used after function inlining to update the scoping of
- * the newly copied/inlined code so that vars are found in the new,
- * inlined scope and not in the original function code.
- */
-static void
-slang_replace_scope(slang_operation *oper,
- slang_variable_scope *oldScope,
- slang_variable_scope *newScope)
-{
- GLuint i;
- if (oper->locals != newScope &&
- oper->locals->outer_scope == oldScope) {
- oper->locals->outer_scope = newScope;
- }
- for (i = 0; i < oper->num_children; i++) {
- slang_replace_scope(&oper->children[i], oldScope, newScope);
- }
-}
-
-
-
-/**
* Produce inline code for a call to an assembly instruction.
* This is typically used to compile a call to a built-in function like this:
*
@@ -1235,6 +1212,16 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun,
}
}
+ /* Now add copies of the function's local vars to the new variable scope */
+ for (i = totalArgs; i < fun->parameters->num_variables; i++) {
+ slang_variable *p = fun->parameters->variables[i];
+ slang_variable *pCopy = slang_variable_scope_grow(inlined->locals);
+ pCopy->type = p->type;
+ pCopy->a_name = p->a_name;
+ pCopy->array_len = p->array_len;
+ }
+
+
/* New epilog statements:
* 1. Create end of function label to jump to from return statements.
* 2. Copy the 'out' parameter vars
@@ -2105,6 +2092,8 @@ static slang_ir_node *
_slang_gen_var_decl(slang_assemble_ctx *A, slang_variable *var)
{
slang_ir_node *n;
+ /*assert(!var->declared);*/
+ var->declared = GL_TRUE;
assert(!is_sampler_type(&var->type));
n = new_node0(IR_VAR_DECL);
if (n) {
@@ -3190,6 +3179,8 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var,
if (store)
var->aux = store; /* save var's storage info */
+ var->declared = GL_TRUE;
+
return success;
}
diff --git a/src/mesa/shader/slang/slang_compile_operation.c b/src/mesa/shader/slang/slang_compile_operation.c
index b18e08d2ae..4d2fd5b666 100644
--- a/src/mesa/shader/slang/slang_compile_operation.c
+++ b/src/mesa/shader/slang/slang_compile_operation.c
@@ -69,8 +69,31 @@ slang_operation_destruct(slang_operation * oper)
oper->locals = NULL;
}
+
+/**
+ * Recursively traverse 'oper', replacing occurances of 'oldScope' with
+ * 'newScope' in the oper->locals->outer_scope field.
+ */
+void
+slang_replace_scope(slang_operation *oper,
+ slang_variable_scope *oldScope,
+ slang_variable_scope *newScope)
+{
+ GLuint i;
+ if (oper->locals != newScope &&
+ oper->locals->outer_scope == oldScope) {
+ oper->locals->outer_scope = newScope;
+ }
+ for (i = 0; i < oper->num_children; i++) {
+ slang_replace_scope(&oper->children[i], oldScope, newScope);
+ }
+}
+
+
/**
* Recursively copy a slang_operation node.
+ * \param x copy target
+ * \param y copy source
* \return GL_TRUE for success, GL_FALSE if failure
*/
GLboolean
@@ -121,6 +144,14 @@ slang_operation_copy(slang_operation * x, const slang_operation * y)
#endif
slang_operation_destruct(x);
*x = z;
+
+ /* If this operation declares a new scope, we need to make sure
+ * all children point to it, not the original operation's scope!
+ */
+ if (x->type == SLANG_OPER_BLOCK_NEW_SCOPE) {
+ slang_replace_scope(x, y->locals, x->locals);
+ }
+
return GL_TRUE;
}
diff --git a/src/mesa/shader/slang/slang_compile_operation.h b/src/mesa/shader/slang/slang_compile_operation.h
index d5cbe779a6..4f92aa9a08 100644
--- a/src/mesa/shader/slang/slang_compile_operation.h
+++ b/src/mesa/shader/slang/slang_compile_operation.h
@@ -128,6 +128,11 @@ slang_operation_construct(slang_operation *);
extern void
slang_operation_destruct(slang_operation *);
+extern void
+slang_replace_scope(slang_operation *oper,
+ slang_variable_scope *oldScope,
+ slang_variable_scope *newScope);
+
extern GLboolean
slang_operation_copy(slang_operation *, const slang_operation *);
diff --git a/src/mesa/shader/slang/slang_compile_variable.h b/src/mesa/shader/slang/slang_compile_variable.h
index d3691f0f51..9b0f85859a 100644
--- a/src/mesa/shader/slang/slang_compile_variable.h
+++ b/src/mesa/shader/slang/slang_compile_variable.h
@@ -80,6 +80,7 @@ typedef struct slang_variable_
GLuint address; /**< Storage location */
GLuint size; /**< Variable's size in bytes */
GLboolean isTemp; /**< a named temporary (__resultTmp) */
+ GLboolean declared; /**< for debug */
void *aux; /**< Used during code gen */
} slang_variable;