glsl2: Make the clone() method take a talloc context.

In most cases, we needed to be reparenting the cloned IR to a
different context (for example, to the linked shader instead of the
unlinked shader), or optimization before the reparent would cause
memory usage of the original object to grow and grow.
This commit is contained in:
Eric Anholt
2010-08-04 12:34:56 -07:00
parent 84ee01f40a
commit 8273bd4687
9 changed files with 130 additions and 131 deletions

View File

@@ -966,7 +966,7 @@ ast_expression::hir(exec_list *instructions,
op[0], op[1]); op[0], op[1]);
result = do_assignment(instructions, state, result = do_assignment(instructions, state,
op[0]->clone(NULL), temp_rhs, op[0]->clone(ctx, NULL), temp_rhs,
this->subexpressions[0]->get_location()); this->subexpressions[0]->get_location());
type = result->type; type = result->type;
error_emitted = (op[0]->type->is_error()); error_emitted = (op[0]->type->is_error());
@@ -992,7 +992,7 @@ ast_expression::hir(exec_list *instructions,
op[0], op[1]); op[0], op[1]);
result = do_assignment(instructions, state, result = do_assignment(instructions, state,
op[0]->clone(NULL), temp_rhs, op[0]->clone(ctx, NULL), temp_rhs,
this->subexpressions[0]->get_location()); this->subexpressions[0]->get_location());
type = result->type; type = result->type;
error_emitted = type->is_error(); error_emitted = type->is_error();
@@ -1113,7 +1113,7 @@ ast_expression::hir(exec_list *instructions,
op[0], op[1]); op[0], op[1]);
result = do_assignment(instructions, state, result = do_assignment(instructions, state,
op[0]->clone(NULL), temp_rhs, op[0]->clone(ctx, NULL), temp_rhs,
this->subexpressions[0]->get_location()); this->subexpressions[0]->get_location());
type = result->type; type = result->type;
error_emitted = op[0]->type->is_error(); error_emitted = op[0]->type->is_error();
@@ -1139,10 +1139,10 @@ ast_expression::hir(exec_list *instructions,
/* Get a temporary of a copy of the lvalue before it's modified. /* Get a temporary of a copy of the lvalue before it's modified.
* This may get thrown away later. * This may get thrown away later.
*/ */
result = get_lvalue_copy(instructions, op[0]->clone(NULL)); result = get_lvalue_copy(instructions, op[0]->clone(ctx, NULL));
(void)do_assignment(instructions, state, (void)do_assignment(instructions, state,
op[0]->clone(NULL), temp_rhs, op[0]->clone(ctx, NULL), temp_rhs,
this->subexpressions[0]->get_location()); this->subexpressions[0]->get_location());
type = result->type; type = result->type;

View File

@@ -76,7 +76,8 @@ public:
virtual void accept(ir_visitor *) = 0; virtual void accept(ir_visitor *) = 0;
virtual ir_visitor_status accept(ir_hierarchical_visitor *) = 0; virtual ir_visitor_status accept(ir_hierarchical_visitor *) = 0;
virtual ir_instruction *clone(struct hash_table *ht) const = 0; virtual ir_instruction *clone(void *mem_ctx,
struct hash_table *ht) const = 0;
/** /**
* \name IR instruction downcast functions * \name IR instruction downcast functions
@@ -113,7 +114,7 @@ protected:
class ir_rvalue : public ir_instruction { class ir_rvalue : public ir_instruction {
public: public:
virtual ir_rvalue *clone(struct hash_table *) const = 0; virtual ir_rvalue *clone(void *mem_ctx, struct hash_table *) const = 0;
virtual ir_constant *constant_expression_value() = 0; virtual ir_constant *constant_expression_value() = 0;
@@ -175,7 +176,7 @@ class ir_variable : public ir_instruction {
public: public:
ir_variable(const struct glsl_type *, const char *, ir_variable_mode); ir_variable(const struct glsl_type *, const char *, ir_variable_mode);
virtual ir_variable *clone(struct hash_table *ht) const; virtual ir_variable *clone(void *mem_ctx, struct hash_table *ht) const;
virtual ir_variable *as_variable() virtual ir_variable *as_variable()
{ {
@@ -283,7 +284,8 @@ class ir_function_signature : public ir_instruction {
public: public:
ir_function_signature(const glsl_type *return_type); ir_function_signature(const glsl_type *return_type);
virtual ir_function_signature *clone(struct hash_table *ht) const; virtual ir_function_signature *clone(void *mem_ctx,
struct hash_table *ht) const;
virtual void accept(ir_visitor *v) virtual void accept(ir_visitor *v)
{ {
@@ -369,7 +371,7 @@ class ir_function : public ir_instruction {
public: public:
ir_function(const char *name); ir_function(const char *name);
virtual ir_function *clone(struct hash_table *ht) const; virtual ir_function *clone(void *mem_ctx, struct hash_table *ht) const;
virtual ir_function *as_function() virtual ir_function *as_function()
{ {
@@ -439,7 +441,7 @@ public:
ir_type = ir_type_if; ir_type = ir_type_if;
} }
virtual ir_if *clone(struct hash_table *ht) const; virtual ir_if *clone(void *mem_ctx, struct hash_table *ht) const;
virtual ir_if *as_if() virtual ir_if *as_if()
{ {
@@ -471,7 +473,7 @@ public:
ir_type = ir_type_loop; ir_type = ir_type_loop;
} }
virtual ir_loop *clone(struct hash_table *ht) const; virtual ir_loop *clone(void *mem_ctx, struct hash_table *ht) const;
virtual void accept(ir_visitor *v) virtual void accept(ir_visitor *v)
{ {
@@ -512,7 +514,7 @@ class ir_assignment : public ir_instruction {
public: public:
ir_assignment(ir_rvalue *lhs, ir_rvalue *rhs, ir_rvalue *condition); ir_assignment(ir_rvalue *lhs, ir_rvalue *rhs, ir_rvalue *condition);
virtual ir_assignment *clone(struct hash_table *ht) const; virtual ir_assignment *clone(void *mem_ctx, struct hash_table *ht) const;
virtual ir_constant *constant_expression_value(); virtual ir_constant *constant_expression_value();
@@ -662,7 +664,7 @@ public:
return this; return this;
} }
virtual ir_expression *clone(struct hash_table *ht) const; virtual ir_expression *clone(void *mem_ctx, struct hash_table *ht) const;
virtual ir_constant *constant_expression_value(); virtual ir_constant *constant_expression_value();
@@ -708,7 +710,7 @@ public:
actual_parameters->move_nodes_to(& this->actual_parameters); actual_parameters->move_nodes_to(& this->actual_parameters);
} }
virtual ir_call *clone(struct hash_table *ht) const; virtual ir_call *clone(void *mem_ctx, struct hash_table *ht) const;
virtual ir_constant *constant_expression_value(); virtual ir_constant *constant_expression_value();
@@ -805,7 +807,7 @@ public:
this->ir_type = ir_type_return; this->ir_type = ir_type_return;
} }
virtual ir_return *clone(struct hash_table *) const; virtual ir_return *clone(void *mem_ctx, struct hash_table *) const;
virtual ir_return *as_return() virtual ir_return *as_return()
{ {
@@ -850,7 +852,7 @@ public:
this->loop = loop; this->loop = loop;
} }
virtual ir_loop_jump *clone(struct hash_table *) const; virtual ir_loop_jump *clone(void *mem_ctx, struct hash_table *) const;
virtual void accept(ir_visitor *v) virtual void accept(ir_visitor *v)
{ {
@@ -893,7 +895,7 @@ public:
this->condition = cond; this->condition = cond;
} }
virtual ir_discard *clone(struct hash_table *ht) const; virtual ir_discard *clone(void *mem_ctx, struct hash_table *ht) const;
virtual void accept(ir_visitor *v) virtual void accept(ir_visitor *v)
{ {
@@ -945,7 +947,7 @@ public:
this->ir_type = ir_type_texture; this->ir_type = ir_type_texture;
} }
virtual ir_texture *clone(struct hash_table *) const; virtual ir_texture *clone(void *mem_ctx, struct hash_table *) const;
virtual ir_constant *constant_expression_value(); virtual ir_constant *constant_expression_value();
@@ -1037,7 +1039,7 @@ public:
ir_swizzle(ir_rvalue *val, ir_swizzle_mask mask); ir_swizzle(ir_rvalue *val, ir_swizzle_mask mask);
virtual ir_swizzle *clone(struct hash_table *) const; virtual ir_swizzle *clone(void *mem_ctx, struct hash_table *) const;
virtual ir_constant *constant_expression_value(); virtual ir_constant *constant_expression_value();
@@ -1083,7 +1085,7 @@ private:
class ir_dereference : public ir_rvalue { class ir_dereference : public ir_rvalue {
public: public:
virtual ir_dereference *clone(struct hash_table *) const = 0; virtual ir_dereference *clone(void *mem_ctx, struct hash_table *) const = 0;
virtual ir_dereference *as_dereference() virtual ir_dereference *as_dereference()
{ {
@@ -1103,7 +1105,8 @@ class ir_dereference_variable : public ir_dereference {
public: public:
ir_dereference_variable(ir_variable *var); ir_dereference_variable(ir_variable *var);
virtual ir_dereference_variable *clone(struct hash_table *) const; virtual ir_dereference_variable *clone(void *mem_ctx,
struct hash_table *) const;
virtual ir_constant *constant_expression_value(); virtual ir_constant *constant_expression_value();
@@ -1151,7 +1154,8 @@ public:
ir_dereference_array(ir_variable *var, ir_rvalue *array_index); ir_dereference_array(ir_variable *var, ir_rvalue *array_index);
virtual ir_dereference_array *clone(struct hash_table *) const; virtual ir_dereference_array *clone(void *mem_ctx,
struct hash_table *) const;
virtual ir_constant *constant_expression_value(); virtual ir_constant *constant_expression_value();
@@ -1189,7 +1193,8 @@ public:
ir_dereference_record(ir_variable *var, const char *field); ir_dereference_record(ir_variable *var, const char *field);
virtual ir_dereference_record *clone(struct hash_table *) const; virtual ir_dereference_record *clone(void *mem_ctx,
struct hash_table *) const;
virtual ir_constant *constant_expression_value(); virtual ir_constant *constant_expression_value();
@@ -1254,7 +1259,7 @@ public:
*/ */
static ir_constant *zero(void *mem_ctx, const glsl_type *type); static ir_constant *zero(void *mem_ctx, const glsl_type *type);
virtual ir_constant *clone(struct hash_table *) const; virtual ir_constant *clone(void *mem_ctx, struct hash_table *) const;
virtual ir_constant *constant_expression_value(); virtual ir_constant *constant_expression_value();
@@ -1327,7 +1332,7 @@ void validate_ir_tree(exec_list *instructions);
* \param out List to hold the cloned instructions * \param out List to hold the cloned instructions
*/ */
void void
clone_ir_list(exec_list *out, const exec_list *in); clone_ir_list(void *mem_ctx, exec_list *out, const exec_list *in);
extern void extern void
_mesa_glsl_initialize_variables(exec_list *instructions, _mesa_glsl_initialize_variables(exec_list *instructions,

View File

@@ -36,11 +36,10 @@ extern "C" {
* eventually. * eventually.
*/ */
ir_variable * ir_variable *
ir_variable::clone(struct hash_table *ht) const ir_variable::clone(void *mem_ctx, struct hash_table *ht) const
{ {
void *ctx = talloc_parent(this); ir_variable *var = new(mem_ctx) ir_variable(this->type, this->name,
ir_variable *var = new(ctx) ir_variable(this->type, this->name, (ir_variable_mode) this->mode);
(ir_variable_mode) this->mode);
var->max_array_access = this->max_array_access; var->max_array_access = this->max_array_access;
var->read_only = this->read_only; var->read_only = this->read_only;
@@ -56,7 +55,7 @@ ir_variable::clone(struct hash_table *ht) const
var->pixel_center_integer = this->pixel_center_integer; var->pixel_center_integer = this->pixel_center_integer;
if (this->constant_value) if (this->constant_value)
var->constant_value = this->constant_value->clone(ht); var->constant_value = this->constant_value->clone(mem_ctx, ht);
if (ht) { if (ht) {
hash_table_insert(ht, var, (void *)const_cast<ir_variable *>(this)); hash_table_insert(ht, var, (void *)const_cast<ir_variable *>(this));
@@ -66,118 +65,109 @@ ir_variable::clone(struct hash_table *ht) const
} }
ir_swizzle * ir_swizzle *
ir_swizzle::clone(struct hash_table *ht) const ir_swizzle::clone(void *mem_ctx, struct hash_table *ht) const
{ {
void *ctx = talloc_parent(this); return new(mem_ctx) ir_swizzle(this->val->clone(mem_ctx, ht), this->mask);
return new(ctx) ir_swizzle(this->val->clone(ht), this->mask);
} }
ir_return * ir_return *
ir_return::clone(struct hash_table *ht) const ir_return::clone(void *mem_ctx, struct hash_table *ht) const
{ {
void *ctx = talloc_parent(this);
ir_rvalue *new_value = NULL; ir_rvalue *new_value = NULL;
if (this->value) if (this->value)
new_value = this->value->clone(ht); new_value = this->value->clone(mem_ctx, ht);
return new(ctx) ir_return(new_value); return new(mem_ctx) ir_return(new_value);
} }
ir_discard * ir_discard *
ir_discard::clone(struct hash_table *ht) const ir_discard::clone(void *mem_ctx, struct hash_table *ht) const
{ {
void *ctx = talloc_parent(this);
ir_rvalue *new_condition = NULL; ir_rvalue *new_condition = NULL;
if (this->condition != NULL) if (this->condition != NULL)
new_condition = this->condition->clone(ht); new_condition = this->condition->clone(mem_ctx, ht);
return new(ctx) ir_discard(new_condition); return new(mem_ctx) ir_discard(new_condition);
} }
ir_loop_jump * ir_loop_jump *
ir_loop_jump::clone(struct hash_table *ht) const ir_loop_jump::clone(void *mem_ctx, struct hash_table *ht) const
{ {
void *ctx = talloc_parent(this);
(void)ht; (void)ht;
return new(ctx) ir_loop_jump(this->mode); return new(mem_ctx) ir_loop_jump(this->mode);
} }
ir_if * ir_if *
ir_if::clone(struct hash_table *ht) const ir_if::clone(void *mem_ctx, struct hash_table *ht) const
{ {
void *ctx = talloc_parent(this); ir_if *new_if = new(mem_ctx) ir_if(this->condition->clone(mem_ctx, ht));
ir_if *new_if = new(ctx) ir_if(this->condition->clone(ht));
foreach_iter(exec_list_iterator, iter, this->then_instructions) { foreach_iter(exec_list_iterator, iter, this->then_instructions) {
ir_instruction *ir = (ir_instruction *)iter.get(); ir_instruction *ir = (ir_instruction *)iter.get();
new_if->then_instructions.push_tail(ir->clone(ht)); new_if->then_instructions.push_tail(ir->clone(mem_ctx, ht));
} }
foreach_iter(exec_list_iterator, iter, this->else_instructions) { foreach_iter(exec_list_iterator, iter, this->else_instructions) {
ir_instruction *ir = (ir_instruction *)iter.get(); ir_instruction *ir = (ir_instruction *)iter.get();
new_if->else_instructions.push_tail(ir->clone(ht)); new_if->else_instructions.push_tail(ir->clone(mem_ctx, ht));
} }
return new_if; return new_if;
} }
ir_loop * ir_loop *
ir_loop::clone(struct hash_table *ht) const ir_loop::clone(void *mem_ctx, struct hash_table *ht) const
{ {
void *ctx = talloc_parent(this); ir_loop *new_loop = new(mem_ctx) ir_loop();
ir_loop *new_loop = new(ctx) ir_loop();
if (this->from) if (this->from)
new_loop->from = this->from->clone(ht); new_loop->from = this->from->clone(mem_ctx, ht);
if (this->to) if (this->to)
new_loop->to = this->to->clone(ht); new_loop->to = this->to->clone(mem_ctx, ht);
if (this->increment) if (this->increment)
new_loop->increment = this->increment->clone(ht); new_loop->increment = this->increment->clone(mem_ctx, ht);
new_loop->counter = counter; new_loop->counter = counter;
foreach_iter(exec_list_iterator, iter, this->body_instructions) { foreach_iter(exec_list_iterator, iter, this->body_instructions) {
ir_instruction *ir = (ir_instruction *)iter.get(); ir_instruction *ir = (ir_instruction *)iter.get();
new_loop->body_instructions.push_tail(ir->clone(ht)); new_loop->body_instructions.push_tail(ir->clone(mem_ctx, ht));
} }
return new_loop; return new_loop;
} }
ir_call * ir_call *
ir_call::clone(struct hash_table *ht) const ir_call::clone(void *mem_ctx, struct hash_table *ht) const
{ {
void *ctx = talloc_parent(this);
exec_list new_parameters; exec_list new_parameters;
foreach_iter(exec_list_iterator, iter, this->actual_parameters) { foreach_iter(exec_list_iterator, iter, this->actual_parameters) {
ir_instruction *ir = (ir_instruction *)iter.get(); ir_instruction *ir = (ir_instruction *)iter.get();
new_parameters.push_tail(ir->clone(ht)); new_parameters.push_tail(ir->clone(mem_ctx, ht));
} }
return new(ctx) ir_call(this->callee, &new_parameters); return new(mem_ctx) ir_call(this->callee, &new_parameters);
} }
ir_expression * ir_expression *
ir_expression::clone(struct hash_table *ht) const ir_expression::clone(void *mem_ctx, struct hash_table *ht) const
{ {
void *ctx = talloc_parent(this);
ir_rvalue *op[2] = {NULL, NULL}; ir_rvalue *op[2] = {NULL, NULL};
unsigned int i; unsigned int i;
for (i = 0; i < get_num_operands(); i++) { for (i = 0; i < get_num_operands(); i++) {
op[i] = this->operands[i]->clone(ht); op[i] = this->operands[i]->clone(mem_ctx, ht);
} }
return new(ctx) ir_expression(this->operation, this->type, op[0], op[1]); return new(mem_ctx) ir_expression(this->operation, this->type, op[0], op[1]);
} }
ir_dereference_variable * ir_dereference_variable *
ir_dereference_variable::clone(struct hash_table *ht) const ir_dereference_variable::clone(void *mem_ctx, struct hash_table *ht) const
{ {
void *ctx = talloc_parent(this);
ir_variable *new_var; ir_variable *new_var;
if (ht) { if (ht) {
@@ -188,38 +178,36 @@ ir_dereference_variable::clone(struct hash_table *ht) const
new_var = this->var; new_var = this->var;
} }
return new(ctx) ir_dereference_variable(new_var); return new(mem_ctx) ir_dereference_variable(new_var);
} }
ir_dereference_array * ir_dereference_array *
ir_dereference_array::clone(struct hash_table *ht) const ir_dereference_array::clone(void *mem_ctx, struct hash_table *ht) const
{ {
void *ctx = talloc_parent(this); return new(mem_ctx) ir_dereference_array(this->array->clone(mem_ctx, ht),
return new(ctx) ir_dereference_array(this->array->clone(ht), this->array_index->clone(mem_ctx,
this->array_index->clone(ht)); ht));
} }
ir_dereference_record * ir_dereference_record *
ir_dereference_record::clone(struct hash_table *ht) const ir_dereference_record::clone(void *mem_ctx, struct hash_table *ht) const
{ {
void *ctx = talloc_parent(this); return new(mem_ctx) ir_dereference_record(this->record->clone(mem_ctx, ht),
return new(ctx) ir_dereference_record(this->record->clone(ht), this->field);
this->field);
} }
ir_texture * ir_texture *
ir_texture::clone(struct hash_table *ht) const ir_texture::clone(void *mem_ctx, struct hash_table *ht) const
{ {
void *ctx = talloc_parent(this); ir_texture *new_tex = new(mem_ctx) ir_texture(this->op);
ir_texture *new_tex = new(ctx) ir_texture(this->op);
new_tex->type = this->type; new_tex->type = this->type;
new_tex->sampler = this->sampler->clone(ht); new_tex->sampler = this->sampler->clone(mem_ctx, ht);
new_tex->coordinate = this->coordinate->clone(ht); new_tex->coordinate = this->coordinate->clone(mem_ctx, ht);
if (this->projector) if (this->projector)
new_tex->projector = this->projector->clone(ht); new_tex->projector = this->projector->clone(mem_ctx, ht);
if (this->shadow_comparitor) { if (this->shadow_comparitor) {
new_tex->shadow_comparitor = this->shadow_comparitor->clone(ht); new_tex->shadow_comparitor = this->shadow_comparitor->clone(mem_ctx, ht);
} }
for (int i = 0; i < 3; i++) for (int i = 0; i < 3; i++)
@@ -229,15 +217,15 @@ ir_texture::clone(struct hash_table *ht) const
case ir_tex: case ir_tex:
break; break;
case ir_txb: case ir_txb:
new_tex->lod_info.bias = this->lod_info.bias->clone(ht); new_tex->lod_info.bias = this->lod_info.bias->clone(mem_ctx, ht);
break; break;
case ir_txl: case ir_txl:
case ir_txf: case ir_txf:
new_tex->lod_info.lod = this->lod_info.lod->clone(ht); new_tex->lod_info.lod = this->lod_info.lod->clone(mem_ctx, ht);
break; break;
case ir_txd: case ir_txd:
new_tex->lod_info.grad.dPdx = this->lod_info.grad.dPdx->clone(ht); new_tex->lod_info.grad.dPdx = this->lod_info.grad.dPdx->clone(mem_ctx, ht);
new_tex->lod_info.grad.dPdy = this->lod_info.grad.dPdy->clone(ht); new_tex->lod_info.grad.dPdy = this->lod_info.grad.dPdy->clone(mem_ctx, ht);
break; break;
} }
@@ -245,30 +233,28 @@ ir_texture::clone(struct hash_table *ht) const
} }
ir_assignment * ir_assignment *
ir_assignment::clone(struct hash_table *ht) const ir_assignment::clone(void *mem_ctx, struct hash_table *ht) const
{ {
ir_rvalue *new_condition = NULL; ir_rvalue *new_condition = NULL;
if (this->condition) if (this->condition)
new_condition = this->condition->clone(ht); new_condition = this->condition->clone(mem_ctx, ht);
void *ctx = talloc_parent(this); return new(mem_ctx) ir_assignment(this->lhs->clone(mem_ctx, ht),
return new(ctx) ir_assignment(this->lhs->clone(ht), this->rhs->clone(mem_ctx, ht),
this->rhs->clone(ht), new_condition);
new_condition);
} }
ir_function * ir_function *
ir_function::clone(struct hash_table *ht) const ir_function::clone(void *mem_ctx, struct hash_table *ht) const
{ {
void *mem_ctx = talloc_parent(this);
ir_function *copy = new(mem_ctx) ir_function(this->name); ir_function *copy = new(mem_ctx) ir_function(this->name);
foreach_list_const(node, &this->signatures) { foreach_list_const(node, &this->signatures) {
const ir_function_signature *const sig = const ir_function_signature *const sig =
(const ir_function_signature *const) node; (const ir_function_signature *const) node;
ir_function_signature *sig_copy = sig->clone(ht); ir_function_signature *sig_copy = sig->clone(mem_ctx, ht);
copy->add_signature(sig_copy); copy->add_signature(sig_copy);
if (ht != NULL) if (ht != NULL)
@@ -280,9 +266,8 @@ ir_function::clone(struct hash_table *ht) const
} }
ir_function_signature * ir_function_signature *
ir_function_signature::clone(struct hash_table *ht) const ir_function_signature::clone(void *mem_ctx, struct hash_table *ht) const
{ {
void *mem_ctx = talloc_parent(this);
ir_function_signature *copy = ir_function_signature *copy =
new(mem_ctx) ir_function_signature(this->return_type); new(mem_ctx) ir_function_signature(this->return_type);
@@ -296,7 +281,7 @@ ir_function_signature::clone(struct hash_table *ht) const
assert(const_cast<ir_variable *>(param)->as_variable() != NULL); assert(const_cast<ir_variable *>(param)->as_variable() != NULL);
ir_variable *const param_copy = param->clone(ht); ir_variable *const param_copy = param->clone(mem_ctx, ht);
copy->parameters.push_tail(param_copy); copy->parameters.push_tail(param_copy);
} }
@@ -305,7 +290,7 @@ ir_function_signature::clone(struct hash_table *ht) const
foreach_list_const(node, &this->body) { foreach_list_const(node, &this->body) {
const ir_instruction *const inst = (const ir_instruction *) node; const ir_instruction *const inst = (const ir_instruction *) node;
ir_instruction *const inst_copy = inst->clone(ht); ir_instruction *const inst_copy = inst->clone(mem_ctx, ht);
copy->body.push_tail(inst_copy); copy->body.push_tail(inst_copy);
} }
@@ -313,9 +298,8 @@ ir_function_signature::clone(struct hash_table *ht) const
} }
ir_constant * ir_constant *
ir_constant::clone(struct hash_table *ht) const ir_constant::clone(void *mem_ctx, struct hash_table *ht) const
{ {
void *ctx = talloc_parent(this);
(void)ht; (void)ht;
switch (this->type->base_type) { switch (this->type->base_type) {
@@ -323,10 +307,10 @@ ir_constant::clone(struct hash_table *ht) const
case GLSL_TYPE_INT: case GLSL_TYPE_INT:
case GLSL_TYPE_FLOAT: case GLSL_TYPE_FLOAT:
case GLSL_TYPE_BOOL: case GLSL_TYPE_BOOL:
return new(ctx) ir_constant(this->type, &this->value); return new(mem_ctx) ir_constant(this->type, &this->value);
case GLSL_TYPE_STRUCT: { case GLSL_TYPE_STRUCT: {
ir_constant *c = new(ctx) ir_constant; ir_constant *c = new(mem_ctx) ir_constant;
c->type = this->type; c->type = this->type;
for (exec_node *node = this->components.head for (exec_node *node = this->components.head
@@ -334,19 +318,19 @@ ir_constant::clone(struct hash_table *ht) const
; node = node->next) { ; node = node->next) {
ir_constant *const orig = (ir_constant *) node; ir_constant *const orig = (ir_constant *) node;
c->components.push_tail(orig->clone(NULL)); c->components.push_tail(orig->clone(mem_ctx, NULL));
} }
return c; return c;
} }
case GLSL_TYPE_ARRAY: { case GLSL_TYPE_ARRAY: {
ir_constant *c = new(ctx) ir_constant; ir_constant *c = new(mem_ctx) ir_constant;
c->type = this->type; c->type = this->type;
c->array_elements = talloc_array(c, ir_constant *, this->type->length); c->array_elements = talloc_array(c, ir_constant *, this->type->length);
for (unsigned i = 0; i < this->type->length; i++) { for (unsigned i = 0; i < this->type->length; i++) {
c->array_elements[i] = this->array_elements[i]->clone(NULL); c->array_elements[i] = this->array_elements[i]->clone(mem_ctx, NULL);
} }
return c; return c;
} }
@@ -395,14 +379,14 @@ fixup_function_calls(struct hash_table *ht, exec_list *instructions)
void void
clone_ir_list(exec_list *out, const exec_list *in) clone_ir_list(void *mem_ctx, exec_list *out, const exec_list *in)
{ {
struct hash_table *ht = struct hash_table *ht =
hash_table_ctor(0, hash_table_pointer_hash, hash_table_pointer_compare); hash_table_ctor(0, hash_table_pointer_hash, hash_table_pointer_compare);
foreach_list_const(node, in) { foreach_list_const(node, in) {
const ir_instruction *const original = (ir_instruction *) node; const ir_instruction *const original = (ir_instruction *) node;
ir_instruction *copy = original->clone(ht); ir_instruction *copy = original->clone(mem_ctx, ht);
out->push_tail(copy); out->push_tail(copy);
} }

View File

@@ -680,7 +680,10 @@ ir_dereference_variable::constant_expression_value()
if (var->mode == ir_var_uniform) if (var->mode == ir_var_uniform)
return NULL; return NULL;
return var->constant_value ? var->constant_value->clone(NULL) : NULL; if (!var->constant_value)
return NULL;
return var->constant_value->clone(talloc_parent(var), NULL);
} }
@@ -732,7 +735,7 @@ ir_dereference_array::constant_expression_value()
return new(ctx) ir_constant(array, component); return new(ctx) ir_constant(array, component);
} else { } else {
const unsigned index = idx->value.u[0]; const unsigned index = idx->value.u[0];
return array->get_array_element(index)->clone(NULL); return array->get_array_element(index)->clone(ctx, NULL);
} }
} }
return NULL; return NULL;

View File

@@ -147,7 +147,7 @@ ir_call::generate_inline(ir_instruction *next_ir)
parameters[i] = NULL; parameters[i] = NULL;
hash_table_insert(ht, param->variable_referenced(), sig_param); hash_table_insert(ht, param->variable_referenced(), sig_param);
} else { } else {
parameters[i] = sig_param->clone(ht); parameters[i] = sig_param->clone(ctx, ht);
parameters[i]->mode = ir_var_auto; parameters[i]->mode = ir_var_auto;
next_ir->insert_before(parameters[i]); next_ir->insert_before(parameters[i]);
} }
@@ -169,7 +169,7 @@ ir_call::generate_inline(ir_instruction *next_ir)
/* Generate the inlined body of the function. */ /* Generate the inlined body of the function. */
foreach_iter(exec_list_iterator, iter, callee->body) { foreach_iter(exec_list_iterator, iter, callee->body) {
ir_instruction *ir = (ir_instruction *)iter.get(); ir_instruction *ir = (ir_instruction *)iter.get();
ir_instruction *new_ir = ir->clone(ht); ir_instruction *new_ir = ir->clone(ctx, ht);
next_ir->insert_before(new_ir); next_ir->insert_before(new_ir);
visit_tree(new_ir, replace_return_with_assignment, retval); visit_tree(new_ir, replace_return_with_assignment, retval);
@@ -190,7 +190,7 @@ ir_call::generate_inline(ir_instruction *next_ir)
sig_param->mode == ir_var_inout)) { sig_param->mode == ir_var_inout)) {
ir_assignment *assign; ir_assignment *assign;
assign = new(ctx) ir_assignment(param->clone(NULL)->as_rvalue(), assign = new(ctx) ir_assignment(param->clone(ctx, NULL)->as_rvalue(),
new(ctx) ir_dereference_variable(parameters[i]), new(ctx) ir_dereference_variable(parameters[i]),
NULL); NULL);
next_ir->insert_before(assign); next_ir->insert_before(assign);

View File

@@ -95,7 +95,7 @@ public:
assert(const_cast<ir_variable *>(param)->as_variable() != NULL); assert(const_cast<ir_variable *>(param)->as_variable() != NULL);
ir_variable *const param_copy = param->clone(NULL); ir_variable *const param_copy = param->clone(mem_ctx, NULL);
copy->parameters.push_tail(param_copy); copy->parameters.push_tail(param_copy);
} }

