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:
parent
f96c52ba2e
commit
9fa99f3b6c
|
@ -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();
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
2
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 */
|
||||
}
|
||||
|
|
14
ir.h
14
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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue