]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/ira-color.c
2014-10-27 Andrew MacLeod <amacleod@redhat.com>
[thirdparty/gcc.git] / gcc / ira-color.c
CommitLineData
47dd2e78 1/* IRA allocation based on graph coloring.
3aea1f79 2 Copyright (C) 2006-2014 Free Software Foundation, Inc.
47dd2e78 3 Contributed by Vladimir Makarov <vmakarov@redhat.com>.
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 3, or (at your option) any later
10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
20
21#include "config.h"
22#include "system.h"
23#include "coretypes.h"
24#include "tm.h"
25#include "rtl.h"
26#include "tm_p.h"
27#include "target.h"
28#include "regs.h"
29#include "flags.h"
30#include "sbitmap.h"
31#include "bitmap.h"
d9dd21a8 32#include "hash-table.h"
47dd2e78 33#include "hard-reg-set.h"
94ea8568 34#include "predict.h"
35#include "vec.h"
36#include "hashtab.h"
37#include "hash-set.h"
38#include "machmode.h"
39#include "input.h"
40#include "function.h"
41#include "dominance.h"
42#include "cfg.h"
47dd2e78 43#include "basic-block.h"
44#include "expr.h"
0b205f4c 45#include "diagnostic-core.h"
47dd2e78 46#include "reload.h"
47#include "params.h"
48#include "df.h"
47dd2e78 49#include "ira-int.h"
50
7fcdc371 51typedef struct allocno_hard_regs *allocno_hard_regs_t;
66d9a7b9 52
53/* The structure contains information about hard registers can be
7fcdc371 54 assigned to allocnos. Usually it is allocno profitable hard
66d9a7b9 55 registers but in some cases this set can be a bit different. Major
56 reason of the difference is a requirement to use hard register sets
57 that form a tree or a forest (set of trees), i.e. hard register set
58 of a node should contain hard register sets of its subnodes. */
7fcdc371 59struct allocno_hard_regs
66d9a7b9 60{
61 /* Hard registers can be assigned to an allocno. */
62 HARD_REG_SET set;
63 /* Overall (spilling) cost of all allocnos with given register
64 set. */
3a4303e7 65 int64_t cost;
66d9a7b9 66};
67
7fcdc371 68typedef struct allocno_hard_regs_node *allocno_hard_regs_node_t;
66d9a7b9 69
7fcdc371 70/* A node representing allocno hard registers. Such nodes form a
66d9a7b9 71 forest (set of trees). Each subnode of given node in the forest
7fcdc371 72 refers for hard register set (usually allocno profitable hard
66d9a7b9 73 register set) which is a subset of one referred from given
74 node. */
7fcdc371 75struct allocno_hard_regs_node
66d9a7b9 76{
77 /* Set up number of the node in preorder traversing of the forest. */
78 int preorder_num;
79 /* Used for different calculation like finding conflict size of an
80 allocno. */
81 int check;
82 /* Used for calculation of conflict size of an allocno. The
7fcdc371 83 conflict size of the allocno is maximal number of given allocno
66d9a7b9 84 hard registers needed for allocation of the conflicting allocnos.
85 Given allocno is trivially colored if this number plus the number
86 of hard registers needed for given allocno is not greater than
87 the number of given allocno hard register set. */
88 int conflict_size;
89 /* The number of hard registers given by member hard_regs. */
90 int hard_regs_num;
91 /* The following member is used to form the final forest. */
92 bool used_p;
93 /* Pointer to the corresponding profitable hard registers. */
7fcdc371 94 allocno_hard_regs_t hard_regs;
66d9a7b9 95 /* Parent, first subnode, previous and next node with the same
96 parent in the forest. */
7fcdc371 97 allocno_hard_regs_node_t parent, first, prev, next;
66d9a7b9 98};
99
284f0696 100/* Info about changing hard reg costs of an allocno. */
101struct update_cost_record
102{
103 /* Hard regno for which we changed the cost. */
104 int hard_regno;
105 /* Divisor used when we changed the cost of HARD_REGNO. */
106 int divisor;
107 /* Next record for given allocno. */
108 struct update_cost_record *next;
109};
110
66d9a7b9 111/* To decrease footprint of ira_allocno structure we store all data
112 needed only for coloring in the following structure. */
113struct allocno_color_data
114{
115 /* TRUE value means that the allocno was not removed yet from the
b59bd98f 116 conflicting graph during coloring. */
66d9a7b9 117 unsigned int in_graph_p : 1;
118 /* TRUE if it is put on the stack to make other allocnos
119 colorable. */
120 unsigned int may_be_spilled_p : 1;
7fcdc371 121 /* TRUE if the allocno is trivially colorable. */
66d9a7b9 122 unsigned int colorable_p : 1;
123 /* Number of hard registers of the allocno class really
124 available for the allocno allocation. It is number of the
125 profitable hard regs. */
126 int available_regs_num;
127 /* Allocnos in a bucket (used in coloring) chained by the following
128 two members. */
129 ira_allocno_t next_bucket_allocno;
130 ira_allocno_t prev_bucket_allocno;
131 /* Used for temporary purposes. */
132 int temp;
7fcdc371 133 /* Used to exclude repeated processing. */
134 int last_process;
66d9a7b9 135 /* Profitable hard regs available for this pseudo allocation. It
136 means that the set excludes unavailable hard regs and hard regs
137 conflicting with given pseudo. They should be of the allocno
138 class. */
139 HARD_REG_SET profitable_hard_regs;
7fcdc371 140 /* The allocno hard registers node. */
141 allocno_hard_regs_node_t hard_regs_node;
142 /* Array of structures allocno_hard_regs_subnode representing
143 given allocno hard registers node (the 1st element in the array)
144 and all its subnodes in the tree (forest) of allocno hard
66d9a7b9 145 register nodes (see comments above). */
146 int hard_regs_subnodes_start;
3ad55f68 147 /* The length of the previous array. */
66d9a7b9 148 int hard_regs_subnodes_num;
284f0696 149 /* Records about updating allocno hard reg costs from copies. If
150 the allocno did not get expected hard register, these records are
151 used to restore original hard reg costs of allocnos connected to
152 this allocno by copies. */
153 struct update_cost_record *update_cost_records;
4bb79f36 154 /* Threads. We collect allocnos connected by copies into threads
155 and try to assign hard regs to allocnos by threads. */
156 /* Allocno representing all thread. */
157 ira_allocno_t first_thread_allocno;
158 /* Allocnos in thread forms a cycle list through the following
159 member. */
160 ira_allocno_t next_thread_allocno;
161 /* All thread frequency. Defined only for first thread allocno. */
162 int thread_freq;
66d9a7b9 163};
164
165/* See above. */
7fcdc371 166typedef struct allocno_color_data *allocno_color_data_t;
66d9a7b9 167
7fcdc371 168/* Container for storing allocno data concerning coloring. */
169static allocno_color_data_t allocno_color_data;
66d9a7b9 170
171/* Macro to access the data concerning coloring. */
7fcdc371 172#define ALLOCNO_COLOR_DATA(a) ((allocno_color_data_t) ALLOCNO_ADD_DATA (a))
173
174/* Used for finding allocno colorability to exclude repeated allocno
175 processing and for updating preferencing to exclude repeated
176 allocno processing during assignment. */
177static int curr_allocno_process;
66d9a7b9 178
47dd2e78 179/* This file contains code for regional graph coloring, spill/restore
180 code placement optimization, and code helping the reload pass to do
181 a better job. */
182
183/* Bitmap of allocnos which should be colored. */
184static bitmap coloring_allocno_bitmap;
185
186/* Bitmap of allocnos which should be taken into account during
187 coloring. In general case it contains allocnos from
188 coloring_allocno_bitmap plus other already colored conflicting
189 allocnos. */
190static bitmap consideration_allocno_bitmap;
191
47dd2e78 192/* All allocnos sorted according their priorities. */
193static ira_allocno_t *sorted_allocnos;
194
195/* Vec representing the stack of allocnos used during coloring. */
f1f41a6c 196static vec<ira_allocno_t> allocno_stack_vec;
47dd2e78 197
cf30f4b7 198/* Helper for qsort comparison callbacks - return a positive integer if
199 X > Y, or a negative value otherwise. Use a conditional expression
200 instead of a difference computation to insulate from possible overflow
201 issues, e.g. X - Y < 0 for some X > 0 and Y < 0. */
202#define SORTGT(x,y) (((x) > (y)) ? 1 : -1)
203
47dd2e78 204\f
205
7fcdc371 206/* Definition of vector of allocno hard registers. */
28491485 207
7fcdc371 208/* Vector of unique allocno hard registers. */
f1f41a6c 209static vec<allocno_hard_regs_t> allocno_hard_regs_vec;
66d9a7b9 210
d9dd21a8 211struct allocno_hard_regs_hasher : typed_noop_remove <allocno_hard_regs>
66d9a7b9 212{
d9dd21a8 213 typedef allocno_hard_regs value_type;
214 typedef allocno_hard_regs compare_type;
215 static inline hashval_t hash (const value_type *);
216 static inline bool equal (const value_type *, const compare_type *);
217};
66d9a7b9 218
d9dd21a8 219/* Returns hash value for allocno hard registers V. */
220inline hashval_t
221allocno_hard_regs_hasher::hash (const value_type *hv)
222{
66d9a7b9 223 return iterative_hash (&hv->set, sizeof (HARD_REG_SET), 0);
224}
225
7fcdc371 226/* Compares allocno hard registers V1 and V2. */
d9dd21a8 227inline bool
228allocno_hard_regs_hasher::equal (const value_type *hv1, const compare_type *hv2)
66d9a7b9 229{
66d9a7b9 230 return hard_reg_set_equal_p (hv1->set, hv2->set);
231}
232
7fcdc371 233/* Hash table of unique allocno hard registers. */
c1f445d2 234static hash_table<allocno_hard_regs_hasher> *allocno_hard_regs_htab;
66d9a7b9 235
7fcdc371 236/* Return allocno hard registers in the hash table equal to HV. */
237static allocno_hard_regs_t
238find_hard_regs (allocno_hard_regs_t hv)
66d9a7b9 239{
c1f445d2 240 return allocno_hard_regs_htab->find (hv);
66d9a7b9 241}
242
243/* Insert allocno hard registers HV in the hash table (if it is not
244 there yet) and return the value which in the table. */
7fcdc371 245static allocno_hard_regs_t
246insert_hard_regs (allocno_hard_regs_t hv)
66d9a7b9 247{
c1f445d2 248 allocno_hard_regs **slot = allocno_hard_regs_htab->find_slot (hv, INSERT);
66d9a7b9 249
250 if (*slot == NULL)
251 *slot = hv;
d9dd21a8 252 return *slot;
66d9a7b9 253}
254
7fcdc371 255/* Initialize data concerning allocno hard registers. */
66d9a7b9 256static void
7fcdc371 257init_allocno_hard_regs (void)
66d9a7b9 258{
f1f41a6c 259 allocno_hard_regs_vec.create (200);
c1f445d2 260 allocno_hard_regs_htab
261 = new hash_table<allocno_hard_regs_hasher> (200);
66d9a7b9 262}
263
7fcdc371 264/* Add (or update info about) allocno hard registers with SET and
66d9a7b9 265 COST. */
7fcdc371 266static allocno_hard_regs_t
3a4303e7 267add_allocno_hard_regs (HARD_REG_SET set, int64_t cost)
66d9a7b9 268{
7fcdc371 269 struct allocno_hard_regs temp;
270 allocno_hard_regs_t hv;
66d9a7b9 271
272 gcc_assert (! hard_reg_set_empty_p (set));
273 COPY_HARD_REG_SET (temp.set, set);
274 if ((hv = find_hard_regs (&temp)) != NULL)
275 hv->cost += cost;
276 else
277 {
7fcdc371 278 hv = ((struct allocno_hard_regs *)
279 ira_allocate (sizeof (struct allocno_hard_regs)));
66d9a7b9 280 COPY_HARD_REG_SET (hv->set, set);
281 hv->cost = cost;
f1f41a6c 282 allocno_hard_regs_vec.safe_push (hv);
66d9a7b9 283 insert_hard_regs (hv);
284 }
285 return hv;
286}
287
288/* Finalize data concerning allocno hard registers. */
289static void
7fcdc371 290finish_allocno_hard_regs (void)
66d9a7b9 291{
292 int i;
7fcdc371 293 allocno_hard_regs_t hv;
66d9a7b9 294
295 for (i = 0;
f1f41a6c 296 allocno_hard_regs_vec.iterate (i, &hv);
66d9a7b9 297 i++)
298 ira_free (hv);
c1f445d2 299 delete allocno_hard_regs_htab;
300 allocno_hard_regs_htab = NULL;
f1f41a6c 301 allocno_hard_regs_vec.release ();
66d9a7b9 302}
303
304/* Sort hard regs according to their frequency of usage. */
305static int
7fcdc371 306allocno_hard_regs_compare (const void *v1p, const void *v2p)
66d9a7b9 307{
7fcdc371 308 allocno_hard_regs_t hv1 = *(const allocno_hard_regs_t *) v1p;
309 allocno_hard_regs_t hv2 = *(const allocno_hard_regs_t *) v2p;
66d9a7b9 310
311 if (hv2->cost > hv1->cost)
312 return 1;
313 else if (hv2->cost < hv1->cost)
314 return -1;
315 else
316 return 0;
317}
318
319\f
320
321/* Used for finding a common ancestor of two allocno hard registers
322 nodes in the forest. We use the current value of
323 'node_check_tick' to mark all nodes from one node to the top and
324 then walking up from another node until we find a marked node.
325
326 It is also used to figure out allocno colorability as a mark that
327 we already reset value of member 'conflict_size' for the forest
328 node corresponding to the processed allocno. */
329static int node_check_tick;
330
331/* Roots of the forest containing hard register sets can be assigned
7fcdc371 332 to allocnos. */
333static allocno_hard_regs_node_t hard_regs_roots;
66d9a7b9 334
7fcdc371 335/* Definition of vector of allocno hard register nodes. */
66d9a7b9 336
337/* Vector used to create the forest. */
f1f41a6c 338static vec<allocno_hard_regs_node_t> hard_regs_node_vec;
66d9a7b9 339
7fcdc371 340/* Create and return allocno hard registers node containing allocno
66d9a7b9 341 hard registers HV. */
7fcdc371 342static allocno_hard_regs_node_t
343create_new_allocno_hard_regs_node (allocno_hard_regs_t hv)
66d9a7b9 344{
7fcdc371 345 allocno_hard_regs_node_t new_node;
66d9a7b9 346
7fcdc371 347 new_node = ((struct allocno_hard_regs_node *)
348 ira_allocate (sizeof (struct allocno_hard_regs_node)));
66d9a7b9 349 new_node->check = 0;
350 new_node->hard_regs = hv;
351 new_node->hard_regs_num = hard_reg_set_size (hv->set);
352 new_node->first = NULL;
353 new_node->used_p = false;
354 return new_node;
355}
356
7fcdc371 357/* Add allocno hard registers node NEW_NODE to the forest on its level
66d9a7b9 358 given by ROOTS. */
359static void
7fcdc371 360add_new_allocno_hard_regs_node_to_forest (allocno_hard_regs_node_t *roots,
361 allocno_hard_regs_node_t new_node)
66d9a7b9 362{
363 new_node->next = *roots;
364 if (new_node->next != NULL)
365 new_node->next->prev = new_node;
366 new_node->prev = NULL;
367 *roots = new_node;
368}
369
7fcdc371 370/* Add allocno hard registers HV (or its best approximation if it is
66d9a7b9 371 not possible) to the forest on its level given by ROOTS. */
372static void
7fcdc371 373add_allocno_hard_regs_to_forest (allocno_hard_regs_node_t *roots,
374 allocno_hard_regs_t hv)
66d9a7b9 375{
376 unsigned int i, start;
7fcdc371 377 allocno_hard_regs_node_t node, prev, new_node;
66d9a7b9 378 HARD_REG_SET temp_set;
7fcdc371 379 allocno_hard_regs_t hv2;
66d9a7b9 380
f1f41a6c 381 start = hard_regs_node_vec.length ();
66d9a7b9 382 for (node = *roots; node != NULL; node = node->next)
383 {
384 if (hard_reg_set_equal_p (hv->set, node->hard_regs->set))
385 return;
386 if (hard_reg_set_subset_p (hv->set, node->hard_regs->set))
387 {
7fcdc371 388 add_allocno_hard_regs_to_forest (&node->first, hv);
66d9a7b9 389 return;
390 }
391 if (hard_reg_set_subset_p (node->hard_regs->set, hv->set))
f1f41a6c 392 hard_regs_node_vec.safe_push (node);
66d9a7b9 393 else if (hard_reg_set_intersect_p (hv->set, node->hard_regs->set))
394 {
395 COPY_HARD_REG_SET (temp_set, hv->set);
396 AND_HARD_REG_SET (temp_set, node->hard_regs->set);
7fcdc371 397 hv2 = add_allocno_hard_regs (temp_set, hv->cost);
398 add_allocno_hard_regs_to_forest (&node->first, hv2);
66d9a7b9 399 }
400 }
f1f41a6c 401 if (hard_regs_node_vec.length ()
66d9a7b9 402 > start + 1)
403 {
404 /* Create a new node which contains nodes in hard_regs_node_vec. */
405 CLEAR_HARD_REG_SET (temp_set);
406 for (i = start;
f1f41a6c 407 i < hard_regs_node_vec.length ();
66d9a7b9 408 i++)
409 {
f1f41a6c 410 node = hard_regs_node_vec[i];
66d9a7b9 411 IOR_HARD_REG_SET (temp_set, node->hard_regs->set);
412 }
7fcdc371 413 hv = add_allocno_hard_regs (temp_set, hv->cost);
414 new_node = create_new_allocno_hard_regs_node (hv);
66d9a7b9 415 prev = NULL;
416 for (i = start;
f1f41a6c 417 i < hard_regs_node_vec.length ();
66d9a7b9 418 i++)
419 {
f1f41a6c 420 node = hard_regs_node_vec[i];
66d9a7b9 421 if (node->prev == NULL)
422 *roots = node->next;
423 else
424 node->prev->next = node->next;
425 if (node->next != NULL)
426 node->next->prev = node->prev;
427 if (prev == NULL)
428 new_node->first = node;
429 else
430 prev->next = node;
431 node->prev = prev;
432 node->next = NULL;
433 prev = node;
434 }
7fcdc371 435 add_new_allocno_hard_regs_node_to_forest (roots, new_node);
66d9a7b9 436 }
f1f41a6c 437 hard_regs_node_vec.truncate (start);
66d9a7b9 438}
439
7fcdc371 440/* Add allocno hard registers nodes starting with the forest level
66d9a7b9 441 given by FIRST which contains biggest set inside SET. */
442static void
7fcdc371 443collect_allocno_hard_regs_cover (allocno_hard_regs_node_t first,
66d9a7b9 444 HARD_REG_SET set)
445{
7fcdc371 446 allocno_hard_regs_node_t node;
66d9a7b9 447
448 ira_assert (first != NULL);
449 for (node = first; node != NULL; node = node->next)
450 if (hard_reg_set_subset_p (node->hard_regs->set, set))
f1f41a6c 451 hard_regs_node_vec.safe_push (node);
66d9a7b9 452 else if (hard_reg_set_intersect_p (set, node->hard_regs->set))
7fcdc371 453 collect_allocno_hard_regs_cover (node->first, set);
66d9a7b9 454}
455
7fcdc371 456/* Set up field parent as PARENT in all allocno hard registers nodes
66d9a7b9 457 in forest given by FIRST. */
458static void
7fcdc371 459setup_allocno_hard_regs_nodes_parent (allocno_hard_regs_node_t first,
460 allocno_hard_regs_node_t parent)
66d9a7b9 461{
7fcdc371 462 allocno_hard_regs_node_t node;
66d9a7b9 463
464 for (node = first; node != NULL; node = node->next)
465 {
466 node->parent = parent;
7fcdc371 467 setup_allocno_hard_regs_nodes_parent (node->first, node);
66d9a7b9 468 }
469}
470
7fcdc371 471/* Return allocno hard registers node which is a first common ancestor
66d9a7b9 472 node of FIRST and SECOND in the forest. */
7fcdc371 473static allocno_hard_regs_node_t
474first_common_ancestor_node (allocno_hard_regs_node_t first,
475 allocno_hard_regs_node_t second)
66d9a7b9 476{
7fcdc371 477 allocno_hard_regs_node_t node;
66d9a7b9 478
479 node_check_tick++;
480 for (node = first; node != NULL; node = node->parent)
481 node->check = node_check_tick;
482 for (node = second; node != NULL; node = node->parent)
483 if (node->check == node_check_tick)
484 return node;
485 return first_common_ancestor_node (second, first);
486}
487
488/* Print hard reg set SET to F. */
489static void
490print_hard_reg_set (FILE *f, HARD_REG_SET set, bool new_line_p)
491{
492 int i, start;
493
494 for (start = -1, i = 0; i < FIRST_PSEUDO_REGISTER; i++)
495 {
496 if (TEST_HARD_REG_BIT (set, i))
497 {
498 if (i == 0 || ! TEST_HARD_REG_BIT (set, i - 1))
499 start = i;
500 }
501 if (start >= 0
502 && (i == FIRST_PSEUDO_REGISTER - 1 || ! TEST_HARD_REG_BIT (set, i)))
503 {
504 if (start == i - 1)
505 fprintf (f, " %d", start);
506 else if (start == i - 2)
507 fprintf (f, " %d %d", start, start + 1);
508 else
509 fprintf (f, " %d-%d", start, i - 1);
510 start = -1;
511 }
512 }
513 if (new_line_p)
514 fprintf (f, "\n");
515}
516
7fcdc371 517/* Print allocno hard register subforest given by ROOTS and its LEVEL
66d9a7b9 518 to F. */
519static void
7fcdc371 520print_hard_regs_subforest (FILE *f, allocno_hard_regs_node_t roots,
66d9a7b9 521 int level)
522{
523 int i;
7fcdc371 524 allocno_hard_regs_node_t node;
66d9a7b9 525
526 for (node = roots; node != NULL; node = node->next)
527 {
528 fprintf (f, " ");
529 for (i = 0; i < level * 2; i++)
530 fprintf (f, " ");
531 fprintf (f, "%d:(", node->preorder_num);
532 print_hard_reg_set (f, node->hard_regs->set, false);
3a4303e7 533 fprintf (f, ")@%"PRId64"\n", node->hard_regs->cost);
66d9a7b9 534 print_hard_regs_subforest (f, node->first, level + 1);
535 }
536}
537
7fcdc371 538/* Print the allocno hard register forest to F. */
66d9a7b9 539static void
540print_hard_regs_forest (FILE *f)
541{
542 fprintf (f, " Hard reg set forest:\n");
543 print_hard_regs_subforest (f, hard_regs_roots, 1);
544}
545
7fcdc371 546/* Print the allocno hard register forest to stderr. */
66d9a7b9 547void
548ira_debug_hard_regs_forest (void)
549{
550 print_hard_regs_forest (stderr);
551}
552
7fcdc371 553/* Remove unused allocno hard registers nodes from forest given by its
66d9a7b9 554 *ROOTS. */
555static void
7fcdc371 556remove_unused_allocno_hard_regs_nodes (allocno_hard_regs_node_t *roots)
66d9a7b9 557{
7fcdc371 558 allocno_hard_regs_node_t node, prev, next, last;
66d9a7b9 559
560 for (prev = NULL, node = *roots; node != NULL; node = next)
561 {
562 next = node->next;
563 if (node->used_p)
564 {
7fcdc371 565 remove_unused_allocno_hard_regs_nodes (&node->first);
66d9a7b9 566 prev = node;
567 }
568 else
569 {
570 for (last = node->first;
571 last != NULL && last->next != NULL;
572 last = last->next)
573 ;
574 if (last != NULL)
575 {
576 if (prev == NULL)
577 *roots = node->first;
578 else
579 prev->next = node->first;
580 if (next != NULL)
581 next->prev = last;
582 last->next = next;
583 next = node->first;
584 }
585 else
586 {
587 if (prev == NULL)
588 *roots = next;
589 else
590 prev->next = next;
591 if (next != NULL)
592 next->prev = prev;
593 }
594 ira_free (node);
595 }
596 }
597}
598
7fcdc371 599/* Set up fields preorder_num starting with START_NUM in all allocno
66d9a7b9 600 hard registers nodes in forest given by FIRST. Return biggest set
601 PREORDER_NUM increased by 1. */
602static int
7fcdc371 603enumerate_allocno_hard_regs_nodes (allocno_hard_regs_node_t first,
604 allocno_hard_regs_node_t parent,
605 int start_num)
66d9a7b9 606{
7fcdc371 607 allocno_hard_regs_node_t node;
66d9a7b9 608
609 for (node = first; node != NULL; node = node->next)
610 {
611 node->preorder_num = start_num++;
612 node->parent = parent;
7fcdc371 613 start_num = enumerate_allocno_hard_regs_nodes (node->first, node,
614 start_num);
66d9a7b9 615 }
616 return start_num;
617}
618
7fcdc371 619/* Number of allocno hard registers nodes in the forest. */
620static int allocno_hard_regs_nodes_num;
66d9a7b9 621
7fcdc371 622/* Table preorder number of allocno hard registers node in the forest
623 -> the allocno hard registers node. */
624static allocno_hard_regs_node_t *allocno_hard_regs_nodes;
66d9a7b9 625
626/* See below. */
7fcdc371 627typedef struct allocno_hard_regs_subnode *allocno_hard_regs_subnode_t;
66d9a7b9 628
629/* The structure is used to describes all subnodes (not only immediate
7fcdc371 630 ones) in the mentioned above tree for given allocno hard register
66d9a7b9 631 node. The usage of such data accelerates calculation of
632 colorability of given allocno. */
7fcdc371 633struct allocno_hard_regs_subnode
66d9a7b9 634{
635 /* The conflict size of conflicting allocnos whose hard register
636 sets are equal sets (plus supersets if given node is given
7fcdc371 637 allocno hard registers node) of one in the given node. */
66d9a7b9 638 int left_conflict_size;
639 /* The summary conflict size of conflicting allocnos whose hard
640 register sets are strict subsets of one in the given node.
641 Overall conflict size is
642 left_conflict_subnodes_size
643 + MIN (max_node_impact - left_conflict_subnodes_size,
644 left_conflict_size)
645 */
646 short left_conflict_subnodes_size;
647 short max_node_impact;
648};
649
7fcdc371 650/* Container for hard regs subnodes of all allocnos. */
651static allocno_hard_regs_subnode_t allocno_hard_regs_subnodes;
66d9a7b9 652
7fcdc371 653/* Table (preorder number of allocno hard registers node in the
654 forest, preorder number of allocno hard registers subnode) -> index
66d9a7b9 655 of the subnode relative to the node. -1 if it is not a
656 subnode. */
7fcdc371 657static int *allocno_hard_regs_subnode_index;
66d9a7b9 658
7fcdc371 659/* Setup arrays ALLOCNO_HARD_REGS_NODES and
660 ALLOCNO_HARD_REGS_SUBNODE_INDEX. */
66d9a7b9 661static void
7fcdc371 662setup_allocno_hard_regs_subnode_index (allocno_hard_regs_node_t first)
66d9a7b9 663{
7fcdc371 664 allocno_hard_regs_node_t node, parent;
66d9a7b9 665 int index;
666
667 for (node = first; node != NULL; node = node->next)
668 {
7fcdc371 669 allocno_hard_regs_nodes[node->preorder_num] = node;
66d9a7b9 670 for (parent = node; parent != NULL; parent = parent->parent)
671 {
7fcdc371 672 index = parent->preorder_num * allocno_hard_regs_nodes_num;
673 allocno_hard_regs_subnode_index[index + node->preorder_num]
66d9a7b9 674 = node->preorder_num - parent->preorder_num;
675 }
7fcdc371 676 setup_allocno_hard_regs_subnode_index (node->first);
66d9a7b9 677 }
678}
679
7fcdc371 680/* Count all allocno hard registers nodes in tree ROOT. */
66d9a7b9 681static int
7fcdc371 682get_allocno_hard_regs_subnodes_num (allocno_hard_regs_node_t root)
66d9a7b9 683{
684 int len = 1;
685
686 for (root = root->first; root != NULL; root = root->next)
7fcdc371 687 len += get_allocno_hard_regs_subnodes_num (root);
66d9a7b9 688 return len;
689}
690
7fcdc371 691/* Build the forest of allocno hard registers nodes and assign each
66d9a7b9 692 allocno a node from the forest. */
693static void
7fcdc371 694form_allocno_hard_regs_nodes_forest (void)
66d9a7b9 695{
696 unsigned int i, j, size, len;
7fcdc371 697 int start;
66d9a7b9 698 ira_allocno_t a;
7fcdc371 699 allocno_hard_regs_t hv;
66d9a7b9 700 bitmap_iterator bi;
701 HARD_REG_SET temp;
7fcdc371 702 allocno_hard_regs_node_t node, allocno_hard_regs_node;
703 allocno_color_data_t allocno_data;
66d9a7b9 704
705 node_check_tick = 0;
7fcdc371 706 init_allocno_hard_regs ();
66d9a7b9 707 hard_regs_roots = NULL;
f1f41a6c 708 hard_regs_node_vec.create (100);
66d9a7b9 709 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
710 if (! TEST_HARD_REG_BIT (ira_no_alloc_regs, i))
711 {
712 CLEAR_HARD_REG_SET (temp);
713 SET_HARD_REG_BIT (temp, i);
7fcdc371 714 hv = add_allocno_hard_regs (temp, 0);
715 node = create_new_allocno_hard_regs_node (hv);
716 add_new_allocno_hard_regs_node_to_forest (&hard_regs_roots, node);
66d9a7b9 717 }
f1f41a6c 718 start = allocno_hard_regs_vec.length ();
66d9a7b9 719 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
720 {
721 a = ira_allocnos[i];
7fcdc371 722 allocno_data = ALLOCNO_COLOR_DATA (a);
723
724 if (hard_reg_set_empty_p (allocno_data->profitable_hard_regs))
725 continue;
726 hv = (add_allocno_hard_regs
727 (allocno_data->profitable_hard_regs,
728 ALLOCNO_MEMORY_COST (a) - ALLOCNO_CLASS_COST (a)));
66d9a7b9 729 }
730 SET_HARD_REG_SET (temp);
731 AND_COMPL_HARD_REG_SET (temp, ira_no_alloc_regs);
7fcdc371 732 add_allocno_hard_regs (temp, 0);
f1f41a6c 733 qsort (allocno_hard_regs_vec.address () + start,
734 allocno_hard_regs_vec.length () - start,
7fcdc371 735 sizeof (allocno_hard_regs_t), allocno_hard_regs_compare);
66d9a7b9 736 for (i = start;
f1f41a6c 737 allocno_hard_regs_vec.iterate (i, &hv);
66d9a7b9 738 i++)
739 {
7fcdc371 740 add_allocno_hard_regs_to_forest (&hard_regs_roots, hv);
f1f41a6c 741 ira_assert (hard_regs_node_vec.length () == 0);
66d9a7b9 742 }
743 /* We need to set up parent fields for right work of
744 first_common_ancestor_node. */
7fcdc371 745 setup_allocno_hard_regs_nodes_parent (hard_regs_roots, NULL);
66d9a7b9 746 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
747 {
748 a = ira_allocnos[i];
7fcdc371 749 allocno_data = ALLOCNO_COLOR_DATA (a);
750 if (hard_reg_set_empty_p (allocno_data->profitable_hard_regs))
751 continue;
f1f41a6c 752 hard_regs_node_vec.truncate (0);
7fcdc371 753 collect_allocno_hard_regs_cover (hard_regs_roots,
754 allocno_data->profitable_hard_regs);
755 allocno_hard_regs_node = NULL;
f1f41a6c 756 for (j = 0; hard_regs_node_vec.iterate (j, &node); j++)
7fcdc371 757 allocno_hard_regs_node
758 = (j == 0
759 ? node
760 : first_common_ancestor_node (node, allocno_hard_regs_node));
761 /* That is a temporary storage. */
762 allocno_hard_regs_node->used_p = true;
763 allocno_data->hard_regs_node = allocno_hard_regs_node;
66d9a7b9 764 }
765 ira_assert (hard_regs_roots->next == NULL);
766 hard_regs_roots->used_p = true;
7fcdc371 767 remove_unused_allocno_hard_regs_nodes (&hard_regs_roots);
768 allocno_hard_regs_nodes_num
769 = enumerate_allocno_hard_regs_nodes (hard_regs_roots, NULL, 0);
770 allocno_hard_regs_nodes
771 = ((allocno_hard_regs_node_t *)
772 ira_allocate (allocno_hard_regs_nodes_num
773 * sizeof (allocno_hard_regs_node_t)));
774 size = allocno_hard_regs_nodes_num * allocno_hard_regs_nodes_num;
775 allocno_hard_regs_subnode_index
66d9a7b9 776 = (int *) ira_allocate (size * sizeof (int));
777 for (i = 0; i < size; i++)
7fcdc371 778 allocno_hard_regs_subnode_index[i] = -1;
779 setup_allocno_hard_regs_subnode_index (hard_regs_roots);
66d9a7b9 780 start = 0;
781 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
782 {
783 a = ira_allocnos[i];
7fcdc371 784 allocno_data = ALLOCNO_COLOR_DATA (a);
785 if (hard_reg_set_empty_p (allocno_data->profitable_hard_regs))
786 continue;
787 len = get_allocno_hard_regs_subnodes_num (allocno_data->hard_regs_node);
788 allocno_data->hard_regs_subnodes_start = start;
789 allocno_data->hard_regs_subnodes_num = len;
790 start += len;
66d9a7b9 791 }
7fcdc371 792 allocno_hard_regs_subnodes
793 = ((allocno_hard_regs_subnode_t)
794 ira_allocate (sizeof (struct allocno_hard_regs_subnode) * start));
f1f41a6c 795 hard_regs_node_vec.release ();
66d9a7b9 796}
797
7fcdc371 798/* Free tree of allocno hard registers nodes given by its ROOT. */
66d9a7b9 799static void
7fcdc371 800finish_allocno_hard_regs_nodes_tree (allocno_hard_regs_node_t root)
66d9a7b9 801{
7fcdc371 802 allocno_hard_regs_node_t child, next;
66d9a7b9 803
804 for (child = root->first; child != NULL; child = next)
805 {
806 next = child->next;
7fcdc371 807 finish_allocno_hard_regs_nodes_tree (child);
66d9a7b9 808 }
809 ira_free (root);
810}
811
7fcdc371 812/* Finish work with the forest of allocno hard registers nodes. */
66d9a7b9 813static void
7fcdc371 814finish_allocno_hard_regs_nodes_forest (void)
66d9a7b9 815{
7fcdc371 816 allocno_hard_regs_node_t node, next;
66d9a7b9 817
7fcdc371 818 ira_free (allocno_hard_regs_subnodes);
66d9a7b9 819 for (node = hard_regs_roots; node != NULL; node = next)
820 {
821 next = node->next;
7fcdc371 822 finish_allocno_hard_regs_nodes_tree (node);
66d9a7b9 823 }
7fcdc371 824 ira_free (allocno_hard_regs_nodes);
825 ira_free (allocno_hard_regs_subnode_index);
826 finish_allocno_hard_regs ();
66d9a7b9 827}
828
829/* Set up left conflict sizes and left conflict subnodes sizes of hard
830 registers subnodes of allocno A. Return TRUE if allocno A is
831 trivially colorable. */
69f8e080 832static bool
66d9a7b9 833setup_left_conflict_sizes_p (ira_allocno_t a)
69f8e080 834{
7fcdc371 835 int i, k, nobj, start;
836 int conflict_size, left_conflict_subnodes_size, node_preorder_num;
66d9a7b9 837 allocno_color_data_t data;
7fcdc371 838 HARD_REG_SET profitable_hard_regs;
839 allocno_hard_regs_subnode_t subnodes;
840 allocno_hard_regs_node_t node;
841 HARD_REG_SET node_set;
be18556f 842
66d9a7b9 843 nobj = ALLOCNO_NUM_OBJECTS (a);
844 conflict_size = 0;
845 data = ALLOCNO_COLOR_DATA (a);
7fcdc371 846 subnodes = allocno_hard_regs_subnodes + data->hard_regs_subnodes_start;
847 COPY_HARD_REG_SET (profitable_hard_regs, data->profitable_hard_regs);
848 node = data->hard_regs_node;
849 node_preorder_num = node->preorder_num;
850 COPY_HARD_REG_SET (node_set, node->hard_regs->set);
851 node_check_tick++;
66d9a7b9 852 for (k = 0; k < nobj; k++)
853 {
66d9a7b9 854 ira_object_t obj = ALLOCNO_OBJECT (a, k);
855 ira_object_t conflict_obj;
856 ira_object_conflict_iterator oci;
66d9a7b9 857
66d9a7b9 858 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
859 {
860 int size;
861 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
7fcdc371 862 allocno_hard_regs_node_t conflict_node, temp_node;
66d9a7b9 863 HARD_REG_SET conflict_node_set;
7fcdc371 864 allocno_color_data_t conflict_data;
66d9a7b9 865
7fcdc371 866 conflict_data = ALLOCNO_COLOR_DATA (conflict_a);
66d9a7b9 867 if (! ALLOCNO_COLOR_DATA (conflict_a)->in_graph_p
868 || ! hard_reg_set_intersect_p (profitable_hard_regs,
7fcdc371 869 conflict_data
66d9a7b9 870 ->profitable_hard_regs))
871 continue;
7fcdc371 872 conflict_node = conflict_data->hard_regs_node;
66d9a7b9 873 COPY_HARD_REG_SET (conflict_node_set, conflict_node->hard_regs->set);
874 if (hard_reg_set_subset_p (node_set, conflict_node_set))
875 temp_node = node;
876 else
877 {
878 ira_assert (hard_reg_set_subset_p (conflict_node_set, node_set));
879 temp_node = conflict_node;
880 }
881 if (temp_node->check != node_check_tick)
882 {
883 temp_node->check = node_check_tick;
884 temp_node->conflict_size = 0;
885 }
886 size = (ira_reg_class_max_nregs
887 [ALLOCNO_CLASS (conflict_a)][ALLOCNO_MODE (conflict_a)]);
888 if (ALLOCNO_NUM_OBJECTS (conflict_a) > 1)
889 /* We will deal with the subwords individually. */
890 size = 1;
891 temp_node->conflict_size += size;
892 }
7fcdc371 893 }
894 for (i = 0; i < data->hard_regs_subnodes_num; i++)
895 {
896 allocno_hard_regs_node_t temp_node;
897
898 temp_node = allocno_hard_regs_nodes[i + node_preorder_num];
899 ira_assert (temp_node->preorder_num == i + node_preorder_num);
900 subnodes[i].left_conflict_size = (temp_node->check != node_check_tick
901 ? 0 : temp_node->conflict_size);
902 if (hard_reg_set_subset_p (temp_node->hard_regs->set,
903 profitable_hard_regs))
904 subnodes[i].max_node_impact = temp_node->hard_regs_num;
905 else
66d9a7b9 906 {
7fcdc371 907 HARD_REG_SET temp_set;
908 int j, n, hard_regno;
909 enum reg_class aclass;
910
911 COPY_HARD_REG_SET (temp_set, temp_node->hard_regs->set);
912 AND_HARD_REG_SET (temp_set, profitable_hard_regs);
913 aclass = ALLOCNO_CLASS (a);
914 for (n = 0, j = ira_class_hard_regs_num[aclass] - 1; j >= 0; j--)
66d9a7b9 915 {
7fcdc371 916 hard_regno = ira_class_hard_regs[aclass][j];
917 if (TEST_HARD_REG_BIT (temp_set, hard_regno))
918 n++;
66d9a7b9 919 }
7fcdc371 920 subnodes[i].max_node_impact = n;
66d9a7b9 921 }
7fcdc371 922 subnodes[i].left_conflict_subnodes_size = 0;
923 }
924 start = node_preorder_num * allocno_hard_regs_nodes_num;
925 for (i = data->hard_regs_subnodes_num - 1; i >= 0; i--)
926 {
927 int size, parent_i;
928 allocno_hard_regs_node_t parent;
929
930 size = (subnodes[i].left_conflict_subnodes_size
931 + MIN (subnodes[i].max_node_impact
932 - subnodes[i].left_conflict_subnodes_size,
933 subnodes[i].left_conflict_size));
934 parent = allocno_hard_regs_nodes[i + node_preorder_num]->parent;
935 if (parent == NULL)
936 continue;
937 parent_i
938 = allocno_hard_regs_subnode_index[start + parent->preorder_num];
939 if (parent_i < 0)
940 continue;
941 subnodes[parent_i].left_conflict_subnodes_size += size;
66d9a7b9 942 }
7fcdc371 943 left_conflict_subnodes_size = subnodes[0].left_conflict_subnodes_size;
944 conflict_size
945 += (left_conflict_subnodes_size
946 + MIN (subnodes[0].max_node_impact - left_conflict_subnodes_size,
947 subnodes[0].left_conflict_size));
66d9a7b9 948 conflict_size += ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)];
949 data->colorable_p = conflict_size <= data->available_regs_num;
950 return data->colorable_p;
951}
be18556f 952
66d9a7b9 953/* Update left conflict sizes of hard registers subnodes of allocno A
7fcdc371 954 after removing allocno REMOVED_A with SIZE from the conflict graph.
955 Return TRUE if A is trivially colorable. */
66d9a7b9 956static bool
957update_left_conflict_sizes_p (ira_allocno_t a,
7fcdc371 958 ira_allocno_t removed_a, int size)
66d9a7b9 959{
7fcdc371 960 int i, conflict_size, before_conflict_size, diff, start;
66d9a7b9 961 int node_preorder_num, parent_i;
7fcdc371 962 allocno_hard_regs_node_t node, removed_node, parent;
963 allocno_hard_regs_subnode_t subnodes;
66d9a7b9 964 allocno_color_data_t data = ALLOCNO_COLOR_DATA (a);
66d9a7b9 965
966 ira_assert (! data->colorable_p);
7fcdc371 967 node = data->hard_regs_node;
968 node_preorder_num = node->preorder_num;
969 removed_node = ALLOCNO_COLOR_DATA (removed_a)->hard_regs_node;
970 ira_assert (hard_reg_set_subset_p (removed_node->hard_regs->set,
971 node->hard_regs->set)
972 || hard_reg_set_subset_p (node->hard_regs->set,
973 removed_node->hard_regs->set));
974 start = node_preorder_num * allocno_hard_regs_nodes_num;
975 i = allocno_hard_regs_subnode_index[start + removed_node->preorder_num];
976 if (i < 0)
977 i = 0;
978 subnodes = allocno_hard_regs_subnodes + data->hard_regs_subnodes_start;
979 before_conflict_size
980 = (subnodes[i].left_conflict_subnodes_size
981 + MIN (subnodes[i].max_node_impact
982 - subnodes[i].left_conflict_subnodes_size,
983 subnodes[i].left_conflict_size));
984 subnodes[i].left_conflict_size -= size;
985 for (;;)
be18556f 986 {
7fcdc371 987 conflict_size
988 = (subnodes[i].left_conflict_subnodes_size
989 + MIN (subnodes[i].max_node_impact
990 - subnodes[i].left_conflict_subnodes_size,
991 subnodes[i].left_conflict_size));
992 if ((diff = before_conflict_size - conflict_size) == 0)
993 break;
994 ira_assert (conflict_size < before_conflict_size);
995 parent = allocno_hard_regs_nodes[i + node_preorder_num]->parent;
996 if (parent == NULL)
997 break;
998 parent_i
999 = allocno_hard_regs_subnode_index[start + parent->preorder_num];
1000 if (parent_i < 0)
1001 break;
1002 i = parent_i;
66d9a7b9 1003 before_conflict_size
1004 = (subnodes[i].left_conflict_subnodes_size
1005 + MIN (subnodes[i].max_node_impact
1006 - subnodes[i].left_conflict_subnodes_size,
1007 subnodes[i].left_conflict_size));
7fcdc371 1008 subnodes[i].left_conflict_subnodes_size -= diff;
be18556f 1009 }
7fcdc371 1010 if (i != 0
1011 || (conflict_size
1012 + ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]
1013 > data->available_regs_num))
1014 return false;
1015 data->colorable_p = true;
1016 return true;
69f8e080 1017}
1018
7fcdc371 1019/* Return true if allocno A has empty profitable hard regs. */
69f8e080 1020static bool
66d9a7b9 1021empty_profitable_hard_regs (ira_allocno_t a)
69f8e080 1022{
7fcdc371 1023 allocno_color_data_t data = ALLOCNO_COLOR_DATA (a);
66d9a7b9 1024
7fcdc371 1025 return hard_reg_set_empty_p (data->profitable_hard_regs);
69f8e080 1026}
1027
66d9a7b9 1028/* Set up profitable hard registers for each allocno being
1029 colored. */
1030static void
1031setup_profitable_hard_regs (void)
1032{
1033 unsigned int i;
1034 int j, k, nobj, hard_regno, nregs, class_size;
1035 ira_allocno_t a;
1036 bitmap_iterator bi;
1037 enum reg_class aclass;
1038 enum machine_mode mode;
7fcdc371 1039 allocno_color_data_t data;
66d9a7b9 1040
1dceb3f2 1041 /* Initial set up from allocno classes and explicitly conflicting
1042 hard regs. */
66d9a7b9 1043 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
1044 {
1045 a = ira_allocnos[i];
1046 if ((aclass = ALLOCNO_CLASS (a)) == NO_REGS)
1047 continue;
7fcdc371 1048 data = ALLOCNO_COLOR_DATA (a);
1049 if (ALLOCNO_UPDATED_HARD_REG_COSTS (a) == NULL
1050 && ALLOCNO_CLASS_COST (a) > ALLOCNO_MEMORY_COST (a))
1051 CLEAR_HARD_REG_SET (data->profitable_hard_regs);
1052 else
66d9a7b9 1053 {
05045a07 1054 mode = ALLOCNO_MODE (a);
7fcdc371 1055 COPY_HARD_REG_SET (data->profitable_hard_regs,
05045a07 1056 ira_useful_class_mode_regs[aclass][mode]);
7fcdc371 1057 nobj = ALLOCNO_NUM_OBJECTS (a);
1058 for (k = 0; k < nobj; k++)
66d9a7b9 1059 {
7fcdc371 1060 ira_object_t obj = ALLOCNO_OBJECT (a, k);
1061
1062 AND_COMPL_HARD_REG_SET (data->profitable_hard_regs,
66d9a7b9 1063 OBJECT_TOTAL_CONFLICT_HARD_REGS (obj));
1064 }
1065 }
1066 }
1dceb3f2 1067 /* Exclude hard regs already assigned for conflicting objects. */
66d9a7b9 1068 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, i, bi)
1069 {
1070 a = ira_allocnos[i];
1071 if ((aclass = ALLOCNO_CLASS (a)) == NO_REGS
1072 || ! ALLOCNO_ASSIGNED_P (a)
1073 || (hard_regno = ALLOCNO_HARD_REGNO (a)) < 0)
1074 continue;
1075 mode = ALLOCNO_MODE (a);
1076 nregs = hard_regno_nregs[hard_regno][mode];
1077 nobj = ALLOCNO_NUM_OBJECTS (a);
1078 for (k = 0; k < nobj; k++)
1079 {
1080 ira_object_t obj = ALLOCNO_OBJECT (a, k);
1081 ira_object_t conflict_obj;
1082 ira_object_conflict_iterator oci;
1083
1084 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
1085 {
7fcdc371 1086 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
1087
1088 /* We can process the conflict allocno repeatedly with
1089 the same result. */
66d9a7b9 1090 if (nregs == nobj && nregs > 1)
1091 {
1092 int num = OBJECT_SUBWORD (conflict_obj);
1093
769de935 1094 if (REG_WORDS_BIG_ENDIAN)
66d9a7b9 1095 CLEAR_HARD_REG_BIT
7fcdc371 1096 (ALLOCNO_COLOR_DATA (conflict_a)->profitable_hard_regs,
66d9a7b9 1097 hard_regno + nobj - num - 1);
1098 else
1099 CLEAR_HARD_REG_BIT
7fcdc371 1100 (ALLOCNO_COLOR_DATA (conflict_a)->profitable_hard_regs,
66d9a7b9 1101 hard_regno + num);
1102 }
1103 else
1104 AND_COMPL_HARD_REG_SET
7fcdc371 1105 (ALLOCNO_COLOR_DATA (conflict_a)->profitable_hard_regs,
66d9a7b9 1106 ira_reg_mode_hard_regset[hard_regno][mode]);
1107 }
1108 }
1109 }
1dceb3f2 1110 /* Exclude too costly hard regs. */
66d9a7b9 1111 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
1112 {
1113 int min_cost = INT_MAX;
1114 int *costs;
1115
1116 a = ira_allocnos[i];
1117 if ((aclass = ALLOCNO_CLASS (a)) == NO_REGS
1118 || empty_profitable_hard_regs (a))
1119 continue;
7fcdc371 1120 data = ALLOCNO_COLOR_DATA (a);
66d9a7b9 1121 mode = ALLOCNO_MODE (a);
7fcdc371 1122 if ((costs = ALLOCNO_UPDATED_HARD_REG_COSTS (a)) != NULL
1123 || (costs = ALLOCNO_HARD_REG_COSTS (a)) != NULL)
66d9a7b9 1124 {
7fcdc371 1125 class_size = ira_class_hard_regs_num[aclass];
1126 for (j = 0; j < class_size; j++)
66d9a7b9 1127 {
7fcdc371 1128 hard_regno = ira_class_hard_regs[aclass][j];
1129 if (! TEST_HARD_REG_BIT (data->profitable_hard_regs,
1130 hard_regno))
1131 continue;
1132 if (ALLOCNO_UPDATED_MEMORY_COST (a) < costs[j])
1133 CLEAR_HARD_REG_BIT (data->profitable_hard_regs,
1134 hard_regno);
1135 else if (min_cost > costs[j])
1136 min_cost = costs[j];
66d9a7b9 1137 }
66d9a7b9 1138 }
7fcdc371 1139 else if (ALLOCNO_UPDATED_MEMORY_COST (a)
1140 < ALLOCNO_UPDATED_CLASS_COST (a))
1141 CLEAR_HARD_REG_SET (data->profitable_hard_regs);
66d9a7b9 1142 if (ALLOCNO_UPDATED_CLASS_COST (a) > min_cost)
1143 ALLOCNO_UPDATED_CLASS_COST (a) = min_cost;
1144 }
1145}
69f8e080 1146
1147\f
1148
47dd2e78 1149/* This page contains functions used to choose hard registers for
1150 allocnos. */
1151
284f0696 1152/* Pool for update cost records. */
1153static alloc_pool update_cost_record_pool;
1154
1155/* Initiate update cost records. */
1156static void
1157init_update_cost_records (void)
1158{
1159 update_cost_record_pool
1160 = create_alloc_pool ("update cost records",
1161 sizeof (struct update_cost_record), 100);
1162}
1163
1164/* Return new update cost record with given params. */
1165static struct update_cost_record *
1166get_update_cost_record (int hard_regno, int divisor,
1167 struct update_cost_record *next)
1168{
1169 struct update_cost_record *record;
1170
1171 record = (struct update_cost_record *) pool_alloc (update_cost_record_pool);
1172 record->hard_regno = hard_regno;
1173 record->divisor = divisor;
1174 record->next = next;
1175 return record;
1176}
1177
1178/* Free memory for all records in LIST. */
1179static void
1180free_update_cost_record_list (struct update_cost_record *list)
1181{
1182 struct update_cost_record *next;
1183
1184 while (list != NULL)
1185 {
1186 next = list->next;
1187 pool_free (update_cost_record_pool, list);
1188 list = next;
1189 }
1190}
1191
1192/* Free memory allocated for all update cost records. */
1193static void
1194finish_update_cost_records (void)
1195{
1196 free_alloc_pool (update_cost_record_pool);
1197}
1198
47dd2e78 1199/* Array whose element value is TRUE if the corresponding hard
1200 register was already allocated for an allocno. */
1201static bool allocated_hardreg_p[FIRST_PSEUDO_REGISTER];
1202
ff1401e7 1203/* Describes one element in a queue of allocnos whose costs need to be
66d9a7b9 1204 updated. Each allocno in the queue is known to have an allocno
1205 class. */
ab2f6b9a 1206struct update_cost_queue_elem
1207{
ff1401e7 1208 /* This element is in the queue iff CHECK == update_cost_check. */
1209 int check;
1210
1211 /* COST_HOP_DIVISOR**N, where N is the length of the shortest path
1212 connecting this allocno to the one being allocated. */
1213 int divisor;
1214
b59bd98f 1215 /* Allocno from which we are chaining costs of connected allocnos.
284f0696 1216 It is used not go back in graph of allocnos connected by
1217 copies. */
1218 ira_allocno_t from;
1219
ff1401e7 1220 /* The next allocno in the queue, or null if this is the last element. */
1221 ira_allocno_t next;
1222};
1223
1224/* The first element in a queue of allocnos whose copy costs need to be
1225 updated. Null if the queue is empty. */
1226static ira_allocno_t update_cost_queue;
1227
1228/* The last element in the queue described by update_cost_queue.
1229 Not valid if update_cost_queue is null. */
1230static struct update_cost_queue_elem *update_cost_queue_tail;
1231
1232/* A pool of elements in the queue described by update_cost_queue.
1233 Elements are indexed by ALLOCNO_NUM. */
1234static struct update_cost_queue_elem *update_cost_queue_elems;
47dd2e78 1235
284f0696 1236/* The current value of update_costs_from_copies call count. */
47dd2e78 1237static int update_cost_check;
1238
1239/* Allocate and initialize data necessary for function
682e13bb 1240 update_costs_from_copies. */
47dd2e78 1241static void
1242initiate_cost_update (void)
1243{
ff1401e7 1244 size_t size;
1245
1246 size = ira_allocnos_num * sizeof (struct update_cost_queue_elem);
1247 update_cost_queue_elems
1248 = (struct update_cost_queue_elem *) ira_allocate (size);
1249 memset (update_cost_queue_elems, 0, size);
47dd2e78 1250 update_cost_check = 0;
284f0696 1251 init_update_cost_records ();
47dd2e78 1252}
1253
284f0696 1254/* Deallocate data used by function update_costs_from_copies. */
47dd2e78 1255static void
1256finish_cost_update (void)
1257{
f0b1b9ce 1258 ira_free (update_cost_queue_elems);
284f0696 1259 finish_update_cost_records ();
47dd2e78 1260}
1261
f0a46d83 1262/* When we traverse allocnos to update hard register costs, the cost
1263 divisor will be multiplied by the following macro value for each
1264 hop from given allocno to directly connected allocnos. */
1265#define COST_HOP_DIVISOR 4
1266
ff1401e7 1267/* Start a new cost-updating pass. */
47dd2e78 1268static void
ff1401e7 1269start_update_cost (void)
47dd2e78 1270{
ff1401e7 1271 update_cost_check++;
1272 update_cost_queue = NULL;
1273}
47dd2e78 1274
284f0696 1275/* Add (ALLOCNO, FROM, DIVISOR) to the end of update_cost_queue, unless
66d9a7b9 1276 ALLOCNO is already in the queue, or has NO_REGS class. */
ff1401e7 1277static inline void
284f0696 1278queue_update_cost (ira_allocno_t allocno, ira_allocno_t from, int divisor)
ff1401e7 1279{
1280 struct update_cost_queue_elem *elem;
1281
1282 elem = &update_cost_queue_elems[ALLOCNO_NUM (allocno)];
1283 if (elem->check != update_cost_check
66d9a7b9 1284 && ALLOCNO_CLASS (allocno) != NO_REGS)
47dd2e78 1285 {
ff1401e7 1286 elem->check = update_cost_check;
284f0696 1287 elem->from = from;
ff1401e7 1288 elem->divisor = divisor;
1289 elem->next = NULL;
1290 if (update_cost_queue == NULL)
1291 update_cost_queue = allocno;
47dd2e78 1292 else
ff1401e7 1293 update_cost_queue_tail->next = allocno;
1294 update_cost_queue_tail = elem;
47dd2e78 1295 }
1296}
1297
284f0696 1298/* Try to remove the first element from update_cost_queue. Return
1299 false if the queue was empty, otherwise make (*ALLOCNO, *FROM,
1300 *DIVISOR) describe the removed element. */
ff1401e7 1301static inline bool
284f0696 1302get_next_update_cost (ira_allocno_t *allocno, ira_allocno_t *from, int *divisor)
47dd2e78 1303{
ff1401e7 1304 struct update_cost_queue_elem *elem;
1305
1306 if (update_cost_queue == NULL)
1307 return false;
1308
1309 *allocno = update_cost_queue;
1310 elem = &update_cost_queue_elems[ALLOCNO_NUM (*allocno)];
284f0696 1311 *from = elem->from;
ff1401e7 1312 *divisor = elem->divisor;
1313 update_cost_queue = elem->next;
1314 return true;
47dd2e78 1315}
1316
284f0696 1317/* Increase costs of HARD_REGNO by UPDATE_COST for ALLOCNO. Return
1318 true if we really modified the cost. */
1319static bool
1320update_allocno_cost (ira_allocno_t allocno, int hard_regno, int update_cost)
1321{
1322 int i;
1323 enum reg_class aclass = ALLOCNO_CLASS (allocno);
1324
1325 i = ira_class_hard_reg_index[aclass][hard_regno];
1326 if (i < 0)
1327 return false;
1328 ira_allocate_and_set_or_copy_costs
1329 (&ALLOCNO_UPDATED_HARD_REG_COSTS (allocno), aclass,
1330 ALLOCNO_UPDATED_CLASS_COST (allocno),
1331 ALLOCNO_HARD_REG_COSTS (allocno));
1332 ira_allocate_and_set_or_copy_costs
1333 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (allocno),
1334 aclass, 0, ALLOCNO_CONFLICT_HARD_REG_COSTS (allocno));
1335 ALLOCNO_UPDATED_HARD_REG_COSTS (allocno)[i] += update_cost;
1336 ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (allocno)[i] += update_cost;
1337 return true;
1338}
1339
1340/* Update (decrease if DECR_P) HARD_REGNO cost of allocnos connected
1341 by copies to ALLOCNO to increase chances to remove some copies as
1342 the result of subsequent assignment. Record cost updates if
1343 RECORD_P is true. */
f0a46d83 1344static void
284f0696 1345update_costs_from_allocno (ira_allocno_t allocno, int hard_regno,
1346 int divisor, bool decr_p, bool record_p)
f0a46d83 1347{
284f0696 1348 int cost, update_cost;
f0a46d83 1349 enum machine_mode mode;
66d9a7b9 1350 enum reg_class rclass, aclass;
284f0696 1351 ira_allocno_t another_allocno, from = NULL;
f0a46d83 1352 ira_copy_t cp, next_cp;
1353
ff1401e7 1354 rclass = REGNO_REG_CLASS (hard_regno);
ff1401e7 1355 do
f0a46d83 1356 {
ff1401e7 1357 mode = ALLOCNO_MODE (allocno);
66d9a7b9 1358 ira_init_register_move_cost_if_necessary (mode);
ff1401e7 1359 for (cp = ALLOCNO_COPIES (allocno); cp != NULL; cp = next_cp)
f0a46d83 1360 {
ff1401e7 1361 if (cp->first == allocno)
f0a46d83 1362 {
ff1401e7 1363 next_cp = cp->next_first_allocno_copy;
1364 another_allocno = cp->second;
1365 }
1366 else if (cp->second == allocno)
1367 {
1368 next_cp = cp->next_second_allocno_copy;
1369 another_allocno = cp->first;
f0a46d83 1370 }
ff1401e7 1371 else
1372 gcc_unreachable ();
1373
284f0696 1374 if (another_allocno == from)
1375 continue;
1376
66d9a7b9 1377 aclass = ALLOCNO_CLASS (another_allocno);
1378 if (! TEST_HARD_REG_BIT (reg_class_contents[aclass],
a79c1c05 1379 hard_regno)
ff1401e7 1380 || ALLOCNO_ASSIGNED_P (another_allocno))
1381 continue;
1382
1383 cost = (cp->second == allocno
66d9a7b9 1384 ? ira_register_move_cost[mode][rclass][aclass]
1385 : ira_register_move_cost[mode][aclass][rclass]);
ff1401e7 1386 if (decr_p)
1387 cost = -cost;
1388
1389 update_cost = cp->freq * cost / divisor;
1390 if (update_cost == 0)
1391 continue;
1392
284f0696 1393 if (! update_allocno_cost (another_allocno, hard_regno, update_cost))
66d9a7b9 1394 continue;
284f0696 1395 queue_update_cost (another_allocno, allocno, divisor * COST_HOP_DIVISOR);
1396 if (record_p && ALLOCNO_COLOR_DATA (another_allocno) != NULL)
1397 ALLOCNO_COLOR_DATA (another_allocno)->update_cost_records
1398 = get_update_cost_record (hard_regno, divisor,
1399 ALLOCNO_COLOR_DATA (another_allocno)
1400 ->update_cost_records);
f0a46d83 1401 }
f0a46d83 1402 }
284f0696 1403 while (get_next_update_cost (&allocno, &from, &divisor));
1404}
1405
1406/* Decrease preferred ALLOCNO hard register costs and costs of
1407 allocnos connected to ALLOCNO through copy. */
1408static void
1409update_costs_from_prefs (ira_allocno_t allocno)
1410{
1411 ira_pref_t pref;
1412
1413 start_update_cost ();
1414 for (pref = ALLOCNO_PREFS (allocno); pref != NULL; pref = pref->next_pref)
1415 update_costs_from_allocno (allocno, pref->hard_regno,
1416 COST_HOP_DIVISOR, true, true);
1417}
1418
1419/* Update (decrease if DECR_P) the cost of allocnos connected to
1420 ALLOCNO through copies to increase chances to remove some copies as
1421 the result of subsequent assignment. ALLOCNO was just assigned to
682e13bb 1422 a hard register. Record cost updates if RECORD_P is true. */
284f0696 1423static void
682e13bb 1424update_costs_from_copies (ira_allocno_t allocno, bool decr_p, bool record_p)
284f0696 1425{
1426 int hard_regno;
1427
1428 hard_regno = ALLOCNO_HARD_REGNO (allocno);
1429 ira_assert (hard_regno >= 0 && ALLOCNO_CLASS (allocno) != NO_REGS);
1430 start_update_cost ();
682e13bb 1431 update_costs_from_allocno (allocno, hard_regno, 1, decr_p, record_p);
284f0696 1432}
1433
1434/* Restore costs of allocnos connected to ALLOCNO by copies as it was
1435 before updating costs of these allocnos from given allocno. This
1436 is a wise thing to do as if given allocno did not get an expected
1437 hard reg, using smaller cost of the hard reg for allocnos connected
1438 by copies to given allocno becomes actually misleading. Free all
1439 update cost records for ALLOCNO as we don't need them anymore. */
1440static void
1441restore_costs_from_copies (ira_allocno_t allocno)
1442{
1443 struct update_cost_record *records, *curr;
1444
1445 if (ALLOCNO_COLOR_DATA (allocno) == NULL)
1446 return;
1447 records = ALLOCNO_COLOR_DATA (allocno)->update_cost_records;
1448 start_update_cost ();
1449 for (curr = records; curr != NULL; curr = curr->next)
1450 update_costs_from_allocno (allocno, curr->hard_regno,
1451 curr->divisor, true, false);
1452 free_update_cost_record_list (records);
1453 ALLOCNO_COLOR_DATA (allocno)->update_cost_records = NULL;
ff1401e7 1454}
1455
14792f4e 1456/* This function updates COSTS (decrease if DECR_P) for hard_registers
66d9a7b9 1457 of ACLASS by conflict costs of the unassigned allocnos
14792f4e 1458 connected by copies with allocnos in update_cost_queue. This
1459 update increases chances to remove some copies. */
ff1401e7 1460static void
66d9a7b9 1461update_conflict_hard_regno_costs (int *costs, enum reg_class aclass,
14792f4e 1462 bool decr_p)
ff1401e7 1463{
1464 int i, cost, class_size, freq, mult, div, divisor;
14792f4e 1465 int index, hard_regno;
ff1401e7 1466 int *conflict_costs;
1467 bool cont_p;
66d9a7b9 1468 enum reg_class another_aclass;
284f0696 1469 ira_allocno_t allocno, another_allocno, from;
ff1401e7 1470 ira_copy_t cp, next_cp;
1471
284f0696 1472 while (get_next_update_cost (&allocno, &from, &divisor))
ff1401e7 1473 for (cp = ALLOCNO_COPIES (allocno); cp != NULL; cp = next_cp)
1474 {
1475 if (cp->first == allocno)
1476 {
1477 next_cp = cp->next_first_allocno_copy;
1478 another_allocno = cp->second;
1479 }
1480 else if (cp->second == allocno)
1481 {
1482 next_cp = cp->next_second_allocno_copy;
1483 another_allocno = cp->first;
1484 }
1485 else
1486 gcc_unreachable ();
284f0696 1487
1488 if (another_allocno == from)
1489 continue;
1490
66d9a7b9 1491 another_aclass = ALLOCNO_CLASS (another_allocno);
1492 if (! ira_reg_classes_intersect_p[aclass][another_aclass]
ff1401e7 1493 || ALLOCNO_ASSIGNED_P (another_allocno)
66d9a7b9 1494 || ALLOCNO_COLOR_DATA (another_allocno)->may_be_spilled_p)
ff1401e7 1495 continue;
66d9a7b9 1496 class_size = ira_class_hard_regs_num[another_aclass];
ff1401e7 1497 ira_allocate_and_copy_costs
1498 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (another_allocno),
66d9a7b9 1499 another_aclass, ALLOCNO_CONFLICT_HARD_REG_COSTS (another_allocno));
ff1401e7 1500 conflict_costs
1501 = ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (another_allocno);
1502 if (conflict_costs == NULL)
1503 cont_p = true;
1504 else
1505 {
1506 mult = cp->freq;
1507 freq = ALLOCNO_FREQ (another_allocno);
1508 if (freq == 0)
1509 freq = 1;
1510 div = freq * divisor;
1511 cont_p = false;
1512 for (i = class_size - 1; i >= 0; i--)
1513 {
66d9a7b9 1514 hard_regno = ira_class_hard_regs[another_aclass][i];
14792f4e 1515 ira_assert (hard_regno >= 0);
66d9a7b9 1516 index = ira_class_hard_reg_index[aclass][hard_regno];
14792f4e 1517 if (index < 0)
1518 continue;
93750926 1519 cost = (int) ((unsigned) conflict_costs [i] * mult) / div;
ff1401e7 1520 if (cost == 0)
1521 continue;
1522 cont_p = true;
1523 if (decr_p)
1524 cost = -cost;
14792f4e 1525 costs[index] += cost;
ff1401e7 1526 }
1527 }
1528 /* Probably 5 hops will be enough. */
1529 if (cont_p
1530 && divisor <= (COST_HOP_DIVISOR
1531 * COST_HOP_DIVISOR
1532 * COST_HOP_DIVISOR
1533 * COST_HOP_DIVISOR))
284f0696 1534 queue_update_cost (another_allocno, allocno, divisor * COST_HOP_DIVISOR);
ff1401e7 1535 }
f0a46d83 1536}
1537
7fcdc371 1538/* Set up conflicting (through CONFLICT_REGS) for each object of
1539 allocno A and the start allocno profitable regs (through
1540 START_PROFITABLE_REGS). Remember that the start profitable regs
1541 exclude hard regs which can not hold value of mode of allocno A.
1542 This covers mostly cases when multi-register value should be
1543 aligned. */
66d9a7b9 1544static inline void
7fcdc371 1545get_conflict_and_start_profitable_regs (ira_allocno_t a, bool retry_p,
1546 HARD_REG_SET *conflict_regs,
1547 HARD_REG_SET *start_profitable_regs)
66d9a7b9 1548{
1549 int i, nwords;
1550 ira_object_t obj;
1551
1552 nwords = ALLOCNO_NUM_OBJECTS (a);
1553 for (i = 0; i < nwords; i++)
1554 {
1555 obj = ALLOCNO_OBJECT (a, i);
1556 COPY_HARD_REG_SET (conflict_regs[i],
1557 OBJECT_TOTAL_CONFLICT_HARD_REGS (obj));
66d9a7b9 1558 }
7fcdc371 1559 if (retry_p)
1560 {
1561 COPY_HARD_REG_SET (*start_profitable_regs,
1562 reg_class_contents[ALLOCNO_CLASS (a)]);
1563 AND_COMPL_HARD_REG_SET (*start_profitable_regs,
1564 ira_prohibited_class_mode_regs
1565 [ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]);
1566 }
1567 else
1568 COPY_HARD_REG_SET (*start_profitable_regs,
1569 ALLOCNO_COLOR_DATA (a)->profitable_hard_regs);
66d9a7b9 1570}
1571
7fcdc371 1572/* Return true if HARD_REGNO is ok for assigning to allocno A with
1573 PROFITABLE_REGS and whose objects have CONFLICT_REGS. */
66d9a7b9 1574static inline bool
1575check_hard_reg_p (ira_allocno_t a, int hard_regno,
7fcdc371 1576 HARD_REG_SET *conflict_regs, HARD_REG_SET profitable_regs)
66d9a7b9 1577{
1578 int j, nwords, nregs;
1dceb3f2 1579 enum reg_class aclass;
1580 enum machine_mode mode;
66d9a7b9 1581
1dceb3f2 1582 aclass = ALLOCNO_CLASS (a);
1583 mode = ALLOCNO_MODE (a);
1584 if (TEST_HARD_REG_BIT (ira_prohibited_class_mode_regs[aclass][mode],
1585 hard_regno))
1586 return false;
7fcdc371 1587 /* Checking only profitable hard regs. */
1588 if (! TEST_HARD_REG_BIT (profitable_regs, hard_regno))
1589 return false;
1dceb3f2 1590 nregs = hard_regno_nregs[hard_regno][mode];
66d9a7b9 1591 nwords = ALLOCNO_NUM_OBJECTS (a);
1592 for (j = 0; j < nregs; j++)
1593 {
1594 int k;
1595 int set_to_test_start = 0, set_to_test_end = nwords;
1596
1597 if (nregs == nwords)
1598 {
769de935 1599 if (REG_WORDS_BIG_ENDIAN)
66d9a7b9 1600 set_to_test_start = nwords - j - 1;
1601 else
1602 set_to_test_start = j;
1603 set_to_test_end = set_to_test_start + 1;
1604 }
1605 for (k = set_to_test_start; k < set_to_test_end; k++)
7fcdc371 1606 if (TEST_HARD_REG_BIT (conflict_regs[k], hard_regno + j))
66d9a7b9 1607 break;
1608 if (k != set_to_test_end)
1609 break;
1610 }
1611 return j == nregs;
1612}
4682ca16 1613
1614/* Return number of registers needed to be saved and restored at
1615 function prologue/epilogue if we allocate HARD_REGNO to hold value
1616 of MODE. */
1617static int
1618calculate_saved_nregs (int hard_regno, enum machine_mode mode)
1619{
1620 int i;
1621 int nregs = 0;
1622
1623 ira_assert (hard_regno >= 0);
1624 for (i = hard_regno_nregs[hard_regno][mode] - 1; i >= 0; i--)
1625 if (!allocated_hardreg_p[hard_regno + i]
1626 && !TEST_HARD_REG_BIT (call_used_reg_set, hard_regno + i)
1627 && !LOCAL_REGNO (hard_regno + i))
1628 nregs++;
1629 return nregs;
1630}
66d9a7b9 1631
e8b4e44b 1632/* Choose a hard register for allocno A. If RETRY_P is TRUE, it means
1633 that the function called from function
66d9a7b9 1634 `ira_reassign_conflict_allocnos' and `allocno_reload_assign'. In
1635 this case some allocno data are not defined or updated and we
1636 should not touch these data. The function returns true if we
1637 managed to assign a hard register to the allocno.
1638
1639 To assign a hard register, first of all we calculate all conflict
1640 hard registers which can come from conflicting allocnos with
1641 already assigned hard registers. After that we find first free
1642 hard register with the minimal cost. During hard register cost
1643 calculation we take conflict hard register costs into account to
1644 give a chance for conflicting allocnos to get a better hard
1645 register in the future.
1646
1647 If the best hard register cost is bigger than cost of memory usage
1648 for the allocno, we don't assign a hard register to given allocno
1649 at all.
1650
1651 If we assign a hard register to the allocno, we update costs of the
1652 hard register for allocnos connected by copies to improve a chance
1653 to coalesce insns represented by the copies when we assign hard
1654 registers to the allocnos connected by the copies. */
47dd2e78 1655static bool
e8b4e44b 1656assign_hard_reg (ira_allocno_t a, bool retry_p)
47dd2e78 1657{
7fcdc371 1658 HARD_REG_SET conflicting_regs[2], profitable_hard_regs;
3d4c18fe 1659 int i, j, hard_regno, best_hard_regno, class_size;
e8b4e44b 1660 int cost, mem_cost, min_cost, full_cost, min_full_cost, nwords, word;
47dd2e78 1661 int *a_costs;
66d9a7b9 1662 enum reg_class aclass;
47dd2e78 1663 enum machine_mode mode;
47dd2e78 1664 static int costs[FIRST_PSEUDO_REGISTER], full_costs[FIRST_PSEUDO_REGISTER];
3d4c18fe 1665 int saved_nregs;
815333e5 1666 enum reg_class rclass;
1667 int add_cost;
47dd2e78 1668#ifdef STACK_REGS
1669 bool no_stack_reg_p;
1670#endif
1671
e8b4e44b 1672 ira_assert (! ALLOCNO_ASSIGNED_P (a));
7fcdc371 1673 get_conflict_and_start_profitable_regs (a, retry_p,
1674 conflicting_regs,
1675 &profitable_hard_regs);
66d9a7b9 1676 aclass = ALLOCNO_CLASS (a);
1677 class_size = ira_class_hard_regs_num[aclass];
47dd2e78 1678 best_hard_regno = -1;
1679 memset (full_costs, 0, sizeof (int) * class_size);
1680 mem_cost = 0;
47dd2e78 1681 memset (costs, 0, sizeof (int) * class_size);
1682 memset (full_costs, 0, sizeof (int) * class_size);
1683#ifdef STACK_REGS
1684 no_stack_reg_p = false;
1685#endif
66d9a7b9 1686 if (! retry_p)
1687 start_update_cost ();
e8b4e44b 1688 mem_cost += ALLOCNO_UPDATED_MEMORY_COST (a);
1689
1690 ira_allocate_and_copy_costs (&ALLOCNO_UPDATED_HARD_REG_COSTS (a),
66d9a7b9 1691 aclass, ALLOCNO_HARD_REG_COSTS (a));
e8b4e44b 1692 a_costs = ALLOCNO_UPDATED_HARD_REG_COSTS (a);
47dd2e78 1693#ifdef STACK_REGS
e8b4e44b 1694 no_stack_reg_p = no_stack_reg_p || ALLOCNO_TOTAL_NO_STACK_REG_P (a);
47dd2e78 1695#endif
66d9a7b9 1696 cost = ALLOCNO_UPDATED_CLASS_COST (a);
e8b4e44b 1697 for (i = 0; i < class_size; i++)
1698 if (a_costs != NULL)
1699 {
1700 costs[i] += a_costs[i];
1701 full_costs[i] += a_costs[i];
1702 }
1703 else
1704 {
1705 costs[i] += cost;
1706 full_costs[i] += cost;
1707 }
66d9a7b9 1708 nwords = ALLOCNO_NUM_OBJECTS (a);
7fcdc371 1709 curr_allocno_process++;
e8b4e44b 1710 for (word = 0; word < nwords; word++)
1711 {
1712 ira_object_t conflict_obj;
1713 ira_object_t obj = ALLOCNO_OBJECT (a, word);
1714 ira_object_conflict_iterator oci;
1715
e8b4e44b 1716 /* Take preferences of conflicting allocnos into account. */
1717 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
66d9a7b9 1718 {
e8b4e44b 1719 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
66d9a7b9 1720 enum reg_class conflict_aclass;
fa2cc02b 1721 allocno_color_data_t data = ALLOCNO_COLOR_DATA (conflict_a);
66d9a7b9 1722
e8b4e44b 1723 /* Reload can give another class so we need to check all
1724 allocnos. */
66d9a7b9 1725 if (!retry_p
1726 && (!bitmap_bit_p (consideration_allocno_bitmap,
1727 ALLOCNO_NUM (conflict_a))
1728 || ((!ALLOCNO_ASSIGNED_P (conflict_a)
1729 || ALLOCNO_HARD_REGNO (conflict_a) < 0)
1730 && !(hard_reg_set_intersect_p
7fcdc371 1731 (profitable_hard_regs,
1732 ALLOCNO_COLOR_DATA
1733 (conflict_a)->profitable_hard_regs)))))
e8b4e44b 1734 continue;
66d9a7b9 1735 conflict_aclass = ALLOCNO_CLASS (conflict_a);
e8b4e44b 1736 ira_assert (ira_reg_classes_intersect_p
66d9a7b9 1737 [aclass][conflict_aclass]);
e8b4e44b 1738 if (ALLOCNO_ASSIGNED_P (conflict_a))
e320331a 1739 {
e8b4e44b 1740 hard_regno = ALLOCNO_HARD_REGNO (conflict_a);
1741 if (hard_regno >= 0
3c5273ff 1742 && (ira_hard_reg_set_intersection_p
1743 (hard_regno, ALLOCNO_MODE (conflict_a),
1744 reg_class_contents[aclass])))
e320331a 1745 {
e8b4e44b 1746 int n_objects = ALLOCNO_NUM_OBJECTS (conflict_a);
04fd8b89 1747 int conflict_nregs;
66d9a7b9 1748
04fd8b89 1749 mode = ALLOCNO_MODE (conflict_a);
1750 conflict_nregs = hard_regno_nregs[hard_regno][mode];
e8b4e44b 1751 if (conflict_nregs == n_objects && conflict_nregs > 1)
e320331a 1752 {
e8b4e44b 1753 int num = OBJECT_SUBWORD (conflict_obj);
be18556f 1754
769de935 1755 if (REG_WORDS_BIG_ENDIAN)
e8b4e44b 1756 SET_HARD_REG_BIT (conflicting_regs[word],
1757 hard_regno + n_objects - num - 1);
1758 else
1759 SET_HARD_REG_BIT (conflicting_regs[word],
1760 hard_regno + num);
be18556f 1761 }
e8b4e44b 1762 else
1763 IOR_HARD_REG_SET
1764 (conflicting_regs[word],
1765 ira_reg_mode_hard_regset[hard_regno][mode]);
7fcdc371 1766 if (hard_reg_set_subset_p (profitable_hard_regs,
e8b4e44b 1767 conflicting_regs[word]))
1768 goto fail;
e320331a 1769 }
1770 }
66d9a7b9 1771 else if (! retry_p
7fcdc371 1772 && ! ALLOCNO_COLOR_DATA (conflict_a)->may_be_spilled_p
1773 /* Don't process the conflict allocno twice. */
1774 && (ALLOCNO_COLOR_DATA (conflict_a)->last_process
1775 != curr_allocno_process))
e8b4e44b 1776 {
1777 int k, *conflict_costs;
1778
7fcdc371 1779 ALLOCNO_COLOR_DATA (conflict_a)->last_process
1780 = curr_allocno_process;
e8b4e44b 1781 ira_allocate_and_copy_costs
1782 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (conflict_a),
66d9a7b9 1783 conflict_aclass,
e8b4e44b 1784 ALLOCNO_CONFLICT_HARD_REG_COSTS (conflict_a));
1785 conflict_costs
1786 = ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (conflict_a);
1787 if (conflict_costs != NULL)
1788 for (j = class_size - 1; j >= 0; j--)
1789 {
66d9a7b9 1790 hard_regno = ira_class_hard_regs[aclass][j];
e8b4e44b 1791 ira_assert (hard_regno >= 0);
66d9a7b9 1792 k = ira_class_hard_reg_index[conflict_aclass][hard_regno];
fa2cc02b 1793 if (k < 0
1794 /* If HARD_REGNO is not available for CONFLICT_A,
1795 the conflict would be ignored, since HARD_REGNO
1796 will never be assigned to CONFLICT_A. */
1797 || !TEST_HARD_REG_BIT (data->profitable_hard_regs,
1798 hard_regno))
e8b4e44b 1799 continue;
1800 full_costs[j] -= conflict_costs[k];
1801 }
284f0696 1802 queue_update_cost (conflict_a, NULL, COST_HOP_DIVISOR);
1803
e8b4e44b 1804 }
e320331a 1805 }
47dd2e78 1806 }
66d9a7b9 1807 if (! retry_p)
1808 /* Take into account preferences of allocnos connected by copies to
1809 the conflict allocnos. */
1810 update_conflict_hard_regno_costs (full_costs, aclass, true);
ff1401e7 1811
f0a46d83 1812 /* Take preferences of allocnos connected by copies into
1813 account. */
66d9a7b9 1814 if (! retry_p)
1815 {
1816 start_update_cost ();
284f0696 1817 queue_update_cost (a, NULL, COST_HOP_DIVISOR);
66d9a7b9 1818 update_conflict_hard_regno_costs (full_costs, aclass, false);
1819 }
47dd2e78 1820 min_cost = min_full_cost = INT_MAX;
1821 /* We don't care about giving callee saved registers to allocnos no
1822 living through calls because call clobbered registers are
1823 allocated first (it is usual practice to put them first in
1824 REG_ALLOC_ORDER). */
66d9a7b9 1825 mode = ALLOCNO_MODE (a);
47dd2e78 1826 for (i = 0; i < class_size; i++)
1827 {
66d9a7b9 1828 hard_regno = ira_class_hard_regs[aclass][i];
47dd2e78 1829#ifdef STACK_REGS
1830 if (no_stack_reg_p
1831 && FIRST_STACK_REG <= hard_regno && hard_regno <= LAST_STACK_REG)
1832 continue;
1833#endif
66d9a7b9 1834 if (! check_hard_reg_p (a, hard_regno,
1835 conflicting_regs, profitable_hard_regs))
47dd2e78 1836 continue;
1837 cost = costs[i];
1838 full_cost = full_costs[i];
f64087e0 1839 if (!HONOR_REG_ALLOC_ORDER)
47dd2e78 1840 {
f64087e0 1841 if ((saved_nregs = calculate_saved_nregs (hard_regno, mode)) != 0)
1842 /* We need to save/restore the hard register in
1843 epilogue/prologue. Therefore we increase the cost. */
1844 {
1845 rclass = REGNO_REG_CLASS (hard_regno);
1846 add_cost = ((ira_memory_move_cost[mode][rclass][0]
1847 + ira_memory_move_cost[mode][rclass][1])
1848 * saved_nregs / hard_regno_nregs[hard_regno][mode] - 1);
1849 cost += add_cost;
1850 full_cost += add_cost;
1851 }
47dd2e78 1852 }
1853 if (min_cost > cost)
1854 min_cost = cost;
1855 if (min_full_cost > full_cost)
1856 {
1857 min_full_cost = full_cost;
1858 best_hard_regno = hard_regno;
1859 ira_assert (hard_regno >= 0);
1860 }
1861 }
1862 if (min_full_cost > mem_cost)
1863 {
1864 if (! retry_p && internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
1865 fprintf (ira_dump_file, "(memory is more profitable %d vs %d) ",
1866 mem_cost, min_full_cost);
1867 best_hard_regno = -1;
1868 }
1869 fail:
47dd2e78 1870 if (best_hard_regno >= 0)
4682ca16 1871 {
1872 for (i = hard_regno_nregs[best_hard_regno][mode] - 1; i >= 0; i--)
125fdf16 1873 allocated_hardreg_p[best_hard_regno + i] = true;
4682ca16 1874 }
682e13bb 1875 if (! retry_p)
1876 restore_costs_from_copies (a);
e8b4e44b 1877 ALLOCNO_HARD_REGNO (a) = best_hard_regno;
1878 ALLOCNO_ASSIGNED_P (a) = true;
1879 if (best_hard_regno >= 0)
682e13bb 1880 update_costs_from_copies (a, true, ! retry_p);
66d9a7b9 1881 ira_assert (ALLOCNO_CLASS (a) == aclass);
3ad55f68 1882 /* We don't need updated costs anymore. */
e8b4e44b 1883 ira_free_allocno_updated_costs (a);
47dd2e78 1884 return best_hard_regno >= 0;
1885}
1886
1887\f
1888
4bb79f36 1889/* An array used to sort copies. */
1890static ira_copy_t *sorted_copies;
1891
1892/* Return TRUE if live ranges of allocnos A1 and A2 intersect. It is
1893 used to find a conflict for new allocnos or allocnos with the
1894 different allocno classes. */
1895static bool
1896allocnos_conflict_by_live_ranges_p (ira_allocno_t a1, ira_allocno_t a2)
1897{
1898 rtx reg1, reg2;
1899 int i, j;
1900 int n1 = ALLOCNO_NUM_OBJECTS (a1);
1901 int n2 = ALLOCNO_NUM_OBJECTS (a2);
1902
1903 if (a1 == a2)
1904 return false;
1905 reg1 = regno_reg_rtx[ALLOCNO_REGNO (a1)];
1906 reg2 = regno_reg_rtx[ALLOCNO_REGNO (a2)];
1907 if (reg1 != NULL && reg2 != NULL
1908 && ORIGINAL_REGNO (reg1) == ORIGINAL_REGNO (reg2))
1909 return false;
1910
1911 for (i = 0; i < n1; i++)
1912 {
1913 ira_object_t c1 = ALLOCNO_OBJECT (a1, i);
1914
1915 for (j = 0; j < n2; j++)
1916 {
1917 ira_object_t c2 = ALLOCNO_OBJECT (a2, j);
1918
1919 if (ira_live_ranges_intersect_p (OBJECT_LIVE_RANGES (c1),
1920 OBJECT_LIVE_RANGES (c2)))
1921 return true;
1922 }
1923 }
1924 return false;
1925}
1926
1927/* The function is used to sort copies according to their execution
1928 frequencies. */
1929static int
1930copy_freq_compare_func (const void *v1p, const void *v2p)
1931{
1932 ira_copy_t cp1 = *(const ira_copy_t *) v1p, cp2 = *(const ira_copy_t *) v2p;
1933 int pri1, pri2;
1934
1935 pri1 = cp1->freq;
1936 pri2 = cp2->freq;
1937 if (pri2 - pri1)
1938 return pri2 - pri1;
1939
b59bd98f 1940 /* If frequencies are equal, sort by copies, so that the results of
4bb79f36 1941 qsort leave nothing to chance. */
1942 return cp1->num - cp2->num;
1943}
1944
1945\f
1946
1947/* Return true if any allocno from thread of A1 conflicts with any
1948 allocno from thread A2. */
1949static bool
1950allocno_thread_conflict_p (ira_allocno_t a1, ira_allocno_t a2)
1951{
1952 ira_allocno_t a, conflict_a;
1953
1954 for (a = ALLOCNO_COLOR_DATA (a2)->next_thread_allocno;;
1955 a = ALLOCNO_COLOR_DATA (a)->next_thread_allocno)
1956 {
1957 for (conflict_a = ALLOCNO_COLOR_DATA (a1)->next_thread_allocno;;
1958 conflict_a = ALLOCNO_COLOR_DATA (conflict_a)->next_thread_allocno)
1959 {
1960 if (allocnos_conflict_by_live_ranges_p (a, conflict_a))
1961 return true;
1962 if (conflict_a == a1)
1963 break;
1964 }
1965 if (a == a2)
1966 break;
1967 }
1968 return false;
1969}
1970
1971/* Merge two threads given correspondingly by their first allocnos T1
1972 and T2 (more accurately merging T2 into T1). */
1973static void
1974merge_threads (ira_allocno_t t1, ira_allocno_t t2)
1975{
1976 ira_allocno_t a, next, last;
1977
1978 gcc_assert (t1 != t2
1979 && ALLOCNO_COLOR_DATA (t1)->first_thread_allocno == t1
1980 && ALLOCNO_COLOR_DATA (t2)->first_thread_allocno == t2);
1981 for (last = t2, a = ALLOCNO_COLOR_DATA (t2)->next_thread_allocno;;
1982 a = ALLOCNO_COLOR_DATA (a)->next_thread_allocno)
1983 {
1984 ALLOCNO_COLOR_DATA (a)->first_thread_allocno = t1;
1985 if (a == t2)
1986 break;
1987 last = a;
1988 }
1989 next = ALLOCNO_COLOR_DATA (t1)->next_thread_allocno;
1990 ALLOCNO_COLOR_DATA (t1)->next_thread_allocno = t2;
1991 ALLOCNO_COLOR_DATA (last)->next_thread_allocno = next;
1992 ALLOCNO_COLOR_DATA (t1)->thread_freq += ALLOCNO_COLOR_DATA (t2)->thread_freq;
1993}
1994
b59bd98f 1995/* Create threads by processing CP_NUM copies from sorted copies. We
4bb79f36 1996 process the most expensive copies first. */
1997static void
1998form_threads_from_copies (int cp_num)
1999{
2000 ira_allocno_t a, thread1, thread2;
2001 ira_copy_t cp;
2002 int i, n;
2003
2004 qsort (sorted_copies, cp_num, sizeof (ira_copy_t), copy_freq_compare_func);
2005 /* Form threads processing copies, most frequently executed
2006 first. */
2007 for (; cp_num != 0;)
2008 {
2009 for (i = 0; i < cp_num; i++)
2010 {
2011 cp = sorted_copies[i];
2012 thread1 = ALLOCNO_COLOR_DATA (cp->first)->first_thread_allocno;
2013 thread2 = ALLOCNO_COLOR_DATA (cp->second)->first_thread_allocno;
2014 if (thread1 == thread2)
2015 continue;
2016 if (! allocno_thread_conflict_p (thread1, thread2))
2017 {
2018 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2019 fprintf
2020 (ira_dump_file,
2021 " Forming thread by copy %d:a%dr%d-a%dr%d (freq=%d):\n",
2022 cp->num, ALLOCNO_NUM (cp->first), ALLOCNO_REGNO (cp->first),
2023 ALLOCNO_NUM (cp->second), ALLOCNO_REGNO (cp->second),
2024 cp->freq);
2025 merge_threads (thread1, thread2);
2026 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2027 {
2028 thread1 = ALLOCNO_COLOR_DATA (thread1)->first_thread_allocno;
2029 fprintf (ira_dump_file, " Result (freq=%d): a%dr%d(%d)",
2030 ALLOCNO_COLOR_DATA (thread1)->thread_freq,
2031 ALLOCNO_NUM (thread1), ALLOCNO_REGNO (thread1),
2032 ALLOCNO_FREQ (thread1));
2033 for (a = ALLOCNO_COLOR_DATA (thread1)->next_thread_allocno;
2034 a != thread1;
2035 a = ALLOCNO_COLOR_DATA (a)->next_thread_allocno)
2036 fprintf (ira_dump_file, " a%dr%d(%d)",
2037 ALLOCNO_NUM (a), ALLOCNO_REGNO (a),
2038 ALLOCNO_FREQ (a));
2039 fprintf (ira_dump_file, "\n");
2040 }
2041 i++;
2042 break;
2043 }
2044 }
2045 /* Collect the rest of copies. */
2046 for (n = 0; i < cp_num; i++)
2047 {
2048 cp = sorted_copies[i];
2049 if (ALLOCNO_COLOR_DATA (cp->first)->first_thread_allocno
2050 != ALLOCNO_COLOR_DATA (cp->second)->first_thread_allocno)
2051 sorted_copies[n++] = cp;
2052 }
2053 cp_num = n;
2054 }
2055}
2056
2057/* Create threads by processing copies of all alocnos from BUCKET. We
2058 process the most expensive copies first. */
2059static void
2060form_threads_from_bucket (ira_allocno_t bucket)
2061{
2062 ira_allocno_t a;
2063 ira_copy_t cp, next_cp;
2064 int cp_num = 0;
2065
2066 for (a = bucket; a != NULL; a = ALLOCNO_COLOR_DATA (a)->next_bucket_allocno)
2067 {
2068 for (cp = ALLOCNO_COPIES (a); cp != NULL; cp = next_cp)
2069 {
2070 if (cp->first == a)
2071 {
2072 next_cp = cp->next_first_allocno_copy;
2073 sorted_copies[cp_num++] = cp;
2074 }
2075 else if (cp->second == a)
2076 next_cp = cp->next_second_allocno_copy;
2077 else
2078 gcc_unreachable ();
2079 }
2080 }
2081 form_threads_from_copies (cp_num);
2082}
2083
2084/* Create threads by processing copies of colorable allocno A. We
2085 process most expensive copies first. */
2086static void
2087form_threads_from_colorable_allocno (ira_allocno_t a)
2088{
2089 ira_allocno_t another_a;
2090 ira_copy_t cp, next_cp;
2091 int cp_num = 0;
2092
2093 for (cp = ALLOCNO_COPIES (a); cp != NULL; cp = next_cp)
2094 {
2095 if (cp->first == a)
2096 {
2097 next_cp = cp->next_first_allocno_copy;
2098 another_a = cp->second;
2099 }
2100 else if (cp->second == a)
2101 {
2102 next_cp = cp->next_second_allocno_copy;
2103 another_a = cp->first;
2104 }
2105 else
2106 gcc_unreachable ();
2107 if ((! ALLOCNO_COLOR_DATA (another_a)->in_graph_p
2108 && !ALLOCNO_COLOR_DATA (another_a)->may_be_spilled_p)
2109 || ALLOCNO_COLOR_DATA (another_a)->colorable_p)
2110 sorted_copies[cp_num++] = cp;
2111 }
2112 form_threads_from_copies (cp_num);
2113}
2114
2115/* Form initial threads which contain only one allocno. */
2116static void
2117init_allocno_threads (void)
2118{
2119 ira_allocno_t a;
2120 unsigned int j;
2121 bitmap_iterator bi;
2122
2123 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
2124 {
2125 a = ira_allocnos[j];
2126 /* Set up initial thread data: */
2127 ALLOCNO_COLOR_DATA (a)->first_thread_allocno
2128 = ALLOCNO_COLOR_DATA (a)->next_thread_allocno = a;
2129 ALLOCNO_COLOR_DATA (a)->thread_freq = ALLOCNO_FREQ (a);
2130 }
2131}
2132
2133\f
2134
47dd2e78 2135/* This page contains the allocator based on the Chaitin-Briggs algorithm. */
2136
2137/* Bucket of allocnos that can colored currently without spilling. */
2138static ira_allocno_t colorable_allocno_bucket;
2139
2140/* Bucket of allocnos that might be not colored currently without
2141 spilling. */
2142static ira_allocno_t uncolorable_allocno_bucket;
2143
66d9a7b9 2144/* The current number of allocnos in the uncolorable_bucket. */
2145static int uncolorable_allocnos_num;
47dd2e78 2146
ddf888a5 2147/* Return the current spill priority of allocno A. The less the
2148 number, the more preferable the allocno for spilling. */
66d9a7b9 2149static inline int
ddf888a5 2150allocno_spill_priority (ira_allocno_t a)
2151{
66d9a7b9 2152 allocno_color_data_t data = ALLOCNO_COLOR_DATA (a);
2153
2154 return (data->temp
2155 / (ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a)
2156 * ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]
ddf888a5 2157 + 1));
2158}
2159
66d9a7b9 2160/* Add allocno A to bucket *BUCKET_PTR. A should be not in a bucket
47dd2e78 2161 before the call. */
2162static void
66d9a7b9 2163add_allocno_to_bucket (ira_allocno_t a, ira_allocno_t *bucket_ptr)
47dd2e78 2164{
66d9a7b9 2165 ira_allocno_t first_a;
2166 allocno_color_data_t data;
47dd2e78 2167
2168 if (bucket_ptr == &uncolorable_allocno_bucket
66d9a7b9 2169 && ALLOCNO_CLASS (a) != NO_REGS)
47dd2e78 2170 {
66d9a7b9 2171 uncolorable_allocnos_num++;
2172 ira_assert (uncolorable_allocnos_num > 0);
47dd2e78 2173 }
66d9a7b9 2174 first_a = *bucket_ptr;
2175 data = ALLOCNO_COLOR_DATA (a);
2176 data->next_bucket_allocno = first_a;
2177 data->prev_bucket_allocno = NULL;
2178 if (first_a != NULL)
2179 ALLOCNO_COLOR_DATA (first_a)->prev_bucket_allocno = a;
2180 *bucket_ptr = a;
47dd2e78 2181}
2182
47dd2e78 2183/* Compare two allocnos to define which allocno should be pushed first
2184 into the coloring stack. If the return is a negative number, the
2185 allocno given by the first parameter will be pushed first. In this
2186 case such allocno has less priority than the second one and the
2187 hard register will be assigned to it after assignment to the second
2188 one. As the result of such assignment order, the second allocno
2189 has a better chance to get the best hard register. */
2190static int
2191bucket_allocno_compare_func (const void *v1p, const void *v2p)
2192{
2193 ira_allocno_t a1 = *(const ira_allocno_t *) v1p;
2194 ira_allocno_t a2 = *(const ira_allocno_t *) v2p;
4bb79f36 2195 int diff, freq1, freq2, a1_num, a2_num;
2196 ira_allocno_t t1 = ALLOCNO_COLOR_DATA (a1)->first_thread_allocno;
2197 ira_allocno_t t2 = ALLOCNO_COLOR_DATA (a2)->first_thread_allocno;
9f7438de 2198 int cl1 = ALLOCNO_CLASS (a1), cl2 = ALLOCNO_CLASS (a2);
2199
4bb79f36 2200 freq1 = ALLOCNO_COLOR_DATA (t1)->thread_freq;
2201 freq2 = ALLOCNO_COLOR_DATA (t2)->thread_freq;
2202 if ((diff = freq1 - freq2) != 0)
2203 return diff;
2204
2205 if ((diff = ALLOCNO_NUM (t2) - ALLOCNO_NUM (t1)) != 0)
2206 return diff;
2207
9f7438de 2208 /* Push pseudos requiring less hard registers first. It means that
2209 we will assign pseudos requiring more hard registers first
2210 avoiding creation small holes in free hard register file into
2211 which the pseudos requiring more hard registers can not fit. */
2212 if ((diff = (ira_reg_class_max_nregs[cl1][ALLOCNO_MODE (a1)]
2213 - ira_reg_class_max_nregs[cl2][ALLOCNO_MODE (a2)])) != 0)
47dd2e78 2214 return diff;
4bb79f36 2215
2216 freq1 = ALLOCNO_FREQ (a1);
2217 freq2 = ALLOCNO_FREQ (a2);
2218 if ((diff = freq1 - freq2) != 0)
47dd2e78 2219 return diff;
4bb79f36 2220
66d9a7b9 2221 a1_num = ALLOCNO_COLOR_DATA (a1)->available_regs_num;
2222 a2_num = ALLOCNO_COLOR_DATA (a2)->available_regs_num;
2223 if ((diff = a2_num - a1_num) != 0)
a5af08d2 2224 return diff;
47dd2e78 2225 return ALLOCNO_NUM (a2) - ALLOCNO_NUM (a1);
2226}
2227
2228/* Sort bucket *BUCKET_PTR and return the result through
2229 BUCKET_PTR. */
2230static void
66d9a7b9 2231sort_bucket (ira_allocno_t *bucket_ptr,
2232 int (*compare_func) (const void *, const void *))
47dd2e78 2233{
2234 ira_allocno_t a, head;
2235 int n;
2236
66d9a7b9 2237 for (n = 0, a = *bucket_ptr;
2238 a != NULL;
2239 a = ALLOCNO_COLOR_DATA (a)->next_bucket_allocno)
47dd2e78 2240 sorted_allocnos[n++] = a;
2241 if (n <= 1)
2242 return;
66d9a7b9 2243 qsort (sorted_allocnos, n, sizeof (ira_allocno_t), compare_func);
47dd2e78 2244 head = NULL;
2245 for (n--; n >= 0; n--)
2246 {
2247 a = sorted_allocnos[n];
66d9a7b9 2248 ALLOCNO_COLOR_DATA (a)->next_bucket_allocno = head;
2249 ALLOCNO_COLOR_DATA (a)->prev_bucket_allocno = NULL;
47dd2e78 2250 if (head != NULL)
66d9a7b9 2251 ALLOCNO_COLOR_DATA (head)->prev_bucket_allocno = a;
47dd2e78 2252 head = a;
2253 }
2254 *bucket_ptr = head;
2255}
2256
4bb79f36 2257/* Add ALLOCNO to colorable bucket maintaining the order according
47dd2e78 2258 their priority. ALLOCNO should be not in a bucket before the
2259 call. */
2260static void
4bb79f36 2261add_allocno_to_ordered_colorable_bucket (ira_allocno_t allocno)
47dd2e78 2262{
2263 ira_allocno_t before, after;
47dd2e78 2264
4bb79f36 2265 form_threads_from_colorable_allocno (allocno);
2266 for (before = colorable_allocno_bucket, after = NULL;
47dd2e78 2267 before != NULL;
66d9a7b9 2268 after = before,
2269 before = ALLOCNO_COLOR_DATA (before)->next_bucket_allocno)
47dd2e78 2270 if (bucket_allocno_compare_func (&allocno, &before) < 0)
2271 break;
66d9a7b9 2272 ALLOCNO_COLOR_DATA (allocno)->next_bucket_allocno = before;
2273 ALLOCNO_COLOR_DATA (allocno)->prev_bucket_allocno = after;
47dd2e78 2274 if (after == NULL)
4bb79f36 2275 colorable_allocno_bucket = allocno;
47dd2e78 2276 else
66d9a7b9 2277 ALLOCNO_COLOR_DATA (after)->next_bucket_allocno = allocno;
47dd2e78 2278 if (before != NULL)
66d9a7b9 2279 ALLOCNO_COLOR_DATA (before)->prev_bucket_allocno = allocno;
47dd2e78 2280}
2281
2282/* Delete ALLOCNO from bucket *BUCKET_PTR. It should be there before
2283 the call. */
2284static void
2285delete_allocno_from_bucket (ira_allocno_t allocno, ira_allocno_t *bucket_ptr)
2286{
2287 ira_allocno_t prev_allocno, next_allocno;
47dd2e78 2288
2289 if (bucket_ptr == &uncolorable_allocno_bucket
66d9a7b9 2290 && ALLOCNO_CLASS (allocno) != NO_REGS)
47dd2e78 2291 {
66d9a7b9 2292 uncolorable_allocnos_num--;
2293 ira_assert (uncolorable_allocnos_num >= 0);
47dd2e78 2294 }
66d9a7b9 2295 prev_allocno = ALLOCNO_COLOR_DATA (allocno)->prev_bucket_allocno;
2296 next_allocno = ALLOCNO_COLOR_DATA (allocno)->next_bucket_allocno;
47dd2e78 2297 if (prev_allocno != NULL)
66d9a7b9 2298 ALLOCNO_COLOR_DATA (prev_allocno)->next_bucket_allocno = next_allocno;
47dd2e78 2299 else
2300 {
2301 ira_assert (*bucket_ptr == allocno);
2302 *bucket_ptr = next_allocno;
2303 }
2304 if (next_allocno != NULL)
66d9a7b9 2305 ALLOCNO_COLOR_DATA (next_allocno)->prev_bucket_allocno = prev_allocno;
47dd2e78 2306}
2307
e8b4e44b 2308/* Put allocno A onto the coloring stack without removing it from its
47dd2e78 2309 bucket. Pushing allocno to the coloring stack can result in moving
2310 conflicting allocnos from the uncolorable bucket to the colorable
2311 one. */
2312static void
e8b4e44b 2313push_allocno_to_stack (ira_allocno_t a)
47dd2e78 2314{
66d9a7b9 2315 enum reg_class aclass;
2316 allocno_color_data_t data, conflict_data;
2317 int size, i, n = ALLOCNO_NUM_OBJECTS (a);
2318
2319 data = ALLOCNO_COLOR_DATA (a);
2320 data->in_graph_p = false;
f1f41a6c 2321 allocno_stack_vec.safe_push (a);
66d9a7b9 2322 aclass = ALLOCNO_CLASS (a);
2323 if (aclass == NO_REGS)
47dd2e78 2324 return;
66d9a7b9 2325 size = ira_reg_class_max_nregs[aclass][ALLOCNO_MODE (a)];
2326 if (n > 1)
be18556f 2327 {
2328 /* We will deal with the subwords individually. */
e8b4e44b 2329 gcc_assert (size == ALLOCNO_NUM_OBJECTS (a));
be18556f 2330 size = 1;
2331 }
e8b4e44b 2332 for (i = 0; i < n; i++)
47dd2e78 2333 {
e8b4e44b 2334 ira_object_t obj = ALLOCNO_OBJECT (a, i);
e8b4e44b 2335 ira_object_t conflict_obj;
2336 ira_object_conflict_iterator oci;
2337
2338 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
b7c06809 2339 {
e8b4e44b 2340 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
e8b4e44b 2341
66d9a7b9 2342 conflict_data = ALLOCNO_COLOR_DATA (conflict_a);
2343 if (conflict_data->colorable_p
2344 || ! conflict_data->in_graph_p
2345 || ALLOCNO_ASSIGNED_P (conflict_a)
2346 || !(hard_reg_set_intersect_p
7fcdc371 2347 (ALLOCNO_COLOR_DATA (a)->profitable_hard_regs,
2348 conflict_data->profitable_hard_regs)))
e8b4e44b 2349 continue;
66d9a7b9 2350 ira_assert (bitmap_bit_p (coloring_allocno_bitmap,
2351 ALLOCNO_NUM (conflict_a)));
7fcdc371 2352 if (update_left_conflict_sizes_p (conflict_a, a, size))
e8b4e44b 2353 {
2354 delete_allocno_from_bucket
7fcdc371 2355 (conflict_a, &uncolorable_allocno_bucket);
4bb79f36 2356 add_allocno_to_ordered_colorable_bucket (conflict_a);
66d9a7b9 2357 if (internal_flag_ira_verbose > 4 && ira_dump_file != NULL)
2358 {
2359 fprintf (ira_dump_file, " Making");
2360 ira_print_expanded_allocno (conflict_a);
2361 fprintf (ira_dump_file, " colorable\n");
2362 }
b7c06809 2363 }
66d9a7b9 2364
b7c06809 2365 }
47dd2e78 2366 }
2367}
2368
2369/* Put ALLOCNO onto the coloring stack and remove it from its bucket.
2370 The allocno is in the colorable bucket if COLORABLE_P is TRUE. */
2371static void
2372remove_allocno_from_bucket_and_push (ira_allocno_t allocno, bool colorable_p)
2373{
47dd2e78 2374 if (colorable_p)
2375 delete_allocno_from_bucket (allocno, &colorable_allocno_bucket);
2376 else
2377 delete_allocno_from_bucket (allocno, &uncolorable_allocno_bucket);
2378 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2379 {
2380 fprintf (ira_dump_file, " Pushing");
e8b4e44b 2381 ira_print_expanded_allocno (allocno);
ddf888a5 2382 if (colorable_p)
66d9a7b9 2383 fprintf (ira_dump_file, "(cost %d)\n",
2384 ALLOCNO_COLOR_DATA (allocno)->temp);
ddf888a5 2385 else
2386 fprintf (ira_dump_file, "(potential spill: %spri=%d, cost=%d)\n",
2387 ALLOCNO_BAD_SPILL_P (allocno) ? "bad spill, " : "",
66d9a7b9 2388 allocno_spill_priority (allocno),
2389 ALLOCNO_COLOR_DATA (allocno)->temp);
2390 }
47dd2e78 2391 if (! colorable_p)
66d9a7b9 2392 ALLOCNO_COLOR_DATA (allocno)->may_be_spilled_p = true;
b7c06809 2393 push_allocno_to_stack (allocno);
47dd2e78 2394}
2395
2396/* Put all allocnos from colorable bucket onto the coloring stack. */
2397static void
2398push_only_colorable (void)
2399{
4bb79f36 2400 form_threads_from_bucket (colorable_allocno_bucket);
66d9a7b9 2401 sort_bucket (&colorable_allocno_bucket, bucket_allocno_compare_func);
47dd2e78 2402 for (;colorable_allocno_bucket != NULL;)
2403 remove_allocno_from_bucket_and_push (colorable_allocno_bucket, true);
2404}
2405
47dd2e78 2406/* Return the frequency of exit edges (if EXIT_P) or entry from/to the
48e1416a 2407 loop given by its LOOP_NODE. */
47dd2e78 2408int
2409ira_loop_edge_freq (ira_loop_tree_node_t loop_node, int regno, bool exit_p)
2410{
2411 int freq, i;
2412 edge_iterator ei;
2413 edge e;
f1f41a6c 2414 vec<edge> edges;
47dd2e78 2415
9f8ac546 2416 ira_assert (current_loops != NULL && loop_node->loop != NULL
47dd2e78 2417 && (regno < 0 || regno >= FIRST_PSEUDO_REGISTER));
2418 freq = 0;
2419 if (! exit_p)
2420 {
2421 FOR_EACH_EDGE (e, ei, loop_node->loop->header->preds)
2422 if (e->src != loop_node->loop->latch
2423 && (regno < 0
0841d295 2424 || (bitmap_bit_p (df_get_live_out (e->src), regno)
2425 && bitmap_bit_p (df_get_live_in (e->dest), regno))))
47dd2e78 2426 freq += EDGE_FREQUENCY (e);
2427 }
2428 else
2429 {
2430 edges = get_loop_exit_edges (loop_node->loop);
f1f41a6c 2431 FOR_EACH_VEC_ELT (edges, i, e)
47dd2e78 2432 if (regno < 0
0841d295 2433 || (bitmap_bit_p (df_get_live_out (e->src), regno)
2434 && bitmap_bit_p (df_get_live_in (e->dest), regno)))
47dd2e78 2435 freq += EDGE_FREQUENCY (e);
f1f41a6c 2436 edges.release ();
47dd2e78 2437 }
2438
2439 return REG_FREQ_FROM_EDGE_FREQ (freq);
2440}
2441
2442/* Calculate and return the cost of putting allocno A into memory. */
2443static int
2444calculate_allocno_spill_cost (ira_allocno_t a)
2445{
2446 int regno, cost;
2447 enum machine_mode mode;
2448 enum reg_class rclass;
2449 ira_allocno_t parent_allocno;
2450 ira_loop_tree_node_t parent_node, loop_node;
2451
2452 regno = ALLOCNO_REGNO (a);
66d9a7b9 2453 cost = ALLOCNO_UPDATED_MEMORY_COST (a) - ALLOCNO_UPDATED_CLASS_COST (a);
47dd2e78 2454 if (ALLOCNO_CAP (a) != NULL)
2455 return cost;
2456 loop_node = ALLOCNO_LOOP_TREE_NODE (a);
2457 if ((parent_node = loop_node->parent) == NULL)
2458 return cost;
2459 if ((parent_allocno = parent_node->regno_allocno_map[regno]) == NULL)
2460 return cost;
2461 mode = ALLOCNO_MODE (a);
66d9a7b9 2462 rclass = ALLOCNO_CLASS (a);
47dd2e78 2463 if (ALLOCNO_HARD_REGNO (parent_allocno) < 0)
2464 cost -= (ira_memory_move_cost[mode][rclass][0]
2465 * ira_loop_edge_freq (loop_node, regno, true)
2466 + ira_memory_move_cost[mode][rclass][1]
2467 * ira_loop_edge_freq (loop_node, regno, false));
2468 else
66d9a7b9 2469 {
2470 ira_init_register_move_cost_if_necessary (mode);
2471 cost += ((ira_memory_move_cost[mode][rclass][1]
2472 * ira_loop_edge_freq (loop_node, regno, true)
2473 + ira_memory_move_cost[mode][rclass][0]
2474 * ira_loop_edge_freq (loop_node, regno, false))
2475 - (ira_register_move_cost[mode][rclass][rclass]
2476 * (ira_loop_edge_freq (loop_node, regno, false)
2477 + ira_loop_edge_freq (loop_node, regno, true))));
2478 }
47dd2e78 2479 return cost;
2480}
2481
66d9a7b9 2482/* Used for sorting allocnos for spilling. */
2483static inline int
2484allocno_spill_priority_compare (ira_allocno_t a1, ira_allocno_t a2)
47dd2e78 2485{
2486 int pri1, pri2, diff;
48e1416a 2487
66d9a7b9 2488 if (ALLOCNO_BAD_SPILL_P (a1) && ! ALLOCNO_BAD_SPILL_P (a2))
2489 return 1;
2490 if (ALLOCNO_BAD_SPILL_P (a2) && ! ALLOCNO_BAD_SPILL_P (a1))
2491 return -1;
2492 pri1 = allocno_spill_priority (a1);
2493 pri2 = allocno_spill_priority (a2);
47dd2e78 2494 if ((diff = pri1 - pri2) != 0)
2495 return diff;
66d9a7b9 2496 if ((diff
2497 = ALLOCNO_COLOR_DATA (a1)->temp - ALLOCNO_COLOR_DATA (a2)->temp) != 0)
47dd2e78 2498 return diff;
2499 return ALLOCNO_NUM (a1) - ALLOCNO_NUM (a2);
2500}
2501
66d9a7b9 2502/* Used for sorting allocnos for spilling. */
2503static int
2504allocno_spill_sort_compare (const void *v1p, const void *v2p)
a5af08d2 2505{
66d9a7b9 2506 ira_allocno_t p1 = *(const ira_allocno_t *) v1p;
2507 ira_allocno_t p2 = *(const ira_allocno_t *) v2p;
a5af08d2 2508
66d9a7b9 2509 return allocno_spill_priority_compare (p1, p2);
47dd2e78 2510}
2511
2512/* Push allocnos to the coloring stack. The order of allocnos in the
66d9a7b9 2513 stack defines the order for the subsequent coloring. */
2514static void
2515push_allocnos_to_stack (void)
2516{
2517 ira_allocno_t a;
2518 int cost;
2519
2520 /* Calculate uncolorable allocno spill costs. */
2521 for (a = uncolorable_allocno_bucket;
2522 a != NULL;
2523 a = ALLOCNO_COLOR_DATA (a)->next_bucket_allocno)
2524 if (ALLOCNO_CLASS (a) != NO_REGS)
2525 {
2526 cost = calculate_allocno_spill_cost (a);
2527 /* ??? Remove cost of copies between the coalesced
2528 allocnos. */
2529 ALLOCNO_COLOR_DATA (a)->temp = cost;
2530 }
2531 sort_bucket (&uncolorable_allocno_bucket, allocno_spill_sort_compare);
2532 for (;;)
2533 {
2534 push_only_colorable ();
2535 a = uncolorable_allocno_bucket;
2536 if (a == NULL)
2537 break;
2538 remove_allocno_from_bucket_and_push (a, false);
47dd2e78 2539 }
2540 ira_assert (colorable_allocno_bucket == NULL
2541 && uncolorable_allocno_bucket == NULL);
66d9a7b9 2542 ira_assert (uncolorable_allocnos_num == 0);
47dd2e78 2543}
2544
2545/* Pop the coloring stack and assign hard registers to the popped
2546 allocnos. */
2547static void
2548pop_allocnos_from_stack (void)
2549{
2550 ira_allocno_t allocno;
66d9a7b9 2551 enum reg_class aclass;
47dd2e78 2552
f1f41a6c 2553 for (;allocno_stack_vec.length () != 0;)
47dd2e78 2554 {
f1f41a6c 2555 allocno = allocno_stack_vec.pop ();
66d9a7b9 2556 aclass = ALLOCNO_CLASS (allocno);
47dd2e78 2557 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2558 {
2559 fprintf (ira_dump_file, " Popping");
e8b4e44b 2560 ira_print_expanded_allocno (allocno);
47dd2e78 2561 fprintf (ira_dump_file, " -- ");
2562 }
66d9a7b9 2563 if (aclass == NO_REGS)
47dd2e78 2564 {
2565 ALLOCNO_HARD_REGNO (allocno) = -1;
2566 ALLOCNO_ASSIGNED_P (allocno) = true;
2567 ira_assert (ALLOCNO_UPDATED_HARD_REG_COSTS (allocno) == NULL);
2568 ira_assert
2569 (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (allocno) == NULL);
2570 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2571 fprintf (ira_dump_file, "assign memory\n");
2572 }
2573 else if (assign_hard_reg (allocno, false))
2574 {
2575 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2576 fprintf (ira_dump_file, "assign reg %d\n",
2577 ALLOCNO_HARD_REGNO (allocno));
2578 }
2579 else if (ALLOCNO_ASSIGNED_P (allocno))
2580 {
2581 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
284f0696 2582 fprintf (ira_dump_file, "spill%s\n",
2583 ALLOCNO_COLOR_DATA (allocno)->may_be_spilled_p
2584 ? "" : "!");
47dd2e78 2585 }
66d9a7b9 2586 ALLOCNO_COLOR_DATA (allocno)->in_graph_p = true;
be18556f 2587 }
2588}
2589
e8b4e44b 2590/* Set up number of available hard registers for allocno A. */
47dd2e78 2591static void
e8b4e44b 2592setup_allocno_available_regs_num (ira_allocno_t a)
47dd2e78 2593{
7fcdc371 2594 int i, n, hard_regno, hard_regs_num, nwords;
66d9a7b9 2595 enum reg_class aclass;
66d9a7b9 2596 allocno_color_data_t data;
47dd2e78 2597
66d9a7b9 2598 aclass = ALLOCNO_CLASS (a);
2599 data = ALLOCNO_COLOR_DATA (a);
2600 data->available_regs_num = 0;
2601 if (aclass == NO_REGS)
47dd2e78 2602 return;
66d9a7b9 2603 hard_regs_num = ira_class_hard_regs_num[aclass];
66d9a7b9 2604 nwords = ALLOCNO_NUM_OBJECTS (a);
47dd2e78 2605 for (n = 0, i = hard_regs_num - 1; i >= 0; i--)
e3c4abfb 2606 {
66d9a7b9 2607 hard_regno = ira_class_hard_regs[aclass][i];
7fcdc371 2608 /* Checking only profitable hard regs. */
2609 if (TEST_HARD_REG_BIT (data->profitable_hard_regs, hard_regno))
e3c4abfb 2610 n++;
2611 }
66d9a7b9 2612 data->available_regs_num = n;
2613 if (internal_flag_ira_verbose <= 2 || ira_dump_file == NULL)
2614 return;
2615 fprintf
2616 (ira_dump_file,
7fcdc371 2617 " Allocno a%dr%d of %s(%d) has %d avail. regs ",
66d9a7b9 2618 ALLOCNO_NUM (a), ALLOCNO_REGNO (a),
2619 reg_class_names[aclass], ira_class_hard_regs_num[aclass], n);
7fcdc371 2620 print_hard_reg_set (ira_dump_file, data->profitable_hard_regs, false);
2621 fprintf (ira_dump_file, ", %snode: ",
2622 hard_reg_set_equal_p (data->profitable_hard_regs,
2623 data->hard_regs_node->hard_regs->set)
2624 ? "" : "^");
2625 print_hard_reg_set (ira_dump_file,
2626 data->hard_regs_node->hard_regs->set, false);
66d9a7b9 2627 for (i = 0; i < nwords; i++)
e8b4e44b 2628 {
66d9a7b9 2629 ira_object_t obj = ALLOCNO_OBJECT (a, i);
be18556f 2630
66d9a7b9 2631 if (nwords != 1)
e8b4e44b 2632 {
66d9a7b9 2633 if (i != 0)
2634 fprintf (ira_dump_file, ", ");
2635 fprintf (ira_dump_file, " obj %d", i);
e8b4e44b 2636 }
66d9a7b9 2637 fprintf (ira_dump_file, " (confl regs = ");
2638 print_hard_reg_set (ira_dump_file, OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
2639 false);
7fcdc371 2640 fprintf (ira_dump_file, ")");
e8b4e44b 2641 }
66d9a7b9 2642 fprintf (ira_dump_file, "\n");
47dd2e78 2643}
2644
2645/* Put ALLOCNO in a bucket corresponding to its number and size of its
2646 conflicting allocnos and hard registers. */
2647static void
2648put_allocno_into_bucket (ira_allocno_t allocno)
2649{
66d9a7b9 2650 ALLOCNO_COLOR_DATA (allocno)->in_graph_p = true;
47dd2e78 2651 setup_allocno_available_regs_num (allocno);
66d9a7b9 2652 if (setup_left_conflict_sizes_p (allocno))
b7c06809 2653 add_allocno_to_bucket (allocno, &colorable_allocno_bucket);
47dd2e78 2654 else
b7c06809 2655 add_allocno_to_bucket (allocno, &uncolorable_allocno_bucket);
47dd2e78 2656}
2657
e8b4e44b 2658/* Map: allocno number -> allocno priority. */
2659static int *allocno_priorities;
47dd2e78 2660
e8b4e44b 2661/* Set up priorities for N allocnos in array
2662 CONSIDERATION_ALLOCNOS. */
47dd2e78 2663static void
e8b4e44b 2664setup_allocno_priorities (ira_allocno_t *consideration_allocnos, int n)
47dd2e78 2665{
e8b4e44b 2666 int i, length, nrefs, priority, max_priority, mult;
2667 ira_allocno_t a;
47dd2e78 2668
e8b4e44b 2669 max_priority = 0;
2670 for (i = 0; i < n; i++)
14792f4e 2671 {
2672 a = consideration_allocnos[i];
2673 nrefs = ALLOCNO_NREFS (a);
2674 ira_assert (nrefs >= 0);
2675 mult = floor_log2 (ALLOCNO_NREFS (a)) + 1;
2676 ira_assert (mult >= 0);
2677 allocno_priorities[ALLOCNO_NUM (a)]
2678 = priority
2679 = (mult
66d9a7b9 2680 * (ALLOCNO_MEMORY_COST (a) - ALLOCNO_CLASS_COST (a))
2681 * ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]);
14792f4e 2682 if (priority < 0)
2683 priority = -priority;
2684 if (max_priority < priority)
2685 max_priority = priority;
2686 }
2687 mult = max_priority == 0 ? 1 : INT_MAX / max_priority;
2688 for (i = 0; i < n; i++)
2689 {
2690 a = consideration_allocnos[i];
2691 length = ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a);
be18556f 2692 if (ALLOCNO_NUM_OBJECTS (a) > 1)
2693 length /= ALLOCNO_NUM_OBJECTS (a);
14792f4e 2694 if (length <= 0)
2695 length = 1;
2696 allocno_priorities[ALLOCNO_NUM (a)]
2697 = allocno_priorities[ALLOCNO_NUM (a)] * mult / length;
2698 }
2699}
2700
66d9a7b9 2701/* Sort allocnos according to the profit of usage of a hard register
2702 instead of memory for them. */
2703static int
2704allocno_cost_compare_func (const void *v1p, const void *v2p)
2705{
2706 ira_allocno_t p1 = *(const ira_allocno_t *) v1p;
2707 ira_allocno_t p2 = *(const ira_allocno_t *) v2p;
2708 int c1, c2;
2709
2710 c1 = ALLOCNO_UPDATED_MEMORY_COST (p1) - ALLOCNO_UPDATED_CLASS_COST (p1);
2711 c2 = ALLOCNO_UPDATED_MEMORY_COST (p2) - ALLOCNO_UPDATED_CLASS_COST (p2);
2712 if (c1 - c2)
2713 return c1 - c2;
2714
2715 /* If regs are equally good, sort by allocno numbers, so that the
2716 results of qsort leave nothing to chance. */
2717 return ALLOCNO_NUM (p1) - ALLOCNO_NUM (p2);
2718}
2719
2720/* We used Chaitin-Briggs coloring to assign as many pseudos as
2721 possible to hard registers. Let us try to improve allocation with
2722 cost point of view. This function improves the allocation by
2723 spilling some allocnos and assigning the freed hard registers to
2724 other allocnos if it decreases the overall allocation cost. */
2725static void
2726improve_allocation (void)
2727{
2728 unsigned int i;
2729 int j, k, n, hregno, conflict_hregno, base_cost, class_size, word, nwords;
2730 int check, spill_cost, min_cost, nregs, conflict_nregs, r, best;
2731 bool try_p;
2732 enum reg_class aclass;
2733 enum machine_mode mode;
2734 int *allocno_costs;
2735 int costs[FIRST_PSEUDO_REGISTER];
7fcdc371 2736 HARD_REG_SET conflicting_regs[2], profitable_hard_regs;
66d9a7b9 2737 ira_allocno_t a;
2738 bitmap_iterator bi;
2739
2740 /* Clear counts used to process conflicting allocnos only once for
2741 each allocno. */
2742 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
2743 ALLOCNO_COLOR_DATA (ira_allocnos[i])->temp = 0;
2744 check = n = 0;
2745 /* Process each allocno and try to assign a hard register to it by
2746 spilling some its conflicting allocnos. */
2747 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
2748 {
2749 a = ira_allocnos[i];
2750 ALLOCNO_COLOR_DATA (a)->temp = 0;
2751 if (empty_profitable_hard_regs (a))
2752 continue;
2753 check++;
2754 aclass = ALLOCNO_CLASS (a);
2755 allocno_costs = ALLOCNO_UPDATED_HARD_REG_COSTS (a);
2756 if (allocno_costs == NULL)
2757 allocno_costs = ALLOCNO_HARD_REG_COSTS (a);
2758 if ((hregno = ALLOCNO_HARD_REGNO (a)) < 0)
2759 base_cost = ALLOCNO_UPDATED_MEMORY_COST (a);
2760 else if (allocno_costs == NULL)
2761 /* It means that assigning a hard register is not profitable
2762 (we don't waste memory for hard register costs in this
2763 case). */
2764 continue;
2765 else
2766 base_cost = allocno_costs[ira_class_hard_reg_index[aclass][hregno]];
2767 try_p = false;
7fcdc371 2768 get_conflict_and_start_profitable_regs (a, false,
2769 conflicting_regs,
2770 &profitable_hard_regs);
66d9a7b9 2771 class_size = ira_class_hard_regs_num[aclass];
2772 /* Set up cost improvement for usage of each profitable hard
2773 register for allocno A. */
2774 for (j = 0; j < class_size; j++)
2775 {
2776 hregno = ira_class_hard_regs[aclass][j];
2777 if (! check_hard_reg_p (a, hregno,
2778 conflicting_regs, profitable_hard_regs))
2779 continue;
2780 ira_assert (ira_class_hard_reg_index[aclass][hregno] == j);
2781 k = allocno_costs == NULL ? 0 : j;
2782 costs[hregno] = (allocno_costs == NULL
2783 ? ALLOCNO_UPDATED_CLASS_COST (a) : allocno_costs[k]);
2784 costs[hregno] -= base_cost;
2785 if (costs[hregno] < 0)
2786 try_p = true;
2787 }
2788 if (! try_p)
2789 /* There is no chance to improve the allocation cost by
2790 assigning hard register to allocno A even without spilling
2791 conflicting allocnos. */
2792 continue;
2793 mode = ALLOCNO_MODE (a);
2794 nwords = ALLOCNO_NUM_OBJECTS (a);
2795 /* Process each allocno conflicting with A and update the cost
2796 improvement for profitable hard registers of A. To use a
2797 hard register for A we need to spill some conflicting
2798 allocnos and that creates penalty for the cost
2799 improvement. */
2800 for (word = 0; word < nwords; word++)
2801 {
2802 ira_object_t conflict_obj;
2803 ira_object_t obj = ALLOCNO_OBJECT (a, word);
2804 ira_object_conflict_iterator oci;
2805
2806 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
2807 {
2808 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
2809
2810 if (ALLOCNO_COLOR_DATA (conflict_a)->temp == check)
2811 /* We already processed this conflicting allocno
2812 because we processed earlier another object of the
2813 conflicting allocno. */
2814 continue;
2815 ALLOCNO_COLOR_DATA (conflict_a)->temp = check;
2816 if ((conflict_hregno = ALLOCNO_HARD_REGNO (conflict_a)) < 0)
2817 continue;
2818 spill_cost = ALLOCNO_UPDATED_MEMORY_COST (conflict_a);
2819 k = (ira_class_hard_reg_index
2820 [ALLOCNO_CLASS (conflict_a)][conflict_hregno]);
2821 ira_assert (k >= 0);
2822 if ((allocno_costs = ALLOCNO_UPDATED_HARD_REG_COSTS (conflict_a))
2823 != NULL)
2824 spill_cost -= allocno_costs[k];
2825 else if ((allocno_costs = ALLOCNO_HARD_REG_COSTS (conflict_a))
2826 != NULL)
2827 spill_cost -= allocno_costs[k];
2828 else
2829 spill_cost -= ALLOCNO_UPDATED_CLASS_COST (conflict_a);
2830 conflict_nregs
2831 = hard_regno_nregs[conflict_hregno][ALLOCNO_MODE (conflict_a)];
2832 for (r = conflict_hregno;
2833 r >= 0 && r + hard_regno_nregs[r][mode] > conflict_hregno;
2834 r--)
2835 if (check_hard_reg_p (a, r,
2836 conflicting_regs, profitable_hard_regs))
2837 costs[r] += spill_cost;
2838 for (r = conflict_hregno + 1;
2839 r < conflict_hregno + conflict_nregs;
2840 r++)
2841 if (check_hard_reg_p (a, r,
2842 conflicting_regs, profitable_hard_regs))
2843 costs[r] += spill_cost;
2844 }
2845 }
2846 min_cost = INT_MAX;
2847 best = -1;
2848 /* Now we choose hard register for A which results in highest
2849 allocation cost improvement. */
2850 for (j = 0; j < class_size; j++)
2851 {
2852 hregno = ira_class_hard_regs[aclass][j];
2853 if (check_hard_reg_p (a, hregno,
2854 conflicting_regs, profitable_hard_regs)
2855 && min_cost > costs[hregno])
2856 {
2857 best = hregno;
2858 min_cost = costs[hregno];
2859 }
2860 }
2861 if (min_cost >= 0)
2862 /* We are in a situation when assigning any hard register to A
2863 by spilling some conflicting allocnos does not improve the
2864 allocation cost. */
2865 continue;
2866 nregs = hard_regno_nregs[best][mode];
2867 /* Now spill conflicting allocnos which contain a hard register
2868 of A when we assign the best chosen hard register to it. */
2869 for (word = 0; word < nwords; word++)
2870 {
2871 ira_object_t conflict_obj;
2872 ira_object_t obj = ALLOCNO_OBJECT (a, word);
2873 ira_object_conflict_iterator oci;
2874
2875 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
2876 {
2877 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
2878
2879 if ((conflict_hregno = ALLOCNO_HARD_REGNO (conflict_a)) < 0)
2880 continue;
2881 conflict_nregs
2882 = hard_regno_nregs[conflict_hregno][ALLOCNO_MODE (conflict_a)];
2883 if (best + nregs <= conflict_hregno
2884 || conflict_hregno + conflict_nregs <= best)
2885 /* No intersection. */
2886 continue;
2887 ALLOCNO_HARD_REGNO (conflict_a) = -1;
2888 sorted_allocnos[n++] = conflict_a;
2889 if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
2890 fprintf (ira_dump_file, "Spilling a%dr%d for a%dr%d\n",
2891 ALLOCNO_NUM (conflict_a), ALLOCNO_REGNO (conflict_a),
2892 ALLOCNO_NUM (a), ALLOCNO_REGNO (a));
2893 }
2894 }
2895 /* Assign the best chosen hard register to A. */
2896 ALLOCNO_HARD_REGNO (a) = best;
2897 if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
2898 fprintf (ira_dump_file, "Assigning %d to a%dr%d\n",
2899 best, ALLOCNO_NUM (a), ALLOCNO_REGNO (a));
2900 }
2901 if (n == 0)
2902 return;
2903 /* We spilled some allocnos to assign their hard registers to other
2904 allocnos. The spilled allocnos are now in array
2905 'sorted_allocnos'. There is still a possibility that some of the
2906 spilled allocnos can get hard registers. So let us try assign
2907 them hard registers again (just a reminder -- function
2908 'assign_hard_reg' assigns hard registers only if it is possible
2909 and profitable). We process the spilled allocnos with biggest
2910 benefit to get hard register first -- see function
2911 'allocno_cost_compare_func'. */
2912 qsort (sorted_allocnos, n, sizeof (ira_allocno_t),
2913 allocno_cost_compare_func);
2914 for (j = 0; j < n; j++)
2915 {
2916 a = sorted_allocnos[j];
2917 ALLOCNO_ASSIGNED_P (a) = false;
2918 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2919 {
2920 fprintf (ira_dump_file, " ");
2921 ira_print_expanded_allocno (a);
2922 fprintf (ira_dump_file, " -- ");
2923 }
2924 if (assign_hard_reg (a, false))
2925 {
2926 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2927 fprintf (ira_dump_file, "assign hard reg %d\n",
2928 ALLOCNO_HARD_REGNO (a));
2929 }
2930 else
2931 {
2932 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2933 fprintf (ira_dump_file, "assign memory\n");
2934 }
2935 }
2936}
2937
957b2bdc 2938/* Sort allocnos according to their priorities. */
14792f4e 2939static int
2940allocno_priority_compare_func (const void *v1p, const void *v2p)
2941{
2942 ira_allocno_t a1 = *(const ira_allocno_t *) v1p;
2943 ira_allocno_t a2 = *(const ira_allocno_t *) v2p;
2944 int pri1, pri2;
2945
2946 pri1 = allocno_priorities[ALLOCNO_NUM (a1)];
2947 pri2 = allocno_priorities[ALLOCNO_NUM (a2)];
cf30f4b7 2948 if (pri2 != pri1)
2949 return SORTGT (pri2, pri1);
14792f4e 2950
2951 /* If regs are equally good, sort by allocnos, so that the results of
2952 qsort leave nothing to chance. */
2953 return ALLOCNO_NUM (a1) - ALLOCNO_NUM (a2);
2954}
2955
47dd2e78 2956/* Chaitin-Briggs coloring for allocnos in COLORING_ALLOCNO_BITMAP
2957 taking into account allocnos in CONSIDERATION_ALLOCNO_BITMAP. */
2958static void
2959color_allocnos (void)
2960{
14792f4e 2961 unsigned int i, n;
47dd2e78 2962 bitmap_iterator bi;
2963 ira_allocno_t a;
2964
f6c60bdb 2965 setup_profitable_hard_regs ();
284f0696 2966 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
2967 {
2968 int l, nr;
2969 HARD_REG_SET conflict_hard_regs;
2970 allocno_color_data_t data;
2971 ira_pref_t pref, next_pref;
2972
2973 a = ira_allocnos[i];
2974 nr = ALLOCNO_NUM_OBJECTS (a);
2975 CLEAR_HARD_REG_SET (conflict_hard_regs);
2976 for (l = 0; l < nr; l++)
2977 {
2978 ira_object_t obj = ALLOCNO_OBJECT (a, l);
2979 IOR_HARD_REG_SET (conflict_hard_regs,
2980 OBJECT_CONFLICT_HARD_REGS (obj));
2981 }
2982 data = ALLOCNO_COLOR_DATA (a);
2983 for (pref = ALLOCNO_PREFS (a); pref != NULL; pref = next_pref)
2984 {
2985 next_pref = pref->next_pref;
2986 if (! ira_hard_reg_in_set_p (pref->hard_regno,
2987 ALLOCNO_MODE (a),
2988 data->profitable_hard_regs))
2989 ira_remove_pref (pref);
2990 }
2991 }
14792f4e 2992 if (flag_ira_algorithm == IRA_ALGORITHM_PRIORITY)
47dd2e78 2993 {
14792f4e 2994 n = 0;
2995 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
47dd2e78 2996 {
14792f4e 2997 a = ira_allocnos[i];
66d9a7b9 2998 if (ALLOCNO_CLASS (a) == NO_REGS)
47dd2e78 2999 {
14792f4e 3000 ALLOCNO_HARD_REGNO (a) = -1;
3001 ALLOCNO_ASSIGNED_P (a) = true;
3002 ira_assert (ALLOCNO_UPDATED_HARD_REG_COSTS (a) == NULL);
3003 ira_assert (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a) == NULL);
3004 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3005 {
3006 fprintf (ira_dump_file, " Spill");
e8b4e44b 3007 ira_print_expanded_allocno (a);
14792f4e 3008 fprintf (ira_dump_file, "\n");
3009 }
3010 continue;
47dd2e78 3011 }
14792f4e 3012 sorted_allocnos[n++] = a;
3013 }
3014 if (n != 0)
3015 {
3016 setup_allocno_priorities (sorted_allocnos, n);
3017 qsort (sorted_allocnos, n, sizeof (ira_allocno_t),
3018 allocno_priority_compare_func);
3019 for (i = 0; i < n; i++)
3020 {
3021 a = sorted_allocnos[i];
3022 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3023 {
3024 fprintf (ira_dump_file, " ");
e8b4e44b 3025 ira_print_expanded_allocno (a);
14792f4e 3026 fprintf (ira_dump_file, " -- ");
3027 }
3028 if (assign_hard_reg (a, false))
3029 {
3030 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3031 fprintf (ira_dump_file, "assign hard reg %d\n",
3032 ALLOCNO_HARD_REGNO (a));
3033 }
3034 else
3035 {
3036 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3037 fprintf (ira_dump_file, "assign memory\n");
3038 }
3039 }
3040 }
3041 }
3042 else
3043 {
7fcdc371 3044 form_allocno_hard_regs_nodes_forest ();
66d9a7b9 3045 if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
3046 print_hard_regs_forest (ira_dump_file);
14792f4e 3047 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
3048 {
3049 a = ira_allocnos[i];
66d9a7b9 3050 if (ALLOCNO_CLASS (a) != NO_REGS && ! empty_profitable_hard_regs (a))
284f0696 3051 {
3052 ALLOCNO_COLOR_DATA (a)->in_graph_p = true;
3053 update_costs_from_prefs (a);
3054 }
66d9a7b9 3055 else
14792f4e 3056 {
3057 ALLOCNO_HARD_REGNO (a) = -1;
3058 ALLOCNO_ASSIGNED_P (a) = true;
66d9a7b9 3059 /* We don't need updated costs anymore. */
3060 ira_free_allocno_updated_costs (a);
14792f4e 3061 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3062 {
3063 fprintf (ira_dump_file, " Spill");
e8b4e44b 3064 ira_print_expanded_allocno (a);
14792f4e 3065 fprintf (ira_dump_file, "\n");
3066 }
14792f4e 3067 }
66d9a7b9 3068 }
3069 /* Put the allocnos into the corresponding buckets. */
3070 colorable_allocno_bucket = NULL;
3071 uncolorable_allocno_bucket = NULL;
3072 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
3073 {
3074 a = ira_allocnos[i];
3075 if (ALLOCNO_COLOR_DATA (a)->in_graph_p)
3076 put_allocno_into_bucket (a);
47dd2e78 3077 }
14792f4e 3078 push_allocnos_to_stack ();
3079 pop_allocnos_from_stack ();
7fcdc371 3080 finish_allocno_hard_regs_nodes_forest ();
47dd2e78 3081 }
66d9a7b9 3082 improve_allocation ();
47dd2e78 3083}
3084
3085\f
3086
3ad55f68 3087/* Output information about the loop given by its LOOP_TREE_NODE. */
47dd2e78 3088static void
3089print_loop_title (ira_loop_tree_node_t loop_tree_node)
3090{
3091 unsigned int j;
3092 bitmap_iterator bi;
0b1329df 3093 ira_loop_tree_node_t subloop_node, dest_loop_node;
3094 edge e;
3095 edge_iterator ei;
47dd2e78 3096
9f8ac546 3097 if (loop_tree_node->parent == NULL)
3098 fprintf (ira_dump_file,
3099 "\n Loop 0 (parent -1, header bb%d, depth 0)\n bbs:",
3100 NUM_FIXED_BLOCKS);
3101 else
3102 {
3103 ira_assert (current_loops != NULL && loop_tree_node->loop != NULL);
3104 fprintf (ira_dump_file,
3105 "\n Loop %d (parent %d, header bb%d, depth %d)\n bbs:",
3106 loop_tree_node->loop_num, loop_tree_node->parent->loop_num,
3107 loop_tree_node->loop->header->index,
3108 loop_depth (loop_tree_node->loop));
3109 }
0b1329df 3110 for (subloop_node = loop_tree_node->children;
3111 subloop_node != NULL;
3112 subloop_node = subloop_node->next)
3113 if (subloop_node->bb != NULL)
3114 {
3115 fprintf (ira_dump_file, " %d", subloop_node->bb->index);
3116 FOR_EACH_EDGE (e, ei, subloop_node->bb->succs)
34154e27 3117 if (e->dest != EXIT_BLOCK_PTR_FOR_FN (cfun)
0b1329df 3118 && ((dest_loop_node = IRA_BB_NODE (e->dest)->parent)
3119 != loop_tree_node))
3120 fprintf (ira_dump_file, "(->%d:l%d)",
9f8ac546 3121 e->dest->index, dest_loop_node->loop_num);
0b1329df 3122 }
3123 fprintf (ira_dump_file, "\n all:");
2bae4acc 3124 EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->all_allocnos, 0, j, bi)
47dd2e78 3125 fprintf (ira_dump_file, " %dr%d", j, ALLOCNO_REGNO (ira_allocnos[j]));
3126 fprintf (ira_dump_file, "\n modified regnos:");
3127 EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->modified_regnos, 0, j, bi)
3128 fprintf (ira_dump_file, " %d", j);
3129 fprintf (ira_dump_file, "\n border:");
3130 EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->border_allocnos, 0, j, bi)
3131 fprintf (ira_dump_file, " %dr%d", j, ALLOCNO_REGNO (ira_allocnos[j]));
3132 fprintf (ira_dump_file, "\n Pressure:");
66d9a7b9 3133 for (j = 0; (int) j < ira_pressure_classes_num; j++)
47dd2e78 3134 {
66d9a7b9 3135 enum reg_class pclass;
48e1416a 3136
66d9a7b9 3137 pclass = ira_pressure_classes[j];
3138 if (loop_tree_node->reg_pressure[pclass] == 0)
47dd2e78 3139 continue;
66d9a7b9 3140 fprintf (ira_dump_file, " %s=%d", reg_class_names[pclass],
3141 loop_tree_node->reg_pressure[pclass]);
47dd2e78 3142 }
3143 fprintf (ira_dump_file, "\n");
3144}
3145
3146/* Color the allocnos inside loop (in the extreme case it can be all
3147 of the function) given the corresponding LOOP_TREE_NODE. The
3148 function is called for each loop during top-down traverse of the
3149 loop tree. */
3150static void
3151color_pass (ira_loop_tree_node_t loop_tree_node)
3152{
7fcdc371 3153 int regno, hard_regno, index = -1, n;
47dd2e78 3154 int cost, exit_freq, enter_freq;
3155 unsigned int j;
3156 bitmap_iterator bi;
3157 enum machine_mode mode;
66d9a7b9 3158 enum reg_class rclass, aclass, pclass;
47dd2e78 3159 ira_allocno_t a, subloop_allocno;
3160 ira_loop_tree_node_t subloop_node;
3161
3162 ira_assert (loop_tree_node->bb == NULL);
3163 if (internal_flag_ira_verbose > 1 && ira_dump_file != NULL)
3164 print_loop_title (loop_tree_node);
3165
2bae4acc 3166 bitmap_copy (coloring_allocno_bitmap, loop_tree_node->all_allocnos);
47dd2e78 3167 bitmap_copy (consideration_allocno_bitmap, coloring_allocno_bitmap);
7fcdc371 3168 n = 0;
66d9a7b9 3169 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
3170 {
3171 a = ira_allocnos[j];
3172 n++;
66d9a7b9 3173 if (! ALLOCNO_ASSIGNED_P (a))
3174 continue;
3175 bitmap_clear_bit (coloring_allocno_bitmap, ALLOCNO_NUM (a));
3176 }
3177 allocno_color_data
3178 = (allocno_color_data_t) ira_allocate (sizeof (struct allocno_color_data)
3179 * n);
3180 memset (allocno_color_data, 0, sizeof (struct allocno_color_data) * n);
7fcdc371 3181 curr_allocno_process = 0;
3182 n = 0;
47dd2e78 3183 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
3184 {
3185 a = ira_allocnos[j];
66d9a7b9 3186 ALLOCNO_ADD_DATA (a) = allocno_color_data + n;
3187 n++;
47dd2e78 3188 }
4bb79f36 3189 init_allocno_threads ();
47dd2e78 3190 /* Color all mentioned allocnos including transparent ones. */
3191 color_allocnos ();
3192 /* Process caps. They are processed just once. */
14792f4e 3193 if (flag_ira_region == IRA_REGION_MIXED
3194 || flag_ira_region == IRA_REGION_ALL)
2bae4acc 3195 EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->all_allocnos, 0, j, bi)
47dd2e78 3196 {
3197 a = ira_allocnos[j];
3198 if (ALLOCNO_CAP_MEMBER (a) == NULL)
3199 continue;
3200 /* Remove from processing in the next loop. */
3201 bitmap_clear_bit (consideration_allocno_bitmap, j);
66d9a7b9 3202 rclass = ALLOCNO_CLASS (a);
3203 pclass = ira_pressure_class_translate[rclass];
14792f4e 3204 if (flag_ira_region == IRA_REGION_MIXED
66d9a7b9 3205 && (loop_tree_node->reg_pressure[pclass]
1072fecf 3206 <= ira_class_hard_regs_num[pclass]))
47dd2e78 3207 {
3208 mode = ALLOCNO_MODE (a);
3209 hard_regno = ALLOCNO_HARD_REGNO (a);
3210 if (hard_regno >= 0)
3211 {
3212 index = ira_class_hard_reg_index[rclass][hard_regno];
3213 ira_assert (index >= 0);
3214 }
3215 regno = ALLOCNO_REGNO (a);
3216 subloop_allocno = ALLOCNO_CAP_MEMBER (a);
3217 subloop_node = ALLOCNO_LOOP_TREE_NODE (subloop_allocno);
3218 ira_assert (!ALLOCNO_ASSIGNED_P (subloop_allocno));
3219 ALLOCNO_HARD_REGNO (subloop_allocno) = hard_regno;
3220 ALLOCNO_ASSIGNED_P (subloop_allocno) = true;
3221 if (hard_regno >= 0)
682e13bb 3222 update_costs_from_copies (subloop_allocno, true, true);
3ad55f68 3223 /* We don't need updated costs anymore. */
47dd2e78 3224 ira_free_allocno_updated_costs (subloop_allocno);
3225 }
3226 }
3227 /* Update costs of the corresponding allocnos (not caps) in the
3228 subloops. */
3229 for (subloop_node = loop_tree_node->subloops;
3230 subloop_node != NULL;
3231 subloop_node = subloop_node->subloop_next)
3232 {
3233 ira_assert (subloop_node->bb == NULL);
3234 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
3235 {
3236 a = ira_allocnos[j];
3237 ira_assert (ALLOCNO_CAP_MEMBER (a) == NULL);
3238 mode = ALLOCNO_MODE (a);
66d9a7b9 3239 rclass = ALLOCNO_CLASS (a);
3240 pclass = ira_pressure_class_translate[rclass];
47dd2e78 3241 hard_regno = ALLOCNO_HARD_REGNO (a);
14792f4e 3242 /* Use hard register class here. ??? */
47dd2e78 3243 if (hard_regno >= 0)
3244 {
3245 index = ira_class_hard_reg_index[rclass][hard_regno];
3246 ira_assert (index >= 0);
3247 }
3248 regno = ALLOCNO_REGNO (a);
3249 /* ??? conflict costs */
3250 subloop_allocno = subloop_node->regno_allocno_map[regno];
3251 if (subloop_allocno == NULL
3252 || ALLOCNO_CAP (subloop_allocno) != NULL)
3253 continue;
66d9a7b9 3254 ira_assert (ALLOCNO_CLASS (subloop_allocno) == rclass);
2bae4acc 3255 ira_assert (bitmap_bit_p (subloop_node->all_allocnos,
3256 ALLOCNO_NUM (subloop_allocno)));
a9d8ab38 3257 if ((flag_ira_region == IRA_REGION_MIXED
3258 && (loop_tree_node->reg_pressure[pclass]
3259 <= ira_class_hard_regs_num[pclass]))
3260 || (pic_offset_table_rtx != NULL
3261 && regno == (int) REGNO (pic_offset_table_rtx)))
47dd2e78 3262 {
3263 if (! ALLOCNO_ASSIGNED_P (subloop_allocno))
3264 {
3265 ALLOCNO_HARD_REGNO (subloop_allocno) = hard_regno;
3266 ALLOCNO_ASSIGNED_P (subloop_allocno) = true;
3267 if (hard_regno >= 0)
682e13bb 3268 update_costs_from_copies (subloop_allocno, true, true);
3ad55f68 3269 /* We don't need updated costs anymore. */
47dd2e78 3270 ira_free_allocno_updated_costs (subloop_allocno);
3271 }
3272 continue;
3273 }
3274 exit_freq = ira_loop_edge_freq (subloop_node, regno, true);
3275 enter_freq = ira_loop_edge_freq (subloop_node, regno, false);
3276 ira_assert (regno < ira_reg_equiv_len);
c6a6cdaa 3277 if (ira_equiv_no_lvalue_p (regno))
47dd2e78 3278 {
3279 if (! ALLOCNO_ASSIGNED_P (subloop_allocno))
3280 {
3281 ALLOCNO_HARD_REGNO (subloop_allocno) = hard_regno;
3282 ALLOCNO_ASSIGNED_P (subloop_allocno) = true;
3283 if (hard_regno >= 0)
682e13bb 3284 update_costs_from_copies (subloop_allocno, true, true);
3ad55f68 3285 /* We don't need updated costs anymore. */
47dd2e78 3286 ira_free_allocno_updated_costs (subloop_allocno);
3287 }
3288 }
3289 else if (hard_regno < 0)
3290 {
3291 ALLOCNO_UPDATED_MEMORY_COST (subloop_allocno)
3292 -= ((ira_memory_move_cost[mode][rclass][1] * enter_freq)
3293 + (ira_memory_move_cost[mode][rclass][0] * exit_freq));
3294 }
3295 else
3296 {
66d9a7b9 3297 aclass = ALLOCNO_CLASS (subloop_allocno);
3298 ira_init_register_move_cost_if_necessary (mode);
3299 cost = (ira_register_move_cost[mode][rclass][rclass]
47dd2e78 3300 * (exit_freq + enter_freq));
df07a54c 3301 ira_allocate_and_set_or_copy_costs
66d9a7b9 3302 (&ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno), aclass,
3303 ALLOCNO_UPDATED_CLASS_COST (subloop_allocno),
df07a54c 3304 ALLOCNO_HARD_REG_COSTS (subloop_allocno));
3305 ira_allocate_and_set_or_copy_costs
3306 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (subloop_allocno),
66d9a7b9 3307 aclass, 0, ALLOCNO_CONFLICT_HARD_REG_COSTS (subloop_allocno));
df07a54c 3308 ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno)[index] -= cost;
3309 ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (subloop_allocno)[index]
47dd2e78 3310 -= cost;
66d9a7b9 3311 if (ALLOCNO_UPDATED_CLASS_COST (subloop_allocno)
df07a54c 3312 > ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno)[index])
66d9a7b9 3313 ALLOCNO_UPDATED_CLASS_COST (subloop_allocno)
df07a54c 3314 = ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno)[index];
47dd2e78 3315 ALLOCNO_UPDATED_MEMORY_COST (subloop_allocno)
3316 += (ira_memory_move_cost[mode][rclass][0] * enter_freq
3317 + ira_memory_move_cost[mode][rclass][1] * exit_freq);
47dd2e78 3318 }
3319 }
3320 }
66d9a7b9 3321 ira_free (allocno_color_data);
4bb79f36 3322 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
66d9a7b9 3323 {
3324 a = ira_allocnos[j];
3325 ALLOCNO_ADD_DATA (a) = NULL;
66d9a7b9 3326 }
47dd2e78 3327}
3328
3329/* Initialize the common data for coloring and calls functions to do
3330 Chaitin-Briggs and regional coloring. */
3331static void
3332do_coloring (void)
3333{
3334 coloring_allocno_bitmap = ira_allocate_bitmap ();
47dd2e78 3335 if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
3336 fprintf (ira_dump_file, "\n**** Allocnos coloring:\n\n");
48e1416a 3337
47dd2e78 3338 ira_traverse_loop_tree (false, ira_loop_tree_root, color_pass, NULL);
3339
3340 if (internal_flag_ira_verbose > 1 && ira_dump_file != NULL)
3341 ira_print_disposition (ira_dump_file);
3342
47dd2e78 3343 ira_free_bitmap (coloring_allocno_bitmap);
47dd2e78 3344}
3345
3346\f
3347
3348/* Move spill/restore code, which are to be generated in ira-emit.c,
3349 to less frequent points (if it is profitable) by reassigning some
3350 allocnos (in loop with subloops containing in another loop) to
3351 memory which results in longer live-range where the corresponding
3352 pseudo-registers will be in memory. */
3353static void
3354move_spill_restore (void)
3355{
3356 int cost, regno, hard_regno, hard_regno2, index;
3357 bool changed_p;
3358 int enter_freq, exit_freq;
3359 enum machine_mode mode;
3360 enum reg_class rclass;
3361 ira_allocno_t a, parent_allocno, subloop_allocno;
3362 ira_loop_tree_node_t parent, loop_node, subloop_node;
3363 ira_allocno_iterator ai;
3364
3365 for (;;)
3366 {
3367 changed_p = false;
3368 if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
3369 fprintf (ira_dump_file, "New iteration of spill/restore move\n");
3370 FOR_EACH_ALLOCNO (a, ai)
3371 {
3372 regno = ALLOCNO_REGNO (a);
3373 loop_node = ALLOCNO_LOOP_TREE_NODE (a);
3374 if (ALLOCNO_CAP_MEMBER (a) != NULL
3375 || ALLOCNO_CAP (a) != NULL
3376 || (hard_regno = ALLOCNO_HARD_REGNO (a)) < 0
3377 || loop_node->children == NULL
3378 /* don't do the optimization because it can create
3379 copies and the reload pass can spill the allocno set
3380 by copy although the allocno will not get memory
3381 slot. */
c6a6cdaa 3382 || ira_equiv_no_lvalue_p (regno)
47dd2e78 3383 || !bitmap_bit_p (loop_node->border_allocnos, ALLOCNO_NUM (a)))
3384 continue;
3385 mode = ALLOCNO_MODE (a);
66d9a7b9 3386 rclass = ALLOCNO_CLASS (a);
47dd2e78 3387 index = ira_class_hard_reg_index[rclass][hard_regno];
3388 ira_assert (index >= 0);
3389 cost = (ALLOCNO_MEMORY_COST (a)
3390 - (ALLOCNO_HARD_REG_COSTS (a) == NULL
66d9a7b9 3391 ? ALLOCNO_CLASS_COST (a)
47dd2e78 3392 : ALLOCNO_HARD_REG_COSTS (a)[index]));
66d9a7b9 3393 ira_init_register_move_cost_if_necessary (mode);
47dd2e78 3394 for (subloop_node = loop_node->subloops;
3395 subloop_node != NULL;
3396 subloop_node = subloop_node->subloop_next)
3397 {
3398 ira_assert (subloop_node->bb == NULL);
3399 subloop_allocno = subloop_node->regno_allocno_map[regno];
3400 if (subloop_allocno == NULL)
3401 continue;
66d9a7b9 3402 ira_assert (rclass == ALLOCNO_CLASS (subloop_allocno));
47dd2e78 3403 /* We have accumulated cost. To get the real cost of
3404 allocno usage in the loop we should subtract costs of
3405 the subloop allocnos. */
3406 cost -= (ALLOCNO_MEMORY_COST (subloop_allocno)
3407 - (ALLOCNO_HARD_REG_COSTS (subloop_allocno) == NULL
66d9a7b9 3408 ? ALLOCNO_CLASS_COST (subloop_allocno)
47dd2e78 3409 : ALLOCNO_HARD_REG_COSTS (subloop_allocno)[index]));
3410 exit_freq = ira_loop_edge_freq (subloop_node, regno, true);
3411 enter_freq = ira_loop_edge_freq (subloop_node, regno, false);
3412 if ((hard_regno2 = ALLOCNO_HARD_REGNO (subloop_allocno)) < 0)
3413 cost -= (ira_memory_move_cost[mode][rclass][0] * exit_freq
3414 + ira_memory_move_cost[mode][rclass][1] * enter_freq);
3415 else
3416 {
3417 cost
3418 += (ira_memory_move_cost[mode][rclass][0] * exit_freq
3419 + ira_memory_move_cost[mode][rclass][1] * enter_freq);
3420 if (hard_regno2 != hard_regno)
66d9a7b9 3421 cost -= (ira_register_move_cost[mode][rclass][rclass]
47dd2e78 3422 * (exit_freq + enter_freq));
3423 }
3424 }
3425 if ((parent = loop_node->parent) != NULL
3426 && (parent_allocno = parent->regno_allocno_map[regno]) != NULL)
3427 {
66d9a7b9 3428 ira_assert (rclass == ALLOCNO_CLASS (parent_allocno));
47dd2e78 3429 exit_freq = ira_loop_edge_freq (loop_node, regno, true);
3430 enter_freq = ira_loop_edge_freq (loop_node, regno, false);
3431 if ((hard_regno2 = ALLOCNO_HARD_REGNO (parent_allocno)) < 0)
3432 cost -= (ira_memory_move_cost[mode][rclass][0] * exit_freq
3433 + ira_memory_move_cost[mode][rclass][1] * enter_freq);
3434 else
3435 {
3436 cost
3437 += (ira_memory_move_cost[mode][rclass][1] * exit_freq
3438 + ira_memory_move_cost[mode][rclass][0] * enter_freq);
3439 if (hard_regno2 != hard_regno)
66d9a7b9 3440 cost -= (ira_register_move_cost[mode][rclass][rclass]
47dd2e78 3441 * (exit_freq + enter_freq));
3442 }
3443 }
3444 if (cost < 0)
3445 {
3446 ALLOCNO_HARD_REGNO (a) = -1;
3447 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3448 {
3449 fprintf
3450 (ira_dump_file,
3451 " Moving spill/restore for a%dr%d up from loop %d",
9f8ac546 3452 ALLOCNO_NUM (a), regno, loop_node->loop_num);
47dd2e78 3453 fprintf (ira_dump_file, " - profit %d\n", -cost);
3454 }
3455 changed_p = true;
3456 }
3457 }
3458 if (! changed_p)
3459 break;
3460 }
3461}
3462
3463\f
3464
3465/* Update current hard reg costs and current conflict hard reg costs
3466 for allocno A. It is done by processing its copies containing
3467 other allocnos already assigned. */
3468static void
3469update_curr_costs (ira_allocno_t a)
3470{
3471 int i, hard_regno, cost;
3472 enum machine_mode mode;
66d9a7b9 3473 enum reg_class aclass, rclass;
47dd2e78 3474 ira_allocno_t another_a;
3475 ira_copy_t cp, next_cp;
3476
0570b029 3477 ira_free_allocno_updated_costs (a);
47dd2e78 3478 ira_assert (! ALLOCNO_ASSIGNED_P (a));
66d9a7b9 3479 aclass = ALLOCNO_CLASS (a);
3480 if (aclass == NO_REGS)
47dd2e78 3481 return;
3482 mode = ALLOCNO_MODE (a);
66d9a7b9 3483 ira_init_register_move_cost_if_necessary (mode);
47dd2e78 3484 for (cp = ALLOCNO_COPIES (a); cp != NULL; cp = next_cp)
3485 {
3486 if (cp->first == a)
3487 {
3488 next_cp = cp->next_first_allocno_copy;
3489 another_a = cp->second;
3490 }
3491 else if (cp->second == a)
3492 {
3493 next_cp = cp->next_second_allocno_copy;
3494 another_a = cp->first;
3495 }
3496 else
3497 gcc_unreachable ();
66d9a7b9 3498 if (! ira_reg_classes_intersect_p[aclass][ALLOCNO_CLASS (another_a)]
47dd2e78 3499 || ! ALLOCNO_ASSIGNED_P (another_a)
3500 || (hard_regno = ALLOCNO_HARD_REGNO (another_a)) < 0)
3501 continue;
3502 rclass = REGNO_REG_CLASS (hard_regno);
66d9a7b9 3503 i = ira_class_hard_reg_index[aclass][hard_regno];
14792f4e 3504 if (i < 0)
3505 continue;
47dd2e78 3506 cost = (cp->first == a
66d9a7b9 3507 ? ira_register_move_cost[mode][rclass][aclass]
3508 : ira_register_move_cost[mode][aclass][rclass]);
47dd2e78 3509 ira_allocate_and_set_or_copy_costs
66d9a7b9 3510 (&ALLOCNO_UPDATED_HARD_REG_COSTS (a), aclass, ALLOCNO_CLASS_COST (a),
47dd2e78 3511 ALLOCNO_HARD_REG_COSTS (a));
3512 ira_allocate_and_set_or_copy_costs
3513 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a),
66d9a7b9 3514 aclass, 0, ALLOCNO_CONFLICT_HARD_REG_COSTS (a));
47dd2e78 3515 ALLOCNO_UPDATED_HARD_REG_COSTS (a)[i] -= cp->freq * cost;
3516 ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a)[i] -= cp->freq * cost;
3517 }
3518}
3519
47dd2e78 3520/* Try to assign hard registers to the unassigned allocnos and
3521 allocnos conflicting with them or conflicting with allocnos whose
3522 regno >= START_REGNO. The function is called after ira_flattening,
3523 so more allocnos (including ones created in ira-emit.c) will have a
3524 chance to get a hard register. We use simple assignment algorithm
3525 based on priorities. */
3526void
3527ira_reassign_conflict_allocnos (int start_regno)
3528{
3529 int i, allocnos_to_color_num;
e320331a 3530 ira_allocno_t a;
66d9a7b9 3531 enum reg_class aclass;
47dd2e78 3532 bitmap allocnos_to_color;
3533 ira_allocno_iterator ai;
3534
3535 allocnos_to_color = ira_allocate_bitmap ();
3536 allocnos_to_color_num = 0;
3537 FOR_EACH_ALLOCNO (a, ai)
3538 {
be18556f 3539 int n = ALLOCNO_NUM_OBJECTS (a);
e320331a 3540
47dd2e78 3541 if (! ALLOCNO_ASSIGNED_P (a)
3542 && ! bitmap_bit_p (allocnos_to_color, ALLOCNO_NUM (a)))
3543 {
66d9a7b9 3544 if (ALLOCNO_CLASS (a) != NO_REGS)
47dd2e78 3545 sorted_allocnos[allocnos_to_color_num++] = a;
3546 else
3547 {
3548 ALLOCNO_ASSIGNED_P (a) = true;
3549 ALLOCNO_HARD_REGNO (a) = -1;
3550 ira_assert (ALLOCNO_UPDATED_HARD_REG_COSTS (a) == NULL);
3551 ira_assert (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a) == NULL);
3552 }
3553 bitmap_set_bit (allocnos_to_color, ALLOCNO_NUM (a));
3554 }
3555 if (ALLOCNO_REGNO (a) < start_regno
66d9a7b9 3556 || (aclass = ALLOCNO_CLASS (a)) == NO_REGS)
47dd2e78 3557 continue;
be18556f 3558 for (i = 0; i < n; i++)
47dd2e78 3559 {
be18556f 3560 ira_object_t obj = ALLOCNO_OBJECT (a, i);
3561 ira_object_t conflict_obj;
3562 ira_object_conflict_iterator oci;
66d9a7b9 3563
be18556f 3564 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
3565 {
3566 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
66d9a7b9 3567
be18556f 3568 ira_assert (ira_reg_classes_intersect_p
66d9a7b9 3569 [aclass][ALLOCNO_CLASS (conflict_a)]);
6ef9bbe0 3570 if (!bitmap_set_bit (allocnos_to_color, ALLOCNO_NUM (conflict_a)))
be18556f 3571 continue;
be18556f 3572 sorted_allocnos[allocnos_to_color_num++] = conflict_a;
3573 }
47dd2e78 3574 }
3575 }
3576 ira_free_bitmap (allocnos_to_color);
3577 if (allocnos_to_color_num > 1)
3578 {
6bf03212 3579 setup_allocno_priorities (sorted_allocnos, allocnos_to_color_num);
47dd2e78 3580 qsort (sorted_allocnos, allocnos_to_color_num, sizeof (ira_allocno_t),
3581 allocno_priority_compare_func);
3582 }
3583 for (i = 0; i < allocnos_to_color_num; i++)
3584 {
3585 a = sorted_allocnos[i];
3586 ALLOCNO_ASSIGNED_P (a) = false;
47dd2e78 3587 update_curr_costs (a);
3588 }
3589 for (i = 0; i < allocnos_to_color_num; i++)
3590 {
3591 a = sorted_allocnos[i];
3592 if (assign_hard_reg (a, true))
3593 {
3594 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3595 fprintf
3596 (ira_dump_file,
3597 " Secondary allocation: assign hard reg %d to reg %d\n",
3598 ALLOCNO_HARD_REGNO (a), ALLOCNO_REGNO (a));
3599 }
3600 }
3601}
3602
3603\f
3604
66d9a7b9 3605/* This page contains functions used to find conflicts using allocno
3606 live ranges. */
3607
66d9a7b9 3608#ifdef ENABLE_IRA_CHECKING
3609
3610/* Return TRUE if live ranges of pseudo-registers REGNO1 and REGNO2
3611 intersect. This should be used when there is only one region.
3612 Currently this is used during reload. */
3613static bool
3614conflict_by_live_ranges_p (int regno1, int regno2)
3615{
3616 ira_allocno_t a1, a2;
3617
3618 ira_assert (regno1 >= FIRST_PSEUDO_REGISTER
3619 && regno2 >= FIRST_PSEUDO_REGISTER);
b59bd98f 3620 /* Reg info calculated by dataflow infrastructure can be different
66d9a7b9 3621 from one calculated by regclass. */
3622 if ((a1 = ira_loop_tree_root->regno_allocno_map[regno1]) == NULL
3623 || (a2 = ira_loop_tree_root->regno_allocno_map[regno2]) == NULL)
3624 return false;
3625 return allocnos_conflict_by_live_ranges_p (a1, a2);
3626}
3627
3628#endif
3629
3630\f
3631
47dd2e78 3632/* This page contains code to coalesce memory stack slots used by
3633 spilled allocnos. This results in smaller stack frame, better data
3634 locality, and in smaller code for some architectures like
3635 x86/x86_64 where insn size depends on address displacement value.
3636 On the other hand, it can worsen insn scheduling after the RA but
3637 in practice it is less important than smaller stack frames. */
3638
e8b4e44b 3639/* TRUE if we coalesced some allocnos. In other words, if we got
3640 loops formed by members first_coalesced_allocno and
3641 next_coalesced_allocno containing more one allocno. */
3642static bool allocno_coalesced_p;
3643
3644/* Bitmap used to prevent a repeated allocno processing because of
3645 coalescing. */
3646static bitmap processed_coalesced_allocno_bitmap;
3647
66d9a7b9 3648/* See below. */
3649typedef struct coalesce_data *coalesce_data_t;
3650
3651/* To decrease footprint of ira_allocno structure we store all data
3652 needed only for coalescing in the following structure. */
3653struct coalesce_data
3654{
3655 /* Coalesced allocnos form a cyclic list. One allocno given by
3656 FIRST represents all coalesced allocnos. The
3657 list is chained by NEXT. */
3658 ira_allocno_t first;
3659 ira_allocno_t next;
3660 int temp;
3661};
3662
3663/* Container for storing allocno data concerning coalescing. */
3664static coalesce_data_t allocno_coalesce_data;
3665
3666/* Macro to access the data concerning coalescing. */
3667#define ALLOCNO_COALESCE_DATA(a) ((coalesce_data_t) ALLOCNO_ADD_DATA (a))
3668
e8b4e44b 3669/* Merge two sets of coalesced allocnos given correspondingly by
3670 allocnos A1 and A2 (more accurately merging A2 set into A1
3671 set). */
3672static void
3673merge_allocnos (ira_allocno_t a1, ira_allocno_t a2)
3674{
3675 ira_allocno_t a, first, last, next;
3676
66d9a7b9 3677 first = ALLOCNO_COALESCE_DATA (a1)->first;
3678 a = ALLOCNO_COALESCE_DATA (a2)->first;
3679 if (first == a)
e8b4e44b 3680 return;
66d9a7b9 3681 for (last = a2, a = ALLOCNO_COALESCE_DATA (a2)->next;;
3682 a = ALLOCNO_COALESCE_DATA (a)->next)
e8b4e44b 3683 {
66d9a7b9 3684 ALLOCNO_COALESCE_DATA (a)->first = first;
e8b4e44b 3685 if (a == a2)
3686 break;
3687 last = a;
3688 }
66d9a7b9 3689 next = allocno_coalesce_data[ALLOCNO_NUM (first)].next;
3690 allocno_coalesce_data[ALLOCNO_NUM (first)].next = a2;
3691 allocno_coalesce_data[ALLOCNO_NUM (last)].next = next;
e8b4e44b 3692}
3693
66d9a7b9 3694/* Return TRUE if there are conflicting allocnos from two sets of
3695 coalesced allocnos given correspondingly by allocnos A1 and A2. We
3696 use live ranges to find conflicts because conflicts are represented
3697 only for allocnos of the same allocno class and during the reload
3698 pass we coalesce allocnos for sharing stack memory slots. */
e8b4e44b 3699static bool
3700coalesced_allocno_conflict_p (ira_allocno_t a1, ira_allocno_t a2)
3701{
66d9a7b9 3702 ira_allocno_t a, conflict_a;
e8b4e44b 3703
e8b4e44b 3704 if (allocno_coalesced_p)
3705 {
66d9a7b9 3706 bitmap_clear (processed_coalesced_allocno_bitmap);
3707 for (a = ALLOCNO_COALESCE_DATA (a1)->next;;
3708 a = ALLOCNO_COALESCE_DATA (a)->next)
e8b4e44b 3709 {
66d9a7b9 3710 bitmap_set_bit (processed_coalesced_allocno_bitmap, ALLOCNO_NUM (a));
e8b4e44b 3711 if (a == a1)
3712 break;
3713 }
3714 }
66d9a7b9 3715 for (a = ALLOCNO_COALESCE_DATA (a2)->next;;
3716 a = ALLOCNO_COALESCE_DATA (a)->next)
e8b4e44b 3717 {
66d9a7b9 3718 for (conflict_a = ALLOCNO_COALESCE_DATA (a1)->next;;
3719 conflict_a = ALLOCNO_COALESCE_DATA (conflict_a)->next)
e8b4e44b 3720 {
66d9a7b9 3721 if (allocnos_conflict_by_live_ranges_p (a, conflict_a))
e8b4e44b 3722 return true;
66d9a7b9 3723 if (conflict_a == a1)
e8b4e44b 3724 break;
3725 }
e8b4e44b 3726 if (a == a2)
3727 break;
3728 }
3729 return false;
3730}
3731
3732/* The major function for aggressive allocno coalescing. We coalesce
3733 only spilled allocnos. If some allocnos have been coalesced, we
3734 set up flag allocno_coalesced_p. */
3735static void
3736coalesce_allocnos (void)
3737{
3738 ira_allocno_t a;
4bb79f36 3739 ira_copy_t cp, next_cp;
e8b4e44b 3740 unsigned int j;
3741 int i, n, cp_num, regno;
3742 bitmap_iterator bi;
3743
e8b4e44b 3744 cp_num = 0;
3745 /* Collect copies. */
3746 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, j, bi)
3747 {
3748 a = ira_allocnos[j];
3749 regno = ALLOCNO_REGNO (a);
3750 if (! ALLOCNO_ASSIGNED_P (a) || ALLOCNO_HARD_REGNO (a) >= 0
c6a6cdaa 3751 || ira_equiv_no_lvalue_p (regno))
e8b4e44b 3752 continue;
3753 for (cp = ALLOCNO_COPIES (a); cp != NULL; cp = next_cp)
3754 {
3755 if (cp->first == a)
3756 {
3757 next_cp = cp->next_first_allocno_copy;
3758 regno = ALLOCNO_REGNO (cp->second);
3759 /* For priority coloring we coalesce allocnos only with
66d9a7b9 3760 the same allocno class not with intersected allocno
e8b4e44b 3761 classes as it were possible. It is done for
3762 simplicity. */
3763 if ((cp->insn != NULL || cp->constraint_p)
3764 && ALLOCNO_ASSIGNED_P (cp->second)
3765 && ALLOCNO_HARD_REGNO (cp->second) < 0
c6a6cdaa 3766 && ! ira_equiv_no_lvalue_p (regno))
e8b4e44b 3767 sorted_copies[cp_num++] = cp;
3768 }
3769 else if (cp->second == a)
3770 next_cp = cp->next_second_allocno_copy;
3771 else
3772 gcc_unreachable ();
3773 }
3774 }
3775 qsort (sorted_copies, cp_num, sizeof (ira_copy_t), copy_freq_compare_func);
3776 /* Coalesced copies, most frequently executed first. */
3777 for (; cp_num != 0;)
3778 {
3779 for (i = 0; i < cp_num; i++)
3780 {
3781 cp = sorted_copies[i];
3782 if (! coalesced_allocno_conflict_p (cp->first, cp->second))
3783 {
3784 allocno_coalesced_p = true;
3785 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3786 fprintf
3787 (ira_dump_file,
3788 " Coalescing copy %d:a%dr%d-a%dr%d (freq=%d)\n",
3789 cp->num, ALLOCNO_NUM (cp->first), ALLOCNO_REGNO (cp->first),
3790 ALLOCNO_NUM (cp->second), ALLOCNO_REGNO (cp->second),
3791 cp->freq);
3792 merge_allocnos (cp->first, cp->second);
3793 i++;
3794 break;
3795 }
3796 }
3797 /* Collect the rest of copies. */
3798 for (n = 0; i < cp_num; i++)
3799 {
3800 cp = sorted_copies[i];
66d9a7b9 3801 if (allocno_coalesce_data[ALLOCNO_NUM (cp->first)].first
3802 != allocno_coalesce_data[ALLOCNO_NUM (cp->second)].first)
e8b4e44b 3803 sorted_copies[n++] = cp;
3804 }
3805 cp_num = n;
3806 }
e8b4e44b 3807}
3808
47dd2e78 3809/* Usage cost and order number of coalesced allocno set to which
3810 given pseudo register belongs to. */
3811static int *regno_coalesced_allocno_cost;
3812static int *regno_coalesced_allocno_num;
3813
3814/* Sort pseudos according frequencies of coalesced allocno sets they
3815 belong to (putting most frequently ones first), and according to
3816 coalesced allocno set order numbers. */
3817static int
3818coalesced_pseudo_reg_freq_compare (const void *v1p, const void *v2p)
3819{
3820 const int regno1 = *(const int *) v1p;
3821 const int regno2 = *(const int *) v2p;
3822 int diff;
3823
3824 if ((diff = (regno_coalesced_allocno_cost[regno2]
3825 - regno_coalesced_allocno_cost[regno1])) != 0)
3826 return diff;
3827 if ((diff = (regno_coalesced_allocno_num[regno1]
3828 - regno_coalesced_allocno_num[regno2])) != 0)
3829 return diff;
3830 return regno1 - regno2;
3831}
3832
3833/* Widest width in which each pseudo reg is referred to (via subreg).
3834 It is used for sorting pseudo registers. */
3835static unsigned int *regno_max_ref_width;
3836
3837/* Redefine STACK_GROWS_DOWNWARD in terms of 0 or 1. */
3838#ifdef STACK_GROWS_DOWNWARD
3839# undef STACK_GROWS_DOWNWARD
3840# define STACK_GROWS_DOWNWARD 1
3841#else
3842# define STACK_GROWS_DOWNWARD 0
3843#endif
3844
3845/* Sort pseudos according their slot numbers (putting ones with
3846 smaller numbers first, or last when the frame pointer is not
3847 needed). */
3848static int
3849coalesced_pseudo_reg_slot_compare (const void *v1p, const void *v2p)
3850{
3851 const int regno1 = *(const int *) v1p;
3852 const int regno2 = *(const int *) v2p;
3853 ira_allocno_t a1 = ira_regno_allocno_map[regno1];
3854 ira_allocno_t a2 = ira_regno_allocno_map[regno2];
3855 int diff, slot_num1, slot_num2;
3856 int total_size1, total_size2;
3857
3858 if (a1 == NULL || ALLOCNO_HARD_REGNO (a1) >= 0)
3859 {
3860 if (a2 == NULL || ALLOCNO_HARD_REGNO (a2) >= 0)
441554ef 3861 return regno1 - regno2;
47dd2e78 3862 return 1;
3863 }
3864 else if (a2 == NULL || ALLOCNO_HARD_REGNO (a2) >= 0)
3865 return -1;
3866 slot_num1 = -ALLOCNO_HARD_REGNO (a1);
3867 slot_num2 = -ALLOCNO_HARD_REGNO (a2);
3868 if ((diff = slot_num1 - slot_num2) != 0)
3869 return (frame_pointer_needed
47ed88a3 3870 || (!FRAME_GROWS_DOWNWARD) == STACK_GROWS_DOWNWARD ? diff : -diff);
66d9a7b9 3871 total_size1 = MAX (PSEUDO_REGNO_BYTES (regno1),
3872 regno_max_ref_width[regno1]);
3873 total_size2 = MAX (PSEUDO_REGNO_BYTES (regno2),
3874 regno_max_ref_width[regno2]);
47dd2e78 3875 if ((diff = total_size2 - total_size1) != 0)
3876 return diff;
441554ef 3877 return regno1 - regno2;
47dd2e78 3878}
3879
3880/* Setup REGNO_COALESCED_ALLOCNO_COST and REGNO_COALESCED_ALLOCNO_NUM
3881 for coalesced allocno sets containing allocnos with their regnos
3882 given in array PSEUDO_REGNOS of length N. */
3883static void
3884setup_coalesced_allocno_costs_and_nums (int *pseudo_regnos, int n)
3885{
3886 int i, num, regno, cost;
3887 ira_allocno_t allocno, a;
3888
3889 for (num = i = 0; i < n; i++)
3890 {
3891 regno = pseudo_regnos[i];
3892 allocno = ira_regno_allocno_map[regno];
3893 if (allocno == NULL)
3894 {
3895 regno_coalesced_allocno_cost[regno] = 0;
3896 regno_coalesced_allocno_num[regno] = ++num;
3897 continue;
3898 }
66d9a7b9 3899 if (ALLOCNO_COALESCE_DATA (allocno)->first != allocno)
47dd2e78 3900 continue;
3901 num++;
66d9a7b9 3902 for (cost = 0, a = ALLOCNO_COALESCE_DATA (allocno)->next;;
3903 a = ALLOCNO_COALESCE_DATA (a)->next)
47dd2e78 3904 {
3905 cost += ALLOCNO_FREQ (a);
3906 if (a == allocno)
3907 break;
3908 }
66d9a7b9 3909 for (a = ALLOCNO_COALESCE_DATA (allocno)->next;;
3910 a = ALLOCNO_COALESCE_DATA (a)->next)
47dd2e78 3911 {
3912 regno_coalesced_allocno_num[ALLOCNO_REGNO (a)] = num;
3913 regno_coalesced_allocno_cost[ALLOCNO_REGNO (a)] = cost;
3914 if (a == allocno)
3915 break;
3916 }
3917 }
3918}
3919
3920/* Collect spilled allocnos representing coalesced allocno sets (the
3921 first coalesced allocno). The collected allocnos are returned
3922 through array SPILLED_COALESCED_ALLOCNOS. The function returns the
3923 number of the collected allocnos. The allocnos are given by their
3924 regnos in array PSEUDO_REGNOS of length N. */
3925static int
3926collect_spilled_coalesced_allocnos (int *pseudo_regnos, int n,
3927 ira_allocno_t *spilled_coalesced_allocnos)
3928{
3929 int i, num, regno;
3930 ira_allocno_t allocno;
3931
3932 for (num = i = 0; i < n; i++)
3933 {
3934 regno = pseudo_regnos[i];
3935 allocno = ira_regno_allocno_map[regno];
3936 if (allocno == NULL || ALLOCNO_HARD_REGNO (allocno) >= 0
66d9a7b9 3937 || ALLOCNO_COALESCE_DATA (allocno)->first != allocno)
47dd2e78 3938 continue;
3939 spilled_coalesced_allocnos[num++] = allocno;
3940 }
3941 return num;
3942}
3943
69f8e080 3944/* Array of live ranges of size IRA_ALLOCNOS_NUM. Live range for
3945 given slot contains live ranges of coalesced allocnos assigned to
3946 given slot. */
fbff82f4 3947static live_range_t *slot_coalesced_allocnos_live_ranges;
7f36fbdf 3948
69f8e080 3949/* Return TRUE if coalesced allocnos represented by ALLOCNO has live
3950 ranges intersected with live ranges of coalesced allocnos assigned
3951 to slot with number N. */
7f36fbdf 3952static bool
69f8e080 3953slot_coalesced_allocno_live_ranges_intersect_p (ira_allocno_t allocno, int n)
7f36fbdf 3954{
7f36fbdf 3955 ira_allocno_t a;
7f36fbdf 3956
66d9a7b9 3957 for (a = ALLOCNO_COALESCE_DATA (allocno)->next;;
3958 a = ALLOCNO_COALESCE_DATA (a)->next)
7f36fbdf 3959 {
be18556f 3960 int i;
3961 int nr = ALLOCNO_NUM_OBJECTS (a);
66d9a7b9 3962
be18556f 3963 for (i = 0; i < nr; i++)
3964 {
3965 ira_object_t obj = ALLOCNO_OBJECT (a, i);
66d9a7b9 3966
3967 if (ira_live_ranges_intersect_p
3968 (slot_coalesced_allocnos_live_ranges[n],
3969 OBJECT_LIVE_RANGES (obj)))
be18556f 3970 return true;
3971 }
7f36fbdf 3972 if (a == allocno)
3973 break;
3974 }
3975 return false;
3976}
3977
69f8e080 3978/* Update live ranges of slot to which coalesced allocnos represented
3979 by ALLOCNO were assigned. */
7f36fbdf 3980static void
69f8e080 3981setup_slot_coalesced_allocno_live_ranges (ira_allocno_t allocno)
7f36fbdf 3982{
be18556f 3983 int i, n;
7f36fbdf 3984 ira_allocno_t a;
fbff82f4 3985 live_range_t r;
7f36fbdf 3986
66d9a7b9 3987 n = ALLOCNO_COALESCE_DATA (allocno)->temp;
3988 for (a = ALLOCNO_COALESCE_DATA (allocno)->next;;
3989 a = ALLOCNO_COALESCE_DATA (a)->next)
7f36fbdf 3990 {
be18556f 3991 int nr = ALLOCNO_NUM_OBJECTS (a);
3992 for (i = 0; i < nr; i++)
3993 {
3994 ira_object_t obj = ALLOCNO_OBJECT (a, i);
66d9a7b9 3995
be18556f 3996 r = ira_copy_live_range_list (OBJECT_LIVE_RANGES (obj));
3997 slot_coalesced_allocnos_live_ranges[n]
3998 = ira_merge_live_ranges
66d9a7b9 3999 (slot_coalesced_allocnos_live_ranges[n], r);
be18556f 4000 }
7f36fbdf 4001 if (a == allocno)
4002 break;
4003 }
4004}
4005
47dd2e78 4006/* We have coalesced allocnos involving in copies. Coalesce allocnos
4007 further in order to share the same memory stack slot. Allocnos
4008 representing sets of allocnos coalesced before the call are given
4009 in array SPILLED_COALESCED_ALLOCNOS of length NUM. Return TRUE if
4010 some allocnos were coalesced in the function. */
4011static bool
4012coalesce_spill_slots (ira_allocno_t *spilled_coalesced_allocnos, int num)
4013{
69f8e080 4014 int i, j, n, last_coalesced_allocno_num;
47dd2e78 4015 ira_allocno_t allocno, a;
4016 bool merged_p = false;
8aad8efd 4017 bitmap set_jump_crosses = regstat_get_setjmp_crosses ();
47dd2e78 4018
69f8e080 4019 slot_coalesced_allocnos_live_ranges
fbff82f4 4020 = (live_range_t *) ira_allocate (sizeof (live_range_t) * ira_allocnos_num);
69f8e080 4021 memset (slot_coalesced_allocnos_live_ranges, 0,
fbff82f4 4022 sizeof (live_range_t) * ira_allocnos_num);
7f36fbdf 4023 last_coalesced_allocno_num = 0;
47dd2e78 4024 /* Coalesce non-conflicting spilled allocnos preferring most
4025 frequently used. */
4026 for (i = 0; i < num; i++)
4027 {
4028 allocno = spilled_coalesced_allocnos[i];
66d9a7b9 4029 if (ALLOCNO_COALESCE_DATA (allocno)->first != allocno
8aad8efd 4030 || bitmap_bit_p (set_jump_crosses, ALLOCNO_REGNO (allocno))
c6a6cdaa 4031 || ira_equiv_no_lvalue_p (ALLOCNO_REGNO (allocno)))
47dd2e78 4032 continue;
4033 for (j = 0; j < i; j++)
4034 {
4035 a = spilled_coalesced_allocnos[j];
66d9a7b9 4036 n = ALLOCNO_COALESCE_DATA (a)->temp;
4037 if (ALLOCNO_COALESCE_DATA (a)->first == a
8aad8efd 4038 && ! bitmap_bit_p (set_jump_crosses, ALLOCNO_REGNO (a))
c6a6cdaa 4039 && ! ira_equiv_no_lvalue_p (ALLOCNO_REGNO (a))
69f8e080 4040 && ! slot_coalesced_allocno_live_ranges_intersect_p (allocno, n))
7f36fbdf 4041 break;
4042 }
4043 if (j >= i)
4044 {
4045 /* No coalescing: set up number for coalesced allocnos
4046 represented by ALLOCNO. */
66d9a7b9 4047 ALLOCNO_COALESCE_DATA (allocno)->temp = last_coalesced_allocno_num++;
69f8e080 4048 setup_slot_coalesced_allocno_live_ranges (allocno);
7f36fbdf 4049 }
4050 else
4051 {
47dd2e78 4052 allocno_coalesced_p = true;
4053 merged_p = true;
4054 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4055 fprintf (ira_dump_file,
4056 " Coalescing spilled allocnos a%dr%d->a%dr%d\n",
4057 ALLOCNO_NUM (allocno), ALLOCNO_REGNO (allocno),
4058 ALLOCNO_NUM (a), ALLOCNO_REGNO (a));
66d9a7b9 4059 ALLOCNO_COALESCE_DATA (allocno)->temp
4060 = ALLOCNO_COALESCE_DATA (a)->temp;
69f8e080 4061 setup_slot_coalesced_allocno_live_ranges (allocno);
47dd2e78 4062 merge_allocnos (a, allocno);
66d9a7b9 4063 ira_assert (ALLOCNO_COALESCE_DATA (a)->first == a);
47dd2e78 4064 }
4065 }
69f8e080 4066 for (i = 0; i < ira_allocnos_num; i++)
9d53e372 4067 ira_finish_live_range_list (slot_coalesced_allocnos_live_ranges[i]);
69f8e080 4068 ira_free (slot_coalesced_allocnos_live_ranges);
47dd2e78 4069 return merged_p;
4070}
4071
4072/* Sort pseudo-register numbers in array PSEUDO_REGNOS of length N for
4073 subsequent assigning stack slots to them in the reload pass. To do
4074 this we coalesce spilled allocnos first to decrease the number of
4075 memory-memory move insns. This function is called by the
4076 reload. */
4077void
4078ira_sort_regnos_for_alter_reg (int *pseudo_regnos, int n,
4079 unsigned int *reg_max_ref_width)
4080{
4081 int max_regno = max_reg_num ();
4082 int i, regno, num, slot_num;
4083 ira_allocno_t allocno, a;
4084 ira_allocno_iterator ai;
4085 ira_allocno_t *spilled_coalesced_allocnos;
4086
432ebf74 4087 ira_assert (! ira_use_lra_p);
4088
47dd2e78 4089 /* Set up allocnos can be coalesced. */
4090 coloring_allocno_bitmap = ira_allocate_bitmap ();
4091 for (i = 0; i < n; i++)
4092 {
4093 regno = pseudo_regnos[i];
4094 allocno = ira_regno_allocno_map[regno];
4095 if (allocno != NULL)
66d9a7b9 4096 bitmap_set_bit (coloring_allocno_bitmap, ALLOCNO_NUM (allocno));
47dd2e78 4097 }
4098 allocno_coalesced_p = false;
e8b4e44b 4099 processed_coalesced_allocno_bitmap = ira_allocate_bitmap ();
66d9a7b9 4100 allocno_coalesce_data
4101 = (coalesce_data_t) ira_allocate (sizeof (struct coalesce_data)
4102 * ira_allocnos_num);
4103 /* Initialize coalesce data for allocnos. */
4104 FOR_EACH_ALLOCNO (a, ai)
4105 {
4106 ALLOCNO_ADD_DATA (a) = allocno_coalesce_data + ALLOCNO_NUM (a);
4107 ALLOCNO_COALESCE_DATA (a)->first = a;
4108 ALLOCNO_COALESCE_DATA (a)->next = a;
4109 }
e8b4e44b 4110 coalesce_allocnos ();
47dd2e78 4111 ira_free_bitmap (coloring_allocno_bitmap);
4112 regno_coalesced_allocno_cost
4113 = (int *) ira_allocate (max_regno * sizeof (int));
4114 regno_coalesced_allocno_num
4115 = (int *) ira_allocate (max_regno * sizeof (int));
4116 memset (regno_coalesced_allocno_num, 0, max_regno * sizeof (int));
4117 setup_coalesced_allocno_costs_and_nums (pseudo_regnos, n);
4118 /* Sort regnos according frequencies of the corresponding coalesced
4119 allocno sets. */
4120 qsort (pseudo_regnos, n, sizeof (int), coalesced_pseudo_reg_freq_compare);
4121 spilled_coalesced_allocnos
4122 = (ira_allocno_t *) ira_allocate (ira_allocnos_num
4123 * sizeof (ira_allocno_t));
4124 /* Collect allocnos representing the spilled coalesced allocno
4125 sets. */
4126 num = collect_spilled_coalesced_allocnos (pseudo_regnos, n,
4127 spilled_coalesced_allocnos);
4128 if (flag_ira_share_spill_slots
4129 && coalesce_spill_slots (spilled_coalesced_allocnos, num))
4130 {
4131 setup_coalesced_allocno_costs_and_nums (pseudo_regnos, n);
4132 qsort (pseudo_regnos, n, sizeof (int),
4133 coalesced_pseudo_reg_freq_compare);
4134 num = collect_spilled_coalesced_allocnos (pseudo_regnos, n,
4135 spilled_coalesced_allocnos);
4136 }
4137 ira_free_bitmap (processed_coalesced_allocno_bitmap);
4138 allocno_coalesced_p = false;
4139 /* Assign stack slot numbers to spilled allocno sets, use smaller
4140 numbers for most frequently used coalesced allocnos. -1 is
4141 reserved for dynamic search of stack slots for pseudos spilled by
4142 the reload. */
4143 slot_num = 1;
4144 for (i = 0; i < num; i++)
4145 {
4146 allocno = spilled_coalesced_allocnos[i];
66d9a7b9 4147 if (ALLOCNO_COALESCE_DATA (allocno)->first != allocno
47dd2e78 4148 || ALLOCNO_HARD_REGNO (allocno) >= 0
c6a6cdaa 4149 || ira_equiv_no_lvalue_p (ALLOCNO_REGNO (allocno)))
47dd2e78 4150 continue;
4151 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4152 fprintf (ira_dump_file, " Slot %d (freq,size):", slot_num);
4153 slot_num++;
66d9a7b9 4154 for (a = ALLOCNO_COALESCE_DATA (allocno)->next;;
4155 a = ALLOCNO_COALESCE_DATA (a)->next)
47dd2e78 4156 {
4157 ira_assert (ALLOCNO_HARD_REGNO (a) < 0);
4158 ALLOCNO_HARD_REGNO (a) = -slot_num;
4159 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4160 fprintf (ira_dump_file, " a%dr%d(%d,%d)",
4161 ALLOCNO_NUM (a), ALLOCNO_REGNO (a), ALLOCNO_FREQ (a),
4162 MAX (PSEUDO_REGNO_BYTES (ALLOCNO_REGNO (a)),
4163 reg_max_ref_width[ALLOCNO_REGNO (a)]));
48e1416a 4164
47dd2e78 4165 if (a == allocno)
4166 break;
4167 }
4168 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4169 fprintf (ira_dump_file, "\n");
4170 }
4171 ira_spilled_reg_stack_slots_num = slot_num - 1;
4172 ira_free (spilled_coalesced_allocnos);
4173 /* Sort regnos according the slot numbers. */
4174 regno_max_ref_width = reg_max_ref_width;
4175 qsort (pseudo_regnos, n, sizeof (int), coalesced_pseudo_reg_slot_compare);
47dd2e78 4176 FOR_EACH_ALLOCNO (a, ai)
66d9a7b9 4177 ALLOCNO_ADD_DATA (a) = NULL;
4178 ira_free (allocno_coalesce_data);
47dd2e78 4179 ira_free (regno_coalesced_allocno_num);
4180 ira_free (regno_coalesced_allocno_cost);
4181}
4182
4183\f
4184
4185/* This page contains code used by the reload pass to improve the
4186 final code. */
4187
4188/* The function is called from reload to mark changes in the
4189 allocation of REGNO made by the reload. Remember that reg_renumber
4190 reflects the change result. */
4191void
4192ira_mark_allocation_change (int regno)
4193{
4194 ira_allocno_t a = ira_regno_allocno_map[regno];
4195 int old_hard_regno, hard_regno, cost;
66d9a7b9 4196 enum reg_class aclass = ALLOCNO_CLASS (a);
47dd2e78 4197
4198 ira_assert (a != NULL);
4199 hard_regno = reg_renumber[regno];
4200 if ((old_hard_regno = ALLOCNO_HARD_REGNO (a)) == hard_regno)
4201 return;
4202 if (old_hard_regno < 0)
4203 cost = -ALLOCNO_MEMORY_COST (a);
4204 else
4205 {
66d9a7b9 4206 ira_assert (ira_class_hard_reg_index[aclass][old_hard_regno] >= 0);
47dd2e78 4207 cost = -(ALLOCNO_HARD_REG_COSTS (a) == NULL
66d9a7b9 4208 ? ALLOCNO_CLASS_COST (a)
47dd2e78 4209 : ALLOCNO_HARD_REG_COSTS (a)
66d9a7b9 4210 [ira_class_hard_reg_index[aclass][old_hard_regno]]);
682e13bb 4211 update_costs_from_copies (a, false, false);
47dd2e78 4212 }
4213 ira_overall_cost -= cost;
4214 ALLOCNO_HARD_REGNO (a) = hard_regno;
4215 if (hard_regno < 0)
4216 {
4217 ALLOCNO_HARD_REGNO (a) = -1;
4218 cost += ALLOCNO_MEMORY_COST (a);
4219 }
66d9a7b9 4220 else if (ira_class_hard_reg_index[aclass][hard_regno] >= 0)
47dd2e78 4221 {
4222 cost += (ALLOCNO_HARD_REG_COSTS (a) == NULL
66d9a7b9 4223 ? ALLOCNO_CLASS_COST (a)
47dd2e78 4224 : ALLOCNO_HARD_REG_COSTS (a)
66d9a7b9 4225 [ira_class_hard_reg_index[aclass][hard_regno]]);
682e13bb 4226 update_costs_from_copies (a, true, false);
47dd2e78 4227 }
4228 else
4229 /* Reload changed class of the allocno. */
4230 cost = 0;
4231 ira_overall_cost += cost;
4232}
4233
4234/* This function is called when reload deletes memory-memory move. In
4235 this case we marks that the allocation of the corresponding
4236 allocnos should be not changed in future. Otherwise we risk to get
4237 a wrong code. */
4238void
4239ira_mark_memory_move_deletion (int dst_regno, int src_regno)
4240{
4241 ira_allocno_t dst = ira_regno_allocno_map[dst_regno];
4242 ira_allocno_t src = ira_regno_allocno_map[src_regno];
4243
4244 ira_assert (dst != NULL && src != NULL
4245 && ALLOCNO_HARD_REGNO (dst) < 0
4246 && ALLOCNO_HARD_REGNO (src) < 0);
4247 ALLOCNO_DONT_REASSIGN_P (dst) = true;
4248 ALLOCNO_DONT_REASSIGN_P (src) = true;
4249}
4250
4251/* Try to assign a hard register (except for FORBIDDEN_REGS) to
ac50b6ef 4252 allocno A and return TRUE in the case of success. */
47dd2e78 4253static bool
4254allocno_reload_assign (ira_allocno_t a, HARD_REG_SET forbidden_regs)
4255{
4256 int hard_regno;
66d9a7b9 4257 enum reg_class aclass;
47dd2e78 4258 int regno = ALLOCNO_REGNO (a);
be18556f 4259 HARD_REG_SET saved[2];
4260 int i, n;
47dd2e78 4261
be18556f 4262 n = ALLOCNO_NUM_OBJECTS (a);
4263 for (i = 0; i < n; i++)
4264 {
4265 ira_object_t obj = ALLOCNO_OBJECT (a, i);
4266 COPY_HARD_REG_SET (saved[i], OBJECT_TOTAL_CONFLICT_HARD_REGS (obj));
4267 IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), forbidden_regs);
4268 if (! flag_caller_saves && ALLOCNO_CALLS_CROSSED_NUM (a) != 0)
4269 IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
4270 call_used_reg_set);
4271 }
47dd2e78 4272 ALLOCNO_ASSIGNED_P (a) = false;
66d9a7b9 4273 aclass = ALLOCNO_CLASS (a);
47dd2e78 4274 update_curr_costs (a);
4275 assign_hard_reg (a, true);
4276 hard_regno = ALLOCNO_HARD_REGNO (a);
4277 reg_renumber[regno] = hard_regno;
4278 if (hard_regno < 0)
4279 ALLOCNO_HARD_REGNO (a) = -1;
4280 else
4281 {
66d9a7b9 4282 ira_assert (ira_class_hard_reg_index[aclass][hard_regno] >= 0);
4283 ira_overall_cost
4284 -= (ALLOCNO_MEMORY_COST (a)
4285 - (ALLOCNO_HARD_REG_COSTS (a) == NULL
4286 ? ALLOCNO_CLASS_COST (a)
4287 : ALLOCNO_HARD_REG_COSTS (a)[ira_class_hard_reg_index
4288 [aclass][hard_regno]]));
47dd2e78 4289 if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0
4682ca16 4290 && ira_hard_reg_set_intersection_p (hard_regno, ALLOCNO_MODE (a),
4291 call_used_reg_set))
47dd2e78 4292 {
4293 ira_assert (flag_caller_saves);
4294 caller_save_needed = 1;
4295 }
4296 }
4297
4298 /* If we found a hard register, modify the RTL for the pseudo
4299 register to show the hard register, and mark the pseudo register
4300 live. */
4301 if (reg_renumber[regno] >= 0)
4302 {
4303 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4304 fprintf (ira_dump_file, ": reassign to %d\n", reg_renumber[regno]);
4305 SET_REGNO (regno_reg_rtx[regno], reg_renumber[regno]);
4306 mark_home_live (regno);
4307 }
4308 else if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4309 fprintf (ira_dump_file, "\n");
be18556f 4310 for (i = 0; i < n; i++)
4311 {
4312 ira_object_t obj = ALLOCNO_OBJECT (a, i);
4313 COPY_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), saved[i]);
4314 }
47dd2e78 4315 return reg_renumber[regno] >= 0;
4316}
4317
4318/* Sort pseudos according their usage frequencies (putting most
4319 frequently ones first). */
4320static int
4321pseudo_reg_compare (const void *v1p, const void *v2p)
4322{
4323 int regno1 = *(const int *) v1p;
4324 int regno2 = *(const int *) v2p;
4325 int diff;
4326
4327 if ((diff = REG_FREQ (regno2) - REG_FREQ (regno1)) != 0)
4328 return diff;
4329 return regno1 - regno2;
4330}
4331
4332/* Try to allocate hard registers to SPILLED_PSEUDO_REGS (there are
4333 NUM of them) or spilled pseudos conflicting with pseudos in
4334 SPILLED_PSEUDO_REGS. Return TRUE and update SPILLED, if the
4335 allocation has been changed. The function doesn't use
4336 BAD_SPILL_REGS and hard registers in PSEUDO_FORBIDDEN_REGS and
4337 PSEUDO_PREVIOUS_REGS for the corresponding pseudos. The function
4338 is called by the reload pass at the end of each reload
4339 iteration. */
4340bool
4341ira_reassign_pseudos (int *spilled_pseudo_regs, int num,
4342 HARD_REG_SET bad_spill_regs,
4343 HARD_REG_SET *pseudo_forbidden_regs,
e8db6cc1 4344 HARD_REG_SET *pseudo_previous_regs,
4345 bitmap spilled)
47dd2e78 4346{
e4c2a550 4347 int i, n, regno;
47dd2e78 4348 bool changed_p;
e320331a 4349 ira_allocno_t a;
47dd2e78 4350 HARD_REG_SET forbidden_regs;
e8db6cc1 4351 bitmap temp = BITMAP_ALLOC (NULL);
4352
4353 /* Add pseudos which conflict with pseudos already in
4354 SPILLED_PSEUDO_REGS to SPILLED_PSEUDO_REGS. This is preferable
4355 to allocating in two steps as some of the conflicts might have
4356 a higher priority than the pseudos passed in SPILLED_PSEUDO_REGS. */
4357 for (i = 0; i < num; i++)
4358 bitmap_set_bit (temp, spilled_pseudo_regs[i]);
4359
4360 for (i = 0, n = num; i < n; i++)
4361 {
be18556f 4362 int nr, j;
e8db6cc1 4363 int regno = spilled_pseudo_regs[i];
4364 bitmap_set_bit (temp, regno);
4365
4366 a = ira_regno_allocno_map[regno];
be18556f 4367 nr = ALLOCNO_NUM_OBJECTS (a);
4368 for (j = 0; j < nr; j++)
e320331a 4369 {
be18556f 4370 ira_object_t conflict_obj;
4371 ira_object_t obj = ALLOCNO_OBJECT (a, j);
4372 ira_object_conflict_iterator oci;
4373
4374 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
e320331a 4375 {
be18556f 4376 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
4377 if (ALLOCNO_HARD_REGNO (conflict_a) < 0
4378 && ! ALLOCNO_DONT_REASSIGN_P (conflict_a)
6ef9bbe0 4379 && bitmap_set_bit (temp, ALLOCNO_REGNO (conflict_a)))
be18556f 4380 {
4381 spilled_pseudo_regs[num++] = ALLOCNO_REGNO (conflict_a);
be18556f 4382 /* ?!? This seems wrong. */
4383 bitmap_set_bit (consideration_allocno_bitmap,
4384 ALLOCNO_NUM (conflict_a));
4385 }
e320331a 4386 }
4387 }
e8db6cc1 4388 }
47dd2e78 4389
4390 if (num > 1)
4391 qsort (spilled_pseudo_regs, num, sizeof (int), pseudo_reg_compare);
4392 changed_p = false;
4393 /* Try to assign hard registers to pseudos from
4394 SPILLED_PSEUDO_REGS. */
e4c2a550 4395 for (i = 0; i < num; i++)
47dd2e78 4396 {
4397 regno = spilled_pseudo_regs[i];
4398 COPY_HARD_REG_SET (forbidden_regs, bad_spill_regs);
4399 IOR_HARD_REG_SET (forbidden_regs, pseudo_forbidden_regs[regno]);
4400 IOR_HARD_REG_SET (forbidden_regs, pseudo_previous_regs[regno]);
4401 gcc_assert (reg_renumber[regno] < 0);
4402 a = ira_regno_allocno_map[regno];
4403 ira_mark_allocation_change (regno);
4404 ira_assert (reg_renumber[regno] < 0);
4405 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4406 fprintf (ira_dump_file,
e8db6cc1 4407 " Try Assign %d(a%d), cost=%d", regno, ALLOCNO_NUM (a),
47dd2e78 4408 ALLOCNO_MEMORY_COST (a)
66d9a7b9 4409 - ALLOCNO_CLASS_COST (a));
47dd2e78 4410 allocno_reload_assign (a, forbidden_regs);
4411 if (reg_renumber[regno] >= 0)
4412 {
4413 CLEAR_REGNO_REG_SET (spilled, regno);
4414 changed_p = true;
4415 }
47dd2e78 4416 }
e8db6cc1 4417 BITMAP_FREE (temp);
47dd2e78 4418 return changed_p;
4419}
4420
4421/* The function is called by reload and returns already allocated
4422 stack slot (if any) for REGNO with given INHERENT_SIZE and
4423 TOTAL_SIZE. In the case of failure to find a slot which can be
4424 used for REGNO, the function returns NULL. */
4425rtx
4426ira_reuse_stack_slot (int regno, unsigned int inherent_size,
4427 unsigned int total_size)
4428{
4429 unsigned int i;
4430 int slot_num, best_slot_num;
4431 int cost, best_cost;
4432 ira_copy_t cp, next_cp;
4433 ira_allocno_t another_allocno, allocno = ira_regno_allocno_map[regno];
4434 rtx x;
4435 bitmap_iterator bi;
4436 struct ira_spilled_reg_stack_slot *slot = NULL;
4437
432ebf74 4438 ira_assert (! ira_use_lra_p);
4439
cf709bf6 4440 ira_assert (inherent_size == PSEUDO_REGNO_BYTES (regno)
47dd2e78 4441 && inherent_size <= total_size
4442 && ALLOCNO_HARD_REGNO (allocno) < 0);
4443 if (! flag_ira_share_spill_slots)
4444 return NULL_RTX;
4445 slot_num = -ALLOCNO_HARD_REGNO (allocno) - 2;
4446 if (slot_num != -1)
4447 {
4448 slot = &ira_spilled_reg_stack_slots[slot_num];
4449 x = slot->mem;
4450 }
4451 else
4452 {
4453 best_cost = best_slot_num = -1;
4454 x = NULL_RTX;
4455 /* It means that the pseudo was spilled in the reload pass, try
4456 to reuse a slot. */
4457 for (slot_num = 0;
4458 slot_num < ira_spilled_reg_stack_slots_num;
4459 slot_num++)
4460 {
4461 slot = &ira_spilled_reg_stack_slots[slot_num];
4462 if (slot->mem == NULL_RTX)
4463 continue;
4464 if (slot->width < total_size
4465 || GET_MODE_SIZE (GET_MODE (slot->mem)) < inherent_size)
4466 continue;
48e1416a 4467
47dd2e78 4468 EXECUTE_IF_SET_IN_BITMAP (&slot->spilled_regs,
4469 FIRST_PSEUDO_REGISTER, i, bi)
4470 {
4471 another_allocno = ira_regno_allocno_map[i];
66d9a7b9 4472 if (allocnos_conflict_by_live_ranges_p (allocno,
4473 another_allocno))
47dd2e78 4474 goto cont;
4475 }
4476 for (cost = 0, cp = ALLOCNO_COPIES (allocno);
4477 cp != NULL;
4478 cp = next_cp)
4479 {
4480 if (cp->first == allocno)
4481 {
4482 next_cp = cp->next_first_allocno_copy;
4483 another_allocno = cp->second;
4484 }
4485 else if (cp->second == allocno)
4486 {
4487 next_cp = cp->next_second_allocno_copy;
4488 another_allocno = cp->first;
4489 }
4490 else
4491 gcc_unreachable ();
4492 if (cp->insn == NULL_RTX)
4493 continue;
4494 if (bitmap_bit_p (&slot->spilled_regs,
4495 ALLOCNO_REGNO (another_allocno)))
4496 cost += cp->freq;
4497 }
4498 if (cost > best_cost)
4499 {
4500 best_cost = cost;
4501 best_slot_num = slot_num;
4502 }
4503 cont:
4504 ;
4505 }
4506 if (best_cost >= 0)
4507 {
f55b350c 4508 slot_num = best_slot_num;
4509 slot = &ira_spilled_reg_stack_slots[slot_num];
47dd2e78 4510 SET_REGNO_REG_SET (&slot->spilled_regs, regno);
4511 x = slot->mem;
f55b350c 4512 ALLOCNO_HARD_REGNO (allocno) = -slot_num - 2;
47dd2e78 4513 }
4514 }
4515 if (x != NULL_RTX)
4516 {
4517 ira_assert (slot->width >= total_size);
7521b07f 4518#ifdef ENABLE_IRA_CHECKING
47dd2e78 4519 EXECUTE_IF_SET_IN_BITMAP (&slot->spilled_regs,
4520 FIRST_PSEUDO_REGISTER, i, bi)
4521 {
66d9a7b9 4522 ira_assert (! conflict_by_live_ranges_p (regno, i));
47dd2e78 4523 }
7521b07f 4524#endif
47dd2e78 4525 SET_REGNO_REG_SET (&slot->spilled_regs, regno);
4526 if (internal_flag_ira_verbose > 3 && ira_dump_file)
4527 {
4528 fprintf (ira_dump_file, " Assigning %d(freq=%d) slot %d of",
4529 regno, REG_FREQ (regno), slot_num);
4530 EXECUTE_IF_SET_IN_BITMAP (&slot->spilled_regs,
4531 FIRST_PSEUDO_REGISTER, i, bi)
4532 {
4533 if ((unsigned) regno != i)
4534 fprintf (ira_dump_file, " %d", i);
4535 }
4536 fprintf (ira_dump_file, "\n");
4537 }
4538 }
4539 return x;
4540}
4541
4542/* This is called by reload every time a new stack slot X with
4543 TOTAL_SIZE was allocated for REGNO. We store this info for
4544 subsequent ira_reuse_stack_slot calls. */
4545void
4546ira_mark_new_stack_slot (rtx x, int regno, unsigned int total_size)
4547{
4548 struct ira_spilled_reg_stack_slot *slot;
4549 int slot_num;
4550 ira_allocno_t allocno;
4551
432ebf74 4552 ira_assert (! ira_use_lra_p);
4553
cf709bf6 4554 ira_assert (PSEUDO_REGNO_BYTES (regno) <= total_size);
47dd2e78 4555 allocno = ira_regno_allocno_map[regno];
4556 slot_num = -ALLOCNO_HARD_REGNO (allocno) - 2;
4557 if (slot_num == -1)
4558 {
4559 slot_num = ira_spilled_reg_stack_slots_num++;
4560 ALLOCNO_HARD_REGNO (allocno) = -slot_num - 2;
4561 }
4562 slot = &ira_spilled_reg_stack_slots[slot_num];
4563 INIT_REG_SET (&slot->spilled_regs);
4564 SET_REGNO_REG_SET (&slot->spilled_regs, regno);
4565 slot->mem = x;
4566 slot->width = total_size;
4567 if (internal_flag_ira_verbose > 3 && ira_dump_file)
4568 fprintf (ira_dump_file, " Assigning %d(freq=%d) a new slot %d\n",
4569 regno, REG_FREQ (regno), slot_num);
4570}
4571
4572
4573/* Return spill cost for pseudo-registers whose numbers are in array
4574 REGNOS (with a negative number as an end marker) for reload with
4575 given IN and OUT for INSN. Return also number points (through
4576 EXCESS_PRESSURE_LIVE_LENGTH) where the pseudo-register lives and
4577 the register pressure is high, number of references of the
4578 pseudo-registers (through NREFS), number of callee-clobbered
4579 hard-registers occupied by the pseudo-registers (through
4580 CALL_USED_COUNT), and the first hard regno occupied by the
4581 pseudo-registers (through FIRST_HARD_REGNO). */
4582static int
4583calculate_spill_cost (int *regnos, rtx in, rtx out, rtx insn,
4584 int *excess_pressure_live_length,
4585 int *nrefs, int *call_used_count, int *first_hard_regno)
4586{
4587 int i, cost, regno, hard_regno, j, count, saved_cost, nregs;
4588 bool in_p, out_p;
4589 int length;
4590 ira_allocno_t a;
4591
4592 *nrefs = 0;
4593 for (length = count = cost = i = 0;; i++)
4594 {
4595 regno = regnos[i];
4596 if (regno < 0)
4597 break;
4598 *nrefs += REG_N_REFS (regno);
4599 hard_regno = reg_renumber[regno];
4600 ira_assert (hard_regno >= 0);
4601 a = ira_regno_allocno_map[regno];
be18556f 4602 length += ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a) / ALLOCNO_NUM_OBJECTS (a);
66d9a7b9 4603 cost += ALLOCNO_MEMORY_COST (a) - ALLOCNO_CLASS_COST (a);
47dd2e78 4604 nregs = hard_regno_nregs[hard_regno][ALLOCNO_MODE (a)];
4605 for (j = 0; j < nregs; j++)
4606 if (! TEST_HARD_REG_BIT (call_used_reg_set, hard_regno + j))
4607 break;
4608 if (j == nregs)
4609 count++;
4610 in_p = in && REG_P (in) && (int) REGNO (in) == hard_regno;
4611 out_p = out && REG_P (out) && (int) REGNO (out) == hard_regno;
4612 if ((in_p || out_p)
4613 && find_regno_note (insn, REG_DEAD, hard_regno) != NULL_RTX)
4614 {
4615 saved_cost = 0;
4616 if (in_p)
4617 saved_cost += ira_memory_move_cost
66d9a7b9 4618 [ALLOCNO_MODE (a)][ALLOCNO_CLASS (a)][1];
47dd2e78 4619 if (out_p)
4620 saved_cost
4621 += ira_memory_move_cost
66d9a7b9 4622 [ALLOCNO_MODE (a)][ALLOCNO_CLASS (a)][0];
47dd2e78 4623 cost -= REG_FREQ_FROM_BB (BLOCK_FOR_INSN (insn)) * saved_cost;
4624 }
4625 }
4626 *excess_pressure_live_length = length;
4627 *call_used_count = count;
4628 hard_regno = -1;
4629 if (regnos[0] >= 0)
4630 {
4631 hard_regno = reg_renumber[regnos[0]];
4632 }
4633 *first_hard_regno = hard_regno;
4634 return cost;
4635}
4636
4637/* Return TRUE if spilling pseudo-registers whose numbers are in array
4638 REGNOS is better than spilling pseudo-registers with numbers in
4639 OTHER_REGNOS for reload with given IN and OUT for INSN. The
4640 function used by the reload pass to make better register spilling
4641 decisions. */
4642bool
4643ira_better_spill_reload_regno_p (int *regnos, int *other_regnos,
4644 rtx in, rtx out, rtx insn)
4645{
4646 int cost, other_cost;
4647 int length, other_length;
4648 int nrefs, other_nrefs;
4649 int call_used_count, other_call_used_count;
4650 int hard_regno, other_hard_regno;
4651
48e1416a 4652 cost = calculate_spill_cost (regnos, in, out, insn,
47dd2e78 4653 &length, &nrefs, &call_used_count, &hard_regno);
4654 other_cost = calculate_spill_cost (other_regnos, in, out, insn,
4655 &other_length, &other_nrefs,
4656 &other_call_used_count,
4657 &other_hard_regno);
4658 if (nrefs == 0 && other_nrefs != 0)
4659 return true;
4660 if (nrefs != 0 && other_nrefs == 0)
4661 return false;
4662 if (cost != other_cost)
4663 return cost < other_cost;
4664 if (length != other_length)
4665 return length > other_length;
4666#ifdef REG_ALLOC_ORDER
4667 if (hard_regno >= 0 && other_hard_regno >= 0)
4668 return (inv_reg_alloc_order[hard_regno]
4669 < inv_reg_alloc_order[other_hard_regno]);
4670#else
4671 if (call_used_count != other_call_used_count)
4672 return call_used_count > other_call_used_count;
4673#endif
4674 return false;
4675}
4676
4677\f
4678
4679/* Allocate and initialize data necessary for assign_hard_reg. */
4680void
4681ira_initiate_assign (void)
4682{
4683 sorted_allocnos
4684 = (ira_allocno_t *) ira_allocate (sizeof (ira_allocno_t)
4685 * ira_allocnos_num);
4686 consideration_allocno_bitmap = ira_allocate_bitmap ();
4687 initiate_cost_update ();
4688 allocno_priorities = (int *) ira_allocate (sizeof (int) * ira_allocnos_num);
4bb79f36 4689 sorted_copies = (ira_copy_t *) ira_allocate (ira_copies_num
4690 * sizeof (ira_copy_t));
47dd2e78 4691}
4692
4693/* Deallocate data used by assign_hard_reg. */
4694void
4695ira_finish_assign (void)
4696{
4697 ira_free (sorted_allocnos);
4698 ira_free_bitmap (consideration_allocno_bitmap);
4699 finish_cost_update ();
4700 ira_free (allocno_priorities);
4bb79f36 4701 ira_free (sorted_copies);
47dd2e78 4702}
4703
4704\f
4705
4706/* Entry function doing color-based register allocation. */
df07a54c 4707static void
4708color (void)
47dd2e78 4709{
f1f41a6c 4710 allocno_stack_vec.create (ira_allocnos_num);
47dd2e78 4711 memset (allocated_hardreg_p, 0, sizeof (allocated_hardreg_p));
4712 ira_initiate_assign ();
4713 do_coloring ();
4714 ira_finish_assign ();
f1f41a6c 4715 allocno_stack_vec.release ();
47dd2e78 4716 move_spill_restore ();
4717}
4718
4719\f
4720
4721/* This page contains a simple register allocator without usage of
4722 allocno conflicts. This is used for fast allocation for -O0. */
4723
4724/* Do register allocation by not using allocno conflicts. It uses
4725 only allocno live ranges. The algorithm is close to Chow's
4726 priority coloring. */
df07a54c 4727static void
4728fast_allocation (void)
47dd2e78 4729{
6bf03212 4730 int i, j, k, num, class_size, hard_regno;
47dd2e78 4731#ifdef STACK_REGS
4732 bool no_stack_reg_p;
4733#endif
66d9a7b9 4734 enum reg_class aclass;
47dd2e78 4735 enum machine_mode mode;
4736 ira_allocno_t a;
4737 ira_allocno_iterator ai;
fbff82f4 4738 live_range_t r;
47dd2e78 4739 HARD_REG_SET conflict_hard_regs, *used_hard_regs;
4740
47dd2e78 4741 sorted_allocnos = (ira_allocno_t *) ira_allocate (sizeof (ira_allocno_t)
4742 * ira_allocnos_num);
4743 num = 0;
4744 FOR_EACH_ALLOCNO (a, ai)
4745 sorted_allocnos[num++] = a;
6bf03212 4746 allocno_priorities = (int *) ira_allocate (sizeof (int) * ira_allocnos_num);
4747 setup_allocno_priorities (sorted_allocnos, num);
4748 used_hard_regs = (HARD_REG_SET *) ira_allocate (sizeof (HARD_REG_SET)
4749 * ira_max_point);
4750 for (i = 0; i < ira_max_point; i++)
4751 CLEAR_HARD_REG_SET (used_hard_regs[i]);
95c83f01 4752 qsort (sorted_allocnos, num, sizeof (ira_allocno_t),
47dd2e78 4753 allocno_priority_compare_func);
4754 for (i = 0; i < num; i++)
4755 {
be18556f 4756 int nr, l;
4757
47dd2e78 4758 a = sorted_allocnos[i];
be18556f 4759 nr = ALLOCNO_NUM_OBJECTS (a);
4760 CLEAR_HARD_REG_SET (conflict_hard_regs);
4761 for (l = 0; l < nr; l++)
4762 {
4763 ira_object_t obj = ALLOCNO_OBJECT (a, l);
4764 IOR_HARD_REG_SET (conflict_hard_regs,
4765 OBJECT_CONFLICT_HARD_REGS (obj));
4766 for (r = OBJECT_LIVE_RANGES (obj); r != NULL; r = r->next)
4767 for (j = r->start; j <= r->finish; j++)
4768 IOR_HARD_REG_SET (conflict_hard_regs, used_hard_regs[j]);
4769 }
66d9a7b9 4770 aclass = ALLOCNO_CLASS (a);
1f4ce237 4771 ALLOCNO_ASSIGNED_P (a) = true;
4772 ALLOCNO_HARD_REGNO (a) = -1;
66d9a7b9 4773 if (hard_reg_set_subset_p (reg_class_contents[aclass],
47dd2e78 4774 conflict_hard_regs))
4775 continue;
4776 mode = ALLOCNO_MODE (a);
4777#ifdef STACK_REGS
4778 no_stack_reg_p = ALLOCNO_NO_STACK_REG_P (a);
4779#endif
66d9a7b9 4780 class_size = ira_class_hard_regs_num[aclass];
47dd2e78 4781 for (j = 0; j < class_size; j++)
4782 {
66d9a7b9 4783 hard_regno = ira_class_hard_regs[aclass][j];
47dd2e78 4784#ifdef STACK_REGS
4785 if (no_stack_reg_p && FIRST_STACK_REG <= hard_regno
4786 && hard_regno <= LAST_STACK_REG)
4787 continue;
4788#endif
4682ca16 4789 if (ira_hard_reg_set_intersection_p (hard_regno, mode, conflict_hard_regs)
47dd2e78 4790 || (TEST_HARD_REG_BIT
66d9a7b9 4791 (ira_prohibited_class_mode_regs[aclass][mode], hard_regno)))
47dd2e78 4792 continue;
4793 ALLOCNO_HARD_REGNO (a) = hard_regno;
be18556f 4794 for (l = 0; l < nr; l++)
4795 {
4796 ira_object_t obj = ALLOCNO_OBJECT (a, l);
4797 for (r = OBJECT_LIVE_RANGES (obj); r != NULL; r = r->next)
4798 for (k = r->start; k <= r->finish; k++)
4799 IOR_HARD_REG_SET (used_hard_regs[k],
4800 ira_reg_mode_hard_regset[hard_regno][mode]);
4801 }
47dd2e78 4802 break;
4803 }
4804 }
4805 ira_free (sorted_allocnos);
4806 ira_free (used_hard_regs);
4807 ira_free (allocno_priorities);
4808 if (internal_flag_ira_verbose > 1 && ira_dump_file != NULL)
4809 ira_print_disposition (ira_dump_file);
4810}
df07a54c 4811
4812\f
4813
4814/* Entry function doing coloring. */
4815void
4816ira_color (void)
4817{
4818 ira_allocno_t a;
4819 ira_allocno_iterator ai;
4820
4821 /* Setup updated costs. */
4822 FOR_EACH_ALLOCNO (a, ai)
4823 {
4824 ALLOCNO_UPDATED_MEMORY_COST (a) = ALLOCNO_MEMORY_COST (a);
66d9a7b9 4825 ALLOCNO_UPDATED_CLASS_COST (a) = ALLOCNO_CLASS_COST (a);
df07a54c 4826 }
95c83f01 4827 if (ira_conflicts_p)
df07a54c 4828 color ();
4829 else
4830 fast_allocation ();
4831}