View File

@@ -82,6 +82,8 @@ ir_vec_index_to_cond_assign_visitor::convert_vec_index_to_cond_assign(ir_rvalue
orig_deref->array->type->is_array()) orig_deref->array->type->is_array())
return ir; return ir;
void *mem_ctx = talloc_parent(ir);
assert(orig_deref->array_index->type->base_type == GLSL_TYPE_INT); assert(orig_deref->array_index->type->base_type == GLSL_TYPE_INT);
/* Store the index to a temporary to avoid reusing its tree. */ /* Store the index to a temporary to avoid reusing its tree. */
@@ -109,7 +111,7 @@ ir_vec_index_to_cond_assign_visitor::convert_vec_index_to_cond_assign(ir_rvalue
/* Just clone the rest of the deref chain when trying to get at the /* Just clone the rest of the deref chain when trying to get at the
* underlying variable. * underlying variable.
*/ */
swizzle = new(base_ir) ir_swizzle(orig_deref->array->clone(NULL), swizzle = new(base_ir) ir_swizzle(orig_deref->array->clone(mem_ctx, NULL),
i, 0, 0, 0, 1); i, 0, 0, 0, 1);
deref = new(base_ir) ir_dereference_variable(var); deref = new(base_ir) ir_dereference_variable(var);
@@ -165,6 +167,8 @@ ir_vec_index_to_cond_assign_visitor::visit_leave(ir_assignment *ir)
orig_deref->array->type->is_array()) orig_deref->array->type->is_array())
return visit_continue; return visit_continue;
void *mem_ctx = talloc_parent(ir);
assert(orig_deref->array_index->type->base_type == GLSL_TYPE_INT); assert(orig_deref->array_index->type->base_type == GLSL_TYPE_INT);
/* Store the index to a temporary to avoid reusing its tree. */ /* Store the index to a temporary to avoid reusing its tree. */
@@ -196,7 +200,7 @@ ir_vec_index_to_cond_assign_visitor::visit_leave(ir_assignment *ir)
/* Just clone the rest of the deref chain when trying to get at the /* Just clone the rest of the deref chain when trying to get at the
* underlying variable. * underlying variable.
*/ */
swizzle = new(ir) ir_swizzle(orig_deref->array->clone(NULL), swizzle = new(ir) ir_swizzle(orig_deref->array->clone(mem_ctx, NULL),
i, 0, 0, 0, 1); i, 0, 0, 0, 1);
deref = new(ir) ir_dereference_variable(var); deref = new(ir) ir_dereference_variable(var);

