Add a virtual clone() method to ir_instruction.
authorEric Anholt <eric@anholt.net>
Wed, 23 Jun 2010 18:37:12 +0000 (11:37 -0700)
committerIan Romanick <ian.d.romanick@intel.com>
Wed, 23 Jun 2010 22:20:29 +0000 (15:20 -0700)
This will be used by function inlining, the linker, and avoiding double
usage of the LHS deref chains in ++, *=, and similar operations.

Makefile.am
ast_to_hir.cpp
ir.cpp
ir.h
ir_clone.cpp [new file with mode: 0644]
ir_constant_expression.cpp
ir_function_inlining.cpp
ir_print_visitor.cpp
ir_reader.cpp
linker.cpp

index b65b8ba..a88bf00 100644 (file)
@@ -38,6 +38,7 @@ glsl_SOURCES = \
        ir_print_visitor.cpp ir_variable.cpp ir_function.cpp \
        ir_basic_block.cpp \
        ir_basic_block.h \
+       ir_clone.cpp \
        ir_constant_expression.cpp \
        ir_constant_folding.cpp \
        ir_constant_variable.cpp \
index aa90d4b..b4692c6 100644 (file)
@@ -2171,8 +2171,7 @@ ast_jump_statement::hir(exec_list *instructions,
 
         if (loop != NULL) {
            ir_loop_jump *const jump =
-              new ir_loop_jump(loop,
-                               (mode == ast_break)
+              new ir_loop_jump((mode == ast_break)
                                ? ir_loop_jump::jump_break
                                : ir_loop_jump::jump_continue);
            instructions->push_tail(jump);
@@ -2251,7 +2250,7 @@ ast_iteration_statement::condition_to_hir(ir_loop *stmt,
         ir_if *const if_stmt = new ir_if(not_cond);
 
         ir_jump *const break_stmt =
-           new ir_loop_jump(stmt, ir_loop_jump::jump_break);
+           new ir_loop_jump(ir_loop_jump::jump_break);
 
         if_stmt->then_instructions.push_tail(break_stmt);
         stmt->body_instructions.push_tail(if_stmt);
diff --git a/ir.cpp b/ir.cpp
index 49191fb..9514201 100644 (file)
--- a/ir.cpp
+++ b/ir.cpp
@@ -297,8 +297,8 @@ ir_constant::ir_constant(const struct glsl_type *type, exec_list *value_list)
    }
 }
 
-ir_constant *
-ir_constant::clone()
+ir_instruction *
+ir_constant::clone(struct hash_table *ht) const
 {
    switch (this->type->base_type) {
    case GLSL_TYPE_UINT:
@@ -316,7 +316,7 @@ ir_constant::clone()
              ; node = node->next) {
         ir_constant *const orig = (ir_constant *) node;
 
-        c->components.push_tail(orig->clone());
+        c->components.push_tail(orig->clone(NULL));
       }
 
       return c;
diff --git a/ir.h b/ir.h
index 9cbe115..f3402a3 100644 (file)
--- a/ir.h
+++ b/ir.h
@@ -47,10 +47,11 @@ public:
    class ir_constant *constant_expression_value();
 
    /** ir_print_visitor helper for debugging. */
-   void print(void);
+   void print(void) const;
 
    virtual void accept(ir_visitor *) = 0;
    virtual ir_visitor_status accept(ir_hierarchical_visitor *) = 0;
+   virtual ir_instruction *clone(struct hash_table *ht) const = 0;
 
    /**
     * \name IR instruction downcast functions
@@ -144,6 +145,8 @@ class ir_variable : public ir_instruction {
 public:
    ir_variable(const struct glsl_type *, const char *);
 
+   virtual ir_instruction *clone(struct hash_table *ht) const;
+
    virtual ir_variable *as_variable()
    {
       return this;
@@ -156,26 +159,6 @@ public:
 
    virtual ir_visitor_status accept(ir_hierarchical_visitor *);
 
-   /**
-    * Duplicate an IR variable
-    *
-    * \note
-    * This will probably be made \c virtual and moved to the base class
-    * eventually.
-    */
-   ir_variable *clone() const
-   {
-      ir_variable *var = new ir_variable(type, name);
-
-      var->max_array_access = this->max_array_access;
-      var->read_only = this->read_only;
-      var->centroid = this->centroid;
-      var->invariant = this->invariant;
-      var->mode = this->mode;
-      var->interpolation = this->interpolation;
-
-      return var;
-   }
 
    /**
     * Get the string value for the interpolation qualifier
@@ -266,6 +249,8 @@ class ir_function_signature : public ir_instruction {
 public:
    ir_function_signature(const glsl_type *return_type);
 
+   virtual ir_instruction *clone(struct hash_table *ht) const;
+
    virtual void accept(ir_visitor *v)
    {
       v->visit(this);
@@ -330,6 +315,8 @@ class ir_function : public ir_instruction {
 public:
    ir_function(const char *name);
 
+   virtual ir_instruction *clone(struct hash_table *ht) const;
+
    virtual ir_function *as_function()
    {
       return this;
@@ -398,6 +385,8 @@ public:
       /* empty */
    }
 
+   virtual ir_instruction *clone(struct hash_table *ht) const;
+
    virtual ir_if *as_if()
    {
       return this;
@@ -428,6 +417,8 @@ public:
       /* empty */
    }
 
+   virtual ir_instruction *clone(struct hash_table *ht) const;
+
    virtual void accept(ir_visitor *v)
    {
       v->visit(this);
@@ -467,6 +458,8 @@ class ir_assignment : public ir_rvalue {
 public:
    ir_assignment(ir_rvalue *lhs, ir_rvalue *rhs, ir_rvalue *condition);
 
+   virtual ir_instruction *clone(struct hash_table *ht) const;
+
    virtual void accept(ir_visitor *v)
    {
       v->visit(this);
@@ -589,8 +582,10 @@ public:
    ir_expression(int op, const struct glsl_type *type,
                 ir_rvalue *, ir_rvalue *);
 
+   virtual ir_instruction *clone(struct hash_table *ht) const;
+
    static unsigned int get_num_operands(ir_expression_operation);
-   unsigned int get_num_operands()
+   unsigned int get_num_operands() const
    {
       return get_num_operands(operation);
    }
@@ -612,8 +607,6 @@ public:
 
    virtual ir_visitor_status accept(ir_hierarchical_visitor *);
 
-   ir_expression *clone();
-
    ir_expression_operation operation;
    ir_rvalue *operands[2];
 };
@@ -632,6 +625,8 @@ public:
       actual_parameters->move_nodes_to(& this->actual_parameters);
    }
 
+   virtual ir_instruction *clone(struct hash_table *ht) const;
+
    virtual ir_call *as_call()
    {
       return this;
@@ -718,6 +713,8 @@ public:
       /* empty */
    }
 
+   virtual ir_instruction *clone(struct hash_table *) const;
+
    virtual ir_return *as_return()
    {
       return this;
@@ -754,12 +751,14 @@ public:
       jump_continue
    };
 
-   ir_loop_jump(ir_loop *loop, jump_mode mode)
-      : loop(loop), mode(mode)
+   ir_loop_jump(jump_mode mode)
+      : mode(mode)
    {
       /* empty */
    }
 
+   virtual ir_instruction *clone(struct hash_table *) const;
+
    virtual void accept(ir_visitor *v)
    {
       v->visit(this);
@@ -778,9 +777,6 @@ public:
    }
 
 private:
-   /** Loop containing this break instruction. */
-   ir_loop *loop;
-
    /** Mode selector for the jump instruction. */
    enum jump_mode mode;
 };
@@ -825,6 +821,8 @@ public:
       /* empty */
    }
 
+   virtual ir_instruction *clone(struct hash_table *) const;
+
    virtual void accept(ir_visitor *v)
    {
       v->visit(this);
@@ -910,16 +908,13 @@ public:
               unsigned count);
    ir_swizzle(ir_rvalue *val, ir_swizzle_mask mask);
 
+   virtual ir_instruction *clone(struct hash_table *) const;
+
    virtual ir_swizzle *as_swizzle()
    {
       return this;
    }
 
-   ir_swizzle *clone()
-   {
-      return new ir_swizzle(this->val, this->mask);
-   }
-
    /**
     * Construct an ir_swizzle from the textual representation.  Can fail.
     */
@@ -967,6 +962,8 @@ class ir_dereference_variable : public ir_dereference {
 public:
    ir_dereference_variable(ir_variable *var);
 
+   virtual ir_instruction *clone(struct hash_table *) const;
+
    /**
     * Get the variable that is ultimately referenced by an r-value
     */
@@ -1006,6 +1003,8 @@ public:
 
    ir_dereference_array(ir_variable *var, ir_rvalue *array_index);
 
+   virtual ir_instruction *clone(struct hash_table *) const;
+
    virtual ir_dereference_array *as_dereference_array()
    {
       return this;
@@ -1040,6 +1039,8 @@ public:
 
    ir_dereference_record(ir_variable *var, const char *field);
 
+   virtual ir_instruction *clone(struct hash_table *) const;
+
    /**
     * Get the variable that is ultimately referenced by an r-value
     */
@@ -1096,6 +1097,8 @@ public:
     */
    ir_constant(const ir_constant *c, unsigned i);
 
+   virtual ir_instruction *clone(struct hash_table *) const;
+
    virtual ir_constant *as_constant()
    {
       return this;
@@ -1108,8 +1111,6 @@ public:
 
    virtual ir_visitor_status accept(ir_hierarchical_visitor *);
 
-   ir_constant *clone();
-
    /**
     * Get a particular component of a constant as a specific type
     *
diff --git a/ir_clone.cpp b/ir_clone.cpp
new file mode 100644 (file)
index 0000000..c810fe8
--- /dev/null
@@ -0,0 +1,240 @@
+/*
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include <string.h>
+#include "ir.h"
+#include "glsl_types.h"
+#include "hash_table.h"
+
+/**
+ * Duplicate an IR variable
+ *
+ * \note
+ * This will probably be made \c virtual and moved to the base class
+ * eventually.
+ */
+ir_instruction *
+ir_variable::clone(struct hash_table *ht) const
+{
+   ir_variable *var = new ir_variable(type, name);
+
+   var->max_array_access = this->max_array_access;
+   var->read_only = this->read_only;
+   var->centroid = this->centroid;
+   var->invariant = this->invariant;
+   var->mode = this->mode;
+   var->interpolation = this->interpolation;
+
+   if (ht) {
+      hash_table_insert(ht, (void *)const_cast<ir_variable *>(this), var);
+   }
+
+   return var;
+}
+
+ir_instruction *
+ir_swizzle::clone(struct hash_table *ht) const
+{
+   return new ir_swizzle((ir_rvalue *)this->val->clone(ht), this->mask);
+}
+
+ir_instruction *
+ir_return::clone(struct hash_table *ht) const
+{
+   ir_rvalue *new_value = NULL;
+
+   if (this->value)
+      new_value = (ir_rvalue *)this->value->clone(ht);
+
+   return new ir_return(new_value);
+}
+
+ir_instruction *
+ir_loop_jump::clone(struct hash_table *ht) const
+{
+   (void)ht;
+
+   return new ir_loop_jump(this->mode);
+}
+
+ir_instruction *
+ir_if::clone(struct hash_table *ht) const
+{
+   ir_if *new_if = new ir_if((ir_rvalue *)this->condition->clone(ht));
+
+   foreach_iter(exec_list_iterator, iter, this->then_instructions) {
+      ir_instruction *ir = (ir_instruction *)iter.get();
+      new_if->then_instructions.push_tail(ir->clone(ht));
+   }
+
+   foreach_iter(exec_list_iterator, iter, this->else_instructions) {
+      ir_instruction *ir = (ir_instruction *)iter.get();
+      new_if->else_instructions.push_tail(ir->clone(ht));
+   }
+
+   return new_if;
+}
+
+ir_instruction *
+ir_loop::clone(struct hash_table *ht) const
+{
+   ir_loop *new_loop = new ir_loop();
+
+   if (this->from)
+      new_loop->from = (ir_rvalue *)this->from->clone(ht);
+   if (this->to)
+      new_loop->to = (ir_rvalue *)this->to->clone(ht);
+   if (this->increment)
+      new_loop->increment = (ir_rvalue *)this->increment->clone(ht);
+   new_loop->counter = counter;
+
+   foreach_iter(exec_list_iterator, iter, this->body_instructions) {
+      ir_instruction *ir = (ir_instruction *)iter.get();
+      new_loop->body_instructions.push_tail(ir->clone(ht));
+   }
+
+   return new_loop;
+}
+
+ir_instruction *
+ir_call::clone(struct hash_table *ht) const
+{
+   exec_list new_parameters;
+
+   foreach_iter(exec_list_iterator, iter, this->actual_parameters) {
+      ir_instruction *ir = (ir_instruction *)iter.get();
+      new_parameters.push_tail(ir->clone(ht));
+   }
+
+   return new ir_call(this->callee, &new_parameters);
+}
+
+ir_instruction *
+ir_expression::clone(struct hash_table *ht) const
+{
+   ir_rvalue *op[2] = {NULL, NULL};
+   unsigned int i;
+
+   for (i = 0; i < get_num_operands(); i++) {
+      op[i] = (ir_rvalue *)this->operands[i]->clone(ht);
+   }
+
+   return new ir_expression(this->operation, this->type, op[0], op[1]);
+}
+
+ir_instruction *
+ir_dereference_variable::clone(struct hash_table *ht) const
+{
+   ir_variable *new_var;
+
+   if (ht) {
+      new_var = (ir_variable *)hash_table_find(ht, this->var);
+      if (!new_var)
+        new_var = this->var;
+   } else {
+      new_var = this->var;
+   }
+
+   return new ir_dereference_variable(new_var);
+}
+
+ir_instruction *
+ir_dereference_array::clone(struct hash_table *ht) const
+{
+   return new ir_dereference_array((ir_rvalue *)this->array->clone(ht),
+                                  (ir_rvalue *)this->array_index->clone(ht));
+}
+
+ir_instruction *
+ir_dereference_record::clone(struct hash_table *ht) const
+{
+   return new ir_dereference_record((ir_rvalue *)this->record->clone(ht),
+                                   this->field);
+}
+
+ir_instruction *
+ir_texture::clone(struct hash_table *ht) const
+{
+   ir_texture *new_tex = new ir_texture(this->op);
+
+   new_tex->sampler = (ir_dereference *)this->sampler->clone(ht);
+   new_tex->coordinate = (ir_rvalue *)this->coordinate->clone(ht);
+   if (this->projector)
+      new_tex->projector = (ir_rvalue *)this->projector->clone(ht);
+   if (this->shadow_comparitor) {
+      new_tex->shadow_comparitor =
+        (ir_rvalue *)this->shadow_comparitor->clone(ht);
+   }
+
+   for (int i = 0; i < 3; i++)
+      new_tex->offsets[i] = this->offsets[i];
+
+   switch (this->op) {
+   case ir_tex:
+      break;
+   case ir_txb:
+      new_tex->lod_info.bias = (ir_rvalue *)this->lod_info.bias->clone(ht);
+      break;
+   case ir_txl:
+   case ir_txf:
+      new_tex->lod_info.lod = (ir_rvalue *)this->lod_info.lod->clone(ht);
+      break;
+   case ir_txd:
+      new_tex->lod_info.grad.dPdx =
+        (ir_rvalue *)this->lod_info.grad.dPdx->clone(ht);
+      new_tex->lod_info.grad.dPdy =
+        (ir_rvalue *)this->lod_info.grad.dPdy->clone(ht);
+      break;
+   }
+
+   return new_tex;
+}
+
+ir_instruction *
+ir_assignment::clone(struct hash_table *ht) const
+{
+   ir_rvalue *new_condition = NULL;
+
+   if (this->condition)
+      new_condition = (ir_rvalue *)this->condition->clone(ht);
+
+   return new ir_assignment((ir_rvalue *)this->lhs->clone(ht),
+                           (ir_rvalue *)this->rhs->clone(ht),
+                           new_condition);
+}
+
+ir_instruction *
+ir_function::clone(struct hash_table *ht) const
+{
+   (void)ht;
+   /* FINISHME */
+   abort();
+}
+
+ir_instruction *
+ir_function_signature::clone(struct hash_table *ht) const
+{
+   (void)ht;
+   /* FINISHME */
+   abort();
+}
index e9f0499..effb888 100644 (file)
@@ -546,7 +546,7 @@ ir_constant_visitor::visit(ir_dereference_variable *ir)
 
    ir_variable *var = ir->variable_referenced();
    if (var && var->constant_value)
-      value = var->constant_value->clone();
+      value = (ir_constant *)var->constant_value->clone(NULL);
 }
 
 
index 4e5604f..effb01c 100644 (file)
  * Replaces calls to functions with the body of the function.
  */
 
+#include <inttypes.h>
 #include "ir.h"
 #include "ir_visitor.h"
 #include "ir_function_inlining.h"
 #include "ir_expression_flattening.h"
 #include "glsl_types.h"
+#include "hash_table.h"
 
 class ir_function_inlining_visitor : public ir_hierarchical_visitor {
 public:
@@ -55,283 +57,15 @@ public:
    bool progress;
 };
 
-class variable_remap : public exec_node {
-public:
-   variable_remap(const ir_variable *old_var, ir_variable *new_var)
-      : old_var(old_var), new_var(new_var)
-   {
-      /* empty */
-   }
-   const ir_variable *old_var;
-   ir_variable *new_var;
-};
-
-class ir_function_cloning_visitor : public ir_visitor {
-public:
-   ir_function_cloning_visitor(ir_variable *retval)
-      : retval(retval)
-   {
-      /* empty */
-   }
-
-   virtual ~ir_function_cloning_visitor()
-   {
-      /* empty */
-   }
-
-   void remap_variable(const ir_variable *old_var, ir_variable *new_var) {
-      variable_remap *remap = new variable_remap(old_var, new_var);
-      this->remap_list.push_tail(remap);
-   }
-
-   ir_variable *get_remapped_variable(ir_variable *var) {
-      foreach_iter(exec_list_iterator, iter, this->remap_list) {
-        variable_remap *remap = (variable_remap *)iter.get();
-
-        if (var == remap->old_var)
-           return remap->new_var;
-      }
-
-      /* Not a reapped variable, so a global scoped reference, for example. */
-      return var;
-   }
-
-   /* List of variable_remap for mapping from original function body variables
-    * to inlined function body variables.
-    */
-   exec_list remap_list;
-
-   /* Return value for the inlined function. */
-   ir_variable *retval;
-
-   /**
-    * \name Visit methods
-    *
-    * As typical for the visitor pattern, there must be one \c visit method for
-    * each concrete subclass of \c ir_instruction.  Virtual base classes within
-    * the hierarchy should not have \c visit methods.
-    */
-   /*@{*/
-   virtual void visit(ir_variable *);
-   virtual void visit(ir_loop *);
-   virtual void visit(ir_loop_jump *);
-   virtual void visit(ir_function_signature *);
-   virtual void visit(ir_function *);
-   virtual void visit(ir_expression *);
-   virtual void visit(ir_texture *);
-   virtual void visit(ir_swizzle *);
-   virtual void visit(ir_dereference_variable *);
-   virtual void visit(ir_dereference_array *);
-   virtual void visit(ir_dereference_record *);
-   virtual void visit(ir_assignment *);
-   virtual void visit(ir_constant *);
-   virtual void visit(ir_call *);
-   virtual void visit(ir_return *);
-   virtual void visit(ir_if *);
-   /*@}*/
-
-   ir_instruction *result;
-};
-
-void
-ir_function_cloning_visitor::visit(ir_variable *ir)
-{
-   ir_variable *new_var = ir->clone();
-
-   this->result = new_var;
 
-   this->remap_variable(ir, new_var);
-}
-
-void
-ir_function_cloning_visitor::visit(ir_loop *ir)
-{
-   /* FINISHME: Implement loop cloning. */
-   assert(0);
-
-   (void)ir;
-   this->result = NULL;
-}
-
-void
-ir_function_cloning_visitor::visit(ir_loop_jump *ir)
-{
-   /* FINISHME: Implement loop cloning. */
-   assert(0);
-
-   (void) ir;
-   this->result = NULL;
-}
-
-
-void
-ir_function_cloning_visitor::visit(ir_function_signature *ir)
-{
-   assert(0);
-   (void)ir;
-   this->result = NULL;
-}
-
-
-void
-ir_function_cloning_visitor::visit(ir_function *ir)
+unsigned int hash_func(const void *key)
 {
-   assert(0);
-   (void) ir;
-   this->result = NULL;
+   return (unsigned int)(uintptr_t)key;
 }
 
-void
-ir_function_cloning_visitor::visit(ir_expression *ir)
+int hash_compare_func(const void *key1, const void *key2)
 {
-   unsigned int operand;
-   ir_rvalue *op[2] = {NULL, NULL};
-
-   for (operand = 0; operand < ir->get_num_operands(); operand++) {
-      ir->operands[operand]->accept(this);
-      op[operand] = this->result->as_rvalue();
-      assert(op[operand]);
-   }
-
-   this->result = new ir_expression(ir->operation, ir->type, op[0], op[1]);
-}
-
-
-void
-ir_function_cloning_visitor::visit(ir_texture *ir)
-{
-   ir_texture *tex = new ir_texture(ir->op);
-
-   ir->sampler->accept(this);
-   tex->set_sampler(this->result->as_dereference());
-
-   ir->coordinate->accept(this);
-   tex->coordinate = this->result->as_rvalue();
-
-   if (ir->projector != NULL) {
-      ir->projector->accept(this);
-      tex->projector = this->result->as_rvalue();
-   }
-
-   if (ir->shadow_comparitor != NULL) {
-      ir->shadow_comparitor->accept(this);
-      tex->shadow_comparitor = this->result->as_rvalue();
-   }
-
-   for (int i = 0; i < 3; i++)
-      tex->offsets[i] = ir->offsets[i];
-
-   tex->lod_info = ir->lod_info;
-}
-
-
-void
-ir_function_cloning_visitor::visit(ir_swizzle *ir)
-{
-   ir->val->accept(this);
-
-   this->result = new ir_swizzle(this->result->as_rvalue(), ir->mask);
-}
-
-void
-ir_function_cloning_visitor::visit(ir_dereference_variable *ir)
-{
-   ir_variable *var = this->get_remapped_variable(ir->variable_referenced());
-   this->result = new ir_dereference_variable(var);
-}
-
-void
-ir_function_cloning_visitor::visit(ir_dereference_array *ir)
-{
-   ir->array->accept(this);
-
-   ir_rvalue *var = this->result->as_rvalue();
-
-   ir->array_index->accept(this);
-
-   ir_rvalue *index = this->result->as_rvalue();
-
-   this->result = new ir_dereference_array(var, index);
-}
-
-void
-ir_function_cloning_visitor::visit(ir_dereference_record *ir)
-{
-   ir->record->accept(this);
-
-   ir_rvalue *var = this->result->as_rvalue();
-
-   this->result = new ir_dereference_record(var, strdup(ir->field));
-}
-
-void
-ir_function_cloning_visitor::visit(ir_assignment *ir)
-{
-   ir_rvalue *lhs, *rhs, *condition = NULL;
-
-   ir->lhs->accept(this);
-   lhs = this->result->as_rvalue();
-
-   ir->rhs->accept(this);
-   rhs = this->result->as_rvalue();
-
-   if (ir->condition) {
-      ir->condition->accept(this);
-      condition = this->result->as_rvalue();
-   }
-
-   this->result = new ir_assignment(lhs, rhs, condition);
-}
-
-
-void
-ir_function_cloning_visitor::visit(ir_constant *ir)
-{
-   this->result = ir->clone();
-}
-
-
-void
-ir_function_cloning_visitor::visit(ir_call *ir)
-{
-   exec_list parameters;
-
-   foreach_iter(exec_list_iterator, iter, *ir) {
-      ir_rvalue *param = (ir_rvalue *)iter.get();
-
-      param->accept(this);
-      parameters.push_tail(this->result);
-   }
-
-   this->result = new ir_call(ir->get_callee(), &parameters);
-}
-
-
-void
-ir_function_cloning_visitor::visit(ir_return *ir)
-{
-   ir_rvalue *rval;
-
-   assert(this->retval);
-
-   rval = ir->get_value();
-   rval->accept(this);
-   rval = this->result->as_rvalue();
-   assert(rval);
-
-   result = new ir_assignment(new ir_dereference_variable(this->retval), rval,
-                             NULL);
-}
-
-
-void
-ir_function_cloning_visitor::visit(ir_if *ir)
-{
-   /* FINISHME: Implement if cloning. */
-   assert(0);
-
-   (void) ir;
-   result = NULL;
+   return key1 == key2 ? 0 : 1;
 }
 
 bool
@@ -364,6 +98,9 @@ ir_call::generate_inline(ir_instruction *next_ir)
    int num_parameters;
    int i;
    ir_variable *retval = NULL;
+   struct hash_table *ht;
+
+   ht = hash_table_ctor(0, hash_func, hash_compare_func);
 
    num_parameters = 0;
    foreach_iter(exec_list_iterator, iter_sig, this->callee->parameters)
@@ -377,8 +114,6 @@ ir_call::generate_inline(ir_instruction *next_ir)
       next_ir->insert_before(retval);
    }
 
-   ir_function_cloning_visitor v = ir_function_cloning_visitor(retval);
-
    /* Generate the declarations for the parameters to our inlined code,
     * and set up the mapping of real function body variables to ours.
     */
@@ -390,11 +125,9 @@ ir_call::generate_inline(ir_instruction *next_ir)
       ir_rvalue *param = (ir_rvalue *) param_iter.get();
 
       /* Generate a new variable for the parameter. */
-      parameters[i] = sig_param->clone();
+      parameters[i] = (ir_variable *)sig_param->clone(ht);
       next_ir->insert_before(parameters[i]);
 
-      v.remap_variable(sig_param, parameters[i]);
-
       /* Move the actual param into our param variable if it's an 'in' type. */
       if (parameters[i]->mode == ir_var_in ||
          parameters[i]->mode == ir_var_inout) {
@@ -413,9 +146,7 @@ ir_call::generate_inline(ir_instruction *next_ir)
    foreach_iter(exec_list_iterator, iter, callee->body) {
       ir_instruction *ir = (ir_instruction *)iter.get();
 
-      ir->accept(&v);
-      assert(v.result);
-      next_ir->insert_before(v.result);
+      next_ir->insert_before(ir->clone(ht));
    }
 
    /* Copy back the value of any 'out' parameters from the function body
@@ -442,6 +173,8 @@ ir_call::generate_inline(ir_instruction *next_ir)
 
    delete [] parameters;
 
+   hash_table_dtor(ht);
+
    if (retval)
       return new ir_dereference_variable(retval);
    else
index 60fb33e..f15ffb6 100644 (file)
 static void print_type(const glsl_type *t);
 
 void
-ir_instruction::print(void)
+ir_instruction::print(void) const
 {
+   ir_instruction *deconsted = const_cast<ir_instruction *>(this);
+
    ir_print_visitor v;
-   accept(&v);
+   deconsted->accept(&v);
 }
 
 void
index a8ccb30..ee320dd 100644 (file)
@@ -334,9 +334,9 @@ read_instruction(_mesa_glsl_parse_state *st, s_expression *expr,
    s_symbol *symbol = SX_AS_SYMBOL(expr);
    if (symbol != NULL) {
       if (strcmp(symbol->value(), "break") == 0 && loop_ctx != NULL)
-        return new ir_loop_jump(loop_ctx, ir_loop_jump::jump_break);
+        return new ir_loop_jump(ir_loop_jump::jump_break);
       if (strcmp(symbol->value(), "continue") == 0 && loop_ctx != NULL)
-        return new ir_loop_jump(loop_ctx, ir_loop_jump::jump_continue);
+        return new ir_loop_jump(ir_loop_jump::jump_continue);
    }
 
    s_list *list = SX_AS_LIST(expr);
index abf5371..ba382fe 100644 (file)
@@ -290,7 +290,8 @@ cross_validate_uniforms(struct glsl_program *prog)
                   * have an initializer but a later instance does, copy the
                   * initializer to the version stored in the symbol table.
                   */
-                 existing->constant_value = var->constant_value->clone();
+                 existing->constant_value =
+                    (ir_constant *)var->constant_value->clone(NULL);
            }
         } else
            uniforms.add_variable(var->name, var);