1*61046927SAndroid Build Coastguard Worker /* 2*61046927SAndroid Build Coastguard Worker * Copyright © 2010 Intel Corporation 3*61046927SAndroid Build Coastguard Worker * 4*61046927SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a 5*61046927SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the "Software"), 6*61046927SAndroid Build Coastguard Worker * to deal in the Software without restriction, including without limitation 7*61046927SAndroid Build Coastguard Worker * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8*61046927SAndroid Build Coastguard Worker * and/or sell copies of the Software, and to permit persons to whom the 9*61046927SAndroid Build Coastguard Worker * Software is furnished to do so, subject to the following conditions: 10*61046927SAndroid Build Coastguard Worker * 11*61046927SAndroid Build Coastguard Worker * The above copyright notice and this permission notice (including the next 12*61046927SAndroid Build Coastguard Worker * paragraph) shall be included in all copies or substantial portions of the 13*61046927SAndroid Build Coastguard Worker * Software. 14*61046927SAndroid Build Coastguard Worker * 15*61046927SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16*61046927SAndroid Build Coastguard Worker * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17*61046927SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18*61046927SAndroid Build Coastguard Worker * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19*61046927SAndroid Build Coastguard Worker * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20*61046927SAndroid Build Coastguard Worker * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21*61046927SAndroid Build Coastguard Worker * IN THE SOFTWARE. 22*61046927SAndroid Build Coastguard Worker * 23*61046927SAndroid Build Coastguard Worker * Authors: 24*61046927SAndroid Build Coastguard Worker * Eric Anholt <[email protected]> 25*61046927SAndroid Build Coastguard Worker * 26*61046927SAndroid Build Coastguard Worker */ 27*61046927SAndroid Build Coastguard Worker 28*61046927SAndroid Build Coastguard Worker #ifndef REGISTER_ALLOCATE_INTERNAL_H 29*61046927SAndroid Build Coastguard Worker #define REGISTER_ALLOCATE_INTERNAL_H 30*61046927SAndroid Build Coastguard Worker 31*61046927SAndroid Build Coastguard Worker #include <stdbool.h> 32*61046927SAndroid Build Coastguard Worker #include "util/bitset.h" 33*61046927SAndroid Build Coastguard Worker #include "util/u_dynarray.h" 34*61046927SAndroid Build Coastguard Worker 35*61046927SAndroid Build Coastguard Worker #ifdef __cplusplus 36*61046927SAndroid Build Coastguard Worker extern "C" { 37*61046927SAndroid Build Coastguard Worker 38*61046927SAndroid Build Coastguard Worker #define class klass 39*61046927SAndroid Build Coastguard Worker #endif 40*61046927SAndroid Build Coastguard Worker 41*61046927SAndroid Build Coastguard Worker struct ra_reg { 42*61046927SAndroid Build Coastguard Worker BITSET_WORD *conflicts; 43*61046927SAndroid Build Coastguard Worker struct util_dynarray conflict_list; 44*61046927SAndroid Build Coastguard Worker }; 45*61046927SAndroid Build Coastguard Worker 46*61046927SAndroid Build Coastguard Worker struct ra_regs { 47*61046927SAndroid Build Coastguard Worker struct ra_reg *regs; 48*61046927SAndroid Build Coastguard Worker unsigned int count; 49*61046927SAndroid Build Coastguard Worker 50*61046927SAndroid Build Coastguard Worker struct ra_class **classes; 51*61046927SAndroid Build Coastguard Worker unsigned int class_count; 52*61046927SAndroid Build Coastguard Worker 53*61046927SAndroid Build Coastguard Worker bool round_robin; 54*61046927SAndroid Build Coastguard Worker }; 55*61046927SAndroid Build Coastguard Worker 56*61046927SAndroid Build Coastguard Worker struct ra_class { 57*61046927SAndroid Build Coastguard Worker struct ra_regs *regset; 58*61046927SAndroid Build Coastguard Worker 59*61046927SAndroid Build Coastguard Worker /** 60*61046927SAndroid Build Coastguard Worker * Bitset indicating which registers belong to this class. 61*61046927SAndroid Build Coastguard Worker * 62*61046927SAndroid Build Coastguard Worker * (If bit N is set, then register N belongs to this class.) 63*61046927SAndroid Build Coastguard Worker */ 64*61046927SAndroid Build Coastguard Worker BITSET_WORD *regs; 65*61046927SAndroid Build Coastguard Worker 66*61046927SAndroid Build Coastguard Worker /** 67*61046927SAndroid Build Coastguard Worker * Number of regs after each bit in *regs that are also conflicted by an 68*61046927SAndroid Build Coastguard Worker * allocation to that reg for this class. 69*61046927SAndroid Build Coastguard Worker */ 70*61046927SAndroid Build Coastguard Worker int contig_len; 71*61046927SAndroid Build Coastguard Worker 72*61046927SAndroid Build Coastguard Worker /** 73*61046927SAndroid Build Coastguard Worker * p(B) in Runeson/Nyström paper. 74*61046927SAndroid Build Coastguard Worker * 75*61046927SAndroid Build Coastguard Worker * This is "how many regs are in the set." 76*61046927SAndroid Build Coastguard Worker */ 77*61046927SAndroid Build Coastguard Worker unsigned int p; 78*61046927SAndroid Build Coastguard Worker 79*61046927SAndroid Build Coastguard Worker /** 80*61046927SAndroid Build Coastguard Worker * q(B,C) (indexed by C, B is this register class) in 81*61046927SAndroid Build Coastguard Worker * Runeson/Nyström paper. This is "how many registers of B could 82*61046927SAndroid Build Coastguard Worker * the worst choice register from C conflict with". 83*61046927SAndroid Build Coastguard Worker */ 84*61046927SAndroid Build Coastguard Worker unsigned int *q; 85*61046927SAndroid Build Coastguard Worker 86*61046927SAndroid Build Coastguard Worker int index; 87*61046927SAndroid Build Coastguard Worker }; 88*61046927SAndroid Build Coastguard Worker 89*61046927SAndroid Build Coastguard Worker struct ra_node { 90*61046927SAndroid Build Coastguard Worker /** @{ 91*61046927SAndroid Build Coastguard Worker * 92*61046927SAndroid Build Coastguard Worker * List of which nodes this node interferes with. This should be 93*61046927SAndroid Build Coastguard Worker * symmetric with the other node. 94*61046927SAndroid Build Coastguard Worker */ 95*61046927SAndroid Build Coastguard Worker struct util_dynarray adjacency_list; 96*61046927SAndroid Build Coastguard Worker /** @} */ 97*61046927SAndroid Build Coastguard Worker 98*61046927SAndroid Build Coastguard Worker unsigned int class; 99*61046927SAndroid Build Coastguard Worker 100*61046927SAndroid Build Coastguard Worker /* Client-assigned register, if assigned, or NO_REG. */ 101*61046927SAndroid Build Coastguard Worker unsigned int forced_reg; 102*61046927SAndroid Build Coastguard Worker 103*61046927SAndroid Build Coastguard Worker /* Register, if assigned, or NO_REG. */ 104*61046927SAndroid Build Coastguard Worker unsigned int reg; 105*61046927SAndroid Build Coastguard Worker 106*61046927SAndroid Build Coastguard Worker /** 107*61046927SAndroid Build Coastguard Worker * The q total, as defined in the Runeson/Nyström paper, for all the 108*61046927SAndroid Build Coastguard Worker * interfering nodes not in the stack. 109*61046927SAndroid Build Coastguard Worker */ 110*61046927SAndroid Build Coastguard Worker unsigned int q_total; 111*61046927SAndroid Build Coastguard Worker 112*61046927SAndroid Build Coastguard Worker /* For an implementation that needs register spilling, this is the 113*61046927SAndroid Build Coastguard Worker * approximate cost of spilling this node. 114*61046927SAndroid Build Coastguard Worker */ 115*61046927SAndroid Build Coastguard Worker float spill_cost; 116*61046927SAndroid Build Coastguard Worker 117*61046927SAndroid Build Coastguard Worker /* Temporary data for the algorithm to scratch around in */ 118*61046927SAndroid Build Coastguard Worker struct { 119*61046927SAndroid Build Coastguard Worker /** 120*61046927SAndroid Build Coastguard Worker * Temporary version of q_total which we decrement as things are placed 121*61046927SAndroid Build Coastguard Worker * into the stack. 122*61046927SAndroid Build Coastguard Worker */ 123*61046927SAndroid Build Coastguard Worker unsigned int q_total; 124*61046927SAndroid Build Coastguard Worker } tmp; 125*61046927SAndroid Build Coastguard Worker }; 126*61046927SAndroid Build Coastguard Worker 127*61046927SAndroid Build Coastguard Worker struct ra_graph { 128*61046927SAndroid Build Coastguard Worker struct ra_regs *regs; 129*61046927SAndroid Build Coastguard Worker /** 130*61046927SAndroid Build Coastguard Worker * the variables that need register allocation. 131*61046927SAndroid Build Coastguard Worker */ 132*61046927SAndroid Build Coastguard Worker struct ra_node *nodes; 133*61046927SAndroid Build Coastguard Worker BITSET_WORD *adjacency; 134*61046927SAndroid Build Coastguard Worker unsigned int count; /**< count of nodes. */ 135*61046927SAndroid Build Coastguard Worker 136*61046927SAndroid Build Coastguard Worker unsigned int alloc; /**< count of nodes allocated. */ 137*61046927SAndroid Build Coastguard Worker 138*61046927SAndroid Build Coastguard Worker ra_select_reg_callback select_reg_callback; 139*61046927SAndroid Build Coastguard Worker void *select_reg_callback_data; 140*61046927SAndroid Build Coastguard Worker 141*61046927SAndroid Build Coastguard Worker /* Temporary data for the algorithm to scratch around in */ 142*61046927SAndroid Build Coastguard Worker struct { 143*61046927SAndroid Build Coastguard Worker unsigned int *stack; 144*61046927SAndroid Build Coastguard Worker unsigned int stack_count; 145*61046927SAndroid Build Coastguard Worker 146*61046927SAndroid Build Coastguard Worker /** Bit-set indicating, for each register, if it's in the stack */ 147*61046927SAndroid Build Coastguard Worker BITSET_WORD *in_stack; 148*61046927SAndroid Build Coastguard Worker 149*61046927SAndroid Build Coastguard Worker /** Bit-set indicating, for each register, if it pre-assigned */ 150*61046927SAndroid Build Coastguard Worker BITSET_WORD *reg_assigned; 151*61046927SAndroid Build Coastguard Worker 152*61046927SAndroid Build Coastguard Worker /** Bit-set indicating, for each register, the value of the pq test */ 153*61046927SAndroid Build Coastguard Worker BITSET_WORD *pq_test; 154*61046927SAndroid Build Coastguard Worker 155*61046927SAndroid Build Coastguard Worker /** For each BITSET_WORD, the minimum q value or ~0 if unknown */ 156*61046927SAndroid Build Coastguard Worker unsigned int *min_q_total; 157*61046927SAndroid Build Coastguard Worker 158*61046927SAndroid Build Coastguard Worker /* 159*61046927SAndroid Build Coastguard Worker * * For each BITSET_WORD, the node with the minimum q_total if 160*61046927SAndroid Build Coastguard Worker * min_q_total[i] != ~0. 161*61046927SAndroid Build Coastguard Worker */ 162*61046927SAndroid Build Coastguard Worker unsigned int *min_q_node; 163*61046927SAndroid Build Coastguard Worker 164*61046927SAndroid Build Coastguard Worker /** 165*61046927SAndroid Build Coastguard Worker * Tracks the start of the set of optimistically-colored registers in the 166*61046927SAndroid Build Coastguard Worker * stack. 167*61046927SAndroid Build Coastguard Worker */ 168*61046927SAndroid Build Coastguard Worker unsigned int stack_optimistic_start; 169*61046927SAndroid Build Coastguard Worker } tmp; 170*61046927SAndroid Build Coastguard Worker }; 171*61046927SAndroid Build Coastguard Worker 172*61046927SAndroid Build Coastguard Worker bool ra_class_allocations_conflict(struct ra_class *c1, unsigned int r1, 173*61046927SAndroid Build Coastguard Worker struct ra_class *c2, unsigned int r2); 174*61046927SAndroid Build Coastguard Worker 175*61046927SAndroid Build Coastguard Worker #ifdef __cplusplus 176*61046927SAndroid Build Coastguard Worker } /* extern "C" */ 177*61046927SAndroid Build Coastguard Worker 178*61046927SAndroid Build Coastguard Worker #undef class 179*61046927SAndroid Build Coastguard Worker #endif 180*61046927SAndroid Build Coastguard Worker 181*61046927SAndroid Build Coastguard Worker #endif /* REGISTER_ALLOCATE_INTERNAL_H */ 182