From 4b6fd39c89f308a379882426c1ed3616d60c4628 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 23 Jun 2010 11:37:12 -0700 Subject: [PATCH] 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. --- Makefile.am | 1 + ast_to_hir.cpp | 5 +- ir.cpp | 6 +- ir.h | 73 +++++------ ir_clone.cpp | 240 +++++++++++++++++++++++++++++++++++++ ir_constant_expression.cpp | 2 +- ir_function_inlining.cpp | 293 ++------------------------------------------- ir_print_visitor.cpp | 6 +- ir_reader.cpp | 4 +- linker.cpp | 3 +- 10 files changed, 305 insertions(+), 328 deletions(-) create mode 100644 ir_clone.cpp diff --git a/Makefile.am b/Makefile.am index b65b8ba..a88bf00 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 aa90d4b..b4692c6 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); diff --git a/ir.cpp b/ir.cpp index 49191fb..9514201 100644 --- 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 --- 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 index 0000000..c810fe8 --- /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 +#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(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 e9f0499..effb888 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 4e5604f..effb01c 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 #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(), ¶meters); -} - - -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 diff --git a/ir_print_visitor.cpp b/ir_print_visitor.cpp index 60fb33e..f15ffb6 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(this); + ir_print_visitor v; - accept(&v); + deconsted->accept(&v); } void diff --git a/ir_reader.cpp b/ir_reader.cpp index a8ccb30..ee320dd 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 abf5371..ba382fe 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); -- 2.7.4