View File

@@ -143,7 +143,7 @@ public:
const ir_instruction *const original = (ir_instruction *) node; const ir_instruction *const original = (ir_instruction *) node;
assert(const_cast<ir_instruction *>(original)->as_variable()); assert(const_cast<ir_instruction *>(original)->as_variable());
ir_instruction *copy = original->clone(ht); ir_instruction *copy = original->clone(linked, ht);
formal_parameters.push_tail(copy); formal_parameters.push_tail(copy);
} }
@@ -152,7 +152,7 @@ public:
foreach_list_const(node, &sig->body) { foreach_list_const(node, &sig->body) {
const ir_instruction *const original = (ir_instruction *) node; const ir_instruction *const original = (ir_instruction *) node;
ir_instruction *copy = original->clone(ht); ir_instruction *copy = original->clone(linked, ht);
linked_sig->body.push_tail(copy); linked_sig->body.push_tail(copy);
} }
@@ -182,7 +182,7 @@ public:
/* Clone the ir_variable that the dereference already has and add /* Clone the ir_variable that the dereference already has and add
* it to the linked shader. * it to the linked shader.
*/ */
var = ir->var->clone(NULL); var = ir->var->clone(linked, NULL);
linked->symbols->add_variable(var->name, var); linked->symbols->add_variable(var->name, var);
linked->ir->push_head(var); linked->ir->push_head(var);
} }

