14b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt/* 24b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt * Copyright © 2010 Intel Corporation 34b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt * 44b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt * Permission is hereby granted, free of charge, to any person obtaining a 54b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt * copy of this software and associated documentation files (the "Software"), 64b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt * to deal in the Software without restriction, including without limitation 74b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt * the rights to use, copy, modify, merge, publish, distribute, sublicense, 84b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt * and/or sell copies of the Software, and to permit persons to whom the 94b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt * Software is furnished to do so, subject to the following conditions: 104b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt * 114b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt * The above copyright notice and this permission notice (including the next 124b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt * paragraph) shall be included in all copies or substantial portions of the 134b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt * Software. 144b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt * 154b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 164b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 174b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 184b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 194b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 204b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 214b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt * DEALINGS IN THE SOFTWARE. 224b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt */ 234b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt 244b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt#include <string.h> 25fc92e87b9757eda01caf0bb3e2c31b1dbbd73aa0Ian Romanick#include "main/compiler.h" 264b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt#include "ir.h" 274b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt#include "glsl_types.h" 2831747155ea3a24190277b125bd188ac8689af719Aras Pranckevicius#include "program/hash_table.h" 294b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt 30807e967c615dc80a264af5a89af7649f95481744Kenneth Graunkeir_rvalue * 31807e967c615dc80a264af5a89af7649f95481744Kenneth Graunkeir_rvalue::clone(void *mem_ctx, struct hash_table *ht) const 32807e967c615dc80a264af5a89af7649f95481744Kenneth Graunke{ 33807e967c615dc80a264af5a89af7649f95481744Kenneth Graunke /* The only possible instantiation is the generic error value. */ 34807e967c615dc80a264af5a89af7649f95481744Kenneth Graunke return error_value(mem_ctx); 35807e967c615dc80a264af5a89af7649f95481744Kenneth Graunke} 36807e967c615dc80a264af5a89af7649f95481744Kenneth Graunke 374b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt/** 384b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt * Duplicate an IR variable 394b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt * 404b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt * \note 414b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt * This will probably be made \c virtual and moved to the base class 424b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt * eventually. 434b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt */ 44ca088cc277ce9f986693c857f3961dc0e1a4d91cIan Romanickir_variable * 458273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholtir_variable::clone(void *mem_ctx, struct hash_table *ht) const 464b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt{ 478273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt ir_variable *var = new(mem_ctx) ir_variable(this->type, this->name, 488273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt (ir_variable_mode) this->mode); 494b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt 504b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt var->max_array_access = this->max_array_access; 514b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt var->read_only = this->read_only; 524b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt var->centroid = this->centroid; 534b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt var->invariant = this->invariant; 544b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt var->interpolation = this->interpolation; 5510d222b70266a1b6e8dde90652156c6e18bcd3c8Ian Romanick var->location = this->location; 566508b0b9b0981662b9ae5bc559b4a6be524f7b86Eric Anholt var->index = this->index; 57b3c093c79c2ec49c36af37aa290d5ae452149f6eEric Anholt var->uniform_block = this->uniform_block; 5810d222b70266a1b6e8dde90652156c6e18bcd3c8Ian Romanick var->warn_extension = this->warn_extension; 594a962170d7cf4243d6ae156fca20a6167388925dEric Anholt var->origin_upper_left = this->origin_upper_left; 604a962170d7cf4243d6ae156fca20a6167388925dEric Anholt var->pixel_center_integer = this->pixel_center_integer; 61eee68d3631813580a14fa51fda6f0c959279256cIan Romanick var->explicit_location = this->explicit_location; 621256a5dcc86014d48bdc6fd10ea5a2fa11241667Dave Airlie var->explicit_index = this->explicit_index; 63f37b1ad937dd2c420f4c9fd9aa5887942bd31f3fIan Romanick var->has_initializer = this->has_initializer; 6490be99427a04a36973f9e3d19161065e1c5177b3Marek Olšák var->depth_layout = this->depth_layout; 6589d81ab16c05818b290ed735c1343d3abde449bfIan Romanick 6689d81ab16c05818b290ed735c1343d3abde449bfIan Romanick var->num_state_slots = this->num_state_slots; 6789d81ab16c05818b290ed735c1343d3abde449bfIan Romanick if (this->state_slots) { 6889d81ab16c05818b290ed735c1343d3abde449bfIan Romanick /* FINISHME: This really wants to use something like talloc_reference, but 6989d81ab16c05818b290ed735c1343d3abde449bfIan Romanick * FINISHME: ralloc doesn't have any similar function. 7089d81ab16c05818b290ed735c1343d3abde449bfIan Romanick */ 7189d81ab16c05818b290ed735c1343d3abde449bfIan Romanick var->state_slots = ralloc_array(var, ir_state_slot, 7289d81ab16c05818b290ed735c1343d3abde449bfIan Romanick this->num_state_slots); 7389d81ab16c05818b290ed735c1343d3abde449bfIan Romanick memcpy(var->state_slots, this->state_slots, 7489d81ab16c05818b290ed735c1343d3abde449bfIan Romanick sizeof(this->state_slots[0]) * var->num_state_slots); 7589d81ab16c05818b290ed735c1343d3abde449bfIan Romanick } 7689d81ab16c05818b290ed735c1343d3abde449bfIan Romanick 7710d222b70266a1b6e8dde90652156c6e18bcd3c8Ian Romanick if (this->constant_value) 788273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt var->constant_value = this->constant_value->clone(mem_ctx, ht); 794b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt 80f37b1ad937dd2c420f4c9fd9aa5887942bd31f3fIan Romanick if (this->constant_initializer) 81f37b1ad937dd2c420f4c9fd9aa5887942bd31f3fIan Romanick var->constant_initializer = 82f37b1ad937dd2c420f4c9fd9aa5887942bd31f3fIan Romanick this->constant_initializer->clone(mem_ctx, ht); 83f37b1ad937dd2c420f4c9fd9aa5887942bd31f3fIan Romanick 844b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt if (ht) { 851b2bcf791365f7bab282e38808efadba19291261Eric Anholt hash_table_insert(ht, var, (void *)const_cast<ir_variable *>(this)); 864b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt } 874b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt 884b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt return var; 894b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt} 904b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt 91ca088cc277ce9f986693c857f3961dc0e1a4d91cIan Romanickir_swizzle * 928273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholtir_swizzle::clone(void *mem_ctx, struct hash_table *ht) const 934b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt{ 948273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt return new(mem_ctx) ir_swizzle(this->val->clone(mem_ctx, ht), this->mask); 954b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt} 964b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt 97ca088cc277ce9f986693c857f3961dc0e1a4d91cIan Romanickir_return * 988273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholtir_return::clone(void *mem_ctx, struct hash_table *ht) const 994b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt{ 1004b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt ir_rvalue *new_value = NULL; 1014b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt 1024b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt if (this->value) 1038273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt new_value = this->value->clone(mem_ctx, ht); 1044b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt 1058273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt return new(mem_ctx) ir_return(new_value); 1064b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt} 1074b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt 108ca088cc277ce9f986693c857f3961dc0e1a4d91cIan Romanickir_discard * 1098273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholtir_discard::clone(void *mem_ctx, struct hash_table *ht) const 11016efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke{ 11116efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke ir_rvalue *new_condition = NULL; 11216efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke 11316efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke if (this->condition != NULL) 1148273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt new_condition = this->condition->clone(mem_ctx, ht); 11516efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke 1168273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt return new(mem_ctx) ir_discard(new_condition); 11716efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke} 11816efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke 119ca088cc277ce9f986693c857f3961dc0e1a4d91cIan Romanickir_loop_jump * 1208273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholtir_loop_jump::clone(void *mem_ctx, struct hash_table *ht) const 1214b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt{ 1224b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt (void)ht; 1234b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt 1248273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt return new(mem_ctx) ir_loop_jump(this->mode); 1254b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt} 1264b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt 127ca088cc277ce9f986693c857f3961dc0e1a4d91cIan Romanickir_if * 1288273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholtir_if::clone(void *mem_ctx, struct hash_table *ht) const 1294b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt{ 1308273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt ir_if *new_if = new(mem_ctx) ir_if(this->condition->clone(mem_ctx, ht)); 1314b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt 1324b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt foreach_iter(exec_list_iterator, iter, this->then_instructions) { 1334b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt ir_instruction *ir = (ir_instruction *)iter.get(); 1348273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt new_if->then_instructions.push_tail(ir->clone(mem_ctx, ht)); 1354b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt } 1364b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt 1374b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt foreach_iter(exec_list_iterator, iter, this->else_instructions) { 1384b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt ir_instruction *ir = (ir_instruction *)iter.get(); 1398273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt new_if->else_instructions.push_tail(ir->clone(mem_ctx, ht)); 1404b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt } 1414b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt 1424b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt return new_if; 1434b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt} 1444b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt 145ca088cc277ce9f986693c857f3961dc0e1a4d91cIan Romanickir_loop * 1468273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholtir_loop::clone(void *mem_ctx, struct hash_table *ht) const 1474b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt{ 1488273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt ir_loop *new_loop = new(mem_ctx) ir_loop(); 1494b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt 1504b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt if (this->from) 1518273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt new_loop->from = this->from->clone(mem_ctx, ht); 1524b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt if (this->to) 1538273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt new_loop->to = this->to->clone(mem_ctx, ht); 1544b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt if (this->increment) 1558273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt new_loop->increment = this->increment->clone(mem_ctx, ht); 1564b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt new_loop->counter = counter; 1574b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt 1584b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt foreach_iter(exec_list_iterator, iter, this->body_instructions) { 1594b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt ir_instruction *ir = (ir_instruction *)iter.get(); 1608273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt new_loop->body_instructions.push_tail(ir->clone(mem_ctx, ht)); 1614b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt } 1624b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt 1633b85f1cc6cb12e9d4931e12cf29adde578f389fdIan Romanick new_loop->cmp = this->cmp; 1644b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt return new_loop; 1654b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt} 1664b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt 167ca088cc277ce9f986693c857f3961dc0e1a4d91cIan Romanickir_call * 1688273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholtir_call::clone(void *mem_ctx, struct hash_table *ht) const 1694b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt{ 170d884f60861f270cdcf7d9d47765efcf1e1de30b6Kenneth Graunke ir_dereference_variable *new_return_ref = NULL; 171d884f60861f270cdcf7d9d47765efcf1e1de30b6Kenneth Graunke if (this->return_deref != NULL) 172d884f60861f270cdcf7d9d47765efcf1e1de30b6Kenneth Graunke new_return_ref = this->return_deref->clone(mem_ctx, ht); 173d884f60861f270cdcf7d9d47765efcf1e1de30b6Kenneth Graunke 1744b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt exec_list new_parameters; 1754b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt 1764b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt foreach_iter(exec_list_iterator, iter, this->actual_parameters) { 1774b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt ir_instruction *ir = (ir_instruction *)iter.get(); 1788273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt new_parameters.push_tail(ir->clone(mem_ctx, ht)); 1794b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt } 1804b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt 181d884f60861f270cdcf7d9d47765efcf1e1de30b6Kenneth Graunke return new(mem_ctx) ir_call(this->callee, new_return_ref, &new_parameters); 1824b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt} 1834b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt 184ca088cc277ce9f986693c857f3961dc0e1a4d91cIan Romanickir_expression * 1858273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholtir_expression::clone(void *mem_ctx, struct hash_table *ht) const 1864b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt{ 187fc92e87b9757eda01caf0bb3e2c31b1dbbd73aa0Ian Romanick ir_rvalue *op[Elements(this->operands)] = { NULL, }; 1884b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt unsigned int i; 1894b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt 1904b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt for (i = 0; i < get_num_operands(); i++) { 1918273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt op[i] = this->operands[i]->clone(mem_ctx, ht); 1924b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt } 1934b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt 19411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick return new(mem_ctx) ir_expression(this->operation, this->type, 19511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick op[0], op[1], op[2], op[3]); 1964b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt} 1974b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt 198ca088cc277ce9f986693c857f3961dc0e1a4d91cIan Romanickir_dereference_variable * 1998273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholtir_dereference_variable::clone(void *mem_ctx, struct hash_table *ht) const 2004b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt{ 2014b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt ir_variable *new_var; 2024b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt 2034b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt if (ht) { 2044b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt new_var = (ir_variable *)hash_table_find(ht, this->var); 2054b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt if (!new_var) 2064b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt new_var = this->var; 2074b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt } else { 2084b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt new_var = this->var; 2094b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt } 2104b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt 2118273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt return new(mem_ctx) ir_dereference_variable(new_var); 2124b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt} 2134b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt 214ca088cc277ce9f986693c857f3961dc0e1a4d91cIan Romanickir_dereference_array * 2158273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholtir_dereference_array::clone(void *mem_ctx, struct hash_table *ht) const 2164b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt{ 2178273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt return new(mem_ctx) ir_dereference_array(this->array->clone(mem_ctx, ht), 2188273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt this->array_index->clone(mem_ctx, 2198273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt ht)); 2204b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt} 2214b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt 222ca088cc277ce9f986693c857f3961dc0e1a4d91cIan Romanickir_dereference_record * 2238273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholtir_dereference_record::clone(void *mem_ctx, struct hash_table *ht) const 2244b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt{ 2258273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt return new(mem_ctx) ir_dereference_record(this->record->clone(mem_ctx, ht), 2268273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt this->field); 2274b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt} 2284b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt 229ca088cc277ce9f986693c857f3961dc0e1a4d91cIan Romanickir_texture * 2308273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholtir_texture::clone(void *mem_ctx, struct hash_table *ht) const 2314b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt{ 2328273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt ir_texture *new_tex = new(mem_ctx) ir_texture(this->op); 233c3081e627302429cdf2ee23a40fb20fa5cbf5770Eric Anholt new_tex->type = this->type; 2344b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt 2358273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt new_tex->sampler = this->sampler->clone(mem_ctx, ht); 2361e3bcbdf31f09666ba358f35ff9486faee3642caKenneth Graunke if (this->coordinate) 2371e3bcbdf31f09666ba358f35ff9486faee3642caKenneth Graunke new_tex->coordinate = this->coordinate->clone(mem_ctx, ht); 2384b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt if (this->projector) 2398273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt new_tex->projector = this->projector->clone(mem_ctx, ht); 2404b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt if (this->shadow_comparitor) { 2418273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt new_tex->shadow_comparitor = this->shadow_comparitor->clone(mem_ctx, ht); 2424b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt } 2434b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt 244c5a27b5939427bdc95c926b450ed3de1ff4baafbKenneth Graunke if (this->offset != NULL) 245c5a27b5939427bdc95c926b450ed3de1ff4baafbKenneth Graunke new_tex->offset = this->offset->clone(mem_ctx, ht); 2464b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt 2474b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt switch (this->op) { 2484b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt case ir_tex: 2494b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt break; 2504b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt case ir_txb: 2518273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt new_tex->lod_info.bias = this->lod_info.bias->clone(mem_ctx, ht); 2524b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt break; 2534b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt case ir_txl: 2544b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt case ir_txf: 2551e3bcbdf31f09666ba358f35ff9486faee3642caKenneth Graunke case ir_txs: 2568273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt new_tex->lod_info.lod = this->lod_info.lod->clone(mem_ctx, ht); 2574b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt break; 2584b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt case ir_txd: 2598273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt new_tex->lod_info.grad.dPdx = this->lod_info.grad.dPdx->clone(mem_ctx, ht); 2608273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt new_tex->lod_info.grad.dPdy = this->lod_info.grad.dPdy->clone(mem_ctx, ht); 2614b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt break; 2624b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt } 2634b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt 2644b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt return new_tex; 2654b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt} 2664b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt 267ca088cc277ce9f986693c857f3961dc0e1a4d91cIan Romanickir_assignment * 2688273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholtir_assignment::clone(void *mem_ctx, struct hash_table *ht) const 2694b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt{ 2704b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt ir_rvalue *new_condition = NULL; 2714b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt 2724b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt if (this->condition) 2738273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt new_condition = this->condition->clone(mem_ctx, ht); 2744b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt 2758273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt return new(mem_ctx) ir_assignment(this->lhs->clone(mem_ctx, ht), 2768273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt this->rhs->clone(mem_ctx, ht), 2775a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick new_condition, 2785a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick this->write_mask); 2794b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt} 2804b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt 281ca088cc277ce9f986693c857f3961dc0e1a4d91cIan Romanickir_function * 2828273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholtir_function::clone(void *mem_ctx, struct hash_table *ht) const 2834b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt{ 284b50098122696c00e7f9e57089197e25e5fe0e0cfIan Romanick ir_function *copy = new(mem_ctx) ir_function(this->name); 285b50098122696c00e7f9e57089197e25e5fe0e0cfIan Romanick 286b50098122696c00e7f9e57089197e25e5fe0e0cfIan Romanick foreach_list_const(node, &this->signatures) { 287b50098122696c00e7f9e57089197e25e5fe0e0cfIan Romanick const ir_function_signature *const sig = 288b50098122696c00e7f9e57089197e25e5fe0e0cfIan Romanick (const ir_function_signature *const) node; 289b50098122696c00e7f9e57089197e25e5fe0e0cfIan Romanick 2908273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt ir_function_signature *sig_copy = sig->clone(mem_ctx, ht); 291b50098122696c00e7f9e57089197e25e5fe0e0cfIan Romanick copy->add_signature(sig_copy); 292b50098122696c00e7f9e57089197e25e5fe0e0cfIan Romanick 293b50098122696c00e7f9e57089197e25e5fe0e0cfIan Romanick if (ht != NULL) 294b50098122696c00e7f9e57089197e25e5fe0e0cfIan Romanick hash_table_insert(ht, sig_copy, 295b50098122696c00e7f9e57089197e25e5fe0e0cfIan Romanick (void *)const_cast<ir_function_signature *>(sig)); 296b50098122696c00e7f9e57089197e25e5fe0e0cfIan Romanick } 297b50098122696c00e7f9e57089197e25e5fe0e0cfIan Romanick 298b50098122696c00e7f9e57089197e25e5fe0e0cfIan Romanick return copy; 2994b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt} 3004b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt 301ca088cc277ce9f986693c857f3961dc0e1a4d91cIan Romanickir_function_signature * 3028273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholtir_function_signature::clone(void *mem_ctx, struct hash_table *ht) const 3034b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt{ 30401a25bb64ecae156729794320f9a39733ff8eeaaKenneth Graunke ir_function_signature *copy = this->clone_prototype(mem_ctx, ht); 30501a25bb64ecae156729794320f9a39733ff8eeaaKenneth Graunke 30601a25bb64ecae156729794320f9a39733ff8eeaaKenneth Graunke copy->is_defined = this->is_defined; 30701a25bb64ecae156729794320f9a39733ff8eeaaKenneth Graunke 30801a25bb64ecae156729794320f9a39733ff8eeaaKenneth Graunke /* Clone the instruction list. 30901a25bb64ecae156729794320f9a39733ff8eeaaKenneth Graunke */ 31001a25bb64ecae156729794320f9a39733ff8eeaaKenneth Graunke foreach_list_const(node, &this->body) { 31101a25bb64ecae156729794320f9a39733ff8eeaaKenneth Graunke const ir_instruction *const inst = (const ir_instruction *) node; 31201a25bb64ecae156729794320f9a39733ff8eeaaKenneth Graunke 31301a25bb64ecae156729794320f9a39733ff8eeaaKenneth Graunke ir_instruction *const inst_copy = inst->clone(mem_ctx, ht); 31401a25bb64ecae156729794320f9a39733ff8eeaaKenneth Graunke copy->body.push_tail(inst_copy); 31501a25bb64ecae156729794320f9a39733ff8eeaaKenneth Graunke } 31601a25bb64ecae156729794320f9a39733ff8eeaaKenneth Graunke 31701a25bb64ecae156729794320f9a39733ff8eeaaKenneth Graunke return copy; 31801a25bb64ecae156729794320f9a39733ff8eeaaKenneth Graunke} 31901a25bb64ecae156729794320f9a39733ff8eeaaKenneth Graunke 32001a25bb64ecae156729794320f9a39733ff8eeaaKenneth Graunkeir_function_signature * 32101a25bb64ecae156729794320f9a39733ff8eeaaKenneth Graunkeir_function_signature::clone_prototype(void *mem_ctx, struct hash_table *ht) const 32201a25bb64ecae156729794320f9a39733ff8eeaaKenneth Graunke{ 323b50098122696c00e7f9e57089197e25e5fe0e0cfIan Romanick ir_function_signature *copy = 324b50098122696c00e7f9e57089197e25e5fe0e0cfIan Romanick new(mem_ctx) ir_function_signature(this->return_type); 325b50098122696c00e7f9e57089197e25e5fe0e0cfIan Romanick 32601a25bb64ecae156729794320f9a39733ff8eeaaKenneth Graunke copy->is_defined = false; 327f412fac5b46eb274cbed8e62234d5dbfd859f1feKenneth Graunke copy->is_builtin = this->is_builtin; 3282ff7b121cad2892698ff1aa7690dd361ea2739a7Olivier Galibert copy->origin = this; 329b50098122696c00e7f9e57089197e25e5fe0e0cfIan Romanick 33001a25bb64ecae156729794320f9a39733ff8eeaaKenneth Graunke /* Clone the parameter list, but NOT the body. 331b50098122696c00e7f9e57089197e25e5fe0e0cfIan Romanick */ 332b50098122696c00e7f9e57089197e25e5fe0e0cfIan Romanick foreach_list_const(node, &this->parameters) { 333b50098122696c00e7f9e57089197e25e5fe0e0cfIan Romanick const ir_variable *const param = (const ir_variable *) node; 334b50098122696c00e7f9e57089197e25e5fe0e0cfIan Romanick 335b50098122696c00e7f9e57089197e25e5fe0e0cfIan Romanick assert(const_cast<ir_variable *>(param)->as_variable() != NULL); 336b50098122696c00e7f9e57089197e25e5fe0e0cfIan Romanick 3378273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt ir_variable *const param_copy = param->clone(mem_ctx, ht); 338b50098122696c00e7f9e57089197e25e5fe0e0cfIan Romanick copy->parameters.push_tail(param_copy); 339b50098122696c00e7f9e57089197e25e5fe0e0cfIan Romanick } 340b50098122696c00e7f9e57089197e25e5fe0e0cfIan Romanick 341b50098122696c00e7f9e57089197e25e5fe0e0cfIan Romanick return copy; 3424b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt} 3435f384088336c23c4fe332d2735450bf455c88200Eric Anholt 344ca088cc277ce9f986693c857f3961dc0e1a4d91cIan Romanickir_constant * 3458273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholtir_constant::clone(void *mem_ctx, struct hash_table *ht) const 3465f384088336c23c4fe332d2735450bf455c88200Eric Anholt{ 3479ca0a022e6fcd46a6ce06b8d08dd4c046ec215c4Eric Anholt (void)ht; 3489ca0a022e6fcd46a6ce06b8d08dd4c046ec215c4Eric Anholt 3495f384088336c23c4fe332d2735450bf455c88200Eric Anholt switch (this->type->base_type) { 3505f384088336c23c4fe332d2735450bf455c88200Eric Anholt case GLSL_TYPE_UINT: 3515f384088336c23c4fe332d2735450bf455c88200Eric Anholt case GLSL_TYPE_INT: 3525f384088336c23c4fe332d2735450bf455c88200Eric Anholt case GLSL_TYPE_FLOAT: 3535f384088336c23c4fe332d2735450bf455c88200Eric Anholt case GLSL_TYPE_BOOL: 3548273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt return new(mem_ctx) ir_constant(this->type, &this->value); 3555f384088336c23c4fe332d2735450bf455c88200Eric Anholt 3565f384088336c23c4fe332d2735450bf455c88200Eric Anholt case GLSL_TYPE_STRUCT: { 3578273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt ir_constant *c = new(mem_ctx) ir_constant; 3585f384088336c23c4fe332d2735450bf455c88200Eric Anholt 3595f384088336c23c4fe332d2735450bf455c88200Eric Anholt c->type = this->type; 3605f384088336c23c4fe332d2735450bf455c88200Eric Anholt for (exec_node *node = this->components.head 36162c4763b707e2227409f81b09dd5cf6e4410ea6aEric Anholt ; !node->is_tail_sentinel() 3625f384088336c23c4fe332d2735450bf455c88200Eric Anholt ; node = node->next) { 3635f384088336c23c4fe332d2735450bf455c88200Eric Anholt ir_constant *const orig = (ir_constant *) node; 3645f384088336c23c4fe332d2735450bf455c88200Eric Anholt 3658273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt c->components.push_tail(orig->clone(mem_ctx, NULL)); 3665f384088336c23c4fe332d2735450bf455c88200Eric Anholt } 3675f384088336c23c4fe332d2735450bf455c88200Eric Anholt 3685f384088336c23c4fe332d2735450bf455c88200Eric Anholt return c; 3695f384088336c23c4fe332d2735450bf455c88200Eric Anholt } 3705f384088336c23c4fe332d2735450bf455c88200Eric Anholt 37174e1802f5dd8921750851abc6128e4073602d405Kenneth Graunke case GLSL_TYPE_ARRAY: { 3728273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt ir_constant *c = new(mem_ctx) ir_constant; 37374e1802f5dd8921750851abc6128e4073602d405Kenneth Graunke 37474e1802f5dd8921750851abc6128e4073602d405Kenneth Graunke c->type = this->type; 375d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke c->array_elements = ralloc_array(c, ir_constant *, this->type->length); 37674e1802f5dd8921750851abc6128e4073602d405Kenneth Graunke for (unsigned i = 0; i < this->type->length; i++) { 3778273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt c->array_elements[i] = this->array_elements[i]->clone(mem_ctx, NULL); 37874e1802f5dd8921750851abc6128e4073602d405Kenneth Graunke } 37974e1802f5dd8921750851abc6128e4073602d405Kenneth Graunke return c; 38074e1802f5dd8921750851abc6128e4073602d405Kenneth Graunke } 38174e1802f5dd8921750851abc6128e4073602d405Kenneth Graunke 3825f384088336c23c4fe332d2735450bf455c88200Eric Anholt default: 3834b1721eaf35ccb60d90850ab34a99d6ab1f89a05José Fonseca assert(!"Should not get here."); 3845f384088336c23c4fe332d2735450bf455c88200Eric Anholt return NULL; 3855f384088336c23c4fe332d2735450bf455c88200Eric Anholt } 3865f384088336c23c4fe332d2735450bf455c88200Eric Anholt} 387f3235eb37f264244f4ea432700be7dd6b2930d6cIan Romanick 388f3235eb37f264244f4ea432700be7dd6b2930d6cIan Romanick 389f3235eb37f264244f4ea432700be7dd6b2930d6cIan Romanickclass fixup_ir_call_visitor : public ir_hierarchical_visitor { 390f3235eb37f264244f4ea432700be7dd6b2930d6cIan Romanickpublic: 391f3235eb37f264244f4ea432700be7dd6b2930d6cIan Romanick fixup_ir_call_visitor(struct hash_table *ht) 392f3235eb37f264244f4ea432700be7dd6b2930d6cIan Romanick { 393f3235eb37f264244f4ea432700be7dd6b2930d6cIan Romanick this->ht = ht; 394f3235eb37f264244f4ea432700be7dd6b2930d6cIan Romanick } 395f3235eb37f264244f4ea432700be7dd6b2930d6cIan Romanick 396f3235eb37f264244f4ea432700be7dd6b2930d6cIan Romanick virtual ir_visitor_status visit_enter(ir_call *ir) 397f3235eb37f264244f4ea432700be7dd6b2930d6cIan Romanick { 398f3235eb37f264244f4ea432700be7dd6b2930d6cIan Romanick /* Try to find the function signature referenced by the ir_call in the 399f3235eb37f264244f4ea432700be7dd6b2930d6cIan Romanick * table. If it is found, replace it with the value from the table. 400f3235eb37f264244f4ea432700be7dd6b2930d6cIan Romanick */ 4011f47245bdda2c85bf0f0174e6c24a50486b413aaEric Anholt ir_function_signature *sig = 40282065fa20ee3f2880a070f1f4f75509b910ceddeKenneth Graunke (ir_function_signature *) hash_table_find(this->ht, ir->callee); 403f3235eb37f264244f4ea432700be7dd6b2930d6cIan Romanick if (sig != NULL) 40482065fa20ee3f2880a070f1f4f75509b910ceddeKenneth Graunke ir->callee = sig; 405f3235eb37f264244f4ea432700be7dd6b2930d6cIan Romanick 406f3235eb37f264244f4ea432700be7dd6b2930d6cIan Romanick /* Since this may be used before function call parameters are flattened, 407f3235eb37f264244f4ea432700be7dd6b2930d6cIan Romanick * the children also need to be processed. 408f3235eb37f264244f4ea432700be7dd6b2930d6cIan Romanick */ 409f3235eb37f264244f4ea432700be7dd6b2930d6cIan Romanick return visit_continue; 410f3235eb37f264244f4ea432700be7dd6b2930d6cIan Romanick } 411f3235eb37f264244f4ea432700be7dd6b2930d6cIan Romanick 412f3235eb37f264244f4ea432700be7dd6b2930d6cIan Romanickprivate: 413f3235eb37f264244f4ea432700be7dd6b2930d6cIan Romanick struct hash_table *ht; 414f3235eb37f264244f4ea432700be7dd6b2930d6cIan Romanick}; 415f3235eb37f264244f4ea432700be7dd6b2930d6cIan Romanick 416f3235eb37f264244f4ea432700be7dd6b2930d6cIan Romanick 417f3235eb37f264244f4ea432700be7dd6b2930d6cIan Romanickstatic void 418f3235eb37f264244f4ea432700be7dd6b2930d6cIan Romanickfixup_function_calls(struct hash_table *ht, exec_list *instructions) 419f3235eb37f264244f4ea432700be7dd6b2930d6cIan Romanick{ 420f3235eb37f264244f4ea432700be7dd6b2930d6cIan Romanick fixup_ir_call_visitor v(ht); 421f3235eb37f264244f4ea432700be7dd6b2930d6cIan Romanick v.run(instructions); 422f3235eb37f264244f4ea432700be7dd6b2930d6cIan Romanick} 423f3235eb37f264244f4ea432700be7dd6b2930d6cIan Romanick 424f3235eb37f264244f4ea432700be7dd6b2930d6cIan Romanick 425f3235eb37f264244f4ea432700be7dd6b2930d6cIan Romanickvoid 4268273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholtclone_ir_list(void *mem_ctx, exec_list *out, const exec_list *in) 427f3235eb37f264244f4ea432700be7dd6b2930d6cIan Romanick{ 428f3235eb37f264244f4ea432700be7dd6b2930d6cIan Romanick struct hash_table *ht = 429f3235eb37f264244f4ea432700be7dd6b2930d6cIan Romanick hash_table_ctor(0, hash_table_pointer_hash, hash_table_pointer_compare); 430f3235eb37f264244f4ea432700be7dd6b2930d6cIan Romanick 431f3235eb37f264244f4ea432700be7dd6b2930d6cIan Romanick foreach_list_const(node, in) { 432f3235eb37f264244f4ea432700be7dd6b2930d6cIan Romanick const ir_instruction *const original = (ir_instruction *) node; 4338273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt ir_instruction *copy = original->clone(mem_ctx, ht); 434f3235eb37f264244f4ea432700be7dd6b2930d6cIan Romanick 435f3235eb37f264244f4ea432700be7dd6b2930d6cIan Romanick out->push_tail(copy); 436f3235eb37f264244f4ea432700be7dd6b2930d6cIan Romanick } 437f3235eb37f264244f4ea432700be7dd6b2930d6cIan Romanick 438f3235eb37f264244f4ea432700be7dd6b2930d6cIan Romanick /* Make a pass over the cloned tree to fix up ir_call nodes to point to the 439f3235eb37f264244f4ea432700be7dd6b2930d6cIan Romanick * cloned ir_function_signature nodes. This cannot be done automatically 440f3235eb37f264244f4ea432700be7dd6b2930d6cIan Romanick * during cloning because the ir_call might be a forward reference (i.e., 441f3235eb37f264244f4ea432700be7dd6b2930d6cIan Romanick * the function signature that it references may not have been cloned yet). 442f3235eb37f264244f4ea432700be7dd6b2930d6cIan Romanick */ 443f3235eb37f264244f4ea432700be7dd6b2930d6cIan Romanick fixup_function_calls(ht, out); 444f3235eb37f264244f4ea432700be7dd6b2930d6cIan Romanick 445f3235eb37f264244f4ea432700be7dd6b2930d6cIan Romanick hash_table_dtor(ht); 446f3235eb37f264244f4ea432700be7dd6b2930d6cIan Romanick} 447