mesa: fix some function inlining bugs
authorBrian Paul <brian.paul@tungstengraphics.com>
Tue, 15 Jul 2008 19:25:57 +0000 (13:25 -0600)
committerBrian Paul <brian.paul@tungstengraphics.com>
Tue, 15 Jul 2008 19:29:25 +0000 (13:29 -0600)
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.

src/mesa/shader/slang/slang_codegen.c
src/mesa/shader/slang/slang_compile_operation.c
src/mesa/shader/slang/slang_compile_operation.h
src/mesa/shader/slang/slang_compile_variable.h

index 425beefe857b41b20de780a4bb7bbd35f35c19da..9d5721214f6df07e14790bf4e86a9a2180fc03f6 100644 (file)
@@ -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);
@@ -924,31 +926,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;
 }
 
index b18e08d2ae513e70e9d9b5fd33818d2f8c0c2445..4d2fd5b6667f75a413753bd4a3b35a81ed515094 100644 (file)
@@ -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;
 }
 
index d5cbe779a6c5d9b83a7db01bcb880271b4efb9b1..4f92aa9a0869286b272ea0f590d82765362f920f 100644 (file)
@@ -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 *);
 
index d3691f0f51113da051dfed1aad7984079b7ee68d..9b0f85859a4ce0517cf2fc9ece8d372f5215e63e 100644 (file)
@@ -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;