diff options
| author | Eric Anholt <eric@anholt.net> | 2010-06-23 11:37:12 -0700 | 
|---|---|---|
| committer | Ian Romanick <ian.d.romanick@intel.com> | 2010-06-23 15:20:29 -0700 | 
| commit | 4b6fd39c89f308a379882426c1ed3616d60c4628 (patch) | |
| tree | 2c8f6f7e2e3eae5922a91c61a686457c614068fe | |
| parent | 02fc4b34e40f655eebc99f6502293b4d4000e0b3 (diff) | |
Add a virtual clone() method to ir_instruction.
This will be used by function inlining, the linker, and avoiding double
usage of the LHS deref chains in ++, *=, and similar operations.
| -rw-r--r-- | Makefile.am | 1 | ||||
| -rw-r--r-- | ast_to_hir.cpp | 5 | ||||
| -rw-r--r-- | ir.cpp | 6 | ||||
| -rw-r--r-- | ir.h | 73 | ||||
| -rw-r--r-- | ir_clone.cpp | 240 | ||||
| -rw-r--r-- | ir_constant_expression.cpp | 2 | ||||
| -rw-r--r-- | ir_function_inlining.cpp | 293 | ||||
| -rw-r--r-- | ir_print_visitor.cpp | 6 | ||||
| -rw-r--r-- | ir_reader.cpp | 4 | ||||
| -rw-r--r-- | linker.cpp | 3 | 
10 files changed, 305 insertions, 328 deletions
| diff --git a/Makefile.am b/Makefile.am index b65b8bab52..a88bf0022a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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 \ diff --git a/ast_to_hir.cpp b/ast_to_hir.cpp index aa90d4b663..b4692c6922 100644 --- a/ast_to_hir.cpp +++ b/ast_to_hir.cpp @@ -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); @@ -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; @@ -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 index 0000000000..c810fe8616 --- /dev/null +++ b/ir_clone.cpp @@ -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(); +} diff --git a/ir_constant_expression.cpp b/ir_constant_expression.cpp index e9f0499820..effb88844e 100644 --- a/ir_constant_expression.cpp +++ b/ir_constant_expression.cpp @@ -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);  } diff --git a/ir_function_inlining.cpp b/ir_function_inlining.cpp index 4e5604f89f..effb01c8f6 100644 --- a/ir_function_inlining.cpp +++ b/ir_function_inlining.cpp @@ -27,11 +27,13 @@   * 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) -{ -   assert(0); -   (void) ir; -   this->result = NULL; -} - -void -ir_function_cloning_visitor::visit(ir_expression *ir) -{ -   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(), ¶meters); -} - - -void -ir_function_cloning_visitor::visit(ir_return *ir) +unsigned int hash_func(const void *key)  { -   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); +   return (unsigned int)(uintptr_t)key;  } - -void -ir_function_cloning_visitor::visit(ir_if *ir) +int hash_compare_func(const void *key1, const void *key2)  { -   /* 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 diff --git a/ir_print_visitor.cpp b/ir_print_visitor.cpp index 60fb33e2f5..f15ffb6614 100644 --- a/ir_print_visitor.cpp +++ b/ir_print_visitor.cpp @@ -28,10 +28,12 @@  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 diff --git a/ir_reader.cpp b/ir_reader.cpp index a8ccb30999..ee320ddac2 100644 --- a/ir_reader.cpp +++ b/ir_reader.cpp @@ -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); diff --git a/linker.cpp b/linker.cpp index abf5371ce9..ba382fe881 100644 --- a/linker.cpp +++ b/linker.cpp @@ -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); | 
