summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKenneth Graunke <kenneth@whitecape.org>2010-04-21 12:30:22 -0700
committerIan Romanick <ian.d.romanick@intel.com>2010-04-21 15:36:36 -0700
commit9fa99f3b6c84fe927ba97e6584cd919f097a6c9a (patch)
tree453be040c7a1948bbb4d9eadbac8ad8ba8c887cd
parentf96c52ba2e290e3ba5f14cd7f87ba5b4382a1785 (diff)
Refactor IR function representation.
Now, ir_function is emitted as part of the IR instructions, rather than simply existing in the symbol table. Individual ir_function_signatures are not emitted themselves, but only as part of ir_function.
-rw-r--r--ast_to_hir.cpp22
-rw-r--r--builtin_function.cpp18
-rw-r--r--glsl_types.cpp36
-rw-r--r--ir.cpp2
-rw-r--r--ir.h14
-rw-r--r--ir_function_inlining.cpp5
-rw-r--r--ir_if_simplification.cpp5
-rw-r--r--ir_print_visitor.cpp12
8 files changed, 61 insertions, 53 deletions
diff --git a/ast_to_hir.cpp b/ast_to_hir.cpp
index 94c8dcfbd8..7b4a855f57 100644
--- a/ast_to_hir.cpp
+++ b/ast_to_hir.cpp
@@ -1922,11 +1922,6 @@ ast_function::hir(exec_list *instructions,
exec_list hir_parameters;
- /* The prototype part of a function does not generate anything in the IR
- * instruction stream.
- */
- (void) instructions;
-
/* Convert the list of function parameters to HIR now so that they can be
* used below to compare this function's signature with previously seen
* signatures for functions with the same name.
@@ -1989,7 +1984,7 @@ ast_function::hir(exec_list *instructions,
name);
}
- if (is_definition && (sig->definition != NULL)) {
+ if (is_definition && sig->is_defined) {
YYLTYPE loc = this->get_location();
_mesa_glsl_error(& loc, state, "function `%s' redefined", name);
@@ -2012,6 +2007,9 @@ ast_function::hir(exec_list *instructions,
} else {
f = new ir_function(name);
state->symbols->add_function(f->name, f);
+
+ /* Emit the new function header */
+ instructions->push_tail(f);
}
/* Verify the return type of main() */
@@ -2068,12 +2066,6 @@ ast_function_definition::hir(exec_list *instructions,
assert(state->current_function == NULL);
state->current_function = signature;
- ir_label *label = new ir_label(signature->function_name(), signature);
- if (signature->definition == NULL) {
- signature->definition = label;
- }
- instructions->push_tail(label);
-
/* Duplicate parameters declared in the prototype as concrete variables.
* Add these to the symbol table.
*/
@@ -2095,11 +2087,9 @@ ast_function_definition::hir(exec_list *instructions,
}
}
- /* Convert the body of the function to HIR, and append the resulting
- * instructions to the list that currently consists of the function label
- * and the function parameters.
- */
+ /* Convert the body of the function to HIR. */
this->body->hir(&signature->body, state);
+ signature->is_defined = true;
state->symbols->pop_scope();
diff --git a/builtin_function.cpp b/builtin_function.cpp
index bdd745062b..4243340b3d 100644
--- a/builtin_function.cpp
+++ b/builtin_function.cpp
@@ -267,9 +267,6 @@ generate_function_instance(ir_function *f,
ir_function_signature *const sig = new ir_function_signature(ret_type);
f->add_signature(sig);
- ir_label *const label = new ir_label(name, sig);
- instructions->push_tail(label);
- sig->definition = label;
static const char *arg_names[] = {
"arg0",
"arg1",
@@ -287,6 +284,7 @@ generate_function_instance(ir_function *f,
}
generate(&sig->body, declarations, type);
+ sig->is_defined = true;
}
void
@@ -306,6 +304,8 @@ make_gentype_function(glsl_symbol_table *symtab, exec_list *instructions,
bool added = symtab->add_function(name, f);
assert(added);
+ instructions->push_tail(f);
+
generate_function_instance(f, name, instructions, n_args, generate,
float_type, float_type);
generate_function_instance(f, name, instructions, n_args, generate,
@@ -424,6 +424,8 @@ generate_vec_compare_function(glsl_symbol_table *symtab,
bool added = symtab->add_function(name, f);
assert(added);
+ instructions->push_tail(f);
+
generate_function_instance(f, name, instructions, 2, generate,
bvec2_type, vec2_type);
generate_function_instance(f, name, instructions, 2, generate,
@@ -487,6 +489,8 @@ generate_length_functions(glsl_symbol_table *symtab, exec_list *instructions)
bool added = symtab->add_function(name, f);
assert(added);
+ instructions->push_tail(f);
+
generate_function_instance(f, name, instructions, 1, generate_length,
float_type, float_type);
generate_function_instance(f, name, instructions, 1, generate_length,
@@ -527,6 +531,8 @@ generate_dot_functions(glsl_symbol_table *symtab, exec_list *instructions)
bool added = symtab->add_function(name, f);
assert(added);
+ instructions->push_tail(f);
+
generate_function_instance(f, name, instructions, 2, generate_dot,
float_type, float_type);
generate_function_instance(f, name, instructions, 2, generate_dot,
@@ -689,6 +695,8 @@ generate_any_functions(glsl_symbol_table *symtab, exec_list *instructions)
bool added = symtab->add_function(name, f);
assert(added);
+ instructions->push_tail(f);
+
generate_function_instance(f, name, instructions, 1, generate_any_bvec2,
glsl_type::bool_type, bvec2_type);
generate_function_instance(f, name, instructions, 1, generate_any_bvec3,
@@ -709,6 +717,8 @@ generate_all_functions(glsl_symbol_table *symtab, exec_list *instructions)
bool added = symtab->add_function(name, f);
assert(added);
+ instructions->push_tail(f);
+
generate_function_instance(f, name, instructions, 1, generate_all_bvec2,
glsl_type::bool_type, bvec2_type);
generate_function_instance(f, name, instructions, 1, generate_all_bvec3,
@@ -729,6 +739,8 @@ generate_not_functions(glsl_symbol_table *symtab, exec_list *instructions)
bool added = symtab->add_function(name, f);
assert(added);
+ instructions->push_tail(f);
+
generate_function_instance(f, name, instructions, 1, generate_not,
bvec2_type, bvec2_type);
generate_function_instance(f, name, instructions, 1, generate_not,
diff --git a/glsl_types.cpp b/glsl_types.cpp
index c8d18b9ee7..e72a8fc39d 100644
--- a/glsl_types.cpp
+++ b/glsl_types.cpp
@@ -173,15 +173,12 @@ glsl_type::generate_constructor_prototype(glsl_symbol_table *symtab) const
* scalar parameters.
* \param parameters Storage for the list of parameters. These are
* typically stored in an \c ir_function_signature.
- * \param instructions Storage for the preamble and body of the function.
* \param declarations Pointers to the variable declarations for the function
* parameters. These are used later to avoid having to use
* the symbol table.
*/
-static ir_label *
+static ir_function_signature *
generate_constructor_intro(const glsl_type *type, unsigned parameter_count,
- ir_function_signature *const signature,
- exec_list *instructions,
ir_variable **declarations)
{
/* Names of parameters used in vector and matrix constructors
@@ -195,8 +192,7 @@ generate_constructor_intro(const glsl_type *type, unsigned parameter_count,
const glsl_type *const parameter_type = type->get_base_type();
- ir_label *const label = new ir_label(type->name, signature);
- instructions->push_tail(label);
+ ir_function_signature *const signature = new ir_function_signature(type);
for (unsigned i = 0; i < parameter_count; i++) {
ir_variable *var = new ir_variable(parameter_type, names[i]);
@@ -211,7 +207,7 @@ generate_constructor_intro(const glsl_type *type, unsigned parameter_count,
signature->body.push_tail(retval);
declarations[16] = retval;
- return label;
+ return signature;
}
@@ -420,13 +416,14 @@ generate_constructor(glsl_symbol_table *symtab, const struct glsl_type *types,
if (types[i].is_scalar())
continue;
- /* Generate the function name and add it to the symbol table.
+ /* Generate the function block, add it to the symbol table, and emit it.
*/
ir_function *const f = new ir_function(types[i].name);
bool added = symtab->add_function(types[i].name, f);
assert(added);
+ instructions->push_tail(f);
/* Each type has several basic constructors. The total number of forms
* depends on the derived type.
@@ -445,24 +442,18 @@ generate_constructor(glsl_symbol_table *symtab, const struct glsl_type *types,
* expectation is that the IR generator will generate a call to the
* appropriate from-scalars constructor.
*/
- ir_function_signature *const sig = new ir_function_signature(& types[i]);
+ ir_function_signature *const sig =
+ generate_constructor_intro(&types[i], 1, declarations);
f->add_signature(sig);
- sig->definition =
- generate_constructor_intro(& types[i], 1, sig,
- instructions, declarations);
-
if (types[i].is_vector()) {
generate_vec_body_from_scalar(&sig->body, declarations);
ir_function_signature *const vec_sig =
- new ir_function_signature(& types[i]);
+ generate_constructor_intro(&types[i], types[i].vector_elements,
+ declarations);
f->add_signature(vec_sig);
- vec_sig->definition =
- generate_constructor_intro(& types[i], types[i].vector_elements,
- vec_sig, instructions,
- declarations);
generate_vec_body_from_N_scalars(&sig->body, declarations);
} else {
assert(types[i].is_matrix());
@@ -470,15 +461,12 @@ generate_constructor(glsl_symbol_table *symtab, const struct glsl_type *types,
generate_mat_body_from_scalar(&sig->body, declarations);
ir_function_signature *const mat_sig =
- new ir_function_signature(& types[i]);
- f->add_signature(mat_sig);
-
- mat_sig->definition =
- generate_constructor_intro(& types[i],
+ generate_constructor_intro(&types[i],
(types[i].vector_elements
* types[i].matrix_columns),
- mat_sig, instructions,
declarations);
+ f->add_signature(mat_sig);
+
generate_mat_body_from_N_scalars(instructions, declarations);
}
}
diff --git a/ir.cpp b/ir.cpp
index a68d01cca9..ad016ddbce 100644
--- a/ir.cpp
+++ b/ir.cpp
@@ -338,7 +338,7 @@ ir_variable::ir_variable(const struct glsl_type *type, const char *name)
ir_function_signature::ir_function_signature(const glsl_type *return_type)
- : return_type(return_type), definition(NULL)
+ : return_type(return_type), is_defined(false)
{
/* empty */
}
diff --git a/ir.h b/ir.h
index 504cffb2d5..0d5b2e4d71 100644
--- a/ir.h
+++ b/ir.h
@@ -204,6 +204,10 @@ public:
/*@{*/
+/**
+ * The representation of a function instance; may be the full definition or
+ * simply a prototype.
+ */
class ir_function_signature : public ir_instruction {
/* An ir_function_signature will be part of the list of signatures in
* an ir_function.
@@ -236,10 +240,8 @@ public:
*/
struct exec_list parameters;
- /**
- * Pointer to the label that begins the function definition.
- */
- ir_label *definition;
+ /** Whether or not this function has a body (which may be empty). */
+ unsigned is_defined:1;
/** Body of instructions in the function. */
struct exec_list body;
@@ -253,7 +255,9 @@ private:
/**
- * Header for tracking functions in the symbol table
+ * Header for tracking multiple overloaded functions with the same name.
+ * Contains a list of ir_function_signatures representing each of the
+ * actual functions.
*/
class ir_function : public ir_instruction {
public:
diff --git a/ir_function_inlining.cpp b/ir_function_inlining.cpp
index af6a477d9b..117b460ae5 100644
--- a/ir_function_inlining.cpp
+++ b/ir_function_inlining.cpp
@@ -481,7 +481,10 @@ ir_function_inlining_visitor::visit(ir_function_signature *ir)
void
ir_function_inlining_visitor::visit(ir_function *ir)
{
- (void) ir;
+ foreach_iter(exec_list_iterator, iter, *ir) {
+ ir_function_signature *const sig = (ir_function_signature *) iter.get();
+ sig->accept(this);
+ }
}
void
diff --git a/ir_if_simplification.cpp b/ir_if_simplification.cpp
index 5637db510c..bc5663f473 100644
--- a/ir_if_simplification.cpp
+++ b/ir_if_simplification.cpp
@@ -167,7 +167,10 @@ ir_if_simplification_visitor::visit(ir_function_signature *ir)
void
ir_if_simplification_visitor::visit(ir_function *ir)
{
- (void) ir;
+ foreach_iter(exec_list_iterator, iter, *ir) {
+ ir_function_signature *const sig = (ir_function_signature *) iter.get();
+ sig->accept(this);
+ }
}
void
diff --git a/ir_print_visitor.cpp b/ir_print_visitor.cpp
index 908f1c3ad8..5d98937c9c 100644
--- a/ir_print_visitor.cpp
+++ b/ir_print_visitor.cpp
@@ -75,14 +75,14 @@ void ir_print_visitor::visit(ir_label *ir)
void ir_print_visitor::visit(ir_function_signature *ir)
{
- printf("(paramaters\n");
+ printf("(signature\n (parameters\n");
foreach_iter(exec_list_iterator, iter, ir->parameters) {
ir_variable *const inst = (ir_variable *) iter.get();
inst->accept(this);
printf("\n");
}
- printf(")\n");
+ printf(" )\n(");
foreach_iter(exec_list_iterator, iter, ir->body) {
ir_instruction *const inst = (ir_instruction *) iter.get();
@@ -90,12 +90,20 @@ void ir_print_visitor::visit(ir_function_signature *ir)
inst->accept(this);
printf("\n");
}
+ printf("))\n");
}
void ir_print_visitor::visit(ir_function *ir)
{
printf("(function %s\n", ir->name);
+ foreach_iter(exec_list_iterator, iter, *ir) {
+ ir_function_signature *const sig = (ir_function_signature *) iter.get();
+
+ sig->accept(this);
+ printf("\n");
+ }
+
printf(")\n");
}