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