summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian <brian@yutani.localnet.net>2007-01-11 11:22:26 -0700
committerBrian <brian@yutani.localnet.net>2007-01-11 11:22:26 -0700
commit95a441112efbe14407f53d035e368b9632d06f06 (patch)
tree8ce0e57e44974a63d384325f77336daac19e2b56
parent063f3f7fc49e1fd5cf99cffd241e16af5e2d1823 (diff)
Fix a problem with inlined "return" statements. Make some attempt to free temporaries.
-rw-r--r--src/mesa/shader/slang/slang_codegen.c165
-rw-r--r--src/mesa/shader/slang/slang_compile.c2
-rw-r--r--src/mesa/shader/slang/slang_compile_variable.c3
-rw-r--r--src/mesa/shader/slang/slang_emit.c16
-rw-r--r--src/mesa/shader/slang/slang_emit.h4
-rw-r--r--src/mesa/shader/slang/slang_error.c1
6 files changed, 174 insertions, 17 deletions
diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c
index 9f21573415..46a5ecd5d5 100644
--- a/src/mesa/shader/slang/slang_codegen.c
+++ b/src/mesa/shader/slang/slang_codegen.c
@@ -285,12 +285,16 @@ slang_allocate_storage(slang_gen_context *gc, slang_ir_node *n,
/* variable declaration */
assert(n->Var);
assert(!is_sampler_type(&n->Var->type));
+ printf("Alloc storage for %p %s:\n", (void*) n->Var, (char*) n->Var->a_name);
+ /*
assert(n->Store->Index < 0);
-
+ */
n->Store->File = PROGRAM_TEMPORARY;
n->Store->Size = _slang_sizeof_type_specifier(&n->Var->type.specifier);
assert(n->Store->Size > 0);
+ if (n->Store->Index < 0)
n->Store->Index = _slang_alloc_temporary(gc, n->Store->Size);
+ printf(" Location = %d\n", n->Store->Index);
/*
printf("alloc var %s storage at %d (size %d)\n",
(char *) n->Var->a_name,
@@ -302,7 +306,11 @@ slang_allocate_storage(slang_gen_context *gc, slang_ir_node *n,
return;
}
- assert(n->Store->File != PROGRAM_UNDEFINED);
+ if (n->Store->File == PROGRAM_UNDEFINED) {
+ printf("*** Var %s size %d\n", (char*) n->Var->a_name, n->Store->Size);
+
+ assert(n->Store->File != PROGRAM_UNDEFINED);
+ }
if (n->Store->Index < 0) {
/* determine storage location for this var */
@@ -479,6 +487,7 @@ typedef struct
static slang_asm_info AsmInfo[] = {
/* vec4 binary op */
{ "vec4_add", IR_ADD, 1, 2 },
+ { "vec4_subtract", IR_SUB, 1, 2 },
{ "vec4_multiply", IR_MUL, 1, 2 },
{ "vec4_dot", IR_DOT4, 1, 2 },
{ "vec3_dot", IR_DOT3, 1, 2 },
@@ -497,7 +506,6 @@ static slang_asm_info AsmInfo[] = {
{ "vec4_ddy", IR_DDY, 1, 1 },
/* float binary op */
{ "float_add", IR_ADD, 1, 2 },
- { "float_subtract", IR_SUB, 1, 2 },
{ "float_multiply", IR_MUL, 1, 2 },
{ "float_divide", IR_DIV, 1, 2 },
{ "float_power", IR_POW, 1, 2 },
@@ -525,6 +533,54 @@ static slang_asm_info AsmInfo[] = {
};
+#if 000 /* prototype for future symbol table scheme */
+
+#define MAX_DEPTH 100
+static slang_variable_scope *Stack[MAX_DEPTH];
+static int CurDepth;
+
+static void
+_slang_push_scope(slang_variable_scope *scope)
+{
+ Stack[CurDepth++] = scope;
+ assert(CurDepth < MAX_DEPTH);
+}
+
+static void
+_slang_pop_scope(void)
+{
+ CurDepth--;
+ assert(CurDepth >= 0);
+}
+
+static slang_variable_scope *
+_slang_current_scope(void)
+{
+ if (CurDepth > 0)
+ return Stack[CurDepth - 1];
+ else
+ return NULL;
+}
+
+static slang_variable *
+_slang_find_variable(slang_atom name)
+{
+ int i;
+ for (i = CurDepth - 1; i >= 0; i--) {
+ int j;
+ for (j = 0; j < Stack[i]->num_variables; j++) {
+ if (Stack[i]->variables[j].a_name == name) {
+ return Stack[i]->variables + j;
+ }
+ }
+ }
+ return NULL;
+}
+
+#endif
+
+
+
/**
* Recursively free an IR tree.
*/
@@ -767,6 +823,9 @@ slang_substitute(slang_assemble_ctx *A, slang_operation *oper,
v = _slang_locate_variable(oper->locals, id, GL_TRUE);
if (!v) {
printf("var %s not found!\n", (char *) oper->a_id);
+ _slang_print_var_scope(oper->locals, 6);
+
+ abort();
break;
}
@@ -776,7 +835,7 @@ slang_substitute(slang_assemble_ctx *A, slang_operation *oper,
/* OK, replace this slang_oper_identifier with a new expr */
assert(substNew[i]->type == slang_oper_identifier ||
substNew[i]->type == slang_oper_literal_float);
-#if 0 /* DEBUG only */
+#if 1 /* DEBUG only */
if (substNew[i]->type == slang_oper_identifier) {
assert(substNew[i]->var);
assert(substNew[i]->var->a_name);
@@ -795,13 +854,46 @@ slang_substitute(slang_assemble_ctx *A, slang_operation *oper,
}
}
break;
-#if 0 /* XXX rely on default case below */
+#if 1 /* XXX rely on default case below */
case slang_oper_return:
/* do return replacement here too */
assert(oper->num_children == 0 || oper->num_children == 1);
if (oper->num_children == 1) {
- slang_substitute(A, &oper->children[0],
+ /* replace:
+ * return expr;
+ * with:
+ * __retVal = expr;
+ * return;
+ * then do substitutions on the assignment.
+ */
+ slang_operation *blockOper, *assignOper, *returnOper;
+ blockOper = slang_operation_new(1);
+ blockOper->type = slang_oper_block_no_new_scope;
+ blockOper->num_children = 2;
+ blockOper->children = slang_operation_new(2);
+ assignOper = blockOper->children + 0;
+ returnOper = blockOper->children + 1;
+
+ assignOper->type = slang_oper_assign;
+ assignOper->num_children = 2;
+ 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 = oper->locals;
+ assignOper->locals = oper->locals;
+ slang_operation_copy(&assignOper->children[1],
+ &oper->children[0]);
+
+ returnOper->type = slang_oper_return;
+ assert(returnOper->num_children == 0);
+
+ /* do substitutions on the "__retVal = expr" sub-tree */
+ slang_substitute(A, assignOper,
substCount, substOld, substNew, GL_FALSE);
+
+ /* install new code */
+ slang_operation_copy(oper, blockOper);
+ slang_operation_destruct(blockOper);
}
break;
#endif
@@ -936,11 +1028,11 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun,
substCount = 0;
for (i = 0; i < totalArgs; i++) {
slang_variable *p = &fun->parameters->variables[i];
- /*
+
printf("Param %d: %s %s \n", i,
slang_type_qual_string(p->type.qualifier),
(char *) p->a_name);
- */
+
if (p->type.qualifier == slang_qual_inout ||
p->type.qualifier == slang_qual_out) {
/* an output param */
@@ -1072,6 +1164,9 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun,
(char *) fun->header.a_name,
fun->parameters->num_variables, numArgs);
+ /*
+ slang_print_tree(top, 0);
+ */
return top;
}
@@ -1123,6 +1218,8 @@ _slang_gen_function_call(slang_assemble_ctx *A, slang_function *fun,
/* assemble what we just made XXX here??? */
n = _slang_gen_operation(A, oper);
+ CurFunction->end_label = NULL;
+
CurFunction = prevFunc;
return n;
@@ -1187,7 +1284,11 @@ _slang_gen_asm(slang_assemble_ctx *A, slang_operation *oper,
assert(oper->type == slang_oper_asm);
info = slang_find_asm_info((char *) oper->a_id);
- assert(info);
+ if (!info) {
+ _mesa_problem(NULL, "undefined __asm function %s\n",
+ (char *) oper->a_id);
+ assert(info);
+ }
assert(info->NumParams <= 2);
if (info->NumParams == oper->num_children) {
@@ -1258,6 +1359,21 @@ _slang_gen_cond(slang_ir_node *n)
}
+static void print_funcs(struct slang_function_scope_ *scope)
+{
+ int i;
+ for (i = 0; i < scope->num_functions; i++) {
+ slang_function *f = &scope->functions[i];
+ printf("func %s\n", (char *) f->header.a_name);
+ if (strcmp("vec3", (char*) f->header.a_name) == 0)
+ printf("VEC3!\n");
+
+ }
+ if (scope->outer_scope)
+ print_funcs(scope->outer_scope);
+}
+
+
/**
* Assemble a function call, given a particular function name.
* \param name the function's name (operators like '*' are possible).
@@ -1278,6 +1394,11 @@ _slang_gen_function_call_name(slang_assemble_ctx *A, const char *name,
fun = _slang_locate_function(A->space.funcs, atom, params, param_count,
&A->space, A->atoms);
if (!fun) {
+ print_funcs(A->space.funcs);
+
+ fun = _slang_locate_function(A->space.funcs, atom, params, param_count,
+ &A->space, A->atoms);
+
RETURN_ERROR2("Undefined function", name, 0);
}
@@ -1569,6 +1690,7 @@ _slang_gen_declaration(slang_assemble_ctx *A, slang_operation *oper)
printf("\n*** ASSEMBLE INITIALIZER %p\n", (void*) v->initializer);
*/
rhs = _slang_gen_operation(A, &oper->children[0]);
+ assert(rhs);
init = new_node(IR_MOVE, var, rhs);
/*assert(rhs->Opcode != IR_SEQ);*/
n = new_seq(varDecl, init);
@@ -1581,6 +1703,7 @@ _slang_gen_declaration(slang_assemble_ctx *A, slang_operation *oper)
printf("\n*** ASSEMBLE INITIALIZER %p\n", (void*) v->initializer);
*/
rhs = _slang_gen_operation(A, v->initializer);
+ assert(rhs);
init = new_node(IR_MOVE, var, rhs);
/*
assert(rhs->Opcode != IR_SEQ);
@@ -1641,6 +1764,7 @@ _slang_gen_assignment(slang_assemble_ctx * A, slang_operation *oper)
c0 = _slang_gen_operation(A, lhs);
c1 = _slang_gen_operation(A, &oper->children[1]);
+ assert(c1);
n = new_node(IR_MOVE, c0, c1);
/*
assert(c1->Opcode != IR_SEQ);
@@ -1777,6 +1901,26 @@ _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper)
return NULL; /* error must have occured */
tree = tree ? new_seq(tree, n) : n;
}
+
+ if (oper->locals->num_variables > 0) {
+ int i;
+ /*
+ printf("\n****** Deallocate vars in scope!\n");
+ */
+ for (i = 0; i < oper->locals->num_variables; i++) {
+ slang_variable *v = oper->locals->variables + i;
+ if (v->aux) {
+ slang_ir_storage *store = (slang_ir_storage *) v->aux;
+ /*
+ printf(" Deallocate var %s\n", (char*) v->a_name);
+ */
+ assert(store->File == PROGRAM_TEMPORARY);
+ assert(store->Index >= 0);
+ _slang_free_temporary(A->codegen, store->Index, store->Size);
+ }
+ }
+ }
+
return tree;
}
break;
@@ -2135,6 +2279,7 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var,
slang_simplify(var->initializer, &A->space, A->atoms);
rhs = _slang_gen_operation(A, var->initializer);
+ assert(rhs);
init = new_node(IR_MOVE, lhs, rhs);
n = new_seq(n, init);
}
@@ -2213,7 +2358,7 @@ _slang_codegen_function(slang_assemble_ctx * A, slang_function * fun)
printf("************* New AST for %s *****\n", (char*)fun->header.a_name);
slang_print_function(fun, 1);
#endif
-#if 1
+#if 0
printf("************* IR for %s *******\n", (char*)fun->header.a_name);
slang_print_ir(n, 0);
printf("************* End codegen function ************\n\n");
diff --git a/src/mesa/shader/slang/slang_compile.c b/src/mesa/shader/slang/slang_compile.c
index bb1da27152..9a77c5a3d6 100644
--- a/src/mesa/shader/slang/slang_compile.c
+++ b/src/mesa/shader/slang/slang_compile.c
@@ -1622,8 +1622,10 @@ initialize_global(slang_assemble_ctx * A, slang_variable * var)
return GL_FALSE;
/* execute the expression */
+#if 0
if (!_slang_execute2(A->file, &mach))
return GL_FALSE;
+#endif
/* restore the old assembly */
if (!slang_assembly_file_restore_point_load(A->file, &point))
diff --git a/src/mesa/shader/slang/slang_compile_variable.c b/src/mesa/shader/slang/slang_compile_variable.c
index f9f02066a3..046db2cefc 100644
--- a/src/mesa/shader/slang/slang_compile_variable.c
+++ b/src/mesa/shader/slang/slang_compile_variable.c
@@ -364,6 +364,9 @@ build_quant(slang_export_data_quant * q, const slang_variable * var)
q->size = var->size;
if (spec->type == slang_spec_array) {
q->array_len = var->array_len;
+#if 1
+ if (var->array_len > 0)
+#endif
q->size /= var->array_len;
spec = spec->_array;
}
diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c
index 909948968a..2670134025 100644
--- a/src/mesa/shader/slang/slang_emit.c
+++ b/src/mesa/shader/slang/slang_emit.c
@@ -285,6 +285,7 @@ _slang_alloc_temporary(slang_gen_context *gc, GLint size)
const GLuint sz4 = (size + 3) / 4;
GLuint i, j;
ASSERT(size > 0); /* number of floats */
+
for (i = 0; i < MAX_PROGRAM_TEMPS; i++) {
GLuint found = 0;
for (j = 0; j < sz4; j++) {
@@ -314,8 +315,8 @@ is_temporary(const slang_gen_context *gc, const slang_ir_storage *st)
}
-static void
-free_temporary(slang_gen_context *gc, GLuint r, GLint size)
+void
+_slang_free_temporary(slang_gen_context *gc, GLuint r, GLint size)
{
const GLuint sz4 = (size + 3) / 4;
GLuint i;
@@ -337,6 +338,7 @@ slang_alloc_temp_storage(slang_gen_context *gc, slang_ir_node *n, GLint size)
assert(!n->Var);
assert(!n->Store);
assert(size > 0);
+ printf("Allocate binop temp:\n");
indx = _slang_alloc_temporary(gc, size);
n->Store = _slang_new_ir_storage(PROGRAM_TEMPORARY, indx, size);
}
@@ -634,8 +636,8 @@ emit(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog)
* Just modify the RHS to put its result into the dest of this
* MOVE operation. Then, this MOVE is a no-op.
*/
- free_temporary(gc, n->Children[1]->Store->Index,
- n->Children[1]->Store->Size);
+ _slang_free_temporary(gc, n->Children[1]->Store->Index,
+ n->Children[1]->Store->Size);
*n->Children[1]->Store = *n->Children[0]->Store;
/* fixup the prev (RHS) instruction */
storage_to_dst_reg(&inst->DstReg, n->Children[0]->Store, n->Writemask);
@@ -672,8 +674,8 @@ emit(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog)
}
/* XXX is this test correct? */
if (n->Children[1]->Store->File == PROGRAM_TEMPORARY) {
- free_temporary(gc, n->Children[1]->Store->Index,
- n->Children[1]->Store->Size);
+ _slang_free_temporary(gc, n->Children[1]->Store->Index,
+ n->Children[1]->Store->Size);
}
/*inst->Comment = _mesa_strdup("IR_MOVE");*/
n->Store = n->Children[0]->Store; /*XXX new */
@@ -741,7 +743,7 @@ emit(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog)
storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask);
storage_to_src_reg(&inst->SrcReg[0], n->Children[0]->Store,
n->Children[0]->Swizzle);
- free_temporary(gc, n->Store->Index, n->Store->Size);
+ _slang_free_temporary(gc, n->Store->Index, n->Store->Size);
return inst; /* XXX or null? */
}
}
diff --git a/src/mesa/shader/slang/slang_emit.h b/src/mesa/shader/slang/slang_emit.h
index cd3352604f..73ae0827c0 100644
--- a/src/mesa/shader/slang/slang_emit.h
+++ b/src/mesa/shader/slang/slang_emit.h
@@ -51,6 +51,10 @@ _slang_clone_ir_storage(slang_ir_storage *store);
extern GLint
_slang_alloc_temporary(slang_gen_context *gc, GLint size);
+extern void
+_slang_free_temporary(slang_gen_context *gc, GLuint r, GLint size);
+
+
extern GLboolean
_slang_emit_code(slang_ir_node *n, slang_gen_context *gc,
struct gl_program *prog, GLboolean withEnd);
diff --git a/src/mesa/shader/slang/slang_error.c b/src/mesa/shader/slang/slang_error.c
index 2767163178..bfa8e80a05 100644
--- a/src/mesa/shader/slang/slang_error.c
+++ b/src/mesa/shader/slang/slang_error.c
@@ -55,6 +55,7 @@ _slang_record_error(const char *msg1, const char *msg2,
msg1, msg2, pos, file, line);
#endif
}
+ abort();
}