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