| 1 |
684 |
jeremybenn |
/* IRA hard register and memory cost calculation for allocnos or pseudos.
|
| 2 |
|
|
Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012
|
| 3 |
|
|
Free Software Foundation, Inc.
|
| 4 |
|
|
Contributed by Vladimir Makarov <vmakarov@redhat.com>.
|
| 5 |
|
|
|
| 6 |
|
|
This file is part of GCC.
|
| 7 |
|
|
|
| 8 |
|
|
GCC is free software; you can redistribute it and/or modify it under
|
| 9 |
|
|
the terms of the GNU General Public License as published by the Free
|
| 10 |
|
|
Software Foundation; either version 3, or (at your option) any later
|
| 11 |
|
|
version.
|
| 12 |
|
|
|
| 13 |
|
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
| 14 |
|
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
| 15 |
|
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
| 16 |
|
|
for more details.
|
| 17 |
|
|
|
| 18 |
|
|
You should have received a copy of the GNU General Public License
|
| 19 |
|
|
along with GCC; see the file COPYING3. If not see
|
| 20 |
|
|
<http://www.gnu.org/licenses/>. */
|
| 21 |
|
|
|
| 22 |
|
|
#include "config.h"
|
| 23 |
|
|
#include "system.h"
|
| 24 |
|
|
#include "coretypes.h"
|
| 25 |
|
|
#include "tm.h"
|
| 26 |
|
|
#include "hard-reg-set.h"
|
| 27 |
|
|
#include "rtl.h"
|
| 28 |
|
|
#include "expr.h"
|
| 29 |
|
|
#include "tm_p.h"
|
| 30 |
|
|
#include "flags.h"
|
| 31 |
|
|
#include "basic-block.h"
|
| 32 |
|
|
#include "regs.h"
|
| 33 |
|
|
#include "addresses.h"
|
| 34 |
|
|
#include "insn-config.h"
|
| 35 |
|
|
#include "recog.h"
|
| 36 |
|
|
#include "reload.h"
|
| 37 |
|
|
#include "diagnostic-core.h"
|
| 38 |
|
|
#include "target.h"
|
| 39 |
|
|
#include "params.h"
|
| 40 |
|
|
#include "ira-int.h"
|
| 41 |
|
|
|
| 42 |
|
|
/* The flags is set up every time when we calculate pseudo register
|
| 43 |
|
|
classes through function ira_set_pseudo_classes. */
|
| 44 |
|
|
static bool pseudo_classes_defined_p = false;
|
| 45 |
|
|
|
| 46 |
|
|
/* TRUE if we work with allocnos. Otherwise we work with pseudos. */
|
| 47 |
|
|
static bool allocno_p;
|
| 48 |
|
|
|
| 49 |
|
|
/* Number of elements in array `costs'. */
|
| 50 |
|
|
static int cost_elements_num;
|
| 51 |
|
|
|
| 52 |
|
|
/* The `costs' struct records the cost of using hard registers of each
|
| 53 |
|
|
class considered for the calculation and of using memory for each
|
| 54 |
|
|
allocno or pseudo. */
|
| 55 |
|
|
struct costs
|
| 56 |
|
|
{
|
| 57 |
|
|
int mem_cost;
|
| 58 |
|
|
/* Costs for register classes start here. We process only some
|
| 59 |
|
|
allocno classes. */
|
| 60 |
|
|
int cost[1];
|
| 61 |
|
|
};
|
| 62 |
|
|
|
| 63 |
|
|
#define max_struct_costs_size \
|
| 64 |
|
|
(this_target_ira_int->x_max_struct_costs_size)
|
| 65 |
|
|
#define init_cost \
|
| 66 |
|
|
(this_target_ira_int->x_init_cost)
|
| 67 |
|
|
#define temp_costs \
|
| 68 |
|
|
(this_target_ira_int->x_temp_costs)
|
| 69 |
|
|
#define op_costs \
|
| 70 |
|
|
(this_target_ira_int->x_op_costs)
|
| 71 |
|
|
#define this_op_costs \
|
| 72 |
|
|
(this_target_ira_int->x_this_op_costs)
|
| 73 |
|
|
|
| 74 |
|
|
/* Costs of each class for each allocno or pseudo. */
|
| 75 |
|
|
static struct costs *costs;
|
| 76 |
|
|
|
| 77 |
|
|
/* Accumulated costs of each class for each allocno. */
|
| 78 |
|
|
static struct costs *total_allocno_costs;
|
| 79 |
|
|
|
| 80 |
|
|
/* It is the current size of struct costs. */
|
| 81 |
|
|
static int struct_costs_size;
|
| 82 |
|
|
|
| 83 |
|
|
/* Return pointer to structure containing costs of allocno or pseudo
|
| 84 |
|
|
with given NUM in array ARR. */
|
| 85 |
|
|
#define COSTS(arr, num) \
|
| 86 |
|
|
((struct costs *) ((char *) (arr) + (num) * struct_costs_size))
|
| 87 |
|
|
|
| 88 |
|
|
/* Return index in COSTS when processing reg with REGNO. */
|
| 89 |
|
|
#define COST_INDEX(regno) (allocno_p \
|
| 90 |
|
|
? ALLOCNO_NUM (ira_curr_regno_allocno_map[regno]) \
|
| 91 |
|
|
: (int) regno)
|
| 92 |
|
|
|
| 93 |
|
|
/* Record register class preferences of each allocno or pseudo. Null
|
| 94 |
|
|
value means no preferences. It happens on the 1st iteration of the
|
| 95 |
|
|
cost calculation. */
|
| 96 |
|
|
static enum reg_class *pref;
|
| 97 |
|
|
|
| 98 |
|
|
/* Allocated buffers for pref. */
|
| 99 |
|
|
static enum reg_class *pref_buffer;
|
| 100 |
|
|
|
| 101 |
|
|
/* Record allocno class of each allocno with the same regno. */
|
| 102 |
|
|
static enum reg_class *regno_aclass;
|
| 103 |
|
|
|
| 104 |
|
|
/* Record cost gains for not allocating a register with an invariant
|
| 105 |
|
|
equivalence. */
|
| 106 |
|
|
static int *regno_equiv_gains;
|
| 107 |
|
|
|
| 108 |
|
|
/* Execution frequency of the current insn. */
|
| 109 |
|
|
static int frequency;
|
| 110 |
|
|
|
| 111 |
|
|
|
| 112 |
|
|
|
| 113 |
|
|
/* Info about reg classes whose costs are calculated for a pseudo. */
|
| 114 |
|
|
struct cost_classes
|
| 115 |
|
|
{
|
| 116 |
|
|
/* Number of the cost classes in the subsequent array. */
|
| 117 |
|
|
int num;
|
| 118 |
|
|
/* Container of the cost classes. */
|
| 119 |
|
|
enum reg_class classes[N_REG_CLASSES];
|
| 120 |
|
|
/* Map reg class -> index of the reg class in the previous array.
|
| 121 |
|
|
-1 if it is not a cost classe. */
|
| 122 |
|
|
int index[N_REG_CLASSES];
|
| 123 |
|
|
/* Map hard regno index of first class in array CLASSES containing
|
| 124 |
|
|
the hard regno, -1 otherwise. */
|
| 125 |
|
|
int hard_regno_index[FIRST_PSEUDO_REGISTER];
|
| 126 |
|
|
};
|
| 127 |
|
|
|
| 128 |
|
|
/* Types of pointers to the structure above. */
|
| 129 |
|
|
typedef struct cost_classes *cost_classes_t;
|
| 130 |
|
|
typedef const struct cost_classes *const_cost_classes_t;
|
| 131 |
|
|
|
| 132 |
|
|
/* Info about cost classes for each pseudo. */
|
| 133 |
|
|
static cost_classes_t *regno_cost_classes;
|
| 134 |
|
|
|
| 135 |
|
|
/* Returns hash value for cost classes info V. */
|
| 136 |
|
|
static hashval_t
|
| 137 |
|
|
cost_classes_hash (const void *v)
|
| 138 |
|
|
{
|
| 139 |
|
|
const_cost_classes_t hv = (const_cost_classes_t) v;
|
| 140 |
|
|
|
| 141 |
|
|
return iterative_hash (&hv->classes, sizeof (enum reg_class) * hv->num, 0);
|
| 142 |
|
|
}
|
| 143 |
|
|
|
| 144 |
|
|
/* Compares cost classes info V1 and V2. */
|
| 145 |
|
|
static int
|
| 146 |
|
|
cost_classes_eq (const void *v1, const void *v2)
|
| 147 |
|
|
{
|
| 148 |
|
|
const_cost_classes_t hv1 = (const_cost_classes_t) v1;
|
| 149 |
|
|
const_cost_classes_t hv2 = (const_cost_classes_t) v2;
|
| 150 |
|
|
|
| 151 |
|
|
return hv1->num == hv2->num && memcmp (hv1->classes, hv2->classes,
|
| 152 |
|
|
sizeof (enum reg_class) * hv1->num);
|
| 153 |
|
|
}
|
| 154 |
|
|
|
| 155 |
|
|
/* Delete cost classes info V from the hash table. */
|
| 156 |
|
|
static void
|
| 157 |
|
|
cost_classes_del (void *v)
|
| 158 |
|
|
{
|
| 159 |
|
|
ira_free (v);
|
| 160 |
|
|
}
|
| 161 |
|
|
|
| 162 |
|
|
/* Hash table of unique cost classes. */
|
| 163 |
|
|
static htab_t cost_classes_htab;
|
| 164 |
|
|
|
| 165 |
|
|
/* Map allocno class -> cost classes for pseudo of given allocno
|
| 166 |
|
|
class. */
|
| 167 |
|
|
static cost_classes_t cost_classes_aclass_cache[N_REG_CLASSES];
|
| 168 |
|
|
|
| 169 |
|
|
/* Map mode -> cost classes for pseudo of give mode. */
|
| 170 |
|
|
static cost_classes_t cost_classes_mode_cache[MAX_MACHINE_MODE];
|
| 171 |
|
|
|
| 172 |
|
|
/* Initialize info about the cost classes for each pseudo. */
|
| 173 |
|
|
static void
|
| 174 |
|
|
initiate_regno_cost_classes (void)
|
| 175 |
|
|
{
|
| 176 |
|
|
int size = sizeof (cost_classes_t) * max_reg_num ();
|
| 177 |
|
|
|
| 178 |
|
|
regno_cost_classes = (cost_classes_t *) ira_allocate (size);
|
| 179 |
|
|
memset (regno_cost_classes, 0, size);
|
| 180 |
|
|
memset (cost_classes_aclass_cache, 0,
|
| 181 |
|
|
sizeof (cost_classes_t) * N_REG_CLASSES);
|
| 182 |
|
|
memset (cost_classes_mode_cache, 0,
|
| 183 |
|
|
sizeof (cost_classes_t) * MAX_MACHINE_MODE);
|
| 184 |
|
|
cost_classes_htab
|
| 185 |
|
|
= htab_create (200, cost_classes_hash, cost_classes_eq, cost_classes_del);
|
| 186 |
|
|
}
|
| 187 |
|
|
|
| 188 |
|
|
/* Create new cost classes from cost classes FROM and set up members
|
| 189 |
|
|
index and hard_regno_index. Return the new classes. The function
|
| 190 |
|
|
implements some common code of two functions
|
| 191 |
|
|
setup_regno_cost_classes_by_aclass and
|
| 192 |
|
|
setup_regno_cost_classes_by_mode. */
|
| 193 |
|
|
static cost_classes_t
|
| 194 |
|
|
setup_cost_classes (cost_classes_t from)
|
| 195 |
|
|
{
|
| 196 |
|
|
cost_classes_t classes_ptr;
|
| 197 |
|
|
enum reg_class cl;
|
| 198 |
|
|
int i, j, hard_regno;
|
| 199 |
|
|
|
| 200 |
|
|
classes_ptr = (cost_classes_t) ira_allocate (sizeof (struct cost_classes));
|
| 201 |
|
|
classes_ptr->num = from->num;
|
| 202 |
|
|
for (i = 0; i < N_REG_CLASSES; i++)
|
| 203 |
|
|
classes_ptr->index[i] = -1;
|
| 204 |
|
|
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
|
| 205 |
|
|
classes_ptr->hard_regno_index[i] = -1;
|
| 206 |
|
|
for (i = 0; i < from->num; i++)
|
| 207 |
|
|
{
|
| 208 |
|
|
cl = classes_ptr->classes[i] = from->classes[i];
|
| 209 |
|
|
classes_ptr->index[cl] = i;
|
| 210 |
|
|
for (j = ira_class_hard_regs_num[cl] - 1; j >= 0; j--)
|
| 211 |
|
|
{
|
| 212 |
|
|
hard_regno = ira_class_hard_regs[cl][j];
|
| 213 |
|
|
if (classes_ptr->hard_regno_index[hard_regno] < 0)
|
| 214 |
|
|
classes_ptr->hard_regno_index[hard_regno] = i;
|
| 215 |
|
|
}
|
| 216 |
|
|
}
|
| 217 |
|
|
return classes_ptr;
|
| 218 |
|
|
}
|
| 219 |
|
|
|
| 220 |
|
|
/* Setup cost classes for pseudo REGNO whose allocno class is ACLASS.
|
| 221 |
|
|
This function is used when we know an initial approximation of
|
| 222 |
|
|
allocno class of the pseudo already, e.g. on the second iteration
|
| 223 |
|
|
of class cost calculation or after class cost calculation in
|
| 224 |
|
|
register-pressure sensitive insn scheduling or register-pressure
|
| 225 |
|
|
sensitive loop-invariant motion. */
|
| 226 |
|
|
static void
|
| 227 |
|
|
setup_regno_cost_classes_by_aclass (int regno, enum reg_class aclass)
|
| 228 |
|
|
{
|
| 229 |
|
|
static struct cost_classes classes;
|
| 230 |
|
|
cost_classes_t classes_ptr;
|
| 231 |
|
|
enum reg_class cl;
|
| 232 |
|
|
int i;
|
| 233 |
|
|
PTR *slot;
|
| 234 |
|
|
HARD_REG_SET temp, temp2;
|
| 235 |
|
|
bool exclude_p;
|
| 236 |
|
|
|
| 237 |
|
|
if ((classes_ptr = cost_classes_aclass_cache[aclass]) == NULL)
|
| 238 |
|
|
{
|
| 239 |
|
|
COPY_HARD_REG_SET (temp, reg_class_contents[aclass]);
|
| 240 |
|
|
AND_COMPL_HARD_REG_SET (temp, ira_no_alloc_regs);
|
| 241 |
|
|
/* We exclude classes from consideration which are subsets of
|
| 242 |
|
|
ACLASS only if ACLASS is a pressure class or subset of a
|
| 243 |
|
|
pressure class. It means by the definition of pressure classes
|
| 244 |
|
|
that cost of moving between susbets of ACLASS is cheaper than
|
| 245 |
|
|
load or store. */
|
| 246 |
|
|
for (i = 0; i < ira_pressure_classes_num; i++)
|
| 247 |
|
|
{
|
| 248 |
|
|
cl = ira_pressure_classes[i];
|
| 249 |
|
|
if (cl == aclass)
|
| 250 |
|
|
break;
|
| 251 |
|
|
COPY_HARD_REG_SET (temp2, reg_class_contents[cl]);
|
| 252 |
|
|
AND_COMPL_HARD_REG_SET (temp2, ira_no_alloc_regs);
|
| 253 |
|
|
if (hard_reg_set_subset_p (temp, temp2))
|
| 254 |
|
|
break;
|
| 255 |
|
|
}
|
| 256 |
|
|
exclude_p = i < ira_pressure_classes_num;
|
| 257 |
|
|
classes.num = 0;
|
| 258 |
|
|
for (i = 0; i < ira_important_classes_num; i++)
|
| 259 |
|
|
{
|
| 260 |
|
|
cl = ira_important_classes[i];
|
| 261 |
|
|
if (exclude_p)
|
| 262 |
|
|
{
|
| 263 |
|
|
/* Exclude no-pressure classes which are subsets of
|
| 264 |
|
|
ACLASS. */
|
| 265 |
|
|
COPY_HARD_REG_SET (temp2, reg_class_contents[cl]);
|
| 266 |
|
|
AND_COMPL_HARD_REG_SET (temp2, ira_no_alloc_regs);
|
| 267 |
|
|
if (! ira_reg_pressure_class_p[cl]
|
| 268 |
|
|
&& hard_reg_set_subset_p (temp2, temp) && cl != aclass)
|
| 269 |
|
|
continue;
|
| 270 |
|
|
}
|
| 271 |
|
|
classes.classes[classes.num++] = cl;
|
| 272 |
|
|
}
|
| 273 |
|
|
slot = htab_find_slot (cost_classes_htab, &classes, INSERT);
|
| 274 |
|
|
if (*slot == NULL)
|
| 275 |
|
|
{
|
| 276 |
|
|
classes_ptr = setup_cost_classes (&classes);
|
| 277 |
|
|
*slot = classes_ptr;
|
| 278 |
|
|
}
|
| 279 |
|
|
classes_ptr = cost_classes_aclass_cache[aclass] = (cost_classes_t) *slot;
|
| 280 |
|
|
}
|
| 281 |
|
|
regno_cost_classes[regno] = classes_ptr;
|
| 282 |
|
|
}
|
| 283 |
|
|
|
| 284 |
|
|
/* Setup cost classes for pseudo REGNO with MODE. Usage of MODE can
|
| 285 |
|
|
decrease number of cost classes for the pseudo, if hard registers
|
| 286 |
|
|
of some important classes can not hold a value of MODE. So the
|
| 287 |
|
|
pseudo can not get hard register of some important classes and cost
|
| 288 |
|
|
calculation for such important classes is only waisting CPU
|
| 289 |
|
|
time. */
|
| 290 |
|
|
static void
|
| 291 |
|
|
setup_regno_cost_classes_by_mode (int regno, enum machine_mode mode)
|
| 292 |
|
|
{
|
| 293 |
|
|
static struct cost_classes classes;
|
| 294 |
|
|
cost_classes_t classes_ptr;
|
| 295 |
|
|
enum reg_class cl;
|
| 296 |
|
|
int i;
|
| 297 |
|
|
PTR *slot;
|
| 298 |
|
|
HARD_REG_SET temp;
|
| 299 |
|
|
|
| 300 |
|
|
if ((classes_ptr = cost_classes_mode_cache[mode]) == NULL)
|
| 301 |
|
|
{
|
| 302 |
|
|
classes.num = 0;
|
| 303 |
|
|
for (i = 0; i < ira_important_classes_num; i++)
|
| 304 |
|
|
{
|
| 305 |
|
|
cl = ira_important_classes[i];
|
| 306 |
|
|
COPY_HARD_REG_SET (temp, ira_prohibited_class_mode_regs[cl][mode]);
|
| 307 |
|
|
IOR_HARD_REG_SET (temp, ira_no_alloc_regs);
|
| 308 |
|
|
if (hard_reg_set_subset_p (reg_class_contents[cl], temp))
|
| 309 |
|
|
continue;
|
| 310 |
|
|
classes.classes[classes.num++] = cl;
|
| 311 |
|
|
}
|
| 312 |
|
|
slot = htab_find_slot (cost_classes_htab, &classes, INSERT);
|
| 313 |
|
|
if (*slot == NULL)
|
| 314 |
|
|
{
|
| 315 |
|
|
classes_ptr = setup_cost_classes (&classes);
|
| 316 |
|
|
*slot = classes_ptr;
|
| 317 |
|
|
}
|
| 318 |
|
|
else
|
| 319 |
|
|
classes_ptr = (cost_classes_t) *slot;
|
| 320 |
|
|
cost_classes_mode_cache[mode] = (cost_classes_t) *slot;
|
| 321 |
|
|
}
|
| 322 |
|
|
regno_cost_classes[regno] = classes_ptr;
|
| 323 |
|
|
}
|
| 324 |
|
|
|
| 325 |
|
|
/* Finilize info about the cost classes for each pseudo. */
|
| 326 |
|
|
static void
|
| 327 |
|
|
finish_regno_cost_classes (void)
|
| 328 |
|
|
{
|
| 329 |
|
|
ira_free (regno_cost_classes);
|
| 330 |
|
|
htab_delete (cost_classes_htab);
|
| 331 |
|
|
}
|
| 332 |
|
|
|
| 333 |
|
|
|
| 334 |
|
|
|
| 335 |
|
|
/* Compute the cost of loading X into (if TO_P is TRUE) or from (if
|
| 336 |
|
|
TO_P is FALSE) a register of class RCLASS in mode MODE. X must not
|
| 337 |
|
|
be a pseudo register. */
|
| 338 |
|
|
static int
|
| 339 |
|
|
copy_cost (rtx x, enum machine_mode mode, reg_class_t rclass, bool to_p,
|
| 340 |
|
|
secondary_reload_info *prev_sri)
|
| 341 |
|
|
{
|
| 342 |
|
|
secondary_reload_info sri;
|
| 343 |
|
|
reg_class_t secondary_class = NO_REGS;
|
| 344 |
|
|
|
| 345 |
|
|
/* If X is a SCRATCH, there is actually nothing to move since we are
|
| 346 |
|
|
assuming optimal allocation. */
|
| 347 |
|
|
if (GET_CODE (x) == SCRATCH)
|
| 348 |
|
|
return 0;
|
| 349 |
|
|
|
| 350 |
|
|
/* Get the class we will actually use for a reload. */
|
| 351 |
|
|
rclass = targetm.preferred_reload_class (x, rclass);
|
| 352 |
|
|
|
| 353 |
|
|
/* If we need a secondary reload for an intermediate, the cost is
|
| 354 |
|
|
that to load the input into the intermediate register, then to
|
| 355 |
|
|
copy it. */
|
| 356 |
|
|
sri.prev_sri = prev_sri;
|
| 357 |
|
|
sri.extra_cost = 0;
|
| 358 |
|
|
secondary_class = targetm.secondary_reload (to_p, x, rclass, mode, &sri);
|
| 359 |
|
|
|
| 360 |
|
|
if (secondary_class != NO_REGS)
|
| 361 |
|
|
{
|
| 362 |
|
|
if (!move_cost[mode])
|
| 363 |
|
|
init_move_cost (mode);
|
| 364 |
|
|
return (move_cost[mode][(int) secondary_class][(int) rclass]
|
| 365 |
|
|
+ sri.extra_cost
|
| 366 |
|
|
+ copy_cost (x, mode, secondary_class, to_p, &sri));
|
| 367 |
|
|
}
|
| 368 |
|
|
|
| 369 |
|
|
/* For memory, use the memory move cost, for (hard) registers, use
|
| 370 |
|
|
the cost to move between the register classes, and use 2 for
|
| 371 |
|
|
everything else (constants). */
|
| 372 |
|
|
if (MEM_P (x) || rclass == NO_REGS)
|
| 373 |
|
|
return sri.extra_cost
|
| 374 |
|
|
+ ira_memory_move_cost[mode][(int) rclass][to_p != 0];
|
| 375 |
|
|
else if (REG_P (x))
|
| 376 |
|
|
{
|
| 377 |
|
|
if (!move_cost[mode])
|
| 378 |
|
|
init_move_cost (mode);
|
| 379 |
|
|
return (sri.extra_cost
|
| 380 |
|
|
+ move_cost[mode][REGNO_REG_CLASS (REGNO (x))][(int) rclass]);
|
| 381 |
|
|
}
|
| 382 |
|
|
else
|
| 383 |
|
|
/* If this is a constant, we may eventually want to call rtx_cost
|
| 384 |
|
|
here. */
|
| 385 |
|
|
return sri.extra_cost + COSTS_N_INSNS (1);
|
| 386 |
|
|
}
|
| 387 |
|
|
|
| 388 |
|
|
|
| 389 |
|
|
|
| 390 |
|
|
/* Record the cost of using memory or hard registers of various
|
| 391 |
|
|
classes for the operands in INSN.
|
| 392 |
|
|
|
| 393 |
|
|
N_ALTS is the number of alternatives.
|
| 394 |
|
|
N_OPS is the number of operands.
|
| 395 |
|
|
OPS is an array of the operands.
|
| 396 |
|
|
MODES are the modes of the operands, in case any are VOIDmode.
|
| 397 |
|
|
CONSTRAINTS are the constraints to use for the operands. This array
|
| 398 |
|
|
is modified by this procedure.
|
| 399 |
|
|
|
| 400 |
|
|
This procedure works alternative by alternative. For each
|
| 401 |
|
|
alternative we assume that we will be able to allocate all allocnos
|
| 402 |
|
|
to their ideal register class and calculate the cost of using that
|
| 403 |
|
|
alternative. Then we compute, for each operand that is a
|
| 404 |
|
|
pseudo-register, the cost of having the allocno allocated to each
|
| 405 |
|
|
register class and using it in that alternative. To this cost is
|
| 406 |
|
|
added the cost of the alternative.
|
| 407 |
|
|
|
| 408 |
|
|
The cost of each class for this insn is its lowest cost among all
|
| 409 |
|
|
the alternatives. */
|
| 410 |
|
|
static void
|
| 411 |
|
|
record_reg_classes (int n_alts, int n_ops, rtx *ops,
|
| 412 |
|
|
enum machine_mode *modes, const char **constraints,
|
| 413 |
|
|
rtx insn, enum reg_class *pref)
|
| 414 |
|
|
{
|
| 415 |
|
|
int alt;
|
| 416 |
|
|
int i, j, k;
|
| 417 |
|
|
rtx set;
|
| 418 |
|
|
int insn_allows_mem[MAX_RECOG_OPERANDS];
|
| 419 |
|
|
|
| 420 |
|
|
for (i = 0; i < n_ops; i++)
|
| 421 |
|
|
insn_allows_mem[i] = 0;
|
| 422 |
|
|
|
| 423 |
|
|
/* Process each alternative, each time minimizing an operand's cost
|
| 424 |
|
|
with the cost for each operand in that alternative. */
|
| 425 |
|
|
for (alt = 0; alt < n_alts; alt++)
|
| 426 |
|
|
{
|
| 427 |
|
|
enum reg_class classes[MAX_RECOG_OPERANDS];
|
| 428 |
|
|
int allows_mem[MAX_RECOG_OPERANDS];
|
| 429 |
|
|
enum reg_class rclass;
|
| 430 |
|
|
int alt_fail = 0;
|
| 431 |
|
|
int alt_cost = 0, op_cost_add;
|
| 432 |
|
|
|
| 433 |
|
|
if (!recog_data.alternative_enabled_p[alt])
|
| 434 |
|
|
{
|
| 435 |
|
|
for (i = 0; i < recog_data.n_operands; i++)
|
| 436 |
|
|
constraints[i] = skip_alternative (constraints[i]);
|
| 437 |
|
|
|
| 438 |
|
|
continue;
|
| 439 |
|
|
}
|
| 440 |
|
|
|
| 441 |
|
|
for (i = 0; i < n_ops; i++)
|
| 442 |
|
|
{
|
| 443 |
|
|
unsigned char c;
|
| 444 |
|
|
const char *p = constraints[i];
|
| 445 |
|
|
rtx op = ops[i];
|
| 446 |
|
|
enum machine_mode mode = modes[i];
|
| 447 |
|
|
int allows_addr = 0;
|
| 448 |
|
|
int win = 0;
|
| 449 |
|
|
|
| 450 |
|
|
/* Initially show we know nothing about the register class. */
|
| 451 |
|
|
classes[i] = NO_REGS;
|
| 452 |
|
|
allows_mem[i] = 0;
|
| 453 |
|
|
|
| 454 |
|
|
/* If this operand has no constraints at all, we can
|
| 455 |
|
|
conclude nothing about it since anything is valid. */
|
| 456 |
|
|
if (*p == 0)
|
| 457 |
|
|
{
|
| 458 |
|
|
if (REG_P (op) && REGNO (op) >= FIRST_PSEUDO_REGISTER)
|
| 459 |
|
|
memset (this_op_costs[i], 0, struct_costs_size);
|
| 460 |
|
|
continue;
|
| 461 |
|
|
}
|
| 462 |
|
|
|
| 463 |
|
|
/* If this alternative is only relevant when this operand
|
| 464 |
|
|
matches a previous operand, we do different things
|
| 465 |
|
|
depending on whether this operand is a allocno-reg or not.
|
| 466 |
|
|
We must process any modifiers for the operand before we
|
| 467 |
|
|
can make this test. */
|
| 468 |
|
|
while (*p == '%' || *p == '=' || *p == '+' || *p == '&')
|
| 469 |
|
|
p++;
|
| 470 |
|
|
|
| 471 |
|
|
if (p[0] >= '0' && p[0] <= '0' + i && (p[1] == ',' || p[1] == 0))
|
| 472 |
|
|
{
|
| 473 |
|
|
/* Copy class and whether memory is allowed from the
|
| 474 |
|
|
matching alternative. Then perform any needed cost
|
| 475 |
|
|
computations and/or adjustments. */
|
| 476 |
|
|
j = p[0] - '0';
|
| 477 |
|
|
classes[i] = classes[j];
|
| 478 |
|
|
allows_mem[i] = allows_mem[j];
|
| 479 |
|
|
if (allows_mem[i])
|
| 480 |
|
|
insn_allows_mem[i] = 1;
|
| 481 |
|
|
|
| 482 |
|
|
if (! REG_P (op) || REGNO (op) < FIRST_PSEUDO_REGISTER)
|
| 483 |
|
|
{
|
| 484 |
|
|
/* If this matches the other operand, we have no
|
| 485 |
|
|
added cost and we win. */
|
| 486 |
|
|
if (rtx_equal_p (ops[j], op))
|
| 487 |
|
|
win = 1;
|
| 488 |
|
|
/* If we can put the other operand into a register,
|
| 489 |
|
|
add to the cost of this alternative the cost to
|
| 490 |
|
|
copy this operand to the register used for the
|
| 491 |
|
|
other operand. */
|
| 492 |
|
|
else if (classes[j] != NO_REGS)
|
| 493 |
|
|
{
|
| 494 |
|
|
alt_cost += copy_cost (op, mode, classes[j], 1, NULL);
|
| 495 |
|
|
win = 1;
|
| 496 |
|
|
}
|
| 497 |
|
|
}
|
| 498 |
|
|
else if (! REG_P (ops[j])
|
| 499 |
|
|
|| REGNO (ops[j]) < FIRST_PSEUDO_REGISTER)
|
| 500 |
|
|
{
|
| 501 |
|
|
/* This op is an allocno but the one it matches is
|
| 502 |
|
|
not. */
|
| 503 |
|
|
|
| 504 |
|
|
/* If we can't put the other operand into a
|
| 505 |
|
|
register, this alternative can't be used. */
|
| 506 |
|
|
|
| 507 |
|
|
if (classes[j] == NO_REGS)
|
| 508 |
|
|
alt_fail = 1;
|
| 509 |
|
|
/* Otherwise, add to the cost of this alternative
|
| 510 |
|
|
the cost to copy the other operand to the hard
|
| 511 |
|
|
register used for this operand. */
|
| 512 |
|
|
else
|
| 513 |
|
|
alt_cost += copy_cost (ops[j], mode, classes[j], 1, NULL);
|
| 514 |
|
|
}
|
| 515 |
|
|
else
|
| 516 |
|
|
{
|
| 517 |
|
|
/* The costs of this operand are not the same as the
|
| 518 |
|
|
other operand since move costs are not symmetric.
|
| 519 |
|
|
Moreover, if we cannot tie them, this alternative
|
| 520 |
|
|
needs to do a copy, which is one insn. */
|
| 521 |
|
|
struct costs *pp = this_op_costs[i];
|
| 522 |
|
|
int *pp_costs = pp->cost;
|
| 523 |
|
|
cost_classes_t cost_classes_ptr
|
| 524 |
|
|
= regno_cost_classes[REGNO (op)];
|
| 525 |
|
|
enum reg_class *cost_classes = cost_classes_ptr->classes;
|
| 526 |
|
|
bool in_p = recog_data.operand_type[i] != OP_OUT;
|
| 527 |
|
|
bool out_p = recog_data.operand_type[i] != OP_IN;
|
| 528 |
|
|
enum reg_class op_class = classes[i];
|
| 529 |
|
|
move_table *move_in_cost, *move_out_cost;
|
| 530 |
|
|
|
| 531 |
|
|
ira_init_register_move_cost_if_necessary (mode);
|
| 532 |
|
|
if (! in_p)
|
| 533 |
|
|
{
|
| 534 |
|
|
ira_assert (out_p);
|
| 535 |
|
|
move_out_cost = ira_may_move_out_cost[mode];
|
| 536 |
|
|
for (k = cost_classes_ptr->num - 1; k >= 0; k--)
|
| 537 |
|
|
{
|
| 538 |
|
|
rclass = cost_classes[k];
|
| 539 |
|
|
pp_costs[k]
|
| 540 |
|
|
= move_out_cost[op_class][rclass] * frequency;
|
| 541 |
|
|
}
|
| 542 |
|
|
}
|
| 543 |
|
|
else if (! out_p)
|
| 544 |
|
|
{
|
| 545 |
|
|
ira_assert (in_p);
|
| 546 |
|
|
move_in_cost = ira_may_move_in_cost[mode];
|
| 547 |
|
|
for (k = cost_classes_ptr->num - 1; k >= 0; k--)
|
| 548 |
|
|
{
|
| 549 |
|
|
rclass = cost_classes[k];
|
| 550 |
|
|
pp_costs[k]
|
| 551 |
|
|
= move_in_cost[rclass][op_class] * frequency;
|
| 552 |
|
|
}
|
| 553 |
|
|
}
|
| 554 |
|
|
else
|
| 555 |
|
|
{
|
| 556 |
|
|
move_in_cost = ira_may_move_in_cost[mode];
|
| 557 |
|
|
move_out_cost = ira_may_move_out_cost[mode];
|
| 558 |
|
|
for (k = cost_classes_ptr->num - 1; k >= 0; k--)
|
| 559 |
|
|
{
|
| 560 |
|
|
rclass = cost_classes[k];
|
| 561 |
|
|
pp_costs[k] = ((move_in_cost[rclass][op_class]
|
| 562 |
|
|
+ move_out_cost[op_class][rclass])
|
| 563 |
|
|
* frequency);
|
| 564 |
|
|
}
|
| 565 |
|
|
}
|
| 566 |
|
|
|
| 567 |
|
|
/* If the alternative actually allows memory, make
|
| 568 |
|
|
things a bit cheaper since we won't need an extra
|
| 569 |
|
|
insn to load it. */
|
| 570 |
|
|
pp->mem_cost
|
| 571 |
|
|
= ((out_p ? ira_memory_move_cost[mode][op_class][0] : 0)
|
| 572 |
|
|
+ (in_p ? ira_memory_move_cost[mode][op_class][1] : 0)
|
| 573 |
|
|
- allows_mem[i]) * frequency;
|
| 574 |
|
|
|
| 575 |
|
|
/* If we have assigned a class to this allocno in
|
| 576 |
|
|
our first pass, add a cost to this alternative
|
| 577 |
|
|
corresponding to what we would add if this
|
| 578 |
|
|
allocno were not in the appropriate class. */
|
| 579 |
|
|
if (pref)
|
| 580 |
|
|
{
|
| 581 |
|
|
enum reg_class pref_class = pref[COST_INDEX (REGNO (op))];
|
| 582 |
|
|
|
| 583 |
|
|
if (pref_class == NO_REGS)
|
| 584 |
|
|
alt_cost
|
| 585 |
|
|
+= ((out_p
|
| 586 |
|
|
? ira_memory_move_cost[mode][op_class][0] : 0)
|
| 587 |
|
|
+ (in_p
|
| 588 |
|
|
? ira_memory_move_cost[mode][op_class][1]
|
| 589 |
|
|
: 0));
|
| 590 |
|
|
else if (ira_reg_class_intersect
|
| 591 |
|
|
[pref_class][op_class] == NO_REGS)
|
| 592 |
|
|
alt_cost
|
| 593 |
|
|
+= ira_register_move_cost[mode][pref_class][op_class];
|
| 594 |
|
|
}
|
| 595 |
|
|
if (REGNO (ops[i]) != REGNO (ops[j])
|
| 596 |
|
|
&& ! find_reg_note (insn, REG_DEAD, op))
|
| 597 |
|
|
alt_cost += 2;
|
| 598 |
|
|
|
| 599 |
|
|
/* This is in place of ordinary cost computation for
|
| 600 |
|
|
this operand, so skip to the end of the
|
| 601 |
|
|
alternative (should be just one character). */
|
| 602 |
|
|
while (*p && *p++ != ',')
|
| 603 |
|
|
;
|
| 604 |
|
|
|
| 605 |
|
|
constraints[i] = p;
|
| 606 |
|
|
continue;
|
| 607 |
|
|
}
|
| 608 |
|
|
}
|
| 609 |
|
|
|
| 610 |
|
|
/* Scan all the constraint letters. See if the operand
|
| 611 |
|
|
matches any of the constraints. Collect the valid
|
| 612 |
|
|
register classes and see if this operand accepts
|
| 613 |
|
|
memory. */
|
| 614 |
|
|
while ((c = *p))
|
| 615 |
|
|
{
|
| 616 |
|
|
switch (c)
|
| 617 |
|
|
{
|
| 618 |
|
|
case ',':
|
| 619 |
|
|
break;
|
| 620 |
|
|
case '*':
|
| 621 |
|
|
/* Ignore the next letter for this pass. */
|
| 622 |
|
|
c = *++p;
|
| 623 |
|
|
break;
|
| 624 |
|
|
|
| 625 |
|
|
case '?':
|
| 626 |
|
|
alt_cost += 2;
|
| 627 |
|
|
case '!': case '#': case '&':
|
| 628 |
|
|
case '0': case '1': case '2': case '3': case '4':
|
| 629 |
|
|
case '5': case '6': case '7': case '8': case '9':
|
| 630 |
|
|
break;
|
| 631 |
|
|
|
| 632 |
|
|
case 'p':
|
| 633 |
|
|
allows_addr = 1;
|
| 634 |
|
|
win = address_operand (op, GET_MODE (op));
|
| 635 |
|
|
/* We know this operand is an address, so we want it
|
| 636 |
|
|
to be allocated to a register that can be the
|
| 637 |
|
|
base of an address, i.e. BASE_REG_CLASS. */
|
| 638 |
|
|
classes[i]
|
| 639 |
|
|
= ira_reg_class_subunion[classes[i]]
|
| 640 |
|
|
[base_reg_class (VOIDmode, ADDR_SPACE_GENERIC,
|
| 641 |
|
|
ADDRESS, SCRATCH)];
|
| 642 |
|
|
break;
|
| 643 |
|
|
|
| 644 |
|
|
case 'm': case 'o': case 'V':
|
| 645 |
|
|
/* It doesn't seem worth distinguishing between
|
| 646 |
|
|
offsettable and non-offsettable addresses
|
| 647 |
|
|
here. */
|
| 648 |
|
|
insn_allows_mem[i] = allows_mem[i] = 1;
|
| 649 |
|
|
if (MEM_P (op))
|
| 650 |
|
|
win = 1;
|
| 651 |
|
|
break;
|
| 652 |
|
|
|
| 653 |
|
|
case '<':
|
| 654 |
|
|
if (MEM_P (op)
|
| 655 |
|
|
&& (GET_CODE (XEXP (op, 0)) == PRE_DEC
|
| 656 |
|
|
|| GET_CODE (XEXP (op, 0)) == POST_DEC))
|
| 657 |
|
|
win = 1;
|
| 658 |
|
|
break;
|
| 659 |
|
|
|
| 660 |
|
|
case '>':
|
| 661 |
|
|
if (MEM_P (op)
|
| 662 |
|
|
&& (GET_CODE (XEXP (op, 0)) == PRE_INC
|
| 663 |
|
|
|| GET_CODE (XEXP (op, 0)) == POST_INC))
|
| 664 |
|
|
win = 1;
|
| 665 |
|
|
break;
|
| 666 |
|
|
|
| 667 |
|
|
case 'E':
|
| 668 |
|
|
case 'F':
|
| 669 |
|
|
if (GET_CODE (op) == CONST_DOUBLE
|
| 670 |
|
|
|| (GET_CODE (op) == CONST_VECTOR
|
| 671 |
|
|
&& (GET_MODE_CLASS (GET_MODE (op))
|
| 672 |
|
|
== MODE_VECTOR_FLOAT)))
|
| 673 |
|
|
win = 1;
|
| 674 |
|
|
break;
|
| 675 |
|
|
|
| 676 |
|
|
case 'G':
|
| 677 |
|
|
case 'H':
|
| 678 |
|
|
if (GET_CODE (op) == CONST_DOUBLE
|
| 679 |
|
|
&& CONST_DOUBLE_OK_FOR_CONSTRAINT_P (op, c, p))
|
| 680 |
|
|
win = 1;
|
| 681 |
|
|
break;
|
| 682 |
|
|
|
| 683 |
|
|
case 's':
|
| 684 |
|
|
if (CONST_INT_P (op)
|
| 685 |
|
|
|| (GET_CODE (op) == CONST_DOUBLE
|
| 686 |
|
|
&& GET_MODE (op) == VOIDmode))
|
| 687 |
|
|
break;
|
| 688 |
|
|
|
| 689 |
|
|
case 'i':
|
| 690 |
|
|
if (CONSTANT_P (op)
|
| 691 |
|
|
&& (! flag_pic || LEGITIMATE_PIC_OPERAND_P (op)))
|
| 692 |
|
|
win = 1;
|
| 693 |
|
|
break;
|
| 694 |
|
|
|
| 695 |
|
|
case 'n':
|
| 696 |
|
|
if (CONST_INT_P (op)
|
| 697 |
|
|
|| (GET_CODE (op) == CONST_DOUBLE
|
| 698 |
|
|
&& GET_MODE (op) == VOIDmode))
|
| 699 |
|
|
win = 1;
|
| 700 |
|
|
break;
|
| 701 |
|
|
|
| 702 |
|
|
case 'I':
|
| 703 |
|
|
case 'J':
|
| 704 |
|
|
case 'K':
|
| 705 |
|
|
case 'L':
|
| 706 |
|
|
case 'M':
|
| 707 |
|
|
case 'N':
|
| 708 |
|
|
case 'O':
|
| 709 |
|
|
case 'P':
|
| 710 |
|
|
if (CONST_INT_P (op)
|
| 711 |
|
|
&& CONST_OK_FOR_CONSTRAINT_P (INTVAL (op), c, p))
|
| 712 |
|
|
win = 1;
|
| 713 |
|
|
break;
|
| 714 |
|
|
|
| 715 |
|
|
case 'X':
|
| 716 |
|
|
win = 1;
|
| 717 |
|
|
break;
|
| 718 |
|
|
|
| 719 |
|
|
case 'g':
|
| 720 |
|
|
if (MEM_P (op)
|
| 721 |
|
|
|| (CONSTANT_P (op)
|
| 722 |
|
|
&& (! flag_pic || LEGITIMATE_PIC_OPERAND_P (op))))
|
| 723 |
|
|
win = 1;
|
| 724 |
|
|
insn_allows_mem[i] = allows_mem[i] = 1;
|
| 725 |
|
|
case 'r':
|
| 726 |
|
|
classes[i] = ira_reg_class_subunion[classes[i]][GENERAL_REGS];
|
| 727 |
|
|
break;
|
| 728 |
|
|
|
| 729 |
|
|
default:
|
| 730 |
|
|
if (REG_CLASS_FROM_CONSTRAINT (c, p) != NO_REGS)
|
| 731 |
|
|
classes[i] = ira_reg_class_subunion[classes[i]]
|
| 732 |
|
|
[REG_CLASS_FROM_CONSTRAINT (c, p)];
|
| 733 |
|
|
#ifdef EXTRA_CONSTRAINT_STR
|
| 734 |
|
|
else if (EXTRA_CONSTRAINT_STR (op, c, p))
|
| 735 |
|
|
win = 1;
|
| 736 |
|
|
|
| 737 |
|
|
if (EXTRA_MEMORY_CONSTRAINT (c, p))
|
| 738 |
|
|
{
|
| 739 |
|
|
/* Every MEM can be reloaded to fit. */
|
| 740 |
|
|
insn_allows_mem[i] = allows_mem[i] = 1;
|
| 741 |
|
|
if (MEM_P (op))
|
| 742 |
|
|
win = 1;
|
| 743 |
|
|
}
|
| 744 |
|
|
if (EXTRA_ADDRESS_CONSTRAINT (c, p))
|
| 745 |
|
|
{
|
| 746 |
|
|
/* Every address can be reloaded to fit. */
|
| 747 |
|
|
allows_addr = 1;
|
| 748 |
|
|
if (address_operand (op, GET_MODE (op)))
|
| 749 |
|
|
win = 1;
|
| 750 |
|
|
/* We know this operand is an address, so we
|
| 751 |
|
|
want it to be allocated to a hard register
|
| 752 |
|
|
that can be the base of an address,
|
| 753 |
|
|
i.e. BASE_REG_CLASS. */
|
| 754 |
|
|
classes[i]
|
| 755 |
|
|
= ira_reg_class_subunion[classes[i]]
|
| 756 |
|
|
[base_reg_class (VOIDmode, ADDR_SPACE_GENERIC,
|
| 757 |
|
|
ADDRESS, SCRATCH)];
|
| 758 |
|
|
}
|
| 759 |
|
|
#endif
|
| 760 |
|
|
break;
|
| 761 |
|
|
}
|
| 762 |
|
|
p += CONSTRAINT_LEN (c, p);
|
| 763 |
|
|
if (c == ',')
|
| 764 |
|
|
break;
|
| 765 |
|
|
}
|
| 766 |
|
|
|
| 767 |
|
|
constraints[i] = p;
|
| 768 |
|
|
|
| 769 |
|
|
/* How we account for this operand now depends on whether it
|
| 770 |
|
|
is a pseudo register or not. If it is, we first check if
|
| 771 |
|
|
any register classes are valid. If not, we ignore this
|
| 772 |
|
|
alternative, since we want to assume that all allocnos get
|
| 773 |
|
|
allocated for register preferencing. If some register
|
| 774 |
|
|
class is valid, compute the costs of moving the allocno
|
| 775 |
|
|
into that class. */
|
| 776 |
|
|
if (REG_P (op) && REGNO (op) >= FIRST_PSEUDO_REGISTER)
|
| 777 |
|
|
{
|
| 778 |
|
|
if (classes[i] == NO_REGS)
|
| 779 |
|
|
{
|
| 780 |
|
|
/* We must always fail if the operand is a REG, but
|
| 781 |
|
|
we did not find a suitable class.
|
| 782 |
|
|
|
| 783 |
|
|
Otherwise we may perform an uninitialized read
|
| 784 |
|
|
from this_op_costs after the `continue' statement
|
| 785 |
|
|
below. */
|
| 786 |
|
|
alt_fail = 1;
|
| 787 |
|
|
}
|
| 788 |
|
|
else
|
| 789 |
|
|
{
|
| 790 |
|
|
unsigned int regno = REGNO (op);
|
| 791 |
|
|
struct costs *pp = this_op_costs[i];
|
| 792 |
|
|
int *pp_costs = pp->cost;
|
| 793 |
|
|
cost_classes_t cost_classes_ptr = regno_cost_classes[regno];
|
| 794 |
|
|
enum reg_class *cost_classes = cost_classes_ptr->classes;
|
| 795 |
|
|
bool in_p = recog_data.operand_type[i] != OP_OUT;
|
| 796 |
|
|
bool out_p = recog_data.operand_type[i] != OP_IN;
|
| 797 |
|
|
enum reg_class op_class = classes[i];
|
| 798 |
|
|
move_table *move_in_cost, *move_out_cost;
|
| 799 |
|
|
|
| 800 |
|
|
ira_init_register_move_cost_if_necessary (mode);
|
| 801 |
|
|
if (! in_p)
|
| 802 |
|
|
{
|
| 803 |
|
|
ira_assert (out_p);
|
| 804 |
|
|
move_out_cost = ira_may_move_out_cost[mode];
|
| 805 |
|
|
for (k = cost_classes_ptr->num - 1; k >= 0; k--)
|
| 806 |
|
|
{
|
| 807 |
|
|
rclass = cost_classes[k];
|
| 808 |
|
|
pp_costs[k]
|
| 809 |
|
|
= move_out_cost[op_class][rclass] * frequency;
|
| 810 |
|
|
}
|
| 811 |
|
|
}
|
| 812 |
|
|
else if (! out_p)
|
| 813 |
|
|
{
|
| 814 |
|
|
ira_assert (in_p);
|
| 815 |
|
|
move_in_cost = ira_may_move_in_cost[mode];
|
| 816 |
|
|
for (k = cost_classes_ptr->num - 1; k >= 0; k--)
|
| 817 |
|
|
{
|
| 818 |
|
|
rclass = cost_classes[k];
|
| 819 |
|
|
pp_costs[k]
|
| 820 |
|
|
= move_in_cost[rclass][op_class] * frequency;
|
| 821 |
|
|
}
|
| 822 |
|
|
}
|
| 823 |
|
|
else
|
| 824 |
|
|
{
|
| 825 |
|
|
move_in_cost = ira_may_move_in_cost[mode];
|
| 826 |
|
|
move_out_cost = ira_may_move_out_cost[mode];
|
| 827 |
|
|
for (k = cost_classes_ptr->num - 1; k >= 0; k--)
|
| 828 |
|
|
{
|
| 829 |
|
|
rclass = cost_classes[k];
|
| 830 |
|
|
pp_costs[k] = ((move_in_cost[rclass][op_class]
|
| 831 |
|
|
+ move_out_cost[op_class][rclass])
|
| 832 |
|
|
* frequency);
|
| 833 |
|
|
}
|
| 834 |
|
|
}
|
| 835 |
|
|
|
| 836 |
|
|
/* If the alternative actually allows memory, make
|
| 837 |
|
|
things a bit cheaper since we won't need an extra
|
| 838 |
|
|
insn to load it. */
|
| 839 |
|
|
pp->mem_cost
|
| 840 |
|
|
= ((out_p ? ira_memory_move_cost[mode][op_class][0] : 0)
|
| 841 |
|
|
+ (in_p ? ira_memory_move_cost[mode][op_class][1] : 0)
|
| 842 |
|
|
- allows_mem[i]) * frequency;
|
| 843 |
|
|
/* If we have assigned a class to this allocno in
|
| 844 |
|
|
our first pass, add a cost to this alternative
|
| 845 |
|
|
corresponding to what we would add if this
|
| 846 |
|
|
allocno were not in the appropriate class. */
|
| 847 |
|
|
if (pref)
|
| 848 |
|
|
{
|
| 849 |
|
|
enum reg_class pref_class = pref[COST_INDEX (REGNO (op))];
|
| 850 |
|
|
|
| 851 |
|
|
if (pref_class == NO_REGS)
|
| 852 |
|
|
alt_cost
|
| 853 |
|
|
+= ((out_p
|
| 854 |
|
|
? ira_memory_move_cost[mode][op_class][0] : 0)
|
| 855 |
|
|
+ (in_p
|
| 856 |
|
|
? ira_memory_move_cost[mode][op_class][1]
|
| 857 |
|
|
: 0));
|
| 858 |
|
|
else if (ira_reg_class_intersect[pref_class][op_class]
|
| 859 |
|
|
== NO_REGS)
|
| 860 |
|
|
alt_cost += ira_register_move_cost[mode][pref_class][op_class];
|
| 861 |
|
|
}
|
| 862 |
|
|
}
|
| 863 |
|
|
}
|
| 864 |
|
|
|
| 865 |
|
|
/* Otherwise, if this alternative wins, either because we
|
| 866 |
|
|
have already determined that or if we have a hard
|
| 867 |
|
|
register of the proper class, there is no cost for this
|
| 868 |
|
|
alternative. */
|
| 869 |
|
|
else if (win || (REG_P (op)
|
| 870 |
|
|
&& reg_fits_class_p (op, classes[i],
|
| 871 |
|
|
0, GET_MODE (op))))
|
| 872 |
|
|
;
|
| 873 |
|
|
|
| 874 |
|
|
/* If registers are valid, the cost of this alternative
|
| 875 |
|
|
includes copying the object to and/or from a
|
| 876 |
|
|
register. */
|
| 877 |
|
|
else if (classes[i] != NO_REGS)
|
| 878 |
|
|
{
|
| 879 |
|
|
if (recog_data.operand_type[i] != OP_OUT)
|
| 880 |
|
|
alt_cost += copy_cost (op, mode, classes[i], 1, NULL);
|
| 881 |
|
|
|
| 882 |
|
|
if (recog_data.operand_type[i] != OP_IN)
|
| 883 |
|
|
alt_cost += copy_cost (op, mode, classes[i], 0, NULL);
|
| 884 |
|
|
}
|
| 885 |
|
|
/* The only other way this alternative can be used is if
|
| 886 |
|
|
this is a constant that could be placed into memory. */
|
| 887 |
|
|
else if (CONSTANT_P (op) && (allows_addr || allows_mem[i]))
|
| 888 |
|
|
alt_cost += ira_memory_move_cost[mode][classes[i]][1];
|
| 889 |
|
|
else
|
| 890 |
|
|
alt_fail = 1;
|
| 891 |
|
|
}
|
| 892 |
|
|
|
| 893 |
|
|
if (alt_fail)
|
| 894 |
|
|
continue;
|
| 895 |
|
|
|
| 896 |
|
|
op_cost_add = alt_cost * frequency;
|
| 897 |
|
|
/* Finally, update the costs with the information we've
|
| 898 |
|
|
calculated about this alternative. */
|
| 899 |
|
|
for (i = 0; i < n_ops; i++)
|
| 900 |
|
|
if (REG_P (ops[i]) && REGNO (ops[i]) >= FIRST_PSEUDO_REGISTER)
|
| 901 |
|
|
{
|
| 902 |
|
|
struct costs *pp = op_costs[i], *qq = this_op_costs[i];
|
| 903 |
|
|
int *pp_costs = pp->cost, *qq_costs = qq->cost;
|
| 904 |
|
|
int scale = 1 + (recog_data.operand_type[i] == OP_INOUT);
|
| 905 |
|
|
cost_classes_t cost_classes_ptr
|
| 906 |
|
|
= regno_cost_classes[REGNO (ops[i])];
|
| 907 |
|
|
|
| 908 |
|
|
pp->mem_cost = MIN (pp->mem_cost,
|
| 909 |
|
|
(qq->mem_cost + op_cost_add) * scale);
|
| 910 |
|
|
|
| 911 |
|
|
for (k = cost_classes_ptr->num - 1; k >= 0; k--)
|
| 912 |
|
|
pp_costs[k]
|
| 913 |
|
|
= MIN (pp_costs[k], (qq_costs[k] + op_cost_add) * scale);
|
| 914 |
|
|
}
|
| 915 |
|
|
}
|
| 916 |
|
|
|
| 917 |
|
|
if (allocno_p)
|
| 918 |
|
|
for (i = 0; i < n_ops; i++)
|
| 919 |
|
|
{
|
| 920 |
|
|
ira_allocno_t a;
|
| 921 |
|
|
rtx op = ops[i];
|
| 922 |
|
|
|
| 923 |
|
|
if (! REG_P (op) || REGNO (op) < FIRST_PSEUDO_REGISTER)
|
| 924 |
|
|
continue;
|
| 925 |
|
|
a = ira_curr_regno_allocno_map [REGNO (op)];
|
| 926 |
|
|
if (! ALLOCNO_BAD_SPILL_P (a) && insn_allows_mem[i] == 0)
|
| 927 |
|
|
ALLOCNO_BAD_SPILL_P (a) = true;
|
| 928 |
|
|
}
|
| 929 |
|
|
|
| 930 |
|
|
/* If this insn is a single set copying operand 1 to operand 0 and
|
| 931 |
|
|
one operand is an allocno with the other a hard reg or an allocno
|
| 932 |
|
|
that prefers a hard register that is in its own register class
|
| 933 |
|
|
then we may want to adjust the cost of that register class to -1.
|
| 934 |
|
|
|
| 935 |
|
|
Avoid the adjustment if the source does not die to avoid
|
| 936 |
|
|
stressing of register allocator by preferrencing two colliding
|
| 937 |
|
|
registers into single class.
|
| 938 |
|
|
|
| 939 |
|
|
Also avoid the adjustment if a copy between hard registers of the
|
| 940 |
|
|
class is expensive (ten times the cost of a default copy is
|
| 941 |
|
|
considered arbitrarily expensive). This avoids losing when the
|
| 942 |
|
|
preferred class is very expensive as the source of a copy
|
| 943 |
|
|
instruction. */
|
| 944 |
|
|
if ((set = single_set (insn)) != 0
|
| 945 |
|
|
&& ops[0] == SET_DEST (set) && ops[1] == SET_SRC (set)
|
| 946 |
|
|
&& REG_P (ops[0]) && REG_P (ops[1])
|
| 947 |
|
|
&& find_regno_note (insn, REG_DEAD, REGNO (ops[1])))
|
| 948 |
|
|
for (i = 0; i <= 1; i++)
|
| 949 |
|
|
if (REGNO (ops[i]) >= FIRST_PSEUDO_REGISTER
|
| 950 |
|
|
&& REGNO (ops[!i]) < FIRST_PSEUDO_REGISTER)
|
| 951 |
|
|
{
|
| 952 |
|
|
unsigned int regno = REGNO (ops[i]);
|
| 953 |
|
|
unsigned int other_regno = REGNO (ops[!i]);
|
| 954 |
|
|
enum machine_mode mode = GET_MODE (ops[!i]);
|
| 955 |
|
|
cost_classes_t cost_classes_ptr = regno_cost_classes[regno];
|
| 956 |
|
|
enum reg_class *cost_classes = cost_classes_ptr->classes;
|
| 957 |
|
|
reg_class_t rclass;
|
| 958 |
|
|
int nr;
|
| 959 |
|
|
|
| 960 |
|
|
for (k = cost_classes_ptr->num - 1; k >= 0; k--)
|
| 961 |
|
|
{
|
| 962 |
|
|
rclass = cost_classes[k];
|
| 963 |
|
|
if (TEST_HARD_REG_BIT (reg_class_contents[rclass], other_regno)
|
| 964 |
|
|
&& (reg_class_size[(int) rclass]
|
| 965 |
|
|
== ira_reg_class_max_nregs [(int) rclass][(int) mode]))
|
| 966 |
|
|
{
|
| 967 |
|
|
if (reg_class_size[rclass] == 1)
|
| 968 |
|
|
op_costs[i]->cost[k] = -frequency;
|
| 969 |
|
|
else
|
| 970 |
|
|
{
|
| 971 |
|
|
for (nr = 0;
|
| 972 |
|
|
nr < hard_regno_nregs[other_regno][mode];
|
| 973 |
|
|
nr++)
|
| 974 |
|
|
if (! TEST_HARD_REG_BIT (reg_class_contents[rclass],
|
| 975 |
|
|
other_regno + nr))
|
| 976 |
|
|
break;
|
| 977 |
|
|
|
| 978 |
|
|
if (nr == hard_regno_nregs[other_regno][mode])
|
| 979 |
|
|
op_costs[i]->cost[k] = -frequency;
|
| 980 |
|
|
}
|
| 981 |
|
|
}
|
| 982 |
|
|
}
|
| 983 |
|
|
}
|
| 984 |
|
|
}
|
| 985 |
|
|
|
| 986 |
|
|
|
| 987 |
|
|
|
| 988 |
|
|
/* Wrapper around REGNO_OK_FOR_INDEX_P, to allow pseudo registers. */
|
| 989 |
|
|
static inline bool
|
| 990 |
|
|
ok_for_index_p_nonstrict (rtx reg)
|
| 991 |
|
|
{
|
| 992 |
|
|
unsigned regno = REGNO (reg);
|
| 993 |
|
|
|
| 994 |
|
|
return regno >= FIRST_PSEUDO_REGISTER || REGNO_OK_FOR_INDEX_P (regno);
|
| 995 |
|
|
}
|
| 996 |
|
|
|
| 997 |
|
|
/* A version of regno_ok_for_base_p for use here, when all
|
| 998 |
|
|
pseudo-registers should count as OK. Arguments as for
|
| 999 |
|
|
regno_ok_for_base_p. */
|
| 1000 |
|
|
static inline bool
|
| 1001 |
|
|
ok_for_base_p_nonstrict (rtx reg, enum machine_mode mode, addr_space_t as,
|
| 1002 |
|
|
enum rtx_code outer_code, enum rtx_code index_code)
|
| 1003 |
|
|
{
|
| 1004 |
|
|
unsigned regno = REGNO (reg);
|
| 1005 |
|
|
|
| 1006 |
|
|
if (regno >= FIRST_PSEUDO_REGISTER)
|
| 1007 |
|
|
return true;
|
| 1008 |
|
|
return ok_for_base_p_1 (regno, mode, as, outer_code, index_code);
|
| 1009 |
|
|
}
|
| 1010 |
|
|
|
| 1011 |
|
|
/* Record the pseudo registers we must reload into hard registers in a
|
| 1012 |
|
|
subexpression of a memory address, X.
|
| 1013 |
|
|
|
| 1014 |
|
|
If CONTEXT is 0, we are looking at the base part of an address,
|
| 1015 |
|
|
otherwise we are looking at the index part.
|
| 1016 |
|
|
|
| 1017 |
|
|
MODE and AS are the mode and address space of the memory reference;
|
| 1018 |
|
|
OUTER_CODE and INDEX_CODE give the context that the rtx appears in.
|
| 1019 |
|
|
These four arguments are passed down to base_reg_class.
|
| 1020 |
|
|
|
| 1021 |
|
|
SCALE is twice the amount to multiply the cost by (it is twice so
|
| 1022 |
|
|
we can represent half-cost adjustments). */
|
| 1023 |
|
|
static void
|
| 1024 |
|
|
record_address_regs (enum machine_mode mode, addr_space_t as, rtx x,
|
| 1025 |
|
|
int context, enum rtx_code outer_code,
|
| 1026 |
|
|
enum rtx_code index_code, int scale)
|
| 1027 |
|
|
{
|
| 1028 |
|
|
enum rtx_code code = GET_CODE (x);
|
| 1029 |
|
|
enum reg_class rclass;
|
| 1030 |
|
|
|
| 1031 |
|
|
if (context == 1)
|
| 1032 |
|
|
rclass = INDEX_REG_CLASS;
|
| 1033 |
|
|
else
|
| 1034 |
|
|
rclass = base_reg_class (mode, as, outer_code, index_code);
|
| 1035 |
|
|
|
| 1036 |
|
|
switch (code)
|
| 1037 |
|
|
{
|
| 1038 |
|
|
case CONST_INT:
|
| 1039 |
|
|
case CONST:
|
| 1040 |
|
|
case CC0:
|
| 1041 |
|
|
case PC:
|
| 1042 |
|
|
case SYMBOL_REF:
|
| 1043 |
|
|
case LABEL_REF:
|
| 1044 |
|
|
return;
|
| 1045 |
|
|
|
| 1046 |
|
|
case PLUS:
|
| 1047 |
|
|
/* When we have an address that is a sum, we must determine
|
| 1048 |
|
|
whether registers are "base" or "index" regs. If there is a
|
| 1049 |
|
|
sum of two registers, we must choose one to be the "base".
|
| 1050 |
|
|
Luckily, we can use the REG_POINTER to make a good choice
|
| 1051 |
|
|
most of the time. We only need to do this on machines that
|
| 1052 |
|
|
can have two registers in an address and where the base and
|
| 1053 |
|
|
index register classes are different.
|
| 1054 |
|
|
|
| 1055 |
|
|
??? This code used to set REGNO_POINTER_FLAG in some cases,
|
| 1056 |
|
|
but that seems bogus since it should only be set when we are
|
| 1057 |
|
|
sure the register is being used as a pointer. */
|
| 1058 |
|
|
{
|
| 1059 |
|
|
rtx arg0 = XEXP (x, 0);
|
| 1060 |
|
|
rtx arg1 = XEXP (x, 1);
|
| 1061 |
|
|
enum rtx_code code0 = GET_CODE (arg0);
|
| 1062 |
|
|
enum rtx_code code1 = GET_CODE (arg1);
|
| 1063 |
|
|
|
| 1064 |
|
|
/* Look inside subregs. */
|
| 1065 |
|
|
if (code0 == SUBREG)
|
| 1066 |
|
|
arg0 = SUBREG_REG (arg0), code0 = GET_CODE (arg0);
|
| 1067 |
|
|
if (code1 == SUBREG)
|
| 1068 |
|
|
arg1 = SUBREG_REG (arg1), code1 = GET_CODE (arg1);
|
| 1069 |
|
|
|
| 1070 |
|
|
/* If this machine only allows one register per address, it
|
| 1071 |
|
|
must be in the first operand. */
|
| 1072 |
|
|
if (MAX_REGS_PER_ADDRESS == 1)
|
| 1073 |
|
|
record_address_regs (mode, as, arg0, 0, PLUS, code1, scale);
|
| 1074 |
|
|
|
| 1075 |
|
|
/* If index and base registers are the same on this machine,
|
| 1076 |
|
|
just record registers in any non-constant operands. We
|
| 1077 |
|
|
assume here, as well as in the tests below, that all
|
| 1078 |
|
|
addresses are in canonical form. */
|
| 1079 |
|
|
else if (INDEX_REG_CLASS
|
| 1080 |
|
|
== base_reg_class (VOIDmode, as, PLUS, SCRATCH))
|
| 1081 |
|
|
{
|
| 1082 |
|
|
record_address_regs (mode, as, arg0, context, PLUS, code1, scale);
|
| 1083 |
|
|
if (! CONSTANT_P (arg1))
|
| 1084 |
|
|
record_address_regs (mode, as, arg1, context, PLUS, code0, scale);
|
| 1085 |
|
|
}
|
| 1086 |
|
|
|
| 1087 |
|
|
/* If the second operand is a constant integer, it doesn't
|
| 1088 |
|
|
change what class the first operand must be. */
|
| 1089 |
|
|
else if (code1 == CONST_INT || code1 == CONST_DOUBLE)
|
| 1090 |
|
|
record_address_regs (mode, as, arg0, context, PLUS, code1, scale);
|
| 1091 |
|
|
/* If the second operand is a symbolic constant, the first
|
| 1092 |
|
|
operand must be an index register. */
|
| 1093 |
|
|
else if (code1 == SYMBOL_REF || code1 == CONST || code1 == LABEL_REF)
|
| 1094 |
|
|
record_address_regs (mode, as, arg0, 1, PLUS, code1, scale);
|
| 1095 |
|
|
/* If both operands are registers but one is already a hard
|
| 1096 |
|
|
register of index or reg-base class, give the other the
|
| 1097 |
|
|
class that the hard register is not. */
|
| 1098 |
|
|
else if (code0 == REG && code1 == REG
|
| 1099 |
|
|
&& REGNO (arg0) < FIRST_PSEUDO_REGISTER
|
| 1100 |
|
|
&& (ok_for_base_p_nonstrict (arg0, mode, as, PLUS, REG)
|
| 1101 |
|
|
|| ok_for_index_p_nonstrict (arg0)))
|
| 1102 |
|
|
record_address_regs (mode, as, arg1,
|
| 1103 |
|
|
ok_for_base_p_nonstrict (arg0, mode, as,
|
| 1104 |
|
|
PLUS, REG) ? 1 : 0,
|
| 1105 |
|
|
PLUS, REG, scale);
|
| 1106 |
|
|
else if (code0 == REG && code1 == REG
|
| 1107 |
|
|
&& REGNO (arg1) < FIRST_PSEUDO_REGISTER
|
| 1108 |
|
|
&& (ok_for_base_p_nonstrict (arg1, mode, as, PLUS, REG)
|
| 1109 |
|
|
|| ok_for_index_p_nonstrict (arg1)))
|
| 1110 |
|
|
record_address_regs (mode, as, arg0,
|
| 1111 |
|
|
ok_for_base_p_nonstrict (arg1, mode, as,
|
| 1112 |
|
|
PLUS, REG) ? 1 : 0,
|
| 1113 |
|
|
PLUS, REG, scale);
|
| 1114 |
|
|
/* If one operand is known to be a pointer, it must be the
|
| 1115 |
|
|
base with the other operand the index. Likewise if the
|
| 1116 |
|
|
other operand is a MULT. */
|
| 1117 |
|
|
else if ((code0 == REG && REG_POINTER (arg0)) || code1 == MULT)
|
| 1118 |
|
|
{
|
| 1119 |
|
|
record_address_regs (mode, as, arg0, 0, PLUS, code1, scale);
|
| 1120 |
|
|
record_address_regs (mode, as, arg1, 1, PLUS, code0, scale);
|
| 1121 |
|
|
}
|
| 1122 |
|
|
else if ((code1 == REG && REG_POINTER (arg1)) || code0 == MULT)
|
| 1123 |
|
|
{
|
| 1124 |
|
|
record_address_regs (mode, as, arg0, 1, PLUS, code1, scale);
|
| 1125 |
|
|
record_address_regs (mode, as, arg1, 0, PLUS, code0, scale);
|
| 1126 |
|
|
}
|
| 1127 |
|
|
/* Otherwise, count equal chances that each might be a base or
|
| 1128 |
|
|
index register. This case should be rare. */
|
| 1129 |
|
|
else
|
| 1130 |
|
|
{
|
| 1131 |
|
|
record_address_regs (mode, as, arg0, 0, PLUS, code1, scale / 2);
|
| 1132 |
|
|
record_address_regs (mode, as, arg0, 1, PLUS, code1, scale / 2);
|
| 1133 |
|
|
record_address_regs (mode, as, arg1, 0, PLUS, code0, scale / 2);
|
| 1134 |
|
|
record_address_regs (mode, as, arg1, 1, PLUS, code0, scale / 2);
|
| 1135 |
|
|
}
|
| 1136 |
|
|
}
|
| 1137 |
|
|
break;
|
| 1138 |
|
|
|
| 1139 |
|
|
/* Double the importance of an allocno that is incremented or
|
| 1140 |
|
|
decremented, since it would take two extra insns if it ends
|
| 1141 |
|
|
up in the wrong place. */
|
| 1142 |
|
|
case POST_MODIFY:
|
| 1143 |
|
|
case PRE_MODIFY:
|
| 1144 |
|
|
record_address_regs (mode, as, XEXP (x, 0), 0, code,
|
| 1145 |
|
|
GET_CODE (XEXP (XEXP (x, 1), 1)), 2 * scale);
|
| 1146 |
|
|
if (REG_P (XEXP (XEXP (x, 1), 1)))
|
| 1147 |
|
|
record_address_regs (mode, as, XEXP (XEXP (x, 1), 1), 1, code, REG,
|
| 1148 |
|
|
2 * scale);
|
| 1149 |
|
|
break;
|
| 1150 |
|
|
|
| 1151 |
|
|
case POST_INC:
|
| 1152 |
|
|
case PRE_INC:
|
| 1153 |
|
|
case POST_DEC:
|
| 1154 |
|
|
case PRE_DEC:
|
| 1155 |
|
|
/* Double the importance of an allocno that is incremented or
|
| 1156 |
|
|
decremented, since it would take two extra insns if it ends
|
| 1157 |
|
|
up in the wrong place. */
|
| 1158 |
|
|
record_address_regs (mode, as, XEXP (x, 0), 0, code, SCRATCH, 2 * scale);
|
| 1159 |
|
|
break;
|
| 1160 |
|
|
|
| 1161 |
|
|
case REG:
|
| 1162 |
|
|
{
|
| 1163 |
|
|
struct costs *pp;
|
| 1164 |
|
|
int *pp_costs;
|
| 1165 |
|
|
enum reg_class i;
|
| 1166 |
|
|
int k, regno, add_cost;
|
| 1167 |
|
|
cost_classes_t cost_classes_ptr;
|
| 1168 |
|
|
enum reg_class *cost_classes;
|
| 1169 |
|
|
move_table *move_in_cost;
|
| 1170 |
|
|
|
| 1171 |
|
|
if (REGNO (x) < FIRST_PSEUDO_REGISTER)
|
| 1172 |
|
|
break;
|
| 1173 |
|
|
|
| 1174 |
|
|
regno = REGNO (x);
|
| 1175 |
|
|
if (allocno_p)
|
| 1176 |
|
|
ALLOCNO_BAD_SPILL_P (ira_curr_regno_allocno_map[regno]) = true;
|
| 1177 |
|
|
pp = COSTS (costs, COST_INDEX (regno));
|
| 1178 |
|
|
add_cost = (ira_memory_move_cost[Pmode][rclass][1] * scale) / 2;
|
| 1179 |
|
|
if (INT_MAX - add_cost < pp->mem_cost)
|
| 1180 |
|
|
pp->mem_cost = INT_MAX;
|
| 1181 |
|
|
else
|
| 1182 |
|
|
pp->mem_cost += add_cost;
|
| 1183 |
|
|
cost_classes_ptr = regno_cost_classes[regno];
|
| 1184 |
|
|
cost_classes = cost_classes_ptr->classes;
|
| 1185 |
|
|
pp_costs = pp->cost;
|
| 1186 |
|
|
ira_init_register_move_cost_if_necessary (Pmode);
|
| 1187 |
|
|
move_in_cost = ira_may_move_in_cost[Pmode];
|
| 1188 |
|
|
for (k = cost_classes_ptr->num - 1; k >= 0; k--)
|
| 1189 |
|
|
{
|
| 1190 |
|
|
i = cost_classes[k];
|
| 1191 |
|
|
add_cost = (move_in_cost[i][rclass] * scale) / 2;
|
| 1192 |
|
|
if (INT_MAX - add_cost < pp_costs[k])
|
| 1193 |
|
|
pp_costs[k] = INT_MAX;
|
| 1194 |
|
|
else
|
| 1195 |
|
|
pp_costs[k] += add_cost;
|
| 1196 |
|
|
}
|
| 1197 |
|
|
}
|
| 1198 |
|
|
break;
|
| 1199 |
|
|
|
| 1200 |
|
|
default:
|
| 1201 |
|
|
{
|
| 1202 |
|
|
const char *fmt = GET_RTX_FORMAT (code);
|
| 1203 |
|
|
int i;
|
| 1204 |
|
|
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
|
| 1205 |
|
|
if (fmt[i] == 'e')
|
| 1206 |
|
|
record_address_regs (mode, as, XEXP (x, i), context, code, SCRATCH,
|
| 1207 |
|
|
scale);
|
| 1208 |
|
|
}
|
| 1209 |
|
|
}
|
| 1210 |
|
|
}
|
| 1211 |
|
|
|
| 1212 |
|
|
|
| 1213 |
|
|
|
| 1214 |
|
|
/* Calculate the costs of insn operands. */
|
| 1215 |
|
|
static void
|
| 1216 |
|
|
record_operand_costs (rtx insn, enum reg_class *pref)
|
| 1217 |
|
|
{
|
| 1218 |
|
|
const char *constraints[MAX_RECOG_OPERANDS];
|
| 1219 |
|
|
enum machine_mode modes[MAX_RECOG_OPERANDS];
|
| 1220 |
|
|
int i;
|
| 1221 |
|
|
|
| 1222 |
|
|
for (i = 0; i < recog_data.n_operands; i++)
|
| 1223 |
|
|
{
|
| 1224 |
|
|
constraints[i] = recog_data.constraints[i];
|
| 1225 |
|
|
modes[i] = recog_data.operand_mode[i];
|
| 1226 |
|
|
}
|
| 1227 |
|
|
|
| 1228 |
|
|
/* If we get here, we are set up to record the costs of all the
|
| 1229 |
|
|
operands for this insn. Start by initializing the costs. Then
|
| 1230 |
|
|
handle any address registers. Finally record the desired classes
|
| 1231 |
|
|
for any allocnos, doing it twice if some pair of operands are
|
| 1232 |
|
|
commutative. */
|
| 1233 |
|
|
for (i = 0; i < recog_data.n_operands; i++)
|
| 1234 |
|
|
{
|
| 1235 |
|
|
memcpy (op_costs[i], init_cost, struct_costs_size);
|
| 1236 |
|
|
|
| 1237 |
|
|
if (GET_CODE (recog_data.operand[i]) == SUBREG)
|
| 1238 |
|
|
recog_data.operand[i] = SUBREG_REG (recog_data.operand[i]);
|
| 1239 |
|
|
|
| 1240 |
|
|
if (MEM_P (recog_data.operand[i]))
|
| 1241 |
|
|
record_address_regs (GET_MODE (recog_data.operand[i]),
|
| 1242 |
|
|
MEM_ADDR_SPACE (recog_data.operand[i]),
|
| 1243 |
|
|
XEXP (recog_data.operand[i], 0),
|
| 1244 |
|
|
0, MEM, SCRATCH, frequency * 2);
|
| 1245 |
|
|
else if (constraints[i][0] == 'p'
|
| 1246 |
|
|
|| EXTRA_ADDRESS_CONSTRAINT (constraints[i][0],
|
| 1247 |
|
|
constraints[i]))
|
| 1248 |
|
|
record_address_regs (VOIDmode, ADDR_SPACE_GENERIC,
|
| 1249 |
|
|
recog_data.operand[i], 0, ADDRESS, SCRATCH,
|
| 1250 |
|
|
frequency * 2);
|
| 1251 |
|
|
}
|
| 1252 |
|
|
|
| 1253 |
|
|
/* Check for commutative in a separate loop so everything will have
|
| 1254 |
|
|
been initialized. We must do this even if one operand is a
|
| 1255 |
|
|
constant--see addsi3 in m68k.md. */
|
| 1256 |
|
|
for (i = 0; i < (int) recog_data.n_operands - 1; i++)
|
| 1257 |
|
|
if (constraints[i][0] == '%')
|
| 1258 |
|
|
{
|
| 1259 |
|
|
const char *xconstraints[MAX_RECOG_OPERANDS];
|
| 1260 |
|
|
int j;
|
| 1261 |
|
|
|
| 1262 |
|
|
/* Handle commutative operands by swapping the constraints.
|
| 1263 |
|
|
We assume the modes are the same. */
|
| 1264 |
|
|
for (j = 0; j < recog_data.n_operands; j++)
|
| 1265 |
|
|
xconstraints[j] = constraints[j];
|
| 1266 |
|
|
|
| 1267 |
|
|
xconstraints[i] = constraints[i+1];
|
| 1268 |
|
|
xconstraints[i+1] = constraints[i];
|
| 1269 |
|
|
record_reg_classes (recog_data.n_alternatives, recog_data.n_operands,
|
| 1270 |
|
|
recog_data.operand, modes,
|
| 1271 |
|
|
xconstraints, insn, pref);
|
| 1272 |
|
|
}
|
| 1273 |
|
|
record_reg_classes (recog_data.n_alternatives, recog_data.n_operands,
|
| 1274 |
|
|
recog_data.operand, modes,
|
| 1275 |
|
|
constraints, insn, pref);
|
| 1276 |
|
|
}
|
| 1277 |
|
|
|
| 1278 |
|
|
|
| 1279 |
|
|
|
| 1280 |
|
|
/* Process one insn INSN. Scan it and record each time it would save
|
| 1281 |
|
|
code to put a certain allocnos in a certain class. Return the last
|
| 1282 |
|
|
insn processed, so that the scan can be continued from there. */
|
| 1283 |
|
|
static rtx
|
| 1284 |
|
|
scan_one_insn (rtx insn)
|
| 1285 |
|
|
{
|
| 1286 |
|
|
enum rtx_code pat_code;
|
| 1287 |
|
|
rtx set, note;
|
| 1288 |
|
|
int i, k;
|
| 1289 |
|
|
bool counted_mem;
|
| 1290 |
|
|
|
| 1291 |
|
|
if (!NONDEBUG_INSN_P (insn))
|
| 1292 |
|
|
return insn;
|
| 1293 |
|
|
|
| 1294 |
|
|
pat_code = GET_CODE (PATTERN (insn));
|
| 1295 |
|
|
if (pat_code == USE || pat_code == CLOBBER || pat_code == ASM_INPUT
|
| 1296 |
|
|
|| pat_code == ADDR_VEC || pat_code == ADDR_DIFF_VEC)
|
| 1297 |
|
|
return insn;
|
| 1298 |
|
|
|
| 1299 |
|
|
counted_mem = false;
|
| 1300 |
|
|
set = single_set (insn);
|
| 1301 |
|
|
extract_insn (insn);
|
| 1302 |
|
|
|
| 1303 |
|
|
/* If this insn loads a parameter from its stack slot, then it
|
| 1304 |
|
|
represents a savings, rather than a cost, if the parameter is
|
| 1305 |
|
|
stored in memory. Record this fact.
|
| 1306 |
|
|
|
| 1307 |
|
|
Similarly if we're loading other constants from memory (constant
|
| 1308 |
|
|
pool, TOC references, small data areas, etc) and this is the only
|
| 1309 |
|
|
assignment to the destination pseudo.
|
| 1310 |
|
|
|
| 1311 |
|
|
Don't do this if SET_SRC (set) isn't a general operand, if it is
|
| 1312 |
|
|
a memory requiring special instructions to load it, decreasing
|
| 1313 |
|
|
mem_cost might result in it being loaded using the specialized
|
| 1314 |
|
|
instruction into a register, then stored into stack and loaded
|
| 1315 |
|
|
again from the stack. See PR52208. */
|
| 1316 |
|
|
if (set != 0 && REG_P (SET_DEST (set)) && MEM_P (SET_SRC (set))
|
| 1317 |
|
|
&& (note = find_reg_note (insn, REG_EQUIV, NULL_RTX)) != NULL_RTX
|
| 1318 |
|
|
&& ((MEM_P (XEXP (note, 0)))
|
| 1319 |
|
|
|| (CONSTANT_P (XEXP (note, 0))
|
| 1320 |
|
|
&& targetm.legitimate_constant_p (GET_MODE (SET_DEST (set)),
|
| 1321 |
|
|
XEXP (note, 0))
|
| 1322 |
|
|
&& REG_N_SETS (REGNO (SET_DEST (set))) == 1))
|
| 1323 |
|
|
&& general_operand (SET_SRC (set), GET_MODE (SET_SRC (set))))
|
| 1324 |
|
|
{
|
| 1325 |
|
|
enum reg_class cl = GENERAL_REGS;
|
| 1326 |
|
|
rtx reg = SET_DEST (set);
|
| 1327 |
|
|
int num = COST_INDEX (REGNO (reg));
|
| 1328 |
|
|
|
| 1329 |
|
|
COSTS (costs, num)->mem_cost
|
| 1330 |
|
|
-= ira_memory_move_cost[GET_MODE (reg)][cl][1] * frequency;
|
| 1331 |
|
|
record_address_regs (GET_MODE (SET_SRC (set)),
|
| 1332 |
|
|
MEM_ADDR_SPACE (SET_SRC (set)),
|
| 1333 |
|
|
XEXP (SET_SRC (set), 0), 0, MEM, SCRATCH,
|
| 1334 |
|
|
frequency * 2);
|
| 1335 |
|
|
counted_mem = true;
|
| 1336 |
|
|
}
|
| 1337 |
|
|
|
| 1338 |
|
|
record_operand_costs (insn, pref);
|
| 1339 |
|
|
|
| 1340 |
|
|
/* Now add the cost for each operand to the total costs for its
|
| 1341 |
|
|
allocno. */
|
| 1342 |
|
|
for (i = 0; i < recog_data.n_operands; i++)
|
| 1343 |
|
|
if (REG_P (recog_data.operand[i])
|
| 1344 |
|
|
&& REGNO (recog_data.operand[i]) >= FIRST_PSEUDO_REGISTER)
|
| 1345 |
|
|
{
|
| 1346 |
|
|
int regno = REGNO (recog_data.operand[i]);
|
| 1347 |
|
|
struct costs *p = COSTS (costs, COST_INDEX (regno));
|
| 1348 |
|
|
struct costs *q = op_costs[i];
|
| 1349 |
|
|
int *p_costs = p->cost, *q_costs = q->cost;
|
| 1350 |
|
|
cost_classes_t cost_classes_ptr = regno_cost_classes[regno];
|
| 1351 |
|
|
int add_cost;
|
| 1352 |
|
|
|
| 1353 |
|
|
/* If the already accounted for the memory "cost" above, don't
|
| 1354 |
|
|
do so again. */
|
| 1355 |
|
|
if (!counted_mem)
|
| 1356 |
|
|
{
|
| 1357 |
|
|
add_cost = q->mem_cost;
|
| 1358 |
|
|
if (add_cost > 0 && INT_MAX - add_cost < p->mem_cost)
|
| 1359 |
|
|
p->mem_cost = INT_MAX;
|
| 1360 |
|
|
else
|
| 1361 |
|
|
p->mem_cost += add_cost;
|
| 1362 |
|
|
}
|
| 1363 |
|
|
for (k = cost_classes_ptr->num - 1; k >= 0; k--)
|
| 1364 |
|
|
{
|
| 1365 |
|
|
add_cost = q_costs[k];
|
| 1366 |
|
|
if (add_cost > 0 && INT_MAX - add_cost < p_costs[k])
|
| 1367 |
|
|
p_costs[k] = INT_MAX;
|
| 1368 |
|
|
else
|
| 1369 |
|
|
p_costs[k] += add_cost;
|
| 1370 |
|
|
}
|
| 1371 |
|
|
}
|
| 1372 |
|
|
|
| 1373 |
|
|
return insn;
|
| 1374 |
|
|
}
|
| 1375 |
|
|
|
| 1376 |
|
|
|
| 1377 |
|
|
|
| 1378 |
|
|
/* Print allocnos costs to file F. */
|
| 1379 |
|
|
static void
|
| 1380 |
|
|
print_allocno_costs (FILE *f)
|
| 1381 |
|
|
{
|
| 1382 |
|
|
int k;
|
| 1383 |
|
|
ira_allocno_t a;
|
| 1384 |
|
|
ira_allocno_iterator ai;
|
| 1385 |
|
|
|
| 1386 |
|
|
ira_assert (allocno_p);
|
| 1387 |
|
|
fprintf (f, "\n");
|
| 1388 |
|
|
FOR_EACH_ALLOCNO (a, ai)
|
| 1389 |
|
|
{
|
| 1390 |
|
|
int i, rclass;
|
| 1391 |
|
|
basic_block bb;
|
| 1392 |
|
|
int regno = ALLOCNO_REGNO (a);
|
| 1393 |
|
|
cost_classes_t cost_classes_ptr = regno_cost_classes[regno];
|
| 1394 |
|
|
enum reg_class *cost_classes = cost_classes_ptr->classes;
|
| 1395 |
|
|
|
| 1396 |
|
|
i = ALLOCNO_NUM (a);
|
| 1397 |
|
|
fprintf (f, " a%d(r%d,", i, regno);
|
| 1398 |
|
|
if ((bb = ALLOCNO_LOOP_TREE_NODE (a)->bb) != NULL)
|
| 1399 |
|
|
fprintf (f, "b%d", bb->index);
|
| 1400 |
|
|
else
|
| 1401 |
|
|
fprintf (f, "l%d", ALLOCNO_LOOP_TREE_NODE (a)->loop_num);
|
| 1402 |
|
|
fprintf (f, ") costs:");
|
| 1403 |
|
|
for (k = 0; k < cost_classes_ptr->num; k++)
|
| 1404 |
|
|
{
|
| 1405 |
|
|
rclass = cost_classes[k];
|
| 1406 |
|
|
if (contains_reg_of_mode[rclass][PSEUDO_REGNO_MODE (regno)]
|
| 1407 |
|
|
#ifdef CANNOT_CHANGE_MODE_CLASS
|
| 1408 |
|
|
&& ! invalid_mode_change_p (regno, (enum reg_class) rclass)
|
| 1409 |
|
|
#endif
|
| 1410 |
|
|
)
|
| 1411 |
|
|
{
|
| 1412 |
|
|
fprintf (f, " %s:%d", reg_class_names[rclass],
|
| 1413 |
|
|
COSTS (costs, i)->cost[k]);
|
| 1414 |
|
|
if (flag_ira_region == IRA_REGION_ALL
|
| 1415 |
|
|
|| flag_ira_region == IRA_REGION_MIXED)
|
| 1416 |
|
|
fprintf (f, ",%d", COSTS (total_allocno_costs, i)->cost[k]);
|
| 1417 |
|
|
}
|
| 1418 |
|
|
}
|
| 1419 |
|
|
fprintf (f, " MEM:%i", COSTS (costs, i)->mem_cost);
|
| 1420 |
|
|
if (flag_ira_region == IRA_REGION_ALL
|
| 1421 |
|
|
|| flag_ira_region == IRA_REGION_MIXED)
|
| 1422 |
|
|
fprintf (f, ",%d", COSTS (total_allocno_costs, i)->mem_cost);
|
| 1423 |
|
|
fprintf (f, "\n");
|
| 1424 |
|
|
}
|
| 1425 |
|
|
}
|
| 1426 |
|
|
|
| 1427 |
|
|
/* Print pseudo costs to file F. */
|
| 1428 |
|
|
static void
|
| 1429 |
|
|
print_pseudo_costs (FILE *f)
|
| 1430 |
|
|
{
|
| 1431 |
|
|
int regno, k;
|
| 1432 |
|
|
int rclass;
|
| 1433 |
|
|
cost_classes_t cost_classes_ptr;
|
| 1434 |
|
|
enum reg_class *cost_classes;
|
| 1435 |
|
|
|
| 1436 |
|
|
ira_assert (! allocno_p);
|
| 1437 |
|
|
fprintf (f, "\n");
|
| 1438 |
|
|
for (regno = max_reg_num () - 1; regno >= FIRST_PSEUDO_REGISTER; regno--)
|
| 1439 |
|
|
{
|
| 1440 |
|
|
if (REG_N_REFS (regno) <= 0)
|
| 1441 |
|
|
continue;
|
| 1442 |
|
|
cost_classes_ptr = regno_cost_classes[regno];
|
| 1443 |
|
|
cost_classes = cost_classes_ptr->classes;
|
| 1444 |
|
|
fprintf (f, " r%d costs:", regno);
|
| 1445 |
|
|
for (k = 0; k < cost_classes_ptr->num; k++)
|
| 1446 |
|
|
{
|
| 1447 |
|
|
rclass = cost_classes[k];
|
| 1448 |
|
|
if (contains_reg_of_mode[rclass][PSEUDO_REGNO_MODE (regno)]
|
| 1449 |
|
|
#ifdef CANNOT_CHANGE_MODE_CLASS
|
| 1450 |
|
|
&& ! invalid_mode_change_p (regno, (enum reg_class) rclass)
|
| 1451 |
|
|
#endif
|
| 1452 |
|
|
)
|
| 1453 |
|
|
fprintf (f, " %s:%d", reg_class_names[rclass],
|
| 1454 |
|
|
COSTS (costs, regno)->cost[k]);
|
| 1455 |
|
|
}
|
| 1456 |
|
|
fprintf (f, " MEM:%i\n", COSTS (costs, regno)->mem_cost);
|
| 1457 |
|
|
}
|
| 1458 |
|
|
}
|
| 1459 |
|
|
|
| 1460 |
|
|
/* Traverse the BB represented by LOOP_TREE_NODE to update the allocno
|
| 1461 |
|
|
costs. */
|
| 1462 |
|
|
static void
|
| 1463 |
|
|
process_bb_for_costs (basic_block bb)
|
| 1464 |
|
|
{
|
| 1465 |
|
|
rtx insn;
|
| 1466 |
|
|
|
| 1467 |
|
|
frequency = REG_FREQ_FROM_BB (bb);
|
| 1468 |
|
|
if (frequency == 0)
|
| 1469 |
|
|
frequency = 1;
|
| 1470 |
|
|
FOR_BB_INSNS (bb, insn)
|
| 1471 |
|
|
insn = scan_one_insn (insn);
|
| 1472 |
|
|
}
|
| 1473 |
|
|
|
| 1474 |
|
|
/* Traverse the BB represented by LOOP_TREE_NODE to update the allocno
|
| 1475 |
|
|
costs. */
|
| 1476 |
|
|
static void
|
| 1477 |
|
|
process_bb_node_for_costs (ira_loop_tree_node_t loop_tree_node)
|
| 1478 |
|
|
{
|
| 1479 |
|
|
basic_block bb;
|
| 1480 |
|
|
|
| 1481 |
|
|
bb = loop_tree_node->bb;
|
| 1482 |
|
|
if (bb != NULL)
|
| 1483 |
|
|
process_bb_for_costs (bb);
|
| 1484 |
|
|
}
|
| 1485 |
|
|
|
| 1486 |
|
|
/* Find costs of register classes and memory for allocnos or pseudos
|
| 1487 |
|
|
and their best costs. Set up preferred, alternative and allocno
|
| 1488 |
|
|
classes for pseudos. */
|
| 1489 |
|
|
static void
|
| 1490 |
|
|
find_costs_and_classes (FILE *dump_file)
|
| 1491 |
|
|
{
|
| 1492 |
|
|
int i, k, start, max_cost_classes_num;
|
| 1493 |
|
|
int pass;
|
| 1494 |
|
|
basic_block bb;
|
| 1495 |
|
|
enum reg_class *regno_best_class;
|
| 1496 |
|
|
|
| 1497 |
|
|
init_recog ();
|
| 1498 |
|
|
regno_best_class
|
| 1499 |
|
|
= (enum reg_class *) ira_allocate (max_reg_num ()
|
| 1500 |
|
|
* sizeof (enum reg_class));
|
| 1501 |
|
|
for (i = max_reg_num () - 1; i >= FIRST_PSEUDO_REGISTER; i--)
|
| 1502 |
|
|
regno_best_class[i] = NO_REGS;
|
| 1503 |
|
|
if (!resize_reg_info () && allocno_p
|
| 1504 |
|
|
&& pseudo_classes_defined_p && flag_expensive_optimizations)
|
| 1505 |
|
|
{
|
| 1506 |
|
|
ira_allocno_t a;
|
| 1507 |
|
|
ira_allocno_iterator ai;
|
| 1508 |
|
|
|
| 1509 |
|
|
pref = pref_buffer;
|
| 1510 |
|
|
max_cost_classes_num = 1;
|
| 1511 |
|
|
FOR_EACH_ALLOCNO (a, ai)
|
| 1512 |
|
|
{
|
| 1513 |
|
|
pref[ALLOCNO_NUM (a)] = reg_preferred_class (ALLOCNO_REGNO (a));
|
| 1514 |
|
|
setup_regno_cost_classes_by_aclass
|
| 1515 |
|
|
(ALLOCNO_REGNO (a), pref[ALLOCNO_NUM (a)]);
|
| 1516 |
|
|
max_cost_classes_num
|
| 1517 |
|
|
= MAX (max_cost_classes_num,
|
| 1518 |
|
|
regno_cost_classes[ALLOCNO_REGNO (a)]->num);
|
| 1519 |
|
|
}
|
| 1520 |
|
|
start = 1;
|
| 1521 |
|
|
}
|
| 1522 |
|
|
else
|
| 1523 |
|
|
{
|
| 1524 |
|
|
pref = NULL;
|
| 1525 |
|
|
max_cost_classes_num = ira_important_classes_num;
|
| 1526 |
|
|
for (i = max_reg_num () - 1; i >= FIRST_PSEUDO_REGISTER; i--)
|
| 1527 |
|
|
if (regno_reg_rtx[i] != NULL_RTX)
|
| 1528 |
|
|
setup_regno_cost_classes_by_mode (i, PSEUDO_REGNO_MODE (i));
|
| 1529 |
|
|
else
|
| 1530 |
|
|
setup_regno_cost_classes_by_aclass (i, ALL_REGS);
|
| 1531 |
|
|
start = 0;
|
| 1532 |
|
|
}
|
| 1533 |
|
|
if (allocno_p)
|
| 1534 |
|
|
/* Clear the flag for the next compiled function. */
|
| 1535 |
|
|
pseudo_classes_defined_p = false;
|
| 1536 |
|
|
/* Normally we scan the insns once and determine the best class to
|
| 1537 |
|
|
use for each allocno. However, if -fexpensive-optimizations are
|
| 1538 |
|
|
on, we do so twice, the second time using the tentative best
|
| 1539 |
|
|
classes to guide the selection. */
|
| 1540 |
|
|
for (pass = start; pass <= flag_expensive_optimizations; pass++)
|
| 1541 |
|
|
{
|
| 1542 |
|
|
if ((!allocno_p || internal_flag_ira_verbose > 0) && dump_file)
|
| 1543 |
|
|
fprintf (dump_file,
|
| 1544 |
|
|
"\nPass %i for finding pseudo/allocno costs\n\n", pass);
|
| 1545 |
|
|
|
| 1546 |
|
|
if (pass != start)
|
| 1547 |
|
|
{
|
| 1548 |
|
|
max_cost_classes_num = 1;
|
| 1549 |
|
|
for (i = max_reg_num () - 1; i >= FIRST_PSEUDO_REGISTER; i--)
|
| 1550 |
|
|
{
|
| 1551 |
|
|
setup_regno_cost_classes_by_aclass (i, regno_best_class[i]);
|
| 1552 |
|
|
max_cost_classes_num
|
| 1553 |
|
|
= MAX (max_cost_classes_num, regno_cost_classes[i]->num);
|
| 1554 |
|
|
}
|
| 1555 |
|
|
}
|
| 1556 |
|
|
|
| 1557 |
|
|
struct_costs_size
|
| 1558 |
|
|
= sizeof (struct costs) + sizeof (int) * (max_cost_classes_num - 1);
|
| 1559 |
|
|
/* Zero out our accumulation of the cost of each class for each
|
| 1560 |
|
|
allocno. */
|
| 1561 |
|
|
memset (costs, 0, cost_elements_num * struct_costs_size);
|
| 1562 |
|
|
|
| 1563 |
|
|
if (allocno_p)
|
| 1564 |
|
|
{
|
| 1565 |
|
|
/* Scan the instructions and record each time it would save code
|
| 1566 |
|
|
to put a certain allocno in a certain class. */
|
| 1567 |
|
|
ira_traverse_loop_tree (true, ira_loop_tree_root,
|
| 1568 |
|
|
process_bb_node_for_costs, NULL);
|
| 1569 |
|
|
|
| 1570 |
|
|
memcpy (total_allocno_costs, costs,
|
| 1571 |
|
|
max_struct_costs_size * ira_allocnos_num);
|
| 1572 |
|
|
}
|
| 1573 |
|
|
else
|
| 1574 |
|
|
{
|
| 1575 |
|
|
basic_block bb;
|
| 1576 |
|
|
|
| 1577 |
|
|
FOR_EACH_BB (bb)
|
| 1578 |
|
|
process_bb_for_costs (bb);
|
| 1579 |
|
|
}
|
| 1580 |
|
|
|
| 1581 |
|
|
if (pass == 0)
|
| 1582 |
|
|
pref = pref_buffer;
|
| 1583 |
|
|
|
| 1584 |
|
|
/* Now for each allocno look at how desirable each class is and
|
| 1585 |
|
|
find which class is preferred. */
|
| 1586 |
|
|
for (i = max_reg_num () - 1; i >= FIRST_PSEUDO_REGISTER; i--)
|
| 1587 |
|
|
{
|
| 1588 |
|
|
ira_allocno_t a, parent_a;
|
| 1589 |
|
|
int rclass, a_num, parent_a_num, add_cost;
|
| 1590 |
|
|
ira_loop_tree_node_t parent;
|
| 1591 |
|
|
int best_cost, allocno_cost;
|
| 1592 |
|
|
enum reg_class best, alt_class;
|
| 1593 |
|
|
cost_classes_t cost_classes_ptr = regno_cost_classes[i];
|
| 1594 |
|
|
enum reg_class *cost_classes = cost_classes_ptr->classes;
|
| 1595 |
|
|
int *i_costs = temp_costs->cost;
|
| 1596 |
|
|
int i_mem_cost;
|
| 1597 |
|
|
int equiv_savings = regno_equiv_gains[i];
|
| 1598 |
|
|
|
| 1599 |
|
|
if (! allocno_p)
|
| 1600 |
|
|
{
|
| 1601 |
|
|
if (regno_reg_rtx[i] == NULL_RTX)
|
| 1602 |
|
|
continue;
|
| 1603 |
|
|
memcpy (temp_costs, COSTS (costs, i), struct_costs_size);
|
| 1604 |
|
|
i_mem_cost = temp_costs->mem_cost;
|
| 1605 |
|
|
}
|
| 1606 |
|
|
else
|
| 1607 |
|
|
{
|
| 1608 |
|
|
if (ira_regno_allocno_map[i] == NULL)
|
| 1609 |
|
|
continue;
|
| 1610 |
|
|
memset (temp_costs, 0, struct_costs_size);
|
| 1611 |
|
|
i_mem_cost = 0;
|
| 1612 |
|
|
/* Find cost of all allocnos with the same regno. */
|
| 1613 |
|
|
for (a = ira_regno_allocno_map[i];
|
| 1614 |
|
|
a != NULL;
|
| 1615 |
|
|
a = ALLOCNO_NEXT_REGNO_ALLOCNO (a))
|
| 1616 |
|
|
{
|
| 1617 |
|
|
int *a_costs, *p_costs;
|
| 1618 |
|
|
|
| 1619 |
|
|
a_num = ALLOCNO_NUM (a);
|
| 1620 |
|
|
if ((flag_ira_region == IRA_REGION_ALL
|
| 1621 |
|
|
|| flag_ira_region == IRA_REGION_MIXED)
|
| 1622 |
|
|
&& (parent = ALLOCNO_LOOP_TREE_NODE (a)->parent) != NULL
|
| 1623 |
|
|
&& (parent_a = parent->regno_allocno_map[i]) != NULL
|
| 1624 |
|
|
/* There are no caps yet. */
|
| 1625 |
|
|
&& bitmap_bit_p (ALLOCNO_LOOP_TREE_NODE
|
| 1626 |
|
|
(a)->border_allocnos,
|
| 1627 |
|
|
ALLOCNO_NUM (a)))
|
| 1628 |
|
|
{
|
| 1629 |
|
|
/* Propagate costs to upper levels in the region
|
| 1630 |
|
|
tree. */
|
| 1631 |
|
|
parent_a_num = ALLOCNO_NUM (parent_a);
|
| 1632 |
|
|
a_costs = COSTS (total_allocno_costs, a_num)->cost;
|
| 1633 |
|
|
p_costs = COSTS (total_allocno_costs, parent_a_num)->cost;
|
| 1634 |
|
|
for (k = cost_classes_ptr->num - 1; k >= 0; k--)
|
| 1635 |
|
|
{
|
| 1636 |
|
|
add_cost = a_costs[k];
|
| 1637 |
|
|
if (add_cost > 0 && INT_MAX - add_cost < p_costs[k])
|
| 1638 |
|
|
p_costs[k] = INT_MAX;
|
| 1639 |
|
|
else
|
| 1640 |
|
|
p_costs[k] += add_cost;
|
| 1641 |
|
|
}
|
| 1642 |
|
|
add_cost = COSTS (total_allocno_costs, a_num)->mem_cost;
|
| 1643 |
|
|
if (add_cost > 0
|
| 1644 |
|
|
&& (INT_MAX - add_cost
|
| 1645 |
|
|
< COSTS (total_allocno_costs,
|
| 1646 |
|
|
parent_a_num)->mem_cost))
|
| 1647 |
|
|
COSTS (total_allocno_costs, parent_a_num)->mem_cost
|
| 1648 |
|
|
= INT_MAX;
|
| 1649 |
|
|
else
|
| 1650 |
|
|
COSTS (total_allocno_costs, parent_a_num)->mem_cost
|
| 1651 |
|
|
+= add_cost;
|
| 1652 |
|
|
|
| 1653 |
|
|
}
|
| 1654 |
|
|
a_costs = COSTS (costs, a_num)->cost;
|
| 1655 |
|
|
for (k = cost_classes_ptr->num - 1; k >= 0; k--)
|
| 1656 |
|
|
{
|
| 1657 |
|
|
add_cost = a_costs[k];
|
| 1658 |
|
|
if (add_cost > 0 && INT_MAX - add_cost < i_costs[k])
|
| 1659 |
|
|
i_costs[k] = INT_MAX;
|
| 1660 |
|
|
else
|
| 1661 |
|
|
i_costs[k] += add_cost;
|
| 1662 |
|
|
}
|
| 1663 |
|
|
add_cost = COSTS (costs, a_num)->mem_cost;
|
| 1664 |
|
|
if (add_cost > 0 && INT_MAX - add_cost < i_mem_cost)
|
| 1665 |
|
|
i_mem_cost = INT_MAX;
|
| 1666 |
|
|
else
|
| 1667 |
|
|
i_mem_cost += add_cost;
|
| 1668 |
|
|
}
|
| 1669 |
|
|
}
|
| 1670 |
|
|
if (equiv_savings < 0)
|
| 1671 |
|
|
i_mem_cost = -equiv_savings;
|
| 1672 |
|
|
else if (equiv_savings > 0)
|
| 1673 |
|
|
{
|
| 1674 |
|
|
i_mem_cost = 0;
|
| 1675 |
|
|
for (k = cost_classes_ptr->num - 1; k >= 0; k--)
|
| 1676 |
|
|
i_costs[k] += equiv_savings;
|
| 1677 |
|
|
}
|
| 1678 |
|
|
|
| 1679 |
|
|
best_cost = (1 << (HOST_BITS_PER_INT - 2)) - 1;
|
| 1680 |
|
|
best = ALL_REGS;
|
| 1681 |
|
|
alt_class = NO_REGS;
|
| 1682 |
|
|
/* Find best common class for all allocnos with the same
|
| 1683 |
|
|
regno. */
|
| 1684 |
|
|
for (k = 0; k < cost_classes_ptr->num; k++)
|
| 1685 |
|
|
{
|
| 1686 |
|
|
rclass = cost_classes[k];
|
| 1687 |
|
|
/* Ignore classes that are too small or invalid for this
|
| 1688 |
|
|
operand. */
|
| 1689 |
|
|
if (! contains_reg_of_mode[rclass][PSEUDO_REGNO_MODE (i)]
|
| 1690 |
|
|
#ifdef CANNOT_CHANGE_MODE_CLASS
|
| 1691 |
|
|
|| invalid_mode_change_p (i, (enum reg_class) rclass)
|
| 1692 |
|
|
#endif
|
| 1693 |
|
|
)
|
| 1694 |
|
|
continue;
|
| 1695 |
|
|
if (i_costs[k] < best_cost)
|
| 1696 |
|
|
{
|
| 1697 |
|
|
best_cost = i_costs[k];
|
| 1698 |
|
|
best = (enum reg_class) rclass;
|
| 1699 |
|
|
}
|
| 1700 |
|
|
else if (i_costs[k] == best_cost)
|
| 1701 |
|
|
best = ira_reg_class_subunion[best][rclass];
|
| 1702 |
|
|
if (pass == flag_expensive_optimizations
|
| 1703 |
|
|
/* We still prefer registers to memory even at this
|
| 1704 |
|
|
stage if their costs are the same. We will make
|
| 1705 |
|
|
a final decision during assigning hard registers
|
| 1706 |
|
|
when we have all info including more accurate
|
| 1707 |
|
|
costs which might be affected by assigning hard
|
| 1708 |
|
|
registers to other pseudos because the pseudos
|
| 1709 |
|
|
involved in moves can be coalesced. */
|
| 1710 |
|
|
&& i_costs[k] <= i_mem_cost
|
| 1711 |
|
|
&& (reg_class_size[reg_class_subunion[alt_class][rclass]]
|
| 1712 |
|
|
> reg_class_size[alt_class]))
|
| 1713 |
|
|
alt_class = reg_class_subunion[alt_class][rclass];
|
| 1714 |
|
|
}
|
| 1715 |
|
|
alt_class = ira_allocno_class_translate[alt_class];
|
| 1716 |
|
|
if (best_cost > i_mem_cost)
|
| 1717 |
|
|
regno_aclass[i] = NO_REGS;
|
| 1718 |
|
|
else
|
| 1719 |
|
|
{
|
| 1720 |
|
|
/* Make the common class the biggest class of best and
|
| 1721 |
|
|
alt_class. */
|
| 1722 |
|
|
regno_aclass[i]
|
| 1723 |
|
|
= ira_reg_class_superunion[best][alt_class];
|
| 1724 |
|
|
ira_assert (regno_aclass[i] != NO_REGS
|
| 1725 |
|
|
&& ira_reg_allocno_class_p[regno_aclass[i]]);
|
| 1726 |
|
|
}
|
| 1727 |
|
|
if (pass == flag_expensive_optimizations)
|
| 1728 |
|
|
{
|
| 1729 |
|
|
if (best_cost > i_mem_cost)
|
| 1730 |
|
|
best = alt_class = NO_REGS;
|
| 1731 |
|
|
else if (best == alt_class)
|
| 1732 |
|
|
alt_class = NO_REGS;
|
| 1733 |
|
|
setup_reg_classes (i, best, alt_class, regno_aclass[i]);
|
| 1734 |
|
|
if ((!allocno_p || internal_flag_ira_verbose > 2)
|
| 1735 |
|
|
&& dump_file != NULL)
|
| 1736 |
|
|
fprintf (dump_file,
|
| 1737 |
|
|
" r%d: preferred %s, alternative %s, allocno %s\n",
|
| 1738 |
|
|
i, reg_class_names[best], reg_class_names[alt_class],
|
| 1739 |
|
|
reg_class_names[regno_aclass[i]]);
|
| 1740 |
|
|
}
|
| 1741 |
|
|
regno_best_class[i] = best;
|
| 1742 |
|
|
if (! allocno_p)
|
| 1743 |
|
|
{
|
| 1744 |
|
|
pref[i] = best_cost > i_mem_cost ? NO_REGS : best;
|
| 1745 |
|
|
continue;
|
| 1746 |
|
|
}
|
| 1747 |
|
|
for (a = ira_regno_allocno_map[i];
|
| 1748 |
|
|
a != NULL;
|
| 1749 |
|
|
a = ALLOCNO_NEXT_REGNO_ALLOCNO (a))
|
| 1750 |
|
|
{
|
| 1751 |
|
|
a_num = ALLOCNO_NUM (a);
|
| 1752 |
|
|
if (regno_aclass[i] == NO_REGS)
|
| 1753 |
|
|
best = NO_REGS;
|
| 1754 |
|
|
else
|
| 1755 |
|
|
{
|
| 1756 |
|
|
int *total_a_costs = COSTS (total_allocno_costs, a_num)->cost;
|
| 1757 |
|
|
int *a_costs = COSTS (costs, a_num)->cost;
|
| 1758 |
|
|
|
| 1759 |
|
|
/* Finding best class which is subset of the common
|
| 1760 |
|
|
class. */
|
| 1761 |
|
|
best_cost = (1 << (HOST_BITS_PER_INT - 2)) - 1;
|
| 1762 |
|
|
allocno_cost = best_cost;
|
| 1763 |
|
|
best = ALL_REGS;
|
| 1764 |
|
|
for (k = 0; k < cost_classes_ptr->num; k++)
|
| 1765 |
|
|
{
|
| 1766 |
|
|
rclass = cost_classes[k];
|
| 1767 |
|
|
if (! ira_class_subset_p[rclass][regno_aclass[i]])
|
| 1768 |
|
|
continue;
|
| 1769 |
|
|
/* Ignore classes that are too small or invalid
|
| 1770 |
|
|
for this operand. */
|
| 1771 |
|
|
if (! contains_reg_of_mode[rclass][PSEUDO_REGNO_MODE (i)]
|
| 1772 |
|
|
#ifdef CANNOT_CHANGE_MODE_CLASS
|
| 1773 |
|
|
|| invalid_mode_change_p (i, (enum reg_class) rclass)
|
| 1774 |
|
|
#endif
|
| 1775 |
|
|
)
|
| 1776 |
|
|
;
|
| 1777 |
|
|
else if (total_a_costs[k] < best_cost)
|
| 1778 |
|
|
{
|
| 1779 |
|
|
best_cost = total_a_costs[k];
|
| 1780 |
|
|
allocno_cost = a_costs[k];
|
| 1781 |
|
|
best = (enum reg_class) rclass;
|
| 1782 |
|
|
}
|
| 1783 |
|
|
else if (total_a_costs[k] == best_cost)
|
| 1784 |
|
|
{
|
| 1785 |
|
|
best = ira_reg_class_subunion[best][rclass];
|
| 1786 |
|
|
allocno_cost = MAX (allocno_cost, a_costs[k]);
|
| 1787 |
|
|
}
|
| 1788 |
|
|
}
|
| 1789 |
|
|
ALLOCNO_CLASS_COST (a) = allocno_cost;
|
| 1790 |
|
|
}
|
| 1791 |
|
|
if (internal_flag_ira_verbose > 2 && dump_file != NULL
|
| 1792 |
|
|
&& (pass == 0 || pref[a_num] != best))
|
| 1793 |
|
|
{
|
| 1794 |
|
|
fprintf (dump_file, " a%d (r%d,", a_num, i);
|
| 1795 |
|
|
if ((bb = ALLOCNO_LOOP_TREE_NODE (a)->bb) != NULL)
|
| 1796 |
|
|
fprintf (dump_file, "b%d", bb->index);
|
| 1797 |
|
|
else
|
| 1798 |
|
|
fprintf (dump_file, "l%d",
|
| 1799 |
|
|
ALLOCNO_LOOP_TREE_NODE (a)->loop_num);
|
| 1800 |
|
|
fprintf (dump_file, ") best %s, allocno %s\n",
|
| 1801 |
|
|
reg_class_names[best],
|
| 1802 |
|
|
reg_class_names[regno_aclass[i]]);
|
| 1803 |
|
|
}
|
| 1804 |
|
|
pref[a_num] = best;
|
| 1805 |
|
|
}
|
| 1806 |
|
|
}
|
| 1807 |
|
|
|
| 1808 |
|
|
if (internal_flag_ira_verbose > 4 && dump_file)
|
| 1809 |
|
|
{
|
| 1810 |
|
|
if (allocno_p)
|
| 1811 |
|
|
print_allocno_costs (dump_file);
|
| 1812 |
|
|
else
|
| 1813 |
|
|
print_pseudo_costs (dump_file);
|
| 1814 |
|
|
fprintf (dump_file,"\n");
|
| 1815 |
|
|
}
|
| 1816 |
|
|
}
|
| 1817 |
|
|
ira_free (regno_best_class);
|
| 1818 |
|
|
}
|
| 1819 |
|
|
|
| 1820 |
|
|
|
| 1821 |
|
|
|
| 1822 |
|
|
/* Process moves involving hard regs to modify allocno hard register
|
| 1823 |
|
|
costs. We can do this only after determining allocno class. If a
|
| 1824 |
|
|
hard register forms a register class, than moves with the hard
|
| 1825 |
|
|
register are already taken into account in class costs for the
|
| 1826 |
|
|
allocno. */
|
| 1827 |
|
|
static void
|
| 1828 |
|
|
process_bb_node_for_hard_reg_moves (ira_loop_tree_node_t loop_tree_node)
|
| 1829 |
|
|
{
|
| 1830 |
|
|
int i, freq, cost, src_regno, dst_regno, hard_regno;
|
| 1831 |
|
|
bool to_p;
|
| 1832 |
|
|
ira_allocno_t a;
|
| 1833 |
|
|
enum reg_class rclass, hard_reg_class;
|
| 1834 |
|
|
enum machine_mode mode;
|
| 1835 |
|
|
basic_block bb;
|
| 1836 |
|
|
rtx insn, set, src, dst;
|
| 1837 |
|
|
|
| 1838 |
|
|
bb = loop_tree_node->bb;
|
| 1839 |
|
|
if (bb == NULL)
|
| 1840 |
|
|
return;
|
| 1841 |
|
|
freq = REG_FREQ_FROM_BB (bb);
|
| 1842 |
|
|
if (freq == 0)
|
| 1843 |
|
|
freq = 1;
|
| 1844 |
|
|
FOR_BB_INSNS (bb, insn)
|
| 1845 |
|
|
{
|
| 1846 |
|
|
if (!NONDEBUG_INSN_P (insn))
|
| 1847 |
|
|
continue;
|
| 1848 |
|
|
set = single_set (insn);
|
| 1849 |
|
|
if (set == NULL_RTX)
|
| 1850 |
|
|
continue;
|
| 1851 |
|
|
dst = SET_DEST (set);
|
| 1852 |
|
|
src = SET_SRC (set);
|
| 1853 |
|
|
if (! REG_P (dst) || ! REG_P (src))
|
| 1854 |
|
|
continue;
|
| 1855 |
|
|
dst_regno = REGNO (dst);
|
| 1856 |
|
|
src_regno = REGNO (src);
|
| 1857 |
|
|
if (dst_regno >= FIRST_PSEUDO_REGISTER
|
| 1858 |
|
|
&& src_regno < FIRST_PSEUDO_REGISTER)
|
| 1859 |
|
|
{
|
| 1860 |
|
|
hard_regno = src_regno;
|
| 1861 |
|
|
to_p = true;
|
| 1862 |
|
|
a = ira_curr_regno_allocno_map[dst_regno];
|
| 1863 |
|
|
}
|
| 1864 |
|
|
else if (src_regno >= FIRST_PSEUDO_REGISTER
|
| 1865 |
|
|
&& dst_regno < FIRST_PSEUDO_REGISTER)
|
| 1866 |
|
|
{
|
| 1867 |
|
|
hard_regno = dst_regno;
|
| 1868 |
|
|
to_p = false;
|
| 1869 |
|
|
a = ira_curr_regno_allocno_map[src_regno];
|
| 1870 |
|
|
}
|
| 1871 |
|
|
else
|
| 1872 |
|
|
continue;
|
| 1873 |
|
|
rclass = ALLOCNO_CLASS (a);
|
| 1874 |
|
|
if (! TEST_HARD_REG_BIT (reg_class_contents[rclass], hard_regno))
|
| 1875 |
|
|
continue;
|
| 1876 |
|
|
i = ira_class_hard_reg_index[rclass][hard_regno];
|
| 1877 |
|
|
if (i < 0)
|
| 1878 |
|
|
continue;
|
| 1879 |
|
|
mode = ALLOCNO_MODE (a);
|
| 1880 |
|
|
hard_reg_class = REGNO_REG_CLASS (hard_regno);
|
| 1881 |
|
|
ira_init_register_move_cost_if_necessary (mode);
|
| 1882 |
|
|
cost
|
| 1883 |
|
|
= (to_p ? ira_register_move_cost[mode][hard_reg_class][rclass]
|
| 1884 |
|
|
: ira_register_move_cost[mode][rclass][hard_reg_class]) * freq;
|
| 1885 |
|
|
ira_allocate_and_set_costs (&ALLOCNO_HARD_REG_COSTS (a), rclass,
|
| 1886 |
|
|
ALLOCNO_CLASS_COST (a));
|
| 1887 |
|
|
ira_allocate_and_set_costs (&ALLOCNO_CONFLICT_HARD_REG_COSTS (a),
|
| 1888 |
|
|
rclass, 0);
|
| 1889 |
|
|
ALLOCNO_HARD_REG_COSTS (a)[i] -= cost;
|
| 1890 |
|
|
ALLOCNO_CONFLICT_HARD_REG_COSTS (a)[i] -= cost;
|
| 1891 |
|
|
ALLOCNO_CLASS_COST (a) = MIN (ALLOCNO_CLASS_COST (a),
|
| 1892 |
|
|
ALLOCNO_HARD_REG_COSTS (a)[i]);
|
| 1893 |
|
|
}
|
| 1894 |
|
|
}
|
| 1895 |
|
|
|
| 1896 |
|
|
/* After we find hard register and memory costs for allocnos, define
|
| 1897 |
|
|
its class and modify hard register cost because insns moving
|
| 1898 |
|
|
allocno to/from hard registers. */
|
| 1899 |
|
|
static void
|
| 1900 |
|
|
setup_allocno_class_and_costs (void)
|
| 1901 |
|
|
{
|
| 1902 |
|
|
int i, j, n, regno, hard_regno, num;
|
| 1903 |
|
|
int *reg_costs;
|
| 1904 |
|
|
enum reg_class aclass, rclass;
|
| 1905 |
|
|
ira_allocno_t a;
|
| 1906 |
|
|
ira_allocno_iterator ai;
|
| 1907 |
|
|
cost_classes_t cost_classes_ptr;
|
| 1908 |
|
|
|
| 1909 |
|
|
ira_assert (allocno_p);
|
| 1910 |
|
|
FOR_EACH_ALLOCNO (a, ai)
|
| 1911 |
|
|
{
|
| 1912 |
|
|
i = ALLOCNO_NUM (a);
|
| 1913 |
|
|
regno = ALLOCNO_REGNO (a);
|
| 1914 |
|
|
aclass = regno_aclass[regno];
|
| 1915 |
|
|
cost_classes_ptr = regno_cost_classes[regno];
|
| 1916 |
|
|
ira_assert (pref[i] == NO_REGS || aclass != NO_REGS);
|
| 1917 |
|
|
ALLOCNO_MEMORY_COST (a) = COSTS (costs, i)->mem_cost;
|
| 1918 |
|
|
ira_set_allocno_class (a, aclass);
|
| 1919 |
|
|
if (aclass == NO_REGS)
|
| 1920 |
|
|
continue;
|
| 1921 |
|
|
if (optimize && ALLOCNO_CLASS (a) != pref[i])
|
| 1922 |
|
|
{
|
| 1923 |
|
|
n = ira_class_hard_regs_num[aclass];
|
| 1924 |
|
|
ALLOCNO_HARD_REG_COSTS (a)
|
| 1925 |
|
|
= reg_costs = ira_allocate_cost_vector (aclass);
|
| 1926 |
|
|
for (j = n - 1; j >= 0; j--)
|
| 1927 |
|
|
{
|
| 1928 |
|
|
hard_regno = ira_class_hard_regs[aclass][j];
|
| 1929 |
|
|
if (TEST_HARD_REG_BIT (reg_class_contents[pref[i]], hard_regno))
|
| 1930 |
|
|
reg_costs[j] = ALLOCNO_CLASS_COST (a);
|
| 1931 |
|
|
else
|
| 1932 |
|
|
{
|
| 1933 |
|
|
rclass = REGNO_REG_CLASS (hard_regno);
|
| 1934 |
|
|
num = cost_classes_ptr->index[rclass];
|
| 1935 |
|
|
if (num < 0)
|
| 1936 |
|
|
{
|
| 1937 |
|
|
num = cost_classes_ptr->hard_regno_index[hard_regno];
|
| 1938 |
|
|
ira_assert (num >= 0);
|
| 1939 |
|
|
}
|
| 1940 |
|
|
reg_costs[j] = COSTS (costs, i)->cost[num];
|
| 1941 |
|
|
}
|
| 1942 |
|
|
}
|
| 1943 |
|
|
}
|
| 1944 |
|
|
}
|
| 1945 |
|
|
if (optimize)
|
| 1946 |
|
|
ira_traverse_loop_tree (true, ira_loop_tree_root,
|
| 1947 |
|
|
process_bb_node_for_hard_reg_moves, NULL);
|
| 1948 |
|
|
}
|
| 1949 |
|
|
|
| 1950 |
|
|
|
| 1951 |
|
|
|
| 1952 |
|
|
/* Function called once during compiler work. */
|
| 1953 |
|
|
void
|
| 1954 |
|
|
ira_init_costs_once (void)
|
| 1955 |
|
|
{
|
| 1956 |
|
|
int i;
|
| 1957 |
|
|
|
| 1958 |
|
|
init_cost = NULL;
|
| 1959 |
|
|
for (i = 0; i < MAX_RECOG_OPERANDS; i++)
|
| 1960 |
|
|
{
|
| 1961 |
|
|
op_costs[i] = NULL;
|
| 1962 |
|
|
this_op_costs[i] = NULL;
|
| 1963 |
|
|
}
|
| 1964 |
|
|
temp_costs = NULL;
|
| 1965 |
|
|
}
|
| 1966 |
|
|
|
| 1967 |
|
|
/* Free allocated temporary cost vectors. */
|
| 1968 |
|
|
static void
|
| 1969 |
|
|
free_ira_costs (void)
|
| 1970 |
|
|
{
|
| 1971 |
|
|
int i;
|
| 1972 |
|
|
|
| 1973 |
|
|
free (init_cost);
|
| 1974 |
|
|
init_cost = NULL;
|
| 1975 |
|
|
for (i = 0; i < MAX_RECOG_OPERANDS; i++)
|
| 1976 |
|
|
{
|
| 1977 |
|
|
free (op_costs[i]);
|
| 1978 |
|
|
free (this_op_costs[i]);
|
| 1979 |
|
|
op_costs[i] = this_op_costs[i] = NULL;
|
| 1980 |
|
|
}
|
| 1981 |
|
|
free (temp_costs);
|
| 1982 |
|
|
temp_costs = NULL;
|
| 1983 |
|
|
}
|
| 1984 |
|
|
|
| 1985 |
|
|
/* This is called each time register related information is
|
| 1986 |
|
|
changed. */
|
| 1987 |
|
|
void
|
| 1988 |
|
|
ira_init_costs (void)
|
| 1989 |
|
|
{
|
| 1990 |
|
|
int i;
|
| 1991 |
|
|
|
| 1992 |
|
|
free_ira_costs ();
|
| 1993 |
|
|
max_struct_costs_size
|
| 1994 |
|
|
= sizeof (struct costs) + sizeof (int) * (ira_important_classes_num - 1);
|
| 1995 |
|
|
/* Don't use ira_allocate because vectors live through several IRA
|
| 1996 |
|
|
calls. */
|
| 1997 |
|
|
init_cost = (struct costs *) xmalloc (max_struct_costs_size);
|
| 1998 |
|
|
init_cost->mem_cost = 1000000;
|
| 1999 |
|
|
for (i = 0; i < ira_important_classes_num; i++)
|
| 2000 |
|
|
init_cost->cost[i] = 1000000;
|
| 2001 |
|
|
for (i = 0; i < MAX_RECOG_OPERANDS; i++)
|
| 2002 |
|
|
{
|
| 2003 |
|
|
op_costs[i] = (struct costs *) xmalloc (max_struct_costs_size);
|
| 2004 |
|
|
this_op_costs[i] = (struct costs *) xmalloc (max_struct_costs_size);
|
| 2005 |
|
|
}
|
| 2006 |
|
|
temp_costs = (struct costs *) xmalloc (max_struct_costs_size);
|
| 2007 |
|
|
}
|
| 2008 |
|
|
|
| 2009 |
|
|
/* Function called once at the end of compiler work. */
|
| 2010 |
|
|
void
|
| 2011 |
|
|
ira_finish_costs_once (void)
|
| 2012 |
|
|
{
|
| 2013 |
|
|
free_ira_costs ();
|
| 2014 |
|
|
}
|
| 2015 |
|
|
|
| 2016 |
|
|
|
| 2017 |
|
|
|
| 2018 |
|
|
/* Common initialization function for ira_costs and
|
| 2019 |
|
|
ira_set_pseudo_classes. */
|
| 2020 |
|
|
static void
|
| 2021 |
|
|
init_costs (void)
|
| 2022 |
|
|
{
|
| 2023 |
|
|
init_subregs_of_mode ();
|
| 2024 |
|
|
costs = (struct costs *) ira_allocate (max_struct_costs_size
|
| 2025 |
|
|
* cost_elements_num);
|
| 2026 |
|
|
pref_buffer = (enum reg_class *) ira_allocate (sizeof (enum reg_class)
|
| 2027 |
|
|
* cost_elements_num);
|
| 2028 |
|
|
regno_aclass = (enum reg_class *) ira_allocate (sizeof (enum reg_class)
|
| 2029 |
|
|
* max_reg_num ());
|
| 2030 |
|
|
regno_equiv_gains = (int *) ira_allocate (sizeof (int) * max_reg_num ());
|
| 2031 |
|
|
memset (regno_equiv_gains, 0, sizeof (int) * max_reg_num ());
|
| 2032 |
|
|
}
|
| 2033 |
|
|
|
| 2034 |
|
|
/* Common finalization function for ira_costs and
|
| 2035 |
|
|
ira_set_pseudo_classes. */
|
| 2036 |
|
|
static void
|
| 2037 |
|
|
finish_costs (void)
|
| 2038 |
|
|
{
|
| 2039 |
|
|
finish_subregs_of_mode ();
|
| 2040 |
|
|
ira_free (regno_equiv_gains);
|
| 2041 |
|
|
ira_free (regno_aclass);
|
| 2042 |
|
|
ira_free (pref_buffer);
|
| 2043 |
|
|
ira_free (costs);
|
| 2044 |
|
|
}
|
| 2045 |
|
|
|
| 2046 |
|
|
/* Entry function which defines register class, memory and hard
|
| 2047 |
|
|
register costs for each allocno. */
|
| 2048 |
|
|
void
|
| 2049 |
|
|
ira_costs (void)
|
| 2050 |
|
|
{
|
| 2051 |
|
|
allocno_p = true;
|
| 2052 |
|
|
cost_elements_num = ira_allocnos_num;
|
| 2053 |
|
|
init_costs ();
|
| 2054 |
|
|
total_allocno_costs = (struct costs *) ira_allocate (max_struct_costs_size
|
| 2055 |
|
|
* ira_allocnos_num);
|
| 2056 |
|
|
initiate_regno_cost_classes ();
|
| 2057 |
|
|
calculate_elim_costs_all_insns ();
|
| 2058 |
|
|
find_costs_and_classes (ira_dump_file);
|
| 2059 |
|
|
setup_allocno_class_and_costs ();
|
| 2060 |
|
|
finish_regno_cost_classes ();
|
| 2061 |
|
|
finish_costs ();
|
| 2062 |
|
|
ira_free (total_allocno_costs);
|
| 2063 |
|
|
}
|
| 2064 |
|
|
|
| 2065 |
|
|
/* Entry function which defines classes for pseudos. */
|
| 2066 |
|
|
void
|
| 2067 |
|
|
ira_set_pseudo_classes (FILE *dump_file)
|
| 2068 |
|
|
{
|
| 2069 |
|
|
allocno_p = false;
|
| 2070 |
|
|
internal_flag_ira_verbose = flag_ira_verbose;
|
| 2071 |
|
|
cost_elements_num = max_reg_num ();
|
| 2072 |
|
|
init_costs ();
|
| 2073 |
|
|
initiate_regno_cost_classes ();
|
| 2074 |
|
|
find_costs_and_classes (dump_file);
|
| 2075 |
|
|
finish_regno_cost_classes ();
|
| 2076 |
|
|
pseudo_classes_defined_p = true;
|
| 2077 |
|
|
finish_costs ();
|
| 2078 |
|
|
}
|
| 2079 |
|
|
|
| 2080 |
|
|
|
| 2081 |
|
|
|
| 2082 |
|
|
/* Change hard register costs for allocnos which lives through
|
| 2083 |
|
|
function calls. This is called only when we found all intersected
|
| 2084 |
|
|
calls during building allocno live ranges. */
|
| 2085 |
|
|
void
|
| 2086 |
|
|
ira_tune_allocno_costs (void)
|
| 2087 |
|
|
{
|
| 2088 |
|
|
int j, n, regno;
|
| 2089 |
|
|
int cost, min_cost, *reg_costs;
|
| 2090 |
|
|
enum reg_class aclass, rclass;
|
| 2091 |
|
|
enum machine_mode mode;
|
| 2092 |
|
|
ira_allocno_t a;
|
| 2093 |
|
|
ira_allocno_iterator ai;
|
| 2094 |
|
|
ira_allocno_object_iterator oi;
|
| 2095 |
|
|
ira_object_t obj;
|
| 2096 |
|
|
bool skip_p;
|
| 2097 |
|
|
|
| 2098 |
|
|
FOR_EACH_ALLOCNO (a, ai)
|
| 2099 |
|
|
{
|
| 2100 |
|
|
aclass = ALLOCNO_CLASS (a);
|
| 2101 |
|
|
if (aclass == NO_REGS)
|
| 2102 |
|
|
continue;
|
| 2103 |
|
|
mode = ALLOCNO_MODE (a);
|
| 2104 |
|
|
n = ira_class_hard_regs_num[aclass];
|
| 2105 |
|
|
min_cost = INT_MAX;
|
| 2106 |
|
|
if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0)
|
| 2107 |
|
|
{
|
| 2108 |
|
|
ira_allocate_and_set_costs
|
| 2109 |
|
|
(&ALLOCNO_HARD_REG_COSTS (a), aclass,
|
| 2110 |
|
|
ALLOCNO_CLASS_COST (a));
|
| 2111 |
|
|
reg_costs = ALLOCNO_HARD_REG_COSTS (a);
|
| 2112 |
|
|
for (j = n - 1; j >= 0; j--)
|
| 2113 |
|
|
{
|
| 2114 |
|
|
regno = ira_class_hard_regs[aclass][j];
|
| 2115 |
|
|
skip_p = false;
|
| 2116 |
|
|
FOR_EACH_ALLOCNO_OBJECT (a, obj, oi)
|
| 2117 |
|
|
{
|
| 2118 |
|
|
if (ira_hard_reg_set_intersection_p (regno, mode,
|
| 2119 |
|
|
OBJECT_CONFLICT_HARD_REGS
|
| 2120 |
|
|
(obj)))
|
| 2121 |
|
|
{
|
| 2122 |
|
|
skip_p = true;
|
| 2123 |
|
|
break;
|
| 2124 |
|
|
}
|
| 2125 |
|
|
}
|
| 2126 |
|
|
if (skip_p)
|
| 2127 |
|
|
continue;
|
| 2128 |
|
|
rclass = REGNO_REG_CLASS (regno);
|
| 2129 |
|
|
cost = 0;
|
| 2130 |
|
|
if (ira_hard_reg_set_intersection_p (regno, mode, call_used_reg_set)
|
| 2131 |
|
|
|| HARD_REGNO_CALL_PART_CLOBBERED (regno, mode))
|
| 2132 |
|
|
cost += (ALLOCNO_CALL_FREQ (a)
|
| 2133 |
|
|
* (ira_memory_move_cost[mode][rclass][0]
|
| 2134 |
|
|
+ ira_memory_move_cost[mode][rclass][1]));
|
| 2135 |
|
|
#ifdef IRA_HARD_REGNO_ADD_COST_MULTIPLIER
|
| 2136 |
|
|
cost += ((ira_memory_move_cost[mode][rclass][0]
|
| 2137 |
|
|
+ ira_memory_move_cost[mode][rclass][1])
|
| 2138 |
|
|
* ALLOCNO_FREQ (a)
|
| 2139 |
|
|
* IRA_HARD_REGNO_ADD_COST_MULTIPLIER (regno) / 2);
|
| 2140 |
|
|
#endif
|
| 2141 |
|
|
if (INT_MAX - cost < reg_costs[j])
|
| 2142 |
|
|
reg_costs[j] = INT_MAX;
|
| 2143 |
|
|
else
|
| 2144 |
|
|
reg_costs[j] += cost;
|
| 2145 |
|
|
if (min_cost > reg_costs[j])
|
| 2146 |
|
|
min_cost = reg_costs[j];
|
| 2147 |
|
|
}
|
| 2148 |
|
|
}
|
| 2149 |
|
|
if (min_cost != INT_MAX)
|
| 2150 |
|
|
ALLOCNO_CLASS_COST (a) = min_cost;
|
| 2151 |
|
|
|
| 2152 |
|
|
/* Some targets allow pseudos to be allocated to unaligned sequences
|
| 2153 |
|
|
of hard registers. However, selecting an unaligned sequence can
|
| 2154 |
|
|
unnecessarily restrict later allocations. So increase the cost of
|
| 2155 |
|
|
unaligned hard regs to encourage the use of aligned hard regs. */
|
| 2156 |
|
|
{
|
| 2157 |
|
|
const int nregs = ira_reg_class_max_nregs[aclass][ALLOCNO_MODE (a)];
|
| 2158 |
|
|
|
| 2159 |
|
|
if (nregs > 1)
|
| 2160 |
|
|
{
|
| 2161 |
|
|
ira_allocate_and_set_costs
|
| 2162 |
|
|
(&ALLOCNO_HARD_REG_COSTS (a), aclass, ALLOCNO_CLASS_COST (a));
|
| 2163 |
|
|
reg_costs = ALLOCNO_HARD_REG_COSTS (a);
|
| 2164 |
|
|
for (j = n - 1; j >= 0; j--)
|
| 2165 |
|
|
{
|
| 2166 |
|
|
regno = ira_non_ordered_class_hard_regs[aclass][j];
|
| 2167 |
|
|
if ((regno % nregs) != 0)
|
| 2168 |
|
|
{
|
| 2169 |
|
|
int index = ira_class_hard_reg_index[aclass][regno];
|
| 2170 |
|
|
ira_assert (index != -1);
|
| 2171 |
|
|
reg_costs[index] += ALLOCNO_FREQ (a);
|
| 2172 |
|
|
}
|
| 2173 |
|
|
}
|
| 2174 |
|
|
}
|
| 2175 |
|
|
}
|
| 2176 |
|
|
}
|
| 2177 |
|
|
}
|
| 2178 |
|
|
|
| 2179 |
|
|
/* Add COST to the estimated gain for eliminating REGNO with its
|
| 2180 |
|
|
equivalence. If COST is zero, record that no such elimination is
|
| 2181 |
|
|
possible. */
|
| 2182 |
|
|
|
| 2183 |
|
|
void
|
| 2184 |
|
|
ira_adjust_equiv_reg_cost (unsigned regno, int cost)
|
| 2185 |
|
|
{
|
| 2186 |
|
|
if (cost == 0)
|
| 2187 |
|
|
regno_equiv_gains[regno] = 0;
|
| 2188 |
|
|
else
|
| 2189 |
|
|
regno_equiv_gains[regno] += cost;
|
| 2190 |
|
|
}
|