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