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