11c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák/* 21c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Copyright 2011 Tom Stellard <tstellar@gmail.com> 31c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 41c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * All Rights Reserved. 51c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 61c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Permission is hereby granted, free of charge, to any person obtaining 71c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * a copy of this software and associated documentation files (the 81c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * "Software"), to deal in the Software without restriction, including 91c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * without limitation the rights to use, copy, modify, merge, publish, 101c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * distribute, sublicense, and/or sell copies of the Software, and to 111c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * permit persons to whom the Software is furnished to do so, subject to 121c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * the following conditions: 131c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 141c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * The above copyright notice and this permission notice (including the 151c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * next paragraph) shall be included in all copies or substantial 161c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * portions of the Software. 171c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 181c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 191c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 201c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 211c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE 221c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 231c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 241c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 251c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 261c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */ 271c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 281c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#include "radeon_variable.h" 291c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 301c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#include "memory_pool.h" 311c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#include "radeon_compiler_util.h" 321c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#include "radeon_dataflow.h" 331c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#include "radeon_list.h" 341c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#include "radeon_opcodes.h" 351c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#include "radeon_program.h" 361c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 371c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák/** 381c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Rewrite the index and writemask for the destination register of var 391c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * and its friends to new_index and new_writemask. This function also takes 401c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * care of rewriting the swizzles for the sources of var. 411c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */ 421c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákvoid rc_variable_change_dst( 431c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_variable * var, 441c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int new_index, 451c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int new_writemask) 461c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 471c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_variable * var_ptr; 481c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_list * readers; 491c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int old_mask = rc_variable_writemask_sum(var); 501c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int conversion_swizzle = 511c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_make_conversion_swizzle(old_mask, new_writemask); 521c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 531c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for (var_ptr = var; var_ptr; var_ptr = var_ptr->Friend) { 541c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (var_ptr->Inst->Type == RC_INSTRUCTION_NORMAL) { 551c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_normal_rewrite_writemask(var_ptr->Inst, 561c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák conversion_swizzle); 571c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák var_ptr->Inst->U.I.DstReg.Index = new_index; 581c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } else { 591c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_pair_sub_instruction * sub; 601c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (var_ptr->Dst.WriteMask == RC_MASK_W) { 611c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák assert(new_writemask & RC_MASK_W); 621c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák sub = &var_ptr->Inst->U.P.Alpha; 631c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } else { 641c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák sub = &var_ptr->Inst->U.P.RGB; 651c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_pair_rewrite_writemask(sub, 661c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák conversion_swizzle); 671c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 681c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák sub->DestIndex = new_index; 691c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 701c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 711c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 721c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák readers = rc_variable_readers_union(var); 731c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 741c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for ( ; readers; readers = readers->Next) { 751c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_reader * reader = readers->Item; 761c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (reader->Inst->Type == RC_INSTRUCTION_NORMAL) { 771c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák reader->U.I.Src->Index = new_index; 781c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák reader->U.I.Src->Swizzle = rc_rewrite_swizzle( 791c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák reader->U.I.Src->Swizzle, conversion_swizzle); 801c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } else { 811c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_pair_instruction * pair_inst = 821c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák &reader->Inst->U.P; 831c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int src_type = rc_source_type_swz( 841c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák reader->U.P.Arg->Swizzle); 851c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 861c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák int src_index = reader->U.P.Arg->Source; 871c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (src_index == RC_PAIR_PRESUB_SRC) { 881c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák src_index = rc_pair_get_src_index( 891c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák pair_inst, reader->U.P.Src); 901c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 911c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* Try to delete the old src, it is OK if this fails, 921c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * because rc_pair_alloc_source might be able to 931c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * find a source the ca be reused. 941c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */ 951c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (rc_pair_remove_src(reader->Inst, src_type, 961c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák src_index, old_mask)) { 971c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* Reuse the source index of the source that 981c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * was just deleted and set its register 991c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * index. We can't use rc_pair_alloc_source 1001c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * for this becuase it might return a source 1011c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * index that is already being used. */ 1021c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (src_type & RC_SOURCE_RGB) { 1031c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák pair_inst->RGB.Src[src_index] 1041c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák .Used = 1; 1051c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák pair_inst->RGB.Src[src_index] 1061c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák .Index = new_index; 1071c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák pair_inst->RGB.Src[src_index] 1081c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák .File = RC_FILE_TEMPORARY; 1091c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 1101c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (src_type & RC_SOURCE_ALPHA) { 1111c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák pair_inst->Alpha.Src[src_index] 1121c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák .Used = 1; 1131c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák pair_inst->Alpha.Src[src_index] 1141c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák .Index = new_index; 1151c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák pair_inst->Alpha.Src[src_index] 1161c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák .File = RC_FILE_TEMPORARY; 1171c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 1181c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } else { 1191c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák src_index = rc_pair_alloc_source( 1201c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák &reader->Inst->U.P, 1211c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák src_type & RC_SOURCE_RGB, 1221c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák src_type & RC_SOURCE_ALPHA, 1231c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_FILE_TEMPORARY, 1241c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák new_index); 1251c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (src_index < 0) { 1261c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_error(var->C, "Rewrite of inst %u failed " 1271c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák "Can't allocate source for " 1281c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák "Inst %u src_type=%x " 1291c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák "new_index=%u new_mask=%u\n", 1301c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák var->Inst->IP, reader->Inst->IP, src_type, new_index, new_writemask); 1311c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák continue; 1321c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 1331c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 1341c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák reader->U.P.Arg->Swizzle = rc_rewrite_swizzle( 1351c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák reader->U.P.Arg->Swizzle, conversion_swizzle); 1361c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (reader->U.P.Arg->Source != RC_PAIR_PRESUB_SRC) { 1371c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák reader->U.P.Arg->Source = src_index; 1381c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 1391c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 1401c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 1411c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 1421c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1431c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák/** 1441c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Compute the live intervals for var and its friends. 1451c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */ 1461c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákvoid rc_variable_compute_live_intervals(struct rc_variable * var) 1471c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 1481c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák while(var) { 1491c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int i; 1501c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int start = var->Inst->IP; 1511c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1521c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for (i = 0; i < var->ReaderCount; i++) { 1531c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int chan; 1541c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int chan_start = start; 1551c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int chan_end = var->Readers[i].Inst->IP; 1561c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int mask = var->Readers[i].WriteMask; 1571c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction * inst; 1581c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1591c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* Extend the live interval of T0 to the start of the 1601c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * loop for sequences like: 1611c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * BGNLOOP 1621c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * read T0 1631c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * ... 1641c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * write T0 1651c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * ENDLOOP 1661c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */ 1671c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (var->Readers[i].Inst->IP < start) { 1681c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction * bgnloop = 1691c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_match_endloop(var->Readers[i].Inst); 1701c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák chan_start = bgnloop->IP; 1711c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 1721c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1731c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* Extend the live interval of T0 to the start of the 1741c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * loop in case there is a BRK instruction in the loop 1751c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * (we don't actually check for a BRK instruction we 1761c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * assume there is one somewhere in the loop, which 1771c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * there usually is) for sequences like: 1781c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * BGNLOOP 1791c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * ... 1801c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * conditional BRK 1811c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * ... 1821c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * write T0 1831c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * ENDLOOP 1841c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * read T0 1851c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák *************************************************** 1861c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Extend the live interval of T0 to the end of the 1871c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * loop for sequences like: 1881c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * write T0 1891c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * BGNLOOP 1901c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * ... 1911c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * read T0 1921c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * ENDLOOP 1931c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */ 1941c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for (inst = var->Inst; inst != var->Readers[i].Inst; 1951c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst = inst->Next) { 1961c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_opcode op = rc_get_flow_control_inst(inst); 1971c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (op == RC_OPCODE_ENDLOOP) { 1981c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction * bgnloop = 1991c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_match_endloop(inst); 2001c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (bgnloop->IP < chan_start) { 2011c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák chan_start = bgnloop->IP; 2021c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 2031c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } else if (op == RC_OPCODE_BGNLOOP) { 2041c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction * endloop = 2051c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_match_bgnloop(inst); 2061c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (endloop->IP > chan_end) { 2071c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák chan_end = endloop->IP; 2081c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 2091c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 2101c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 2111c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 2121c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for (chan = 0; chan < 4; chan++) { 2131c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if ((mask >> chan) & 0x1) { 2141c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (!var->Live[chan].Used 2151c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák || chan_start < var->Live[chan].Start) { 2161c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák var->Live[chan].Start = 2171c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák chan_start; 2181c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 2191c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (!var->Live[chan].Used 2201c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák || chan_end > var->Live[chan].End) { 2211c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák var->Live[chan].End = chan_end; 2221c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 2231c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák var->Live[chan].Used = 1; 2241c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 2251c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 2261c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 2271c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák var = var->Friend; 2281c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 2291c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 2301c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 2311c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák/** 2321c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * @return 1 if a and b share a reader 2331c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * @return 0 if they do not 2341c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */ 2351c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic unsigned int readers_intersect( 2361c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_variable * a, 2371c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_variable * b) 2381c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 2391c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int a_index, b_index; 2401c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for (a_index = 0; a_index < a->ReaderCount; a_index++) { 2411c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_reader reader_a = a->Readers[a_index]; 2421c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for (b_index = 0; b_index < b->ReaderCount; b_index++) { 2431c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_reader reader_b = b->Readers[b_index]; 2441c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (reader_a.Inst->Type == RC_INSTRUCTION_NORMAL 2451c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák && reader_b.Inst->Type == RC_INSTRUCTION_NORMAL 2461c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák && reader_a.U.I.Src == reader_b.U.I.Src) { 2471c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 2481c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return 1; 2491c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 2501c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (reader_a.Inst->Type == RC_INSTRUCTION_PAIR 2511c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák && reader_b.Inst->Type == RC_INSTRUCTION_PAIR 2521c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák && reader_a.U.P.Src == reader_b.U.P.Src) { 2531c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 2541c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return 1; 2551c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 2561c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 2571c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 2581c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return 0; 2591c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 2601c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 2611c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákvoid rc_variable_add_friend( 2621c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_variable * var, 2631c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_variable * friend) 2641c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 2651c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák assert(var->Dst.Index == friend->Dst.Index); 2661c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák while(var->Friend) { 2671c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák var = var->Friend; 2681c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 2691c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák var->Friend = friend; 2701c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 2711c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 2721c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstruct rc_variable * rc_variable( 2731c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct radeon_compiler * c, 2741c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int DstFile, 2751c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int DstIndex, 2761c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int DstWriteMask, 2771c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_reader_data * reader_data) 2781c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 2791c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_variable * new = 2801c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák memory_pool_malloc(&c->Pool, sizeof(struct rc_variable)); 2811c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák memset(new, 0, sizeof(struct rc_variable)); 2821c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák new->C = c; 2831c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák new->Dst.File = DstFile; 2841c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák new->Dst.Index = DstIndex; 2851c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák new->Dst.WriteMask = DstWriteMask; 2861c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (reader_data) { 2871c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák new->Inst = reader_data->Writer; 2881c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák new->ReaderCount = reader_data->ReaderCount; 2891c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák new->Readers = reader_data->Readers; 2901c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 2911c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return new; 2921c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 2931c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 2941c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void get_variable_helper( 2951c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_list ** variable_list, 2961c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_variable * variable) 2971c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 2981c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_list * list_ptr; 2991c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for (list_ptr = *variable_list; list_ptr; list_ptr = list_ptr->Next) { 3002d1004d9aa719bb93a4f057b0eefe88f23b44e44Tom Stellard struct rc_variable * var; 3012d1004d9aa719bb93a4f057b0eefe88f23b44e44Tom Stellard for (var = list_ptr->Item; var; var = var->Friend) { 3022d1004d9aa719bb93a4f057b0eefe88f23b44e44Tom Stellard if (readers_intersect(var, variable)) { 3032d1004d9aa719bb93a4f057b0eefe88f23b44e44Tom Stellard rc_variable_add_friend(var, variable); 3042d1004d9aa719bb93a4f057b0eefe88f23b44e44Tom Stellard return; 3052d1004d9aa719bb93a4f057b0eefe88f23b44e44Tom Stellard } 3061c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 3071c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 3081c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_list_add(variable_list, rc_list(&variable->C->Pool, variable)); 3091c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 3101c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 3111c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void get_variable_pair_helper( 3121c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_list ** variable_list, 3131c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct radeon_compiler * c, 3141c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction * inst, 3151c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_pair_sub_instruction * sub_inst) 3161c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 3171c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_reader_data reader_data; 3181c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_variable * new_var; 3191c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_register_file file; 3201c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int writemask; 3211c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 3221c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (sub_inst->Opcode == RC_OPCODE_NOP) { 3231c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return; 3241c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 3251c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák memset(&reader_data, 0, sizeof(struct rc_reader_data)); 3261c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_get_readers_sub(c, inst, sub_inst, &reader_data, NULL, NULL, NULL); 3271c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 3281c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (reader_data.ReaderCount == 0) { 3291c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return; 3301c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 3311c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 3321c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (sub_inst->WriteMask) { 3331c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák file = RC_FILE_TEMPORARY; 3341c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák writemask = sub_inst->WriteMask; 3351c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } else if (sub_inst->OutputWriteMask) { 3361c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák file = RC_FILE_OUTPUT; 3371c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák writemask = sub_inst->OutputWriteMask; 3381c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } else { 3391c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák writemask = 0; 3401c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák file = RC_FILE_NONE; 3411c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 3421c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák new_var = rc_variable(c, file, sub_inst->DestIndex, writemask, 3431c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák &reader_data); 3441c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák get_variable_helper(variable_list, new_var); 3451c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 3461c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 3471c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák/** 3481c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Generate a list of variables used by the shader program. Each instruction 3491c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * that writes to a register is considered a variable. The struct rc_variable 3501c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * data structure includes a list of readers and is essentially a 3511c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * definition-use chain. Any two variables that share a reader are considered 3521c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * "friends" and they are linked together via the Friend attribute. 3531c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */ 3541c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstruct rc_list * rc_get_variables(struct radeon_compiler * c) 3551c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 3561c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction * inst; 3571c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_list * variable_list = NULL; 3581c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 3591c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for (inst = c->Program.Instructions.Next; 3601c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst != &c->Program.Instructions; 3611c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst = inst->Next) { 3621c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_reader_data reader_data; 3631c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_variable * new_var; 3641c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák memset(&reader_data, 0, sizeof(reader_data)); 3651c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 3661c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (inst->Type == RC_INSTRUCTION_NORMAL) { 3671c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_get_readers(c, inst, &reader_data, NULL, NULL, NULL); 3681c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (reader_data.ReaderCount == 0) { 3691c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák continue; 3701c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 3711c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák new_var = rc_variable(c, inst->U.I.DstReg.File, 3721c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.DstReg.Index, 3731c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.DstReg.WriteMask, &reader_data); 3741c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák get_variable_helper(&variable_list, new_var); 3751c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } else { 3761c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák get_variable_pair_helper(&variable_list, c, inst, 3771c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák &inst->U.P.RGB); 3781c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák get_variable_pair_helper(&variable_list, c, inst, 3791c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák &inst->U.P.Alpha); 3801c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 3811c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 3821c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 3831c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return variable_list; 3841c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 3851c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 3861c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák/** 3871c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * @return The bitwise or of the writemasks of a variable and all of its 3881c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * friends. 3891c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */ 3901c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákunsigned int rc_variable_writemask_sum(struct rc_variable * var) 3911c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 3921c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int writemask = 0; 3931c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák while(var) { 3941c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák writemask |= var->Dst.WriteMask; 3951c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák var = var->Friend; 3961c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 3971c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return writemask; 3981c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 3991c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4001c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák/* 4011c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * @return A list of readers for a variable and its friends. Readers 4021c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * that read from two different variable friends are only included once in 4031c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * this list. 4041c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */ 4051c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstruct rc_list * rc_variable_readers_union(struct rc_variable * var) 4061c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 4071c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_list * list = NULL; 4081c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák while (var) { 4091c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int i; 4101c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for (i = 0; i < var->ReaderCount; i++) { 4111c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_list * temp; 4121c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_reader * a = &var->Readers[i]; 4131c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int match = 0; 4141c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for (temp = list; temp; temp = temp->Next) { 4151c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_reader * b = temp->Item; 4161c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (a->Inst->Type != b->Inst->Type) { 4171c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák continue; 4181c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 4191c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (a->Inst->Type == RC_INSTRUCTION_NORMAL) { 4201c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (a->U.I.Src == b->U.I.Src) { 4211c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák match = 1; 4221c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák break; 4231c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 4241c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 4251c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (a->Inst->Type == RC_INSTRUCTION_PAIR) { 4261c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (a->U.P.Arg == b->U.P.Arg 4271c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák && a->U.P.Src == b->U.P.Src) { 4281c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák match = 1; 4291c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák break; 4301c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 4311c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 4321c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 4331c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (match) { 4341c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák continue; 4351c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 4361c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_list_add(&list, rc_list(&var->C->Pool, a)); 4371c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 4381c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák var = var->Friend; 4391c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 4401c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return list; 4411c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 4421c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4431c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic unsigned int reader_equals_src( 4441c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_reader reader, 4451c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int src_type, 4461c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák void * src) 4471c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 4481c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (reader.Inst->Type != src_type) { 4491c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return 0; 4501c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 4511c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (src_type == RC_INSTRUCTION_NORMAL) { 4521c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return reader.U.I.Src == src; 4531c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } else { 4541c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return reader.U.P.Src == src; 4551c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 4561c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 4571c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4581c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic unsigned int variable_writes_src( 4591c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_variable * var, 4601c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int src_type, 4611c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák void * src) 4621c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 4631c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int i; 4641c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for (i = 0; i < var->ReaderCount; i++) { 4651c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (reader_equals_src(var->Readers[i], src_type, src)) { 4661c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return 1; 4671c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 4681c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 4691c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return 0; 4701c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 4711c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4721c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4731c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstruct rc_list * rc_variable_list_get_writers( 4741c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_list * var_list, 4751c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int src_type, 4761c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák void * src) 4771c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 4781c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_list * list_ptr; 4791c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_list * writer_list = NULL; 4801c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for (list_ptr = var_list; list_ptr; list_ptr = list_ptr->Next) { 4811c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_variable * var = list_ptr->Item; 4821c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (variable_writes_src(var, src_type, src)) { 4831c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_variable * friend; 4841c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_list_add(&writer_list, rc_list(&var->C->Pool, var)); 4851c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for (friend = var->Friend; friend; 4861c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák friend = friend->Friend) { 4871c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (variable_writes_src(friend, src_type, src)) { 4881c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_list_add(&writer_list, 4891c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_list(&var->C->Pool, friend)); 4901c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 4911c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 4921c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* Once we have indentifed the variable and its 4931c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * friends that write this source, we can stop 4941c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * stop searching, because we know know of the 4951c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * other variables in the list will write this source. 4961c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * If they did they would be friends of var. 4971c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */ 4981c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák break; 4991c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 5001c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 5011c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return writer_list; 5021c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 5031c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 504e945fb04d04c33da5e77d22d739c5740a522a61eTom Stellardstruct rc_list * rc_variable_list_get_writers_one_reader( 505e945fb04d04c33da5e77d22d739c5740a522a61eTom Stellard struct rc_list * var_list, 506e945fb04d04c33da5e77d22d739c5740a522a61eTom Stellard unsigned int src_type, 507e945fb04d04c33da5e77d22d739c5740a522a61eTom Stellard void * src) 508e945fb04d04c33da5e77d22d739c5740a522a61eTom Stellard{ 509e945fb04d04c33da5e77d22d739c5740a522a61eTom Stellard struct rc_list * writer_list = 510e945fb04d04c33da5e77d22d739c5740a522a61eTom Stellard rc_variable_list_get_writers(var_list, src_type, src); 511e945fb04d04c33da5e77d22d739c5740a522a61eTom Stellard struct rc_list * reader_list = 512e945fb04d04c33da5e77d22d739c5740a522a61eTom Stellard rc_variable_readers_union(writer_list->Item); 513e945fb04d04c33da5e77d22d739c5740a522a61eTom Stellard if (rc_list_count(reader_list) > 1) { 514e945fb04d04c33da5e77d22d739c5740a522a61eTom Stellard return NULL; 515e945fb04d04c33da5e77d22d739c5740a522a61eTom Stellard } else { 516e945fb04d04c33da5e77d22d739c5740a522a61eTom Stellard return writer_list; 517e945fb04d04c33da5e77d22d739c5740a522a61eTom Stellard } 518e945fb04d04c33da5e77d22d739c5740a522a61eTom Stellard} 519e945fb04d04c33da5e77d22d739c5740a522a61eTom Stellard 5201c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákvoid rc_variable_print(struct rc_variable * var) 5211c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 5221c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int i; 5231c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák while (var) { 5241c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák fprintf(stderr, "%u: TEMP[%u].%u: ", 5251c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák var->Inst->IP, var->Dst.Index, var->Dst.WriteMask); 5261c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for (i = 0; i < 4; i++) { 5271c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák fprintf(stderr, "chan %u: start=%u end=%u ", i, 5281c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák var->Live[i].Start, var->Live[i].End); 5291c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 5301c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák fprintf(stderr, "%u readers\n", var->ReaderCount); 5311c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (var->Friend) { 5321c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák fprintf(stderr, "Friend: \n\t"); 5331c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 5341c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák var = var->Friend; 5351c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 5361c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 537