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.
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);
} 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() */
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.
*/
}
}
- /* 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();
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",
}
generate(&sig->body, declarations, type);
+ sig->is_defined = true;
}
void
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,
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,
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,
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,
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,
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,
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,
* 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
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]);
signature->body.push_tail(retval);
declarations[16] = retval;
- return label;
+ return signature;
}
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.
* 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());
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);
}
}
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 */
}
/*@{*/
+/**
+ * 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.
*/
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;
/**
- * 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:
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
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
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();
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");
}