11c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák/* 21c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Copyright (C) 2009 Nicolai Haehnle. 31c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Copyright 2011 Tom Stellard <tstellar@gmail.com> 41c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 51c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * All Rights Reserved. 61c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 71c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Permission is hereby granted, free of charge, to any person obtaining 81c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * a copy of this software and associated documentation files (the 91c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * "Software"), to deal in the Software without restriction, including 101c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * without limitation the rights to use, copy, modify, merge, publish, 111c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * distribute, sublicense, and/or sell copies of the Software, and to 121c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * permit persons to whom the Software is furnished to do so, subject to 131c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * the following conditions: 141c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 151c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * The above copyright notice and this permission notice (including the 161c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * next paragraph) shall be included in all copies or substantial 171c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * portions of the Software. 181c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 191c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 201c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 211c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 221c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE 231c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 241c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 251c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 261c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 271c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */ 281c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 291c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#include "radeon_program_pair.h" 301c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 311c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#include <stdio.h> 321c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 331c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#include "main/glheader.h" 341c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#include "program/register_allocate.h" 351c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#include "ralloc.h" 361c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 371c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#include "r300_fragprog_swizzle.h" 381c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#include "radeon_compiler.h" 391c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#include "radeon_compiler_util.h" 401c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#include "radeon_dataflow.h" 411c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#include "radeon_list.h" 421c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#include "radeon_variable.h" 431c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 441c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#define VERBOSE 0 451c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 461c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#define DBG(...) do { if (VERBOSE) fprintf(stderr, __VA_ARGS__); } while(0) 471c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 481c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 491c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 501c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstruct register_info { 511c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct live_intervals Live[4]; 521c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 531c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int Used:1; 541c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int Allocated:1; 551c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int File:3; 561c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int Index:RC_REGISTER_INDEX_BITS; 571c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int Writemask; 581c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák}; 591c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 601c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstruct regalloc_state { 611c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct radeon_compiler * C; 621c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 631c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct register_info * Input; 641c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int NumInputs; 651c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 661c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct register_info * Temporary; 671c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int NumTemporaries; 681c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 691c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int Simple; 701c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák int LoopEnd; 711c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák}; 721c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 731c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákenum rc_reg_class { 741c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_REG_CLASS_SINGLE, 751c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_REG_CLASS_DOUBLE, 761c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_REG_CLASS_TRIPLE, 771c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_REG_CLASS_ALPHA, 781c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_REG_CLASS_SINGLE_PLUS_ALPHA, 791c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_REG_CLASS_DOUBLE_PLUS_ALPHA, 801c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_REG_CLASS_TRIPLE_PLUS_ALPHA, 811c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_REG_CLASS_X, 821c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_REG_CLASS_Y, 831c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_REG_CLASS_Z, 841c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_REG_CLASS_XY, 851c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_REG_CLASS_YZ, 861c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_REG_CLASS_XZ, 871c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_REG_CLASS_XW, 881c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_REG_CLASS_YW, 891c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_REG_CLASS_ZW, 901c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_REG_CLASS_XYW, 911c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_REG_CLASS_YZW, 921c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_REG_CLASS_XZW, 931c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_REG_CLASS_COUNT 941c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák}; 951c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 961c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstruct rc_class { 971c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák enum rc_reg_class Class; 981c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 991c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int WritemaskCount; 1001c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1011c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /** This is 1 if this class is being used by the register allocator 1021c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * and 0 otherwise */ 1031c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int Used; 1041c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1051c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /** This is the ID number assigned to this class by ra. */ 1061c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int Id; 1071c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1081c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /** List of writemasks that belong to this class */ 1091c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int Writemasks[3]; 1101c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1111c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1121c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák}; 1131c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1141c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void print_live_intervals(struct live_intervals * src) 1151c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 1161c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (!src || !src->Used) { 1171c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák DBG("(null)"); 1181c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return; 1191c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 1201c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1211c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák DBG("(%i,%i)", src->Start, src->End); 1221c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 1231c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1241c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic int overlap_live_intervals(struct live_intervals * a, struct live_intervals * b) 1251c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 1261c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (VERBOSE) { 1271c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák DBG("overlap_live_intervals: "); 1281c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák print_live_intervals(a); 1291c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák DBG(" to "); 1301c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák print_live_intervals(b); 1311c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák DBG("\n"); 1321c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 1331c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1341c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (!a->Used || !b->Used) { 1351c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák DBG(" unused interval\n"); 1361c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return 0; 1371c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 1381c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1391c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (a->Start > b->Start) { 1401c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (a->Start < b->End) { 1411c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák DBG(" overlap\n"); 1421c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return 1; 1431c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 1441c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } else if (b->Start > a->Start) { 1451c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (b->Start < a->End) { 1461c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák DBG(" overlap\n"); 1471c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return 1; 1481c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 1491c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } else { /* a->Start == b->Start */ 1501c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (a->Start != a->End && b->Start != b->End) { 1511c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák DBG(" overlap\n"); 1521c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return 1; 1531c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 1541c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 1551c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1561c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák DBG(" no overlap\n"); 1571c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1581c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return 0; 1591c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 1601c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1611c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void scan_read_callback(void * data, struct rc_instruction * inst, 1621c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_register_file file, unsigned int index, unsigned int mask) 1631c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 1641c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct regalloc_state * s = data; 1651c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct register_info * reg; 1661c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int i; 1671c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1681c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (file != RC_FILE_INPUT) 1691c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return; 1701c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1711c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák s->Input[index].Used = 1; 1721c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák reg = &s->Input[index]; 1731c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1741c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for (i = 0; i < 4; i++) { 1751c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (!((mask >> i) & 0x1)) { 1761c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák continue; 1771c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 1781c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák reg->Live[i].Used = 1; 1791c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák reg->Live[i].Start = 0; 1801c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák reg->Live[i].End = 1811c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák s->LoopEnd > inst->IP ? s->LoopEnd : inst->IP; 1821c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 1831c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 1841c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1851c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void remap_register(void * data, struct rc_instruction * inst, 1861c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_register_file * file, unsigned int * index) 1871c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 1881c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct regalloc_state * s = data; 1891c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák const struct register_info * reg; 1901c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1911c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (*file == RC_FILE_TEMPORARY && s->Simple) 1921c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák reg = &s->Temporary[*index]; 1931c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák else if (*file == RC_FILE_INPUT) 1941c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák reg = &s->Input[*index]; 1951c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák else 1961c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return; 1971c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1981c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (reg->Allocated) { 1991c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák *index = reg->Index; 2001c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 2011c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 2021c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 2031c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void alloc_input_simple(void * data, unsigned int input, 2041c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int hwreg) 2051c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 2061c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct regalloc_state * s = data; 2071c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 2081c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (input >= s->NumInputs) 2091c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return; 2101c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 2111c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák s->Input[input].Allocated = 1; 2121c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák s->Input[input].File = RC_FILE_TEMPORARY; 2131c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák s->Input[input].Index = hwreg; 2141c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 2151c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 2161c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák/* This functions offsets the temporary register indices by the number 2171c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * of input registers, because input registers are actually temporaries and 2181c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * should not occupy the same space. 2191c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 2201c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * This pass is supposed to be used to maintain correct allocation of inputs 2211c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * if the standard register allocation is disabled. */ 2221c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void do_regalloc_inputs_only(struct regalloc_state * s) 2231c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 2241c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for (unsigned i = 0; i < s->NumTemporaries; i++) { 2251c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák s->Temporary[i].Allocated = 1; 2261c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák s->Temporary[i].File = RC_FILE_TEMPORARY; 2271c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák s->Temporary[i].Index = i + s->NumInputs; 2281c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 2291c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 2301c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 2311c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic unsigned int is_derivative(rc_opcode op) 2321c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 2331c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return (op == RC_OPCODE_DDX || op == RC_OPCODE_DDY); 2341c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 2351c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 2361c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic int find_class( 2371c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_class * classes, 2381c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int writemask, 2391c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int max_writemask_count) 2401c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 2411c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int i; 2421c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for (i = 0; i < RC_REG_CLASS_COUNT; i++) { 2431c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int j; 2441c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (classes[i].WritemaskCount > max_writemask_count) { 2451c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák continue; 2461c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 2471c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for (j = 0; j < 3; j++) { 2481c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (classes[i].Writemasks[j] == writemask) { 2491c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return i; 2501c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 2511c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 2521c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 2531c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return -1; 2541c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 2551c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 2566fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellardstruct variable_get_class_cb_data { 2576fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard unsigned int * can_change_writemask; 2586fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard unsigned int conversion_swizzle; 2596fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard}; 2606fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard 2616fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellardstatic void variable_get_class_read_cb( 2626fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard void * userdata, 2636fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard struct rc_instruction * inst, 2646fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard struct rc_pair_instruction_arg * arg, 2656fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard struct rc_pair_instruction_source * src) 2666fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard{ 2676fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard struct variable_get_class_cb_data * d = userdata; 2686fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard unsigned int new_swizzle = rc_adjust_channels(arg->Swizzle, 2696fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard d->conversion_swizzle); 2706fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard if (!r300_swizzle_is_native_basic(new_swizzle)) { 2716fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard *d->can_change_writemask = 0; 2726fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard } 2736fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard} 2746fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard 2751c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic enum rc_reg_class variable_get_class( 2761c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_variable * variable, 2771c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_class * classes) 2781c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 2791c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int i; 2801c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int can_change_writemask= 1; 2811c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int writemask = rc_variable_writemask_sum(variable); 2821c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_list * readers = rc_variable_readers_union(variable); 2831c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák int class_index; 2841c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 2851c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (!variable->C->is_r500) { 2861c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_class c; 2876fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard struct rc_variable * var_ptr; 2881c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* The assumption here is that if an instruction has type 2891c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * RC_INSTRUCTION_NORMAL then it is a TEX instruction. 2901c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * r300 and r400 can't swizzle the result of a TEX lookup. */ 2916fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard for (var_ptr = variable; var_ptr; var_ptr = var_ptr->Friend) { 2926fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard if (var_ptr->Inst->Type == RC_INSTRUCTION_NORMAL) { 2936fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard writemask = RC_MASK_XYZW; 2946fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard } 2951c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 2961c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 2971c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* Check if it is possible to do swizzle packing for r300/r400 2981c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * without creating non-native swizzles. */ 2991c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák class_index = find_class(classes, writemask, 3); 3001c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (class_index < 0) { 3011c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák goto error; 3021c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 3031c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák c = classes[class_index]; 3046fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard if (c.WritemaskCount == 1) { 3056fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard goto done; 3066fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard } 3071c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for (i = 0; i < c.WritemaskCount; i++) { 3086fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard struct rc_variable * var_ptr; 3096fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard for (var_ptr = variable; var_ptr; 3106fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard var_ptr = var_ptr->Friend) { 3116fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard int j; 3126fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard unsigned int conversion_swizzle = 3131c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_make_conversion_swizzle( 3141c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák writemask, c.Writemasks[i]); 3156fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard struct variable_get_class_cb_data d; 3166fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard d.can_change_writemask = &can_change_writemask; 3176fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard d.conversion_swizzle = conversion_swizzle; 3186fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard /* If we get this far var_ptr->Inst has to 3196fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard * be a pair instruction. If variable or any 3206fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard * of its friends are normal instructions, 3216fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard * then the writemask will be set to RC_MASK_XYZW 3226fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard * and the function will return before it gets 3236fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard * here. */ 3246fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard rc_pair_for_all_reads_arg(var_ptr->Inst, 3256fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard variable_get_class_read_cb, &d); 3266fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard 3276fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard for (j = 0; j < var_ptr->ReaderCount; j++) { 3286fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard unsigned int old_swizzle; 3296fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard unsigned int new_swizzle; 3306fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard struct rc_reader r = var_ptr->Readers[j]; 3316fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard if (r.Inst->Type == 3326fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard RC_INSTRUCTION_PAIR ) { 3336fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard old_swizzle = r.U.P.Arg->Swizzle; 3346fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard } else { 3356fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard old_swizzle = r.U.I.Src->Swizzle; 3366fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard } 3376fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard new_swizzle = rc_adjust_channels( 3386fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard old_swizzle, conversion_swizzle); 3396fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard if (!r300_swizzle_is_native_basic( 3406fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard new_swizzle)) { 3416fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard can_change_writemask = 0; 3426fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard break; 3436fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard } 3441c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 3456fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard if (!can_change_writemask) { 3461c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák break; 3471c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 3481c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 3491c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (!can_change_writemask) { 3501c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák break; 3511c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 3521c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 3531c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 3541c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 3551c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (variable->Inst->Type == RC_INSTRUCTION_PAIR) { 3561c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* DDX/DDY seem to always fail when their writemasks are 3571c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * changed.*/ 3581c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (is_derivative(variable->Inst->U.P.RGB.Opcode) 3591c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák || is_derivative(variable->Inst->U.P.Alpha.Opcode)) { 3601c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák can_change_writemask = 0; 3611c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 3621c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 3631c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for ( ; readers; readers = readers->Next) { 3641c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_reader * r = readers->Item; 3651c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (r->Inst->Type == RC_INSTRUCTION_PAIR) { 3661c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (r->U.P.Arg->Source == RC_PAIR_PRESUB_SRC) { 3671c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák can_change_writemask = 0; 3681c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák break; 3691c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 3701c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* DDX/DDY also fail when their swizzles are changed. */ 3711c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (is_derivative(r->Inst->U.P.RGB.Opcode) 3721c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák || is_derivative(r->Inst->U.P.Alpha.Opcode)) { 3731c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák can_change_writemask = 0; 3741c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák break; 3751c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 3761c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 3771c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 3781c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 3791c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák class_index = find_class(classes, writemask, 3801c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák can_change_writemask ? 3 : 1); 3816fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellarddone: 3821c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (class_index > -1) { 3831c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return classes[class_index].Class; 3841c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } else { 3851c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákerror: 3861c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_error(variable->C, 3871c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák "Could not find class for index=%u mask=%u\n", 3881c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák variable->Dst.Index, writemask); 3891c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return 0; 3901c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 3911c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 3921c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 3931c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic unsigned int overlap_live_intervals_array( 3941c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct live_intervals * a, 3951c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct live_intervals * b) 3961c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 3971c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int a_chan, b_chan; 3981c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for (a_chan = 0; a_chan < 4; a_chan++) { 3991c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for (b_chan = 0; b_chan < 4; b_chan++) { 4001c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (overlap_live_intervals(&a[a_chan], &b[b_chan])) { 4011c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return 1; 4021c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 4031c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 4041c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 4051c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return 0; 4061c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 4071c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4081c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic unsigned int reg_get_index(int reg) 4091c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 4101c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return reg / RC_MASK_XYZW; 4111c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 4121c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4131c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic unsigned int reg_get_writemask(int reg) 4141c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 4151c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return (reg % RC_MASK_XYZW) + 1; 4161c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 4171c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4181c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic int get_reg_id(unsigned int index, unsigned int writemask) 4191c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 4201c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák assert(writemask); 4211c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (writemask == 0) { 4221c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return 0; 4231c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 4241c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return (index * RC_MASK_XYZW) + (writemask - 1); 4251c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 4261c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4271c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#if VERBOSE 4281c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void print_reg(int reg) 4291c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 4301c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int index = reg_get_index(reg); 4311c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int mask = reg_get_writemask(reg); 4321c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák fprintf(stderr, "Temp[%u].%c%c%c%c", index, 4331c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák mask & RC_MASK_X ? 'x' : '_', 4341c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák mask & RC_MASK_Y ? 'y' : '_', 4351c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák mask & RC_MASK_Z ? 'z' : '_', 4361c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák mask & RC_MASK_W ? 'w' : '_'); 4371c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 4381c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#endif 4391c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4401c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void add_register_conflicts( 4411c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct ra_regs * regs, 4421c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int max_temp_regs) 4431c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 4441c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int index, a_mask, b_mask; 4451c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for (index = 0; index < max_temp_regs; index++) { 4461c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for(a_mask = 1; a_mask <= RC_MASK_XYZW; a_mask++) { 4471c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for (b_mask = a_mask + 1; b_mask <= RC_MASK_XYZW; 4481c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák b_mask++) { 4491c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (a_mask & b_mask) { 4501c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák ra_add_reg_conflict(regs, 4511c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák get_reg_id(index, a_mask), 4521c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák get_reg_id(index, b_mask)); 4531c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 4541c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 4551c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 4561c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 4571c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 4581c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4591c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void do_advanced_regalloc(struct regalloc_state * s) 4601c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 4611c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_class rc_class_list [] = { 4621c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák {RC_REG_CLASS_SINGLE, 3, 0, 0, 4631c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák {RC_MASK_X, 4641c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_MASK_Y, 4651c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_MASK_Z}}, 4661c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák {RC_REG_CLASS_DOUBLE, 3, 0, 0, 4671c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák {RC_MASK_X | RC_MASK_Y, 4681c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_MASK_X | RC_MASK_Z, 4691c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_MASK_Y | RC_MASK_Z}}, 4701c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák {RC_REG_CLASS_TRIPLE, 1, 0, 0, 4711c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák {RC_MASK_X | RC_MASK_Y | RC_MASK_Z, 4721c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_MASK_NONE, 4731c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_MASK_NONE}}, 4741c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák {RC_REG_CLASS_ALPHA, 1, 0, 0, 4751c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák {RC_MASK_W, 4761c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_MASK_NONE, 4771c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_MASK_NONE}}, 4781c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák {RC_REG_CLASS_SINGLE_PLUS_ALPHA, 3, 0, 0, 4791c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák {RC_MASK_X | RC_MASK_W, 4801c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_MASK_Y | RC_MASK_W, 4811c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_MASK_Z | RC_MASK_W}}, 4821c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák {RC_REG_CLASS_DOUBLE_PLUS_ALPHA, 3, 0, 0, 4831c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák {RC_MASK_X | RC_MASK_Y | RC_MASK_W, 4841c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_MASK_X | RC_MASK_Z | RC_MASK_W, 4851c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_MASK_Y | RC_MASK_Z | RC_MASK_W}}, 4861c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák {RC_REG_CLASS_TRIPLE_PLUS_ALPHA, 1, 0, 0, 4871c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák {RC_MASK_X | RC_MASK_Y | RC_MASK_Z | RC_MASK_W, 4881c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_MASK_NONE, 4891c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_MASK_NONE}}, 4901c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák {RC_REG_CLASS_X, 1, 0, 0, 4911c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák {RC_MASK_X, 4921c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_MASK_NONE, 4931c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_MASK_NONE}}, 4941c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák {RC_REG_CLASS_Y, 1, 0, 0, 4951c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák {RC_MASK_Y, 4961c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_MASK_NONE, 4971c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_MASK_NONE}}, 4981c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák {RC_REG_CLASS_Z, 1, 0, 0, 4991c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák {RC_MASK_Z, 5001c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_MASK_NONE, 5011c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_MASK_NONE}}, 5021c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák {RC_REG_CLASS_XY, 1, 0, 0, 5031c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák {RC_MASK_X | RC_MASK_Y, 5041c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_MASK_NONE, 5051c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_MASK_NONE}}, 5061c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák {RC_REG_CLASS_YZ, 1, 0, 0, 5071c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák {RC_MASK_Y | RC_MASK_Z, 5081c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_MASK_NONE, 5091c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_MASK_NONE}}, 5101c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák {RC_REG_CLASS_XZ, 1, 0, 0, 5111c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák {RC_MASK_X | RC_MASK_Z, 5121c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_MASK_NONE, 5131c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_MASK_NONE}}, 5141c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák {RC_REG_CLASS_XW, 1, 0, 0, 5151c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák {RC_MASK_X | RC_MASK_W, 5161c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_MASK_NONE, 5171c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_MASK_NONE}}, 5181c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák {RC_REG_CLASS_YW, 1, 0, 0, 5191c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák {RC_MASK_Y | RC_MASK_W, 5201c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_MASK_NONE, 5211c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_MASK_NONE}}, 5221c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák {RC_REG_CLASS_ZW, 1, 0, 0, 5231c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák {RC_MASK_Z | RC_MASK_W, 5241c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_MASK_NONE, 5251c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_MASK_NONE}}, 5261c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák {RC_REG_CLASS_XYW, 1, 0, 0, 5271c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák {RC_MASK_X | RC_MASK_Y | RC_MASK_W, 5281c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_MASK_NONE, 5291c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_MASK_NONE}}, 5301c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák {RC_REG_CLASS_YZW, 1, 0, 0, 5311c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák {RC_MASK_Y | RC_MASK_Z | RC_MASK_W, 5321c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_MASK_NONE, 5331c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_MASK_NONE}}, 5341c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák {RC_REG_CLASS_XZW, 1, 0, 0, 5351c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák {RC_MASK_X | RC_MASK_Z | RC_MASK_W, 5361c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_MASK_NONE, 5371c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_MASK_NONE}} 5381c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák }; 5391c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5401c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int i, j, index, input_node, node_count, node_index; 5411c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int * node_classes; 5421c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int * input_classes; 5431c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction * inst; 5441c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_list * var_ptr; 5451c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_list * variables; 5461c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct ra_regs * regs; 5471c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct ra_graph * graph; 5481c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5491c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* Allocate the main ra data structure */ 550b972744c78e45928876ea781b9eeef09b3baf083Eric Anholt regs = ra_alloc_reg_set(NULL, s->C->max_temp_regs * RC_MASK_XYZW); 5511c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5521c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* Get list of program variables */ 5531c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák variables = rc_get_variables(s->C); 5541c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák node_count = rc_list_count(variables); 5551c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák node_classes = memory_pool_malloc(&s->C->Pool, 5561c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák node_count * sizeof(unsigned int)); 5571c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák input_classes = memory_pool_malloc(&s->C->Pool, 5581c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák s->NumInputs * sizeof(unsigned int)); 5591c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5601c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for (var_ptr = variables, node_index = 0; var_ptr; 5611c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák var_ptr = var_ptr->Next, node_index++) { 5621c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int class_index; 5631c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* Compute the live intervals */ 5641c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_variable_compute_live_intervals(var_ptr->Item); 5651c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5661c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák class_index = variable_get_class(var_ptr->Item, rc_class_list); 5671c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5681c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* If we haven't used this register class yet, mark it 5691c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * as used and allocate space for it. */ 5701c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (!rc_class_list[class_index].Used) { 5711c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_class_list[class_index].Used = 1; 5721c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_class_list[class_index].Id = ra_alloc_reg_class(regs); 5731c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 5741c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5751c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák node_classes[node_index] = rc_class_list[class_index].Id; 5761c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 5771c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5781c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5791c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* Assign registers to the classes */ 5801c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for (i = 0; i < RC_REG_CLASS_COUNT; i++) { 5811c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_class class = rc_class_list[i]; 5821c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (!class.Used) { 5831c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák continue; 5841c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 5851c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5861c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for (index = 0; index < s->C->max_temp_regs; index++) { 5871c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for (j = 0; j < class.WritemaskCount; j++) { 5881c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák int reg_id = get_reg_id(index, 5891c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák class.Writemasks[j]); 5901c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák ra_class_add_reg(regs, class.Id, reg_id); 5911c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 5921c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 5931c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 5941c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5951c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* Add register conflicts */ 5961c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák add_register_conflicts(regs, s->C->max_temp_regs); 5971c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5981c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* Calculate live intervals for input registers */ 5991c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for (inst = s->C->Program.Instructions.Next; 6001c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst != &s->C->Program.Instructions; 6011c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst = inst->Next) { 6021c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_opcode op = rc_get_flow_control_inst(inst); 6031c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (op == RC_OPCODE_BGNLOOP) { 6041c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction * endloop = 6051c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_match_bgnloop(inst); 6061c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (endloop->IP > s->LoopEnd) { 6071c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák s->LoopEnd = endloop->IP; 6081c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 6091c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 6101c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_for_all_reads_mask(inst, scan_read_callback, s); 6111c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 6121c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 6131c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* Create classes for input registers */ 6141c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for (i = 0; i < s->NumInputs; i++) { 6151c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int chan, class_id, writemask = 0; 6161c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for (chan = 0; chan < 4; chan++) { 6171c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (s->Input[i].Live[chan].Used) { 6181c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák writemask |= (1 << chan); 6191c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 6201c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 6211c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák s->Input[i].Writemask = writemask; 6221c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (!writemask) { 6231c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák continue; 6241c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 6251c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 6261c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák class_id = ra_alloc_reg_class(regs); 6271c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák input_classes[i] = class_id; 6281c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák ra_class_add_reg(regs, class_id, 6291c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák get_reg_id(s->Input[i].Index, writemask)); 6301c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 6311c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 6321c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák ra_set_finalize(regs); 6331c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 6341c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák graph = ra_alloc_interference_graph(regs, node_count + s->NumInputs); 6351c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 6361c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* Build the interference graph */ 6371c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for (var_ptr = variables, node_index = 0; var_ptr; 6381c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák var_ptr = var_ptr->Next,node_index++) { 6391c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_list * a, * b; 6401c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int b_index; 6411c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 6421c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák ra_set_node_class(graph, node_index, node_classes[node_index]); 6431c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 6441c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for (a = var_ptr, b = var_ptr->Next, b_index = node_index + 1; 6451c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák b; b = b->Next, b_index++) { 6461c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_variable * var_a = a->Item; 6471c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák while (var_a) { 6481c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_variable * var_b = b->Item; 6491c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák while (var_b) { 6501c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (overlap_live_intervals_array(var_a->Live, var_b->Live)) { 6511c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák ra_add_node_interference(graph, 6521c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák node_index, b_index); 6531c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 6541c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák var_b = var_b->Friend; 6551c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 6561c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák var_a = var_a->Friend; 6571c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 6581c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 6591c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 6601c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 6611c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* Add input registers to the interference graph */ 6621c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for (i = 0, input_node = 0; i< s->NumInputs; i++) { 6631c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (!s->Input[i].Writemask) { 6641c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák continue; 6651c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 6661c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák ra_set_node_class(graph, node_count + input_node, 6671c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák input_classes[i]); 6681c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for (var_ptr = variables, node_index = 0; 6691c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák var_ptr; var_ptr = var_ptr->Next, node_index++) { 6701c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_variable * var = var_ptr->Item; 6711c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (overlap_live_intervals_array(s->Input[i].Live, 6721c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák var->Live)) { 6731c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák ra_add_node_interference(graph, node_index, 6741c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák node_count + input_node); 6751c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 6761c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 6771c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* Manually allocate a register for this input */ 6781c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák ra_set_node_reg(graph, node_count + input_node, get_reg_id( 6791c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák s->Input[i].Index, s->Input[i].Writemask)); 6801c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák input_node++; 6811c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 6821c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 6831c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (!ra_allocate_no_spills(graph)) { 6841c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_error(s->C, "Ran out of hardware temporaries\n"); 6851c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return; 6861c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 6871c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 6881c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* Rewrite the registers */ 6891c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for (var_ptr = variables, node_index = 0; var_ptr; 6901c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák var_ptr = var_ptr->Next, node_index++) { 6911c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák int reg = ra_get_node_reg(graph, node_index); 6921c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int writemask = reg_get_writemask(reg); 6931c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int index = reg_get_index(reg); 6941c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_variable * var = var_ptr->Item; 6951c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 6961c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (!s->C->is_r500 && var->Inst->Type == RC_INSTRUCTION_NORMAL) { 6971c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák writemask = rc_variable_writemask_sum(var); 6981c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 6991c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 7001c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (var->Dst.File == RC_FILE_INPUT) { 7011c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák continue; 7021c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 7031c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_variable_change_dst(var, index, writemask); 7041c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 7051c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 7061c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák ralloc_free(graph); 7071c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák ralloc_free(regs); 7081c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 7091c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 7101c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák/** 7111c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * @param user This parameter should be a pointer to an integer value. If this 7121c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * integer value is zero, then a simple register allocator will be used that 7131c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * only allocates space for input registers (\sa do_regalloc_inputs_only). If 7141c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * user is non-zero, then the regular register allocator will be used 7151c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * (\sa do_regalloc). 7161c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */ 7171c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákvoid rc_pair_regalloc(struct radeon_compiler *cc, void *user) 7181c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 7191c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct r300_fragment_program_compiler *c = 7201c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák (struct r300_fragment_program_compiler*)cc; 7211c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct regalloc_state s; 7221c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák int * do_full_regalloc = (int*)user; 7231c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 7241c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák memset(&s, 0, sizeof(s)); 7251c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák s.C = cc; 7261c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák s.NumInputs = rc_get_max_index(cc, RC_FILE_INPUT) + 1; 7271c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák s.Input = memory_pool_malloc(&cc->Pool, 7281c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák s.NumInputs * sizeof(struct register_info)); 7291c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák memset(s.Input, 0, s.NumInputs * sizeof(struct register_info)); 7301c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 7311c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák s.NumTemporaries = rc_get_max_index(cc, RC_FILE_TEMPORARY) + 1; 7321c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák s.Temporary = memory_pool_malloc(&cc->Pool, 7331c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák s.NumTemporaries * sizeof(struct register_info)); 7341c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák memset(s.Temporary, 0, s.NumTemporaries * sizeof(struct register_info)); 7351c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 7361c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_recompute_ips(s.C); 7371c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 7381c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák c->AllocateHwInputs(c, &alloc_input_simple, &s); 7391c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (*do_full_regalloc) { 7401c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák do_advanced_regalloc(&s); 7411c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } else { 7421c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák s.Simple = 1; 7431c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák do_regalloc_inputs_only(&s); 7441c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 7451c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 7461c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* Rewrite inputs and if we are doing the simple allocation, rewrite 7471c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * temporaries too. */ 7481c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for (struct rc_instruction *inst = s.C->Program.Instructions.Next; 7491c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst != &s.C->Program.Instructions; 7501c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst = inst->Next) { 7511c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_remap_registers(inst, &remap_register, &s); 7521c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 7531c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 754