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