101e04c3fSmrg/*
201e04c3fSmrg * Copyright © 2010 Intel Corporation
301e04c3fSmrg *
401e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a
501e04c3fSmrg * copy of this software and associated documentation files (the "Software"),
601e04c3fSmrg * to deal in the Software without restriction, including without limitation
701e04c3fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
801e04c3fSmrg * and/or sell copies of the Software, and to permit persons to whom the
901e04c3fSmrg * Software is furnished to do so, subject to the following conditions:
1001e04c3fSmrg *
1101e04c3fSmrg * The above copyright notice and this permission notice (including the next
1201e04c3fSmrg * paragraph) shall be included in all copies or substantial portions of the
1301e04c3fSmrg * Software.
1401e04c3fSmrg *
1501e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1601e04c3fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1701e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1801e04c3fSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1901e04c3fSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2001e04c3fSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
2101e04c3fSmrg * DEALINGS IN THE SOFTWARE.
2201e04c3fSmrg */
2301e04c3fSmrg
2401e04c3fSmrg#include <string.h>
257ec681f3Smrg#include "util/compiler.h"
2601e04c3fSmrg#include "ir.h"
2701e04c3fSmrg#include "compiler/glsl_types.h"
2801e04c3fSmrg#include "util/hash_table.h"
2901e04c3fSmrg
3001e04c3fSmrgir_rvalue *
3101e04c3fSmrgir_rvalue::clone(void *mem_ctx, struct hash_table *) const
3201e04c3fSmrg{
3301e04c3fSmrg   /* The only possible instantiation is the generic error value. */
3401e04c3fSmrg   return error_value(mem_ctx);
3501e04c3fSmrg}
3601e04c3fSmrg
3701e04c3fSmrg/**
3801e04c3fSmrg * Duplicate an IR variable
3901e04c3fSmrg */
4001e04c3fSmrgir_variable *
4101e04c3fSmrgir_variable::clone(void *mem_ctx, struct hash_table *ht) const
4201e04c3fSmrg{
4301e04c3fSmrg   ir_variable *var = new(mem_ctx) ir_variable(this->type, this->name,
4401e04c3fSmrg					       (ir_variable_mode) this->data.mode);
4501e04c3fSmrg
4601e04c3fSmrg   var->data.max_array_access = this->data.max_array_access;
4701e04c3fSmrg   if (this->is_interface_instance()) {
4801e04c3fSmrg      var->u.max_ifc_array_access =
4901e04c3fSmrg         rzalloc_array(var, int, this->interface_type->length);
5001e04c3fSmrg      memcpy(var->u.max_ifc_array_access, this->u.max_ifc_array_access,
5101e04c3fSmrg             this->interface_type->length * sizeof(unsigned));
5201e04c3fSmrg   }
5301e04c3fSmrg
5401e04c3fSmrg   memcpy(&var->data, &this->data, sizeof(var->data));
5501e04c3fSmrg
5601e04c3fSmrg   if (this->get_state_slots()) {
5701e04c3fSmrg      ir_state_slot *s = var->allocate_state_slots(this->get_num_state_slots());
5801e04c3fSmrg      memcpy(s, this->get_state_slots(),
5901e04c3fSmrg             sizeof(s[0]) * var->get_num_state_slots());
6001e04c3fSmrg   }
6101e04c3fSmrg
6201e04c3fSmrg   if (this->constant_value)
6301e04c3fSmrg      var->constant_value = this->constant_value->clone(mem_ctx, ht);
6401e04c3fSmrg
6501e04c3fSmrg   if (this->constant_initializer)
6601e04c3fSmrg      var->constant_initializer =
6701e04c3fSmrg	 this->constant_initializer->clone(mem_ctx, ht);
6801e04c3fSmrg
6901e04c3fSmrg   var->interface_type = this->interface_type;
7001e04c3fSmrg
7101e04c3fSmrg   if (ht)
7201e04c3fSmrg      _mesa_hash_table_insert(ht, (void *)const_cast<ir_variable *>(this), var);
7301e04c3fSmrg
7401e04c3fSmrg   return var;
7501e04c3fSmrg}
7601e04c3fSmrg
7701e04c3fSmrgir_swizzle *
7801e04c3fSmrgir_swizzle::clone(void *mem_ctx, struct hash_table *ht) const
7901e04c3fSmrg{
8001e04c3fSmrg   return new(mem_ctx) ir_swizzle(this->val->clone(mem_ctx, ht), this->mask);
8101e04c3fSmrg}
8201e04c3fSmrg
8301e04c3fSmrgir_return *
8401e04c3fSmrgir_return::clone(void *mem_ctx, struct hash_table *ht) const
8501e04c3fSmrg{
8601e04c3fSmrg   ir_rvalue *new_value = NULL;
8701e04c3fSmrg
8801e04c3fSmrg   if (this->value)
8901e04c3fSmrg      new_value = this->value->clone(mem_ctx, ht);
9001e04c3fSmrg
9101e04c3fSmrg   return new(mem_ctx) ir_return(new_value);
9201e04c3fSmrg}
9301e04c3fSmrg
9401e04c3fSmrgir_discard *
9501e04c3fSmrgir_discard::clone(void *mem_ctx, struct hash_table *ht) const
9601e04c3fSmrg{
9701e04c3fSmrg   ir_rvalue *new_condition = NULL;
9801e04c3fSmrg
9901e04c3fSmrg   if (this->condition != NULL)
10001e04c3fSmrg      new_condition = this->condition->clone(mem_ctx, ht);
10101e04c3fSmrg
10201e04c3fSmrg   return new(mem_ctx) ir_discard(new_condition);
10301e04c3fSmrg}
10401e04c3fSmrg
1057ec681f3Smrgir_demote *
1067ec681f3Smrgir_demote::clone(void *mem_ctx, struct hash_table *ht) const
1077ec681f3Smrg{
1087ec681f3Smrg   return new(mem_ctx) ir_demote();
1097ec681f3Smrg}
1107ec681f3Smrg
11101e04c3fSmrgir_loop_jump *
11201e04c3fSmrgir_loop_jump::clone(void *mem_ctx, struct hash_table *ht) const
11301e04c3fSmrg{
11401e04c3fSmrg   (void)ht;
11501e04c3fSmrg
11601e04c3fSmrg   return new(mem_ctx) ir_loop_jump(this->mode);
11701e04c3fSmrg}
11801e04c3fSmrg
11901e04c3fSmrgir_if *
12001e04c3fSmrgir_if::clone(void *mem_ctx, struct hash_table *ht) const
12101e04c3fSmrg{
12201e04c3fSmrg   ir_if *new_if = new(mem_ctx) ir_if(this->condition->clone(mem_ctx, ht));
12301e04c3fSmrg
12401e04c3fSmrg   foreach_in_list(ir_instruction, ir, &this->then_instructions) {
12501e04c3fSmrg      new_if->then_instructions.push_tail(ir->clone(mem_ctx, ht));
12601e04c3fSmrg   }
12701e04c3fSmrg
12801e04c3fSmrg   foreach_in_list(ir_instruction, ir, &this->else_instructions) {
12901e04c3fSmrg      new_if->else_instructions.push_tail(ir->clone(mem_ctx, ht));
13001e04c3fSmrg   }
13101e04c3fSmrg
13201e04c3fSmrg   return new_if;
13301e04c3fSmrg}
13401e04c3fSmrg
13501e04c3fSmrgir_loop *
13601e04c3fSmrgir_loop::clone(void *mem_ctx, struct hash_table *ht) const
13701e04c3fSmrg{
13801e04c3fSmrg   ir_loop *new_loop = new(mem_ctx) ir_loop();
13901e04c3fSmrg
14001e04c3fSmrg   foreach_in_list(ir_instruction, ir, &this->body_instructions) {
14101e04c3fSmrg      new_loop->body_instructions.push_tail(ir->clone(mem_ctx, ht));
14201e04c3fSmrg   }
14301e04c3fSmrg
14401e04c3fSmrg   return new_loop;
14501e04c3fSmrg}
14601e04c3fSmrg
14701e04c3fSmrgir_call *
14801e04c3fSmrgir_call::clone(void *mem_ctx, struct hash_table *ht) const
14901e04c3fSmrg{
15001e04c3fSmrg   ir_dereference_variable *new_return_ref = NULL;
15101e04c3fSmrg   if (this->return_deref != NULL)
15201e04c3fSmrg      new_return_ref = this->return_deref->clone(mem_ctx, ht);
15301e04c3fSmrg
15401e04c3fSmrg   exec_list new_parameters;
15501e04c3fSmrg
15601e04c3fSmrg   foreach_in_list(ir_instruction, ir, &this->actual_parameters) {
15701e04c3fSmrg      new_parameters.push_tail(ir->clone(mem_ctx, ht));
15801e04c3fSmrg   }
15901e04c3fSmrg
16001e04c3fSmrg   return new(mem_ctx) ir_call(this->callee, new_return_ref, &new_parameters);
16101e04c3fSmrg}
16201e04c3fSmrg
16301e04c3fSmrgir_expression *
16401e04c3fSmrgir_expression::clone(void *mem_ctx, struct hash_table *ht) const
16501e04c3fSmrg{
16601e04c3fSmrg   ir_rvalue *op[ARRAY_SIZE(this->operands)] = { NULL, };
16701e04c3fSmrg   unsigned int i;
16801e04c3fSmrg
16901e04c3fSmrg   for (i = 0; i < num_operands; i++) {
17001e04c3fSmrg      op[i] = this->operands[i]->clone(mem_ctx, ht);
17101e04c3fSmrg   }
17201e04c3fSmrg
17301e04c3fSmrg   return new(mem_ctx) ir_expression(this->operation, this->type,
17401e04c3fSmrg				     op[0], op[1], op[2], op[3]);
17501e04c3fSmrg}
17601e04c3fSmrg
17701e04c3fSmrgir_dereference_variable *
17801e04c3fSmrgir_dereference_variable::clone(void *mem_ctx, struct hash_table *ht) const
17901e04c3fSmrg{
18001e04c3fSmrg   ir_variable *new_var;
18101e04c3fSmrg
18201e04c3fSmrg   if (ht) {
18301e04c3fSmrg      hash_entry *entry = _mesa_hash_table_search(ht, this->var);
18401e04c3fSmrg      new_var = entry ? (ir_variable *) entry->data : this->var;
18501e04c3fSmrg   } else {
18601e04c3fSmrg      new_var = this->var;
18701e04c3fSmrg   }
18801e04c3fSmrg
18901e04c3fSmrg   return new(mem_ctx) ir_dereference_variable(new_var);
19001e04c3fSmrg}
19101e04c3fSmrg
19201e04c3fSmrgir_dereference_array *
19301e04c3fSmrgir_dereference_array::clone(void *mem_ctx, struct hash_table *ht) const
19401e04c3fSmrg{
19501e04c3fSmrg   return new(mem_ctx) ir_dereference_array(this->array->clone(mem_ctx, ht),
19601e04c3fSmrg					    this->array_index->clone(mem_ctx,
19701e04c3fSmrg								     ht));
19801e04c3fSmrg}
19901e04c3fSmrg
20001e04c3fSmrgir_dereference_record *
20101e04c3fSmrgir_dereference_record::clone(void *mem_ctx, struct hash_table *ht) const
20201e04c3fSmrg{
20301e04c3fSmrg   assert(this->field_idx >= 0);
20401e04c3fSmrg   const char *field_name =
20501e04c3fSmrg      this->record->type->fields.structure[this->field_idx].name;
20601e04c3fSmrg   return new(mem_ctx) ir_dereference_record(this->record->clone(mem_ctx, ht),
20701e04c3fSmrg                                             field_name);
20801e04c3fSmrg}
20901e04c3fSmrg
21001e04c3fSmrgir_texture *
21101e04c3fSmrgir_texture::clone(void *mem_ctx, struct hash_table *ht) const
21201e04c3fSmrg{
21301e04c3fSmrg   ir_texture *new_tex = new(mem_ctx) ir_texture(this->op);
21401e04c3fSmrg   new_tex->type = this->type;
21501e04c3fSmrg
21601e04c3fSmrg   new_tex->sampler = this->sampler->clone(mem_ctx, ht);
21701e04c3fSmrg   if (this->coordinate)
21801e04c3fSmrg      new_tex->coordinate = this->coordinate->clone(mem_ctx, ht);
21901e04c3fSmrg   if (this->projector)
22001e04c3fSmrg      new_tex->projector = this->projector->clone(mem_ctx, ht);
22101e04c3fSmrg   if (this->shadow_comparator) {
22201e04c3fSmrg      new_tex->shadow_comparator = this->shadow_comparator->clone(mem_ctx, ht);
22301e04c3fSmrg   }
22401e04c3fSmrg
22501e04c3fSmrg   if (this->offset != NULL)
22601e04c3fSmrg      new_tex->offset = this->offset->clone(mem_ctx, ht);
22701e04c3fSmrg
22801e04c3fSmrg   switch (this->op) {
22901e04c3fSmrg   case ir_tex:
23001e04c3fSmrg   case ir_lod:
23101e04c3fSmrg   case ir_query_levels:
23201e04c3fSmrg   case ir_texture_samples:
23301e04c3fSmrg   case ir_samples_identical:
23401e04c3fSmrg      break;
23501e04c3fSmrg   case ir_txb:
23601e04c3fSmrg      new_tex->lod_info.bias = this->lod_info.bias->clone(mem_ctx, ht);
23701e04c3fSmrg      break;
23801e04c3fSmrg   case ir_txl:
23901e04c3fSmrg   case ir_txf:
24001e04c3fSmrg   case ir_txs:
24101e04c3fSmrg      new_tex->lod_info.lod = this->lod_info.lod->clone(mem_ctx, ht);
24201e04c3fSmrg      break;
24301e04c3fSmrg   case ir_txf_ms:
24401e04c3fSmrg      new_tex->lod_info.sample_index = this->lod_info.sample_index->clone(mem_ctx, ht);
24501e04c3fSmrg      break;
24601e04c3fSmrg   case ir_txd:
24701e04c3fSmrg      new_tex->lod_info.grad.dPdx = this->lod_info.grad.dPdx->clone(mem_ctx, ht);
24801e04c3fSmrg      new_tex->lod_info.grad.dPdy = this->lod_info.grad.dPdy->clone(mem_ctx, ht);
24901e04c3fSmrg      break;
25001e04c3fSmrg   case ir_tg4:
25101e04c3fSmrg      new_tex->lod_info.component = this->lod_info.component->clone(mem_ctx, ht);
25201e04c3fSmrg      break;
25301e04c3fSmrg   }
25401e04c3fSmrg
25501e04c3fSmrg   return new_tex;
25601e04c3fSmrg}
25701e04c3fSmrg
25801e04c3fSmrgir_assignment *
25901e04c3fSmrgir_assignment::clone(void *mem_ctx, struct hash_table *ht) const
26001e04c3fSmrg{
26101e04c3fSmrg   ir_rvalue *new_condition = NULL;
26201e04c3fSmrg
26301e04c3fSmrg   if (this->condition)
26401e04c3fSmrg      new_condition = this->condition->clone(mem_ctx, ht);
26501e04c3fSmrg
26601e04c3fSmrg   ir_assignment *cloned =
26701e04c3fSmrg      new(mem_ctx) ir_assignment(this->lhs->clone(mem_ctx, ht),
26801e04c3fSmrg                                 this->rhs->clone(mem_ctx, ht),
26901e04c3fSmrg                                 new_condition);
27001e04c3fSmrg   cloned->write_mask = this->write_mask;
27101e04c3fSmrg   return cloned;
27201e04c3fSmrg}
27301e04c3fSmrg
27401e04c3fSmrgir_function *
27501e04c3fSmrgir_function::clone(void *mem_ctx, struct hash_table *ht) const
27601e04c3fSmrg{
27701e04c3fSmrg   ir_function *copy = new(mem_ctx) ir_function(this->name);
27801e04c3fSmrg
27901e04c3fSmrg   copy->is_subroutine = this->is_subroutine;
28001e04c3fSmrg   copy->subroutine_index = this->subroutine_index;
28101e04c3fSmrg   copy->num_subroutine_types = this->num_subroutine_types;
28201e04c3fSmrg   copy->subroutine_types = ralloc_array(mem_ctx, const struct glsl_type *, copy->num_subroutine_types);
28301e04c3fSmrg   for (int i = 0; i < copy->num_subroutine_types; i++)
28401e04c3fSmrg     copy->subroutine_types[i] = this->subroutine_types[i];
28501e04c3fSmrg
28601e04c3fSmrg   foreach_in_list(const ir_function_signature, sig, &this->signatures) {
28701e04c3fSmrg      ir_function_signature *sig_copy = sig->clone(mem_ctx, ht);
28801e04c3fSmrg      copy->add_signature(sig_copy);
28901e04c3fSmrg
29001e04c3fSmrg      if (ht != NULL) {
29101e04c3fSmrg         _mesa_hash_table_insert(ht,
29201e04c3fSmrg               (void *)const_cast<ir_function_signature *>(sig), sig_copy);
29301e04c3fSmrg      }
29401e04c3fSmrg   }
29501e04c3fSmrg
29601e04c3fSmrg   return copy;
29701e04c3fSmrg}
29801e04c3fSmrg
29901e04c3fSmrgir_function_signature *
30001e04c3fSmrgir_function_signature::clone(void *mem_ctx, struct hash_table *ht) const
30101e04c3fSmrg{
30201e04c3fSmrg   ir_function_signature *copy = this->clone_prototype(mem_ctx, ht);
30301e04c3fSmrg
30401e04c3fSmrg   copy->is_defined = this->is_defined;
30501e04c3fSmrg
30601e04c3fSmrg   /* Clone the instruction list.
30701e04c3fSmrg    */
30801e04c3fSmrg   foreach_in_list(const ir_instruction, inst, &this->body) {
30901e04c3fSmrg      ir_instruction *const inst_copy = inst->clone(mem_ctx, ht);
31001e04c3fSmrg      copy->body.push_tail(inst_copy);
31101e04c3fSmrg   }
31201e04c3fSmrg
31301e04c3fSmrg   return copy;
31401e04c3fSmrg}
31501e04c3fSmrg
31601e04c3fSmrgir_function_signature *
31701e04c3fSmrgir_function_signature::clone_prototype(void *mem_ctx, struct hash_table *ht) const
31801e04c3fSmrg{
31901e04c3fSmrg   ir_function_signature *copy =
32001e04c3fSmrg      new(mem_ctx) ir_function_signature(this->return_type);
32101e04c3fSmrg
32201e04c3fSmrg   copy->is_defined = false;
32301e04c3fSmrg   copy->builtin_avail = this->builtin_avail;
32401e04c3fSmrg   copy->origin = this;
32501e04c3fSmrg
32601e04c3fSmrg   /* Clone the parameter list, but NOT the body.
32701e04c3fSmrg    */
32801e04c3fSmrg   foreach_in_list(const ir_variable, param, &this->parameters) {
32901e04c3fSmrg      assert(const_cast<ir_variable *>(param)->as_variable() != NULL);
33001e04c3fSmrg
33101e04c3fSmrg      ir_variable *const param_copy = param->clone(mem_ctx, ht);
33201e04c3fSmrg      copy->parameters.push_tail(param_copy);
33301e04c3fSmrg   }
33401e04c3fSmrg
33501e04c3fSmrg   return copy;
33601e04c3fSmrg}
33701e04c3fSmrg
33801e04c3fSmrgir_constant *
33901e04c3fSmrgir_constant::clone(void *mem_ctx, struct hash_table *ht) const
34001e04c3fSmrg{
34101e04c3fSmrg   (void)ht;
34201e04c3fSmrg
34301e04c3fSmrg   switch (this->type->base_type) {
34401e04c3fSmrg   case GLSL_TYPE_UINT:
34501e04c3fSmrg   case GLSL_TYPE_INT:
34601e04c3fSmrg   case GLSL_TYPE_FLOAT:
34701e04c3fSmrg   case GLSL_TYPE_FLOAT16:
34801e04c3fSmrg   case GLSL_TYPE_DOUBLE:
34901e04c3fSmrg   case GLSL_TYPE_BOOL:
35001e04c3fSmrg   case GLSL_TYPE_UINT64:
35101e04c3fSmrg   case GLSL_TYPE_INT64:
35201e04c3fSmrg   case GLSL_TYPE_UINT16:
35301e04c3fSmrg   case GLSL_TYPE_INT16:
35401e04c3fSmrg   case GLSL_TYPE_UINT8:
35501e04c3fSmrg   case GLSL_TYPE_INT8:
35601e04c3fSmrg   case GLSL_TYPE_SAMPLER:
35701e04c3fSmrg   case GLSL_TYPE_IMAGE:
35801e04c3fSmrg      return new(mem_ctx) ir_constant(this->type, &this->value);
35901e04c3fSmrg
36001e04c3fSmrg   case GLSL_TYPE_STRUCT:
36101e04c3fSmrg   case GLSL_TYPE_ARRAY: {
36201e04c3fSmrg      ir_constant *c = new(mem_ctx) ir_constant;
36301e04c3fSmrg
36401e04c3fSmrg      c->type = this->type;
36501e04c3fSmrg      c->const_elements = ralloc_array(c, ir_constant *, this->type->length);
36601e04c3fSmrg      for (unsigned i = 0; i < this->type->length; i++) {
36701e04c3fSmrg         c->const_elements[i] = this->const_elements[i]->clone(mem_ctx, NULL);
36801e04c3fSmrg      }
36901e04c3fSmrg      return c;
37001e04c3fSmrg   }
37101e04c3fSmrg
37201e04c3fSmrg   case GLSL_TYPE_ATOMIC_UINT:
37301e04c3fSmrg   case GLSL_TYPE_VOID:
37401e04c3fSmrg   case GLSL_TYPE_ERROR:
37501e04c3fSmrg   case GLSL_TYPE_SUBROUTINE:
37601e04c3fSmrg   case GLSL_TYPE_INTERFACE:
37701e04c3fSmrg   case GLSL_TYPE_FUNCTION:
37801e04c3fSmrg      assert(!"Should not get here.");
37901e04c3fSmrg      break;
38001e04c3fSmrg   }
38101e04c3fSmrg
38201e04c3fSmrg   return NULL;
38301e04c3fSmrg}
38401e04c3fSmrg
38501e04c3fSmrg
38601e04c3fSmrgclass fixup_ir_call_visitor : public ir_hierarchical_visitor {
38701e04c3fSmrgpublic:
38801e04c3fSmrg   fixup_ir_call_visitor(struct hash_table *ht)
38901e04c3fSmrg   {
39001e04c3fSmrg      this->ht = ht;
39101e04c3fSmrg   }
39201e04c3fSmrg
39301e04c3fSmrg   virtual ir_visitor_status visit_enter(ir_call *ir)
39401e04c3fSmrg   {
39501e04c3fSmrg      /* Try to find the function signature referenced by the ir_call in the
39601e04c3fSmrg       * table.  If it is found, replace it with the value from the table.
39701e04c3fSmrg       */
39801e04c3fSmrg      ir_function_signature *sig;
39901e04c3fSmrg      hash_entry *entry = _mesa_hash_table_search(this->ht, ir->callee);
40001e04c3fSmrg
40101e04c3fSmrg      if (entry != NULL) {
40201e04c3fSmrg         sig = (ir_function_signature *) entry->data;
40301e04c3fSmrg         ir->callee = sig;
40401e04c3fSmrg      }
40501e04c3fSmrg
40601e04c3fSmrg      /* Since this may be used before function call parameters are flattened,
40701e04c3fSmrg       * the children also need to be processed.
40801e04c3fSmrg       */
40901e04c3fSmrg      return visit_continue;
41001e04c3fSmrg   }
41101e04c3fSmrg
41201e04c3fSmrgprivate:
41301e04c3fSmrg   struct hash_table *ht;
41401e04c3fSmrg};
41501e04c3fSmrg
41601e04c3fSmrg
41701e04c3fSmrgstatic void
41801e04c3fSmrgfixup_function_calls(struct hash_table *ht, exec_list *instructions)
41901e04c3fSmrg{
42001e04c3fSmrg   fixup_ir_call_visitor v(ht);
42101e04c3fSmrg   v.run(instructions);
42201e04c3fSmrg}
42301e04c3fSmrg
42401e04c3fSmrg
42501e04c3fSmrgvoid
42601e04c3fSmrgclone_ir_list(void *mem_ctx, exec_list *out, const exec_list *in)
42701e04c3fSmrg{
4287e102996Smaya   struct hash_table *ht = _mesa_pointer_hash_table_create(NULL);
42901e04c3fSmrg
43001e04c3fSmrg   foreach_in_list(const ir_instruction, original, in) {
43101e04c3fSmrg      ir_instruction *copy = original->clone(mem_ctx, ht);
43201e04c3fSmrg
43301e04c3fSmrg      out->push_tail(copy);
43401e04c3fSmrg   }
43501e04c3fSmrg
43601e04c3fSmrg   /* Make a pass over the cloned tree to fix up ir_call nodes to point to the
43701e04c3fSmrg    * cloned ir_function_signature nodes.  This cannot be done automatically
43801e04c3fSmrg    * during cloning because the ir_call might be a forward reference (i.e.,
43901e04c3fSmrg    * the function signature that it references may not have been cloned yet).
44001e04c3fSmrg    */
44101e04c3fSmrg   fixup_function_calls(ht, out);
44201e04c3fSmrg
44301e04c3fSmrg   _mesa_hash_table_destroy(ht, NULL);
44401e04c3fSmrg}
445