View File

@@ -323,7 +323,8 @@ cross_validate_globals(struct gl_shader_program *prog,
* FINISHME: modify the shader, and linking with the second * FINISHME: modify the shader, and linking with the second
* FINISHME: will fail. * FINISHME: will fail.
*/ */
existing->constant_value = var->constant_value->clone(NULL); existing->constant_value =
var->constant_value->clone(talloc_parent(existing), NULL);
} }
} else } else
variables.add_variable(var->name, var); variables.add_variable(var->name, var);
@@ -488,16 +489,17 @@ populate_symbol_table(gl_shader *sh)
* should be added. * should be added.
*/ */
void void
remap_variables(ir_instruction *inst, glsl_symbol_table *symbols, remap_variables(ir_instruction *inst, struct gl_shader *target,
exec_list *instructions, hash_table *temps) hash_table *temps)
{ {
class remap_visitor : public ir_hierarchical_visitor { class remap_visitor : public ir_hierarchical_visitor {
public: public:
remap_visitor(glsl_symbol_table *symbols, exec_list *instructions, remap_visitor(struct gl_shader *target,
hash_table *temps) hash_table *temps)
{ {
this->symbols = symbols; this->target = target;
this->instructions = instructions; this->symbols = target->symbols;
this->instructions = target->ir;
this->temps = temps; this->temps = temps;
} }
@@ -516,7 +518,7 @@ remap_variables(ir_instruction *inst, glsl_symbol_table *symbols,
if (existing != NULL) if (existing != NULL)
ir->var = existing; ir->var = existing;
else { else {
ir_variable *copy = ir->var->clone(NULL); ir_variable *copy = ir->var->clone(this->target, NULL);
this->symbols->add_variable(copy->name, copy); this->symbols->add_variable(copy->name, copy);
this->instructions->push_head(copy); this->instructions->push_head(copy);
@@ -527,12 +529,13 @@ remap_variables(ir_instruction *inst, glsl_symbol_table *symbols,
} }
private: private:
struct gl_shader *target;
glsl_symbol_table *symbols; glsl_symbol_table *symbols;
exec_list *instructions; exec_list *instructions;
hash_table *temps; hash_table *temps;
}; };
remap_visitor v(symbols, instructions, temps); remap_visitor v(target, temps);
inst->accept(&v); inst->accept(&v);
} }
@@ -583,12 +586,12 @@ move_non_declarations(exec_list *instructions, exec_node *last,
|| ((var != NULL) && (var->mode == ir_var_temporary))); || ((var != NULL) && (var->mode == ir_var_temporary)));
if (make_copies) { if (make_copies) {
inst = inst->clone(NULL); inst = inst->clone(target, NULL);
if (var != NULL) if (var != NULL)
hash_table_insert(temps, inst, var); hash_table_insert(temps, inst, var);
else else
remap_variables(inst, target->symbols, target->ir, temps); remap_variables(inst, target, temps);
} else { } else {
inst->remove(); inst->remove();
} }
@@ -713,7 +716,7 @@ link_intrastage_shaders(struct gl_shader_program *prog,
gl_shader *const linked = _mesa_new_shader(NULL, 0, main->Type); gl_shader *const linked = _mesa_new_shader(NULL, 0, main->Type);
linked->ir = new(linked) exec_list; linked->ir = new(linked) exec_list;
clone_ir_list(linked->ir, main->ir); clone_ir_list(linked, linked->ir, main->ir);
populate_symbol_table(linked); populate_symbol_table(linked);