1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* 2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright (C) 2009 Nicolai Haehnle. 3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2011 Tom Stellard <tstellar@gmail.com> 4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * All Rights Reserved. 6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining 8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * a copy of this software and associated documentation files (the 9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Software"), to deal in the Software without restriction, including 10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * without limitation the rights to use, copy, modify, merge, publish, 11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * distribute, sublicense, and/or sell copies of the Software, and to 12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * permit persons to whom the Software is furnished to do so, subject to 13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the following conditions: 14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the 16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * next paragraph) shall be included in all copies or substantial 17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * portions of the Software. 18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE 23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "radeon_program_pair.h" 30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <stdio.h> 32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/glheader.h" 34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "program/register_allocate.h" 35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "ralloc.h" 36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "r300_fragprog_swizzle.h" 38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "radeon_compiler.h" 39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "radeon_compiler_util.h" 40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "radeon_dataflow.h" 41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "radeon_list.h" 42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "radeon_variable.h" 43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define VERBOSE 0 45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define DBG(...) do { if (VERBOSE) fprintf(stderr, __VA_ARGS__); } while(0) 47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct register_info { 51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct live_intervals Live[4]; 52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int Used:1; 54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int Allocated:1; 55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int File:3; 56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int Index:RC_REGISTER_INDEX_BITS; 57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int Writemask; 58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct regalloc_state { 61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct radeon_compiler * C; 62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct register_info * Input; 64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int NumInputs; 65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct register_info * Temporary; 67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int NumTemporaries; 68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int Simple; 70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int LoopEnd; 71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgenum rc_reg_class { 74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_REG_CLASS_SINGLE, 75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_REG_CLASS_DOUBLE, 76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_REG_CLASS_TRIPLE, 77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_REG_CLASS_ALPHA, 78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_REG_CLASS_SINGLE_PLUS_ALPHA, 79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_REG_CLASS_DOUBLE_PLUS_ALPHA, 80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_REG_CLASS_TRIPLE_PLUS_ALPHA, 81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_REG_CLASS_X, 82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_REG_CLASS_Y, 83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_REG_CLASS_Z, 84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_REG_CLASS_XY, 85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_REG_CLASS_YZ, 86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_REG_CLASS_XZ, 87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_REG_CLASS_XW, 88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_REG_CLASS_YW, 89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_REG_CLASS_ZW, 90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_REG_CLASS_XYW, 91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_REG_CLASS_YZW, 92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_REG_CLASS_XZW, 93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_REG_CLASS_COUNT 94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct rc_class { 97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org enum rc_reg_class Class; 98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int WritemaskCount; 100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /** This is 1 if this class is being used by the register allocator 102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and 0 otherwise */ 103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int Used; 104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /** This is the ID number assigned to this class by ra. */ 106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int Id; 107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /** List of writemasks that belong to this class */ 109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int Writemasks[3]; 110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void print_live_intervals(struct live_intervals * src) 115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!src || !src->Used) { 117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DBG("(null)"); 118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DBG("(%i,%i)", src->Start, src->End); 122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic int overlap_live_intervals(struct live_intervals * a, struct live_intervals * b) 125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (VERBOSE) { 127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DBG("overlap_live_intervals: "); 128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org print_live_intervals(a); 129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DBG(" to "); 130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org print_live_intervals(b); 131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DBG("\n"); 132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!a->Used || !b->Used) { 135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DBG(" unused interval\n"); 136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (a->Start > b->Start) { 140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (a->Start < b->End) { 141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DBG(" overlap\n"); 142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 1; 143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (b->Start > a->Start) { 145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (b->Start < a->End) { 146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DBG(" overlap\n"); 147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 1; 148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { /* a->Start == b->Start */ 150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (a->Start != a->End && b->Start != b->End) { 151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DBG(" overlap\n"); 152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 1; 153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DBG(" no overlap\n"); 157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void scan_read_callback(void * data, struct rc_instruction * inst, 162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_register_file file, unsigned int index, unsigned int mask) 163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct regalloc_state * s = data; 165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct register_info * reg; 166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int i; 167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (file != RC_FILE_INPUT) 169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s->Input[index].Used = 1; 172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org reg = &s->Input[index]; 173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < 4; i++) { 175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!((mask >> i) & 0x1)) { 176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org reg->Live[i].Used = 1; 179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org reg->Live[i].Start = 0; 180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org reg->Live[i].End = 181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s->LoopEnd > inst->IP ? s->LoopEnd : inst->IP; 182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void remap_register(void * data, struct rc_instruction * inst, 186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_register_file * file, unsigned int * index) 187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct regalloc_state * s = data; 189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct register_info * reg; 190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (*file == RC_FILE_TEMPORARY && s->Simple) 192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org reg = &s->Temporary[*index]; 193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (*file == RC_FILE_INPUT) 194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org reg = &s->Input[*index]; 195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (reg->Allocated) { 199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *index = reg->Index; 200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void alloc_input_simple(void * data, unsigned int input, 204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int hwreg) 205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct regalloc_state * s = data; 207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (input >= s->NumInputs) 209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s->Input[input].Allocated = 1; 212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s->Input[input].File = RC_FILE_TEMPORARY; 213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s->Input[input].Index = hwreg; 214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* This functions offsets the temporary register indices by the number 217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of input registers, because input registers are actually temporaries and 218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * should not occupy the same space. 219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This pass is supposed to be used to maintain correct allocation of inputs 221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * if the standard register allocation is disabled. */ 222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void do_regalloc_inputs_only(struct regalloc_state * s) 223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (unsigned i = 0; i < s->NumTemporaries; i++) { 225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s->Temporary[i].Allocated = 1; 226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s->Temporary[i].File = RC_FILE_TEMPORARY; 227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s->Temporary[i].Index = i + s->NumInputs; 228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic unsigned int is_derivative(rc_opcode op) 232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (op == RC_OPCODE_DDX || op == RC_OPCODE_DDY); 234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic int find_class( 237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_class * classes, 238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int writemask, 239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int max_writemask_count) 240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int i; 242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < RC_REG_CLASS_COUNT; i++) { 243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int j; 244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (classes[i].WritemaskCount > max_writemask_count) { 245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (j = 0; j < 3; j++) { 248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (classes[i].Writemasks[j] == writemask) { 249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return i; 250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return -1; 254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct variable_get_class_cb_data { 257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int * can_change_writemask; 258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int conversion_swizzle; 259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void variable_get_class_read_cb( 262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void * userdata, 263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_instruction * inst, 264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_pair_instruction_arg * arg, 265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_pair_instruction_source * src) 266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct variable_get_class_cb_data * d = userdata; 268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int new_swizzle = rc_adjust_channels(arg->Swizzle, 269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org d->conversion_swizzle); 270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!r300_swizzle_is_native_basic(new_swizzle)) { 271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *d->can_change_writemask = 0; 272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic enum rc_reg_class variable_get_class( 276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_variable * variable, 277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_class * classes) 278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int i; 280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int can_change_writemask= 1; 281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int writemask = rc_variable_writemask_sum(variable); 282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_list * readers = rc_variable_readers_union(variable); 283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int class_index; 284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!variable->C->is_r500) { 286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_class c; 287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_variable * var_ptr; 288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* The assumption here is that if an instruction has type 289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * RC_INSTRUCTION_NORMAL then it is a TEX instruction. 290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * r300 and r400 can't swizzle the result of a TEX lookup. */ 291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (var_ptr = variable; var_ptr; var_ptr = var_ptr->Friend) { 292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (var_ptr->Inst->Type == RC_INSTRUCTION_NORMAL) { 293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org writemask = RC_MASK_XYZW; 294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Check if it is possible to do swizzle packing for r300/r400 298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * without creating non-native swizzles. */ 299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org class_index = find_class(classes, writemask, 3); 300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (class_index < 0) { 301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org goto error; 302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org c = classes[class_index]; 304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (c.WritemaskCount == 1) { 305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org goto done; 306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < c.WritemaskCount; i++) { 308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_variable * var_ptr; 309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (var_ptr = variable; var_ptr; 310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var_ptr = var_ptr->Friend) { 311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int j; 312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int conversion_swizzle = 313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_make_conversion_swizzle( 314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org writemask, c.Writemasks[i]); 315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct variable_get_class_cb_data d; 316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org d.can_change_writemask = &can_change_writemask; 317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org d.conversion_swizzle = conversion_swizzle; 318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* If we get this far var_ptr->Inst has to 319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * be a pair instruction. If variable or any 320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of its friends are normal instructions, 321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * then the writemask will be set to RC_MASK_XYZW 322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and the function will return before it gets 323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * here. */ 324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_pair_for_all_reads_arg(var_ptr->Inst, 325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org variable_get_class_read_cb, &d); 326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (j = 0; j < var_ptr->ReaderCount; j++) { 328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int old_swizzle; 329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int new_swizzle; 330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_reader r = var_ptr->Readers[j]; 331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (r.Inst->Type == 332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_INSTRUCTION_PAIR ) { 333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org old_swizzle = r.U.P.Arg->Swizzle; 334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org old_swizzle = r.U.I.Src->Swizzle; 336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new_swizzle = rc_adjust_channels( 338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org old_swizzle, conversion_swizzle); 339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!r300_swizzle_is_native_basic( 340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new_swizzle)) { 341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org can_change_writemask = 0; 342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!can_change_writemask) { 346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!can_change_writemask) { 350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (variable->Inst->Type == RC_INSTRUCTION_PAIR) { 356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* DDX/DDY seem to always fail when their writemasks are 357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * changed.*/ 358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (is_derivative(variable->Inst->U.P.RGB.Opcode) 359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org || is_derivative(variable->Inst->U.P.Alpha.Opcode)) { 360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org can_change_writemask = 0; 361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for ( ; readers; readers = readers->Next) { 364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_reader * r = readers->Item; 365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (r->Inst->Type == RC_INSTRUCTION_PAIR) { 366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (r->U.P.Arg->Source == RC_PAIR_PRESUB_SRC) { 367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org can_change_writemask = 0; 368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* DDX/DDY also fail when their swizzles are changed. */ 371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (is_derivative(r->Inst->U.P.RGB.Opcode) 372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org || is_derivative(r->Inst->U.P.Alpha.Opcode)) { 373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org can_change_writemask = 0; 374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org class_index = find_class(classes, writemask, 380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org can_change_writemask ? 3 : 1); 381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdone: 382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (class_index > -1) { 383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return classes[class_index].Class; 384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgerror: 386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_error(variable->C, 387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "Could not find class for index=%u mask=%u\n", 388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org variable->Dst.Index, writemask); 389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic unsigned int overlap_live_intervals_array( 394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct live_intervals * a, 395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct live_intervals * b) 396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int a_chan, b_chan; 398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (a_chan = 0; a_chan < 4; a_chan++) { 399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (b_chan = 0; b_chan < 4; b_chan++) { 400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (overlap_live_intervals(&a[a_chan], &b[b_chan])) { 401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 1; 402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic unsigned int reg_get_index(int reg) 409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return reg / RC_MASK_XYZW; 411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic unsigned int reg_get_writemask(int reg) 414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (reg % RC_MASK_XYZW) + 1; 416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic int get_reg_id(unsigned int index, unsigned int writemask) 419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(writemask); 421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (writemask == 0) { 422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (index * RC_MASK_XYZW) + (writemask - 1); 425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if VERBOSE 428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void print_reg(int reg) 429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int index = reg_get_index(reg); 431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int mask = reg_get_writemask(reg); 432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fprintf(stderr, "Temp[%u].%c%c%c%c", index, 433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mask & RC_MASK_X ? 'x' : '_', 434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mask & RC_MASK_Y ? 'y' : '_', 435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mask & RC_MASK_Z ? 'z' : '_', 436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mask & RC_MASK_W ? 'w' : '_'); 437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void add_register_conflicts( 441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct ra_regs * regs, 442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int max_temp_regs) 443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int index, a_mask, b_mask; 445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (index = 0; index < max_temp_regs; index++) { 446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(a_mask = 1; a_mask <= RC_MASK_XYZW; a_mask++) { 447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (b_mask = a_mask + 1; b_mask <= RC_MASK_XYZW; 448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org b_mask++) { 449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (a_mask & b_mask) { 450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ra_add_reg_conflict(regs, 451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org get_reg_id(index, a_mask), 452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org get_reg_id(index, b_mask)); 453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void do_advanced_regalloc(struct regalloc_state * s) 460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_class rc_class_list [] = { 462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {RC_REG_CLASS_SINGLE, 3, 0, 0, 463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {RC_MASK_X, 464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_MASK_Y, 465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_MASK_Z}}, 466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {RC_REG_CLASS_DOUBLE, 3, 0, 0, 467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {RC_MASK_X | RC_MASK_Y, 468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_MASK_X | RC_MASK_Z, 469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_MASK_Y | RC_MASK_Z}}, 470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {RC_REG_CLASS_TRIPLE, 1, 0, 0, 471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {RC_MASK_X | RC_MASK_Y | RC_MASK_Z, 472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_MASK_NONE, 473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_MASK_NONE}}, 474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {RC_REG_CLASS_ALPHA, 1, 0, 0, 475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {RC_MASK_W, 476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_MASK_NONE, 477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_MASK_NONE}}, 478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {RC_REG_CLASS_SINGLE_PLUS_ALPHA, 3, 0, 0, 479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {RC_MASK_X | RC_MASK_W, 480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_MASK_Y | RC_MASK_W, 481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_MASK_Z | RC_MASK_W}}, 482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {RC_REG_CLASS_DOUBLE_PLUS_ALPHA, 3, 0, 0, 483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {RC_MASK_X | RC_MASK_Y | RC_MASK_W, 484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_MASK_X | RC_MASK_Z | RC_MASK_W, 485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_MASK_Y | RC_MASK_Z | RC_MASK_W}}, 486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {RC_REG_CLASS_TRIPLE_PLUS_ALPHA, 1, 0, 0, 487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {RC_MASK_X | RC_MASK_Y | RC_MASK_Z | RC_MASK_W, 488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_MASK_NONE, 489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_MASK_NONE}}, 490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {RC_REG_CLASS_X, 1, 0, 0, 491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {RC_MASK_X, 492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_MASK_NONE, 493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_MASK_NONE}}, 494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {RC_REG_CLASS_Y, 1, 0, 0, 495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {RC_MASK_Y, 496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_MASK_NONE, 497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_MASK_NONE}}, 498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {RC_REG_CLASS_Z, 1, 0, 0, 499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {RC_MASK_Z, 500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_MASK_NONE, 501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_MASK_NONE}}, 502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {RC_REG_CLASS_XY, 1, 0, 0, 503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {RC_MASK_X | RC_MASK_Y, 504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_MASK_NONE, 505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_MASK_NONE}}, 506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {RC_REG_CLASS_YZ, 1, 0, 0, 507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {RC_MASK_Y | RC_MASK_Z, 508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_MASK_NONE, 509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_MASK_NONE}}, 510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {RC_REG_CLASS_XZ, 1, 0, 0, 511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {RC_MASK_X | RC_MASK_Z, 512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_MASK_NONE, 513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_MASK_NONE}}, 514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {RC_REG_CLASS_XW, 1, 0, 0, 515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {RC_MASK_X | RC_MASK_W, 516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_MASK_NONE, 517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_MASK_NONE}}, 518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {RC_REG_CLASS_YW, 1, 0, 0, 519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {RC_MASK_Y | RC_MASK_W, 520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_MASK_NONE, 521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_MASK_NONE}}, 522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {RC_REG_CLASS_ZW, 1, 0, 0, 523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {RC_MASK_Z | RC_MASK_W, 524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_MASK_NONE, 525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_MASK_NONE}}, 526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {RC_REG_CLASS_XYW, 1, 0, 0, 527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {RC_MASK_X | RC_MASK_Y | RC_MASK_W, 528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_MASK_NONE, 529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_MASK_NONE}}, 530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {RC_REG_CLASS_YZW, 1, 0, 0, 531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {RC_MASK_Y | RC_MASK_Z | RC_MASK_W, 532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_MASK_NONE, 533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_MASK_NONE}}, 534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {RC_REG_CLASS_XZW, 1, 0, 0, 535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {RC_MASK_X | RC_MASK_Z | RC_MASK_W, 536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_MASK_NONE, 537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_MASK_NONE}} 538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org }; 539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int i, j, index, input_node, node_count, node_index; 541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int * node_classes; 542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int * input_classes; 543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_instruction * inst; 544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_list * var_ptr; 545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_list * variables; 546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct ra_regs * regs; 547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct ra_graph * graph; 548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Allocate the main ra data structure */ 550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org regs = ra_alloc_reg_set(NULL, s->C->max_temp_regs * RC_MASK_XYZW); 551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Get list of program variables */ 553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org variables = rc_get_variables(s->C); 554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org node_count = rc_list_count(variables); 555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org node_classes = memory_pool_malloc(&s->C->Pool, 556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org node_count * sizeof(unsigned int)); 557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org input_classes = memory_pool_malloc(&s->C->Pool, 558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s->NumInputs * sizeof(unsigned int)); 559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (var_ptr = variables, node_index = 0; var_ptr; 561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var_ptr = var_ptr->Next, node_index++) { 562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int class_index; 563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Compute the live intervals */ 564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_variable_compute_live_intervals(var_ptr->Item); 565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org class_index = variable_get_class(var_ptr->Item, rc_class_list); 567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* If we haven't used this register class yet, mark it 569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * as used and allocate space for it. */ 570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!rc_class_list[class_index].Used) { 571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_class_list[class_index].Used = 1; 572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_class_list[class_index].Id = ra_alloc_reg_class(regs); 573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org node_classes[node_index] = rc_class_list[class_index].Id; 576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Assign registers to the classes */ 580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < RC_REG_CLASS_COUNT; i++) { 581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_class class = rc_class_list[i]; 582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!class.Used) { 583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (index = 0; index < s->C->max_temp_regs; index++) { 587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (j = 0; j < class.WritemaskCount; j++) { 588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int reg_id = get_reg_id(index, 589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org class.Writemasks[j]); 590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ra_class_add_reg(regs, class.Id, reg_id); 591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Add register conflicts */ 596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org add_register_conflicts(regs, s->C->max_temp_regs); 597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Calculate live intervals for input registers */ 599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (inst = s->C->Program.Instructions.Next; 600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst != &s->C->Program.Instructions; 601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst = inst->Next) { 602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_opcode op = rc_get_flow_control_inst(inst); 603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (op == RC_OPCODE_BGNLOOP) { 604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_instruction * endloop = 605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_match_bgnloop(inst); 606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (endloop->IP > s->LoopEnd) { 607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s->LoopEnd = endloop->IP; 608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_for_all_reads_mask(inst, scan_read_callback, s); 611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Create classes for input registers */ 614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < s->NumInputs; i++) { 615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int chan, class_id, writemask = 0; 616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (chan = 0; chan < 4; chan++) { 617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (s->Input[i].Live[chan].Used) { 618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org writemask |= (1 << chan); 619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s->Input[i].Writemask = writemask; 622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!writemask) { 623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org class_id = ra_alloc_reg_class(regs); 627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org input_classes[i] = class_id; 628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ra_class_add_reg(regs, class_id, 629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org get_reg_id(s->Input[i].Index, writemask)); 630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ra_set_finalize(regs); 633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org graph = ra_alloc_interference_graph(regs, node_count + s->NumInputs); 635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Build the interference graph */ 637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (var_ptr = variables, node_index = 0; var_ptr; 638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var_ptr = var_ptr->Next,node_index++) { 639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_list * a, * b; 640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int b_index; 641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ra_set_node_class(graph, node_index, node_classes[node_index]); 643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (a = var_ptr, b = var_ptr->Next, b_index = node_index + 1; 645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org b; b = b->Next, b_index++) { 646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_variable * var_a = a->Item; 647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while (var_a) { 648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_variable * var_b = b->Item; 649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while (var_b) { 650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (overlap_live_intervals_array(var_a->Live, var_b->Live)) { 651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ra_add_node_interference(graph, 652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org node_index, b_index); 653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var_b = var_b->Friend; 655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var_a = var_a->Friend; 657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Add input registers to the interference graph */ 662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0, input_node = 0; i< s->NumInputs; i++) { 663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!s->Input[i].Writemask) { 664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ra_set_node_class(graph, node_count + input_node, 667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org input_classes[i]); 668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (var_ptr = variables, node_index = 0; 669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var_ptr; var_ptr = var_ptr->Next, node_index++) { 670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_variable * var = var_ptr->Item; 671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (overlap_live_intervals_array(s->Input[i].Live, 672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->Live)) { 673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ra_add_node_interference(graph, node_index, 674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org node_count + input_node); 675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Manually allocate a register for this input */ 678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ra_set_node_reg(graph, node_count + input_node, get_reg_id( 679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s->Input[i].Index, s->Input[i].Writemask)); 680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org input_node++; 681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!ra_allocate_no_spills(graph)) { 684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_error(s->C, "Ran out of hardware temporaries\n"); 685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Rewrite the registers */ 689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (var_ptr = variables, node_index = 0; var_ptr; 690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var_ptr = var_ptr->Next, node_index++) { 691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int reg = ra_get_node_reg(graph, node_index); 692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int writemask = reg_get_writemask(reg); 693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int index = reg_get_index(reg); 694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_variable * var = var_ptr->Item; 695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!s->C->is_r500 && var->Inst->Type == RC_INSTRUCTION_NORMAL) { 697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org writemask = rc_variable_writemask_sum(var); 698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (var->Dst.File == RC_FILE_INPUT) { 701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_variable_change_dst(var, index, writemask); 704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ralloc_free(graph); 707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ralloc_free(regs); 708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @param user This parameter should be a pointer to an integer value. If this 712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * integer value is zero, then a simple register allocator will be used that 713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * only allocates space for input registers (\sa do_regalloc_inputs_only). If 714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * user is non-zero, then the regular register allocator will be used 715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * (\sa do_regalloc). 716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid rc_pair_regalloc(struct radeon_compiler *cc, void *user) 718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct r300_fragment_program_compiler *c = 720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (struct r300_fragment_program_compiler*)cc; 721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct regalloc_state s; 722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int * do_full_regalloc = (int*)user; 723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(&s, 0, sizeof(s)); 725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s.C = cc; 726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s.NumInputs = rc_get_max_index(cc, RC_FILE_INPUT) + 1; 727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s.Input = memory_pool_malloc(&cc->Pool, 728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s.NumInputs * sizeof(struct register_info)); 729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(s.Input, 0, s.NumInputs * sizeof(struct register_info)); 730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s.NumTemporaries = rc_get_max_index(cc, RC_FILE_TEMPORARY) + 1; 732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s.Temporary = memory_pool_malloc(&cc->Pool, 733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s.NumTemporaries * sizeof(struct register_info)); 734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(s.Temporary, 0, s.NumTemporaries * sizeof(struct register_info)); 735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_recompute_ips(s.C); 737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org c->AllocateHwInputs(c, &alloc_input_simple, &s); 739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (*do_full_regalloc) { 740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org do_advanced_regalloc(&s); 741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s.Simple = 1; 743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org do_regalloc_inputs_only(&s); 744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Rewrite inputs and if we are doing the simple allocation, rewrite 747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * temporaries too. */ 748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (struct rc_instruction *inst = s.C->Program.Instructions.Next; 749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst != &s.C->Program.Instructions; 750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst = inst->Next) { 751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_remap_registers(inst, &remap_register, &s); 752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 754