From 9fa99f3b6c84fe927ba97e6584cd919f097a6c9a Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Wed, 21 Apr 2010 12:30:22 -0700 Subject: [PATCH] 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. --- ast_to_hir.cpp | 22 ++++++---------------- builtin_function.cpp | 18 +++++++++++++++--- glsl_types.cpp | 36 ++++++++++++------------------------ ir.cpp | 2 +- ir.h | 14 +++++++++----- ir_function_inlining.cpp | 5 ++++- ir_if_simplification.cpp | 5 ++++- ir_print_visitor.cpp | 12 ++++++++++-- 8 files changed, 61 insertions(+), 53 deletions(-) diff --git a/ast_to_hir.cpp b/ast_to_hir.cpp index 94c8dcfbd81..7b4a855f576 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 bdd745062b7..4243340b3d7 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 c8d18b9ee7a..e72a8fc39d4 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 a68d01cca96..ad016ddbce8 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 504cffb2d54..0d5b2e4d710 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 af6a477d9b4..117b460ae5c 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 5637db510ce..bc5663f4734 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 908f1c3ad8d..5d98937c9c2 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"); } -- 2.30.2