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.
This commit is contained in:
Kenneth Graunke 2010-04-21 12:30:22 -07:00 committed by Ian Romanick
parent f96c52ba2e
commit 9fa99f3b6c
8 changed files with 61 additions and 53 deletions

View File

@ -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();

View File

@ -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,

View File

@ -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);
}
}

2
ir.cpp
View File

@ -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 */
}

14
ir.h
View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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");
}