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; 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 /* 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 * used below to compare this function's signature with previously seen
* signatures for functions with the same name. * signatures for functions with the same name.
@@ -1989,7 +1984,7 @@ ast_function::hir(exec_list *instructions,
name); name);
} }
if (is_definition && (sig->definition != NULL)) { if (is_definition && sig->is_defined) {
YYLTYPE loc = this->get_location(); YYLTYPE loc = this->get_location();
_mesa_glsl_error(& loc, state, "function `%s' redefined", name); _mesa_glsl_error(& loc, state, "function `%s' redefined", name);
@@ -2012,6 +2007,9 @@ ast_function::hir(exec_list *instructions,
} else { } else {
f = new ir_function(name); f = new ir_function(name);
state->symbols->add_function(f->name, f); state->symbols->add_function(f->name, f);
/* Emit the new function header */
instructions->push_tail(f);
} }
/* Verify the return type of main() */ /* Verify the return type of main() */
@@ -2068,12 +2066,6 @@ ast_function_definition::hir(exec_list *instructions,
assert(state->current_function == NULL); assert(state->current_function == NULL);
state->current_function = signature; 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. /* Duplicate parameters declared in the prototype as concrete variables.
* Add these to the symbol table. * 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 /* Convert the body of the function to HIR. */
* instructions to the list that currently consists of the function label
* and the function parameters.
*/
this->body->hir(&signature->body, state); this->body->hir(&signature->body, state);
signature->is_defined = true;
state->symbols->pop_scope(); 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); ir_function_signature *const sig = new ir_function_signature(ret_type);
f->add_signature(sig); 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[] = { static const char *arg_names[] = {
"arg0", "arg0",
"arg1", "arg1",
@@ -287,6 +284,7 @@ generate_function_instance(ir_function *f,
} }
generate(&sig->body, declarations, type); generate(&sig->body, declarations, type);
sig->is_defined = true;
} }
void void
@@ -306,6 +304,8 @@ make_gentype_function(glsl_symbol_table *symtab, exec_list *instructions,
bool added = symtab->add_function(name, f); bool added = symtab->add_function(name, f);
assert(added); assert(added);
instructions->push_tail(f);
generate_function_instance(f, name, instructions, n_args, generate, generate_function_instance(f, name, instructions, n_args, generate,
float_type, float_type); float_type, float_type);
generate_function_instance(f, name, instructions, n_args, generate, 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); bool added = symtab->add_function(name, f);
assert(added); assert(added);
instructions->push_tail(f);
generate_function_instance(f, name, instructions, 2, generate, generate_function_instance(f, name, instructions, 2, generate,
bvec2_type, vec2_type); bvec2_type, vec2_type);
generate_function_instance(f, name, instructions, 2, generate, 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); bool added = symtab->add_function(name, f);
assert(added); assert(added);
instructions->push_tail(f);
generate_function_instance(f, name, instructions, 1, generate_length, generate_function_instance(f, name, instructions, 1, generate_length,
float_type, float_type); float_type, float_type);
generate_function_instance(f, name, instructions, 1, generate_length, 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); bool added = symtab->add_function(name, f);
assert(added); assert(added);
instructions->push_tail(f);
generate_function_instance(f, name, instructions, 2, generate_dot, generate_function_instance(f, name, instructions, 2, generate_dot,
float_type, float_type); float_type, float_type);
generate_function_instance(f, name, instructions, 2, generate_dot, 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); bool added = symtab->add_function(name, f);
assert(added); assert(added);
instructions->push_tail(f);
generate_function_instance(f, name, instructions, 1, generate_any_bvec2, generate_function_instance(f, name, instructions, 1, generate_any_bvec2,
glsl_type::bool_type, bvec2_type); glsl_type::bool_type, bvec2_type);
generate_function_instance(f, name, instructions, 1, generate_any_bvec3, 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); bool added = symtab->add_function(name, f);
assert(added); assert(added);
instructions->push_tail(f);
generate_function_instance(f, name, instructions, 1, generate_all_bvec2, generate_function_instance(f, name, instructions, 1, generate_all_bvec2,
glsl_type::bool_type, bvec2_type); glsl_type::bool_type, bvec2_type);
generate_function_instance(f, name, instructions, 1, generate_all_bvec3, 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); bool added = symtab->add_function(name, f);
assert(added); assert(added);
instructions->push_tail(f);
generate_function_instance(f, name, instructions, 1, generate_not, generate_function_instance(f, name, instructions, 1, generate_not,
bvec2_type, bvec2_type); bvec2_type, bvec2_type);
generate_function_instance(f, name, instructions, 1, generate_not, 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. * scalar parameters.
* \param parameters Storage for the list of parameters. These are * \param parameters Storage for the list of parameters. These are
* typically stored in an \c ir_function_signature. * 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 * \param declarations Pointers to the variable declarations for the function
* parameters. These are used later to avoid having to use * parameters. These are used later to avoid having to use
* the symbol table. * the symbol table.
*/ */
static ir_label * static ir_function_signature *
generate_constructor_intro(const glsl_type *type, unsigned parameter_count, generate_constructor_intro(const glsl_type *type, unsigned parameter_count,
ir_function_signature *const signature,
exec_list *instructions,
ir_variable **declarations) ir_variable **declarations)
{ {
/* Names of parameters used in vector and matrix constructors /* 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(); const glsl_type *const parameter_type = type->get_base_type();
ir_label *const label = new ir_label(type->name, signature); ir_function_signature *const signature = new ir_function_signature(type);
instructions->push_tail(label);
for (unsigned i = 0; i < parameter_count; i++) { for (unsigned i = 0; i < parameter_count; i++) {
ir_variable *var = new ir_variable(parameter_type, names[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); signature->body.push_tail(retval);
declarations[16] = 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()) if (types[i].is_scalar())
continue; 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); ir_function *const f = new ir_function(types[i].name);
bool added = symtab->add_function(types[i].name, f); bool added = symtab->add_function(types[i].name, f);
assert(added); assert(added);
instructions->push_tail(f);
/* Each type has several basic constructors. The total number of forms /* Each type has several basic constructors. The total number of forms
* depends on the derived type. * 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 * expectation is that the IR generator will generate a call to the
* appropriate from-scalars constructor. * 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); f->add_signature(sig);
sig->definition =
generate_constructor_intro(& types[i], 1, sig,
instructions, declarations);
if (types[i].is_vector()) { if (types[i].is_vector()) {
generate_vec_body_from_scalar(&sig->body, declarations); generate_vec_body_from_scalar(&sig->body, declarations);
ir_function_signature *const vec_sig = 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); 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); generate_vec_body_from_N_scalars(&sig->body, declarations);
} else { } else {
assert(types[i].is_matrix()); 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); generate_mat_body_from_scalar(&sig->body, declarations);
ir_function_signature *const mat_sig = ir_function_signature *const mat_sig =
new ir_function_signature(& types[i]); generate_constructor_intro(&types[i],
f->add_signature(mat_sig);
mat_sig->definition =
generate_constructor_intro(& types[i],
(types[i].vector_elements (types[i].vector_elements
* types[i].matrix_columns), * types[i].matrix_columns),
mat_sig, instructions,
declarations); declarations);
f->add_signature(mat_sig);
generate_mat_body_from_N_scalars(instructions, declarations); 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) 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 */ /* 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 { class ir_function_signature : public ir_instruction {
/* An ir_function_signature will be part of the list of signatures in /* An ir_function_signature will be part of the list of signatures in
* an ir_function. * an ir_function.
@@ -236,10 +240,8 @@ public:
*/ */
struct exec_list parameters; struct exec_list parameters;
/** /** Whether or not this function has a body (which may be empty). */
* Pointer to the label that begins the function definition. unsigned is_defined:1;
*/
ir_label *definition;
/** Body of instructions in the function. */ /** Body of instructions in the function. */
struct exec_list body; 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 { class ir_function : public ir_instruction {
public: public:

View File

@@ -481,7 +481,10 @@ ir_function_inlining_visitor::visit(ir_function_signature *ir)
void void
ir_function_inlining_visitor::visit(ir_function *ir) 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 void

View File

@@ -167,7 +167,10 @@ ir_if_simplification_visitor::visit(ir_function_signature *ir)
void void
ir_if_simplification_visitor::visit(ir_function *ir) 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 void

View File

@@ -75,14 +75,14 @@ void ir_print_visitor::visit(ir_label *ir)
void ir_print_visitor::visit(ir_function_signature *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) { foreach_iter(exec_list_iterator, iter, ir->parameters) {
ir_variable *const inst = (ir_variable *) iter.get(); ir_variable *const inst = (ir_variable *) iter.get();
inst->accept(this); inst->accept(this);
printf("\n"); printf("\n");
} }
printf(")\n"); printf(" )\n(");
foreach_iter(exec_list_iterator, iter, ir->body) { foreach_iter(exec_list_iterator, iter, ir->body) {
ir_instruction *const inst = (ir_instruction *) iter.get(); ir_instruction *const inst = (ir_instruction *) iter.get();
@@ -90,12 +90,20 @@ void ir_print_visitor::visit(ir_function_signature *ir)
inst->accept(this); inst->accept(this);
printf("\n"); printf("\n");
} }
printf("))\n");
} }
void ir_print_visitor::visit(ir_function *ir) void ir_print_visitor::visit(ir_function *ir)
{ {
printf("(function %s\n", ir->name); 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"); printf(")\n");
} }