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