Refactor IR function representation.
authorKenneth Graunke <kenneth@whitecape.org>
Wed, 21 Apr 2010 19:30:22 +0000 (12:30 -0700)
committerIan Romanick <ian.d.romanick@intel.com>
Wed, 21 Apr 2010 22:36:36 +0000 (15:36 -0700)
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
builtin_function.cpp
glsl_types.cpp
ir.cpp
ir.h
ir_function_inlining.cpp
ir_if_simplification.cpp
ir_print_visitor.cpp

index 94c8dcfbd81dbd22ffc4f144a70818ab1204b68d..7b4a855f57674d20852f0dc3e530322e0cd8e72d 100644 (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();
 
index bdd745062b7302f14378734611f33d9f2e815114..4243340b3d7b02046bdc0867bf521f704fbb3409 100644 (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,
index c8d18b9ee7a058d58ed2e983466c9141186bd545..e72a8fc39d4fdf7af815f259c22a6d9fab74eb52 100644 (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);
       }
    }
diff --git a/ir.cpp b/ir.cpp
index a68d01cca9688956c7e2320a739a5041f09dde1b..ad016ddbce84d9ab6395224b890875578b6d5762 100644 (file)
--- 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 504cffb2d5495301f46bd5f401f95a52562bdccf..0d5b2e4d710488db0fd5b172fe7ce667d95405be 100644 (file)
--- 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:
index af6a477d9b48948741d2bbab0b91c96ab25519b6..117b460ae5ca133267288e4a78e313f581b17743 100644 (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
index 5637db510ced54cfc92d27e851b5d11925cefce1..bc5663f4734a15b7aad64552ced6dd0bdc5a39e6 100644 (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
index 908f1c3ad8df73df3b0484910abe945671f8335c..5d98937c9c2a169e4d821ff3d46267590f22c8eb 100644 (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");
 }