2015-06-25 Zhouyi Zhou <yizhouzhou@ict.ac.cn>
[official-gcc.git] / gcc / ira-color.c
blob860547c191d3a91a12837ee7f4fc8bddf03dc6ed
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 "tm.h"
25 #include "rtl.h"
26 #include "tm_p.h"
27 #include "target.h"
28 #include "regs.h"
29 #include "flags.h"
30 #include "sbitmap.h"
31 #include "bitmap.h"
32 #include "hard-reg-set.h"
33 #include "predict.h"
34 #include "function.h"
35 #include "dominance.h"
36 #include "cfg.h"
37 #include "basic-block.h"
38 #include "symtab.h"
39 #include "alias.h"
40 #include "tree.h"
41 #include "insn-config.h"
42 #include "expmed.h"
43 #include "dojump.h"
44 #include "explow.h"
45 #include "calls.h"
46 #include "emit-rtl.h"
47 #include "varasm.h"
48 #include "stmt.h"
49 #include "expr.h"
50 #include "diagnostic-core.h"
51 #include "reload.h"
52 #include "params.h"
53 #include "df.h"
54 #include "ira-int.h"
56 typedef struct allocno_hard_regs *allocno_hard_regs_t;
58 /* The structure contains information about hard registers can be
59 assigned to allocnos. Usually it is allocno profitable hard
60 registers but in some cases this set can be a bit different. Major
61 reason of the difference is a requirement to use hard register sets
62 that form a tree or a forest (set of trees), i.e. hard register set
63 of a node should contain hard register sets of its subnodes. */
64 struct allocno_hard_regs
66 /* Hard registers can be assigned to an allocno. */
67 HARD_REG_SET set;
68 /* Overall (spilling) cost of all allocnos with given register
69 set. */
70 int64_t cost;
73 typedef struct allocno_hard_regs_node *allocno_hard_regs_node_t;
75 /* A node representing allocno hard registers. Such nodes form a
76 forest (set of trees). Each subnode of given node in the forest
77 refers for hard register set (usually allocno profitable hard
78 register set) which is a subset of one referred from given
79 node. */
80 struct allocno_hard_regs_node
82 /* Set up number of the node in preorder traversing of the forest. */
83 int preorder_num;
84 /* Used for different calculation like finding conflict size of an
85 allocno. */
86 int check;
87 /* Used for calculation of conflict size of an allocno. The
88 conflict size of the allocno is maximal number of given allocno
89 hard registers needed for allocation of the conflicting allocnos.
90 Given allocno is trivially colored if this number plus the number
91 of hard registers needed for given allocno is not greater than
92 the number of given allocno hard register set. */
93 int conflict_size;
94 /* The number of hard registers given by member hard_regs. */
95 int hard_regs_num;
96 /* The following member is used to form the final forest. */
97 bool used_p;
98 /* Pointer to the corresponding profitable hard registers. */
99 allocno_hard_regs_t hard_regs;
100 /* Parent, first subnode, previous and next node with the same
101 parent in the forest. */
102 allocno_hard_regs_node_t parent, first, prev, next;
105 /* Info about changing hard reg costs of an allocno. */
106 struct update_cost_record
108 /* Hard regno for which we changed the cost. */
109 int hard_regno;
110 /* Divisor used when we changed the cost of HARD_REGNO. */
111 int divisor;
112 /* Next record for given allocno. */
113 struct update_cost_record *next;
115 /* Pool allocation new operator. */
116 inline void *operator new (size_t)
118 return pool.allocate ();
121 /* Delete operator utilizing pool allocation. */
122 inline void operator delete (void *ptr)
124 pool.remove ((update_cost_record *) ptr);
127 /* Memory allocation pool. */
128 static pool_allocator<update_cost_record> pool;
131 /* To decrease footprint of ira_allocno structure we store all data
132 needed only for coloring in the following structure. */
133 struct allocno_color_data
135 /* TRUE value means that the allocno was not removed yet from the
136 conflicting graph during coloring. */
137 unsigned int in_graph_p : 1;
138 /* TRUE if it is put on the stack to make other allocnos
139 colorable. */
140 unsigned int may_be_spilled_p : 1;
141 /* TRUE if the allocno is trivially colorable. */
142 unsigned int colorable_p : 1;
143 /* Number of hard registers of the allocno class really
144 available for the allocno allocation. It is number of the
145 profitable hard regs. */
146 int available_regs_num;
147 /* Allocnos in a bucket (used in coloring) chained by the following
148 two members. */
149 ira_allocno_t next_bucket_allocno;
150 ira_allocno_t prev_bucket_allocno;
151 /* Used for temporary purposes. */
152 int temp;
153 /* Used to exclude repeated processing. */
154 int last_process;
155 /* Profitable hard regs available for this pseudo allocation. It
156 means that the set excludes unavailable hard regs and hard regs
157 conflicting with given pseudo. They should be of the allocno
158 class. */
159 HARD_REG_SET profitable_hard_regs;
160 /* The allocno hard registers node. */
161 allocno_hard_regs_node_t hard_regs_node;
162 /* Array of structures allocno_hard_regs_subnode representing
163 given allocno hard registers node (the 1st element in the array)
164 and all its subnodes in the tree (forest) of allocno hard
165 register nodes (see comments above). */
166 int hard_regs_subnodes_start;
167 /* The length of the previous array. */
168 int hard_regs_subnodes_num;
169 /* Records about updating allocno hard reg costs from copies. If
170 the allocno did not get expected hard register, these records are
171 used to restore original hard reg costs of allocnos connected to
172 this allocno by copies. */
173 struct update_cost_record *update_cost_records;
174 /* Threads. We collect allocnos connected by copies into threads
175 and try to assign hard regs to allocnos by threads. */
176 /* Allocno representing all thread. */
177 ira_allocno_t first_thread_allocno;
178 /* Allocnos in thread forms a cycle list through the following
179 member. */
180 ira_allocno_t next_thread_allocno;
181 /* All thread frequency. Defined only for first thread allocno. */
182 int thread_freq;
185 /* See above. */
186 typedef struct allocno_color_data *allocno_color_data_t;
188 /* Container for storing allocno data concerning coloring. */
189 static allocno_color_data_t allocno_color_data;
191 /* Macro to access the data concerning coloring. */
192 #define ALLOCNO_COLOR_DATA(a) ((allocno_color_data_t) ALLOCNO_ADD_DATA (a))
194 /* Used for finding allocno colorability to exclude repeated allocno
195 processing and for updating preferencing to exclude repeated
196 allocno processing during assignment. */
197 static int curr_allocno_process;
199 /* This file contains code for regional graph coloring, spill/restore
200 code placement optimization, and code helping the reload pass to do
201 a better job. */
203 /* Bitmap of allocnos which should be colored. */
204 static bitmap coloring_allocno_bitmap;
206 /* Bitmap of allocnos which should be taken into account during
207 coloring. In general case it contains allocnos from
208 coloring_allocno_bitmap plus other already colored conflicting
209 allocnos. */
210 static bitmap consideration_allocno_bitmap;
212 /* All allocnos sorted according their priorities. */
213 static ira_allocno_t *sorted_allocnos;
215 /* Vec representing the stack of allocnos used during coloring. */
216 static vec<ira_allocno_t> allocno_stack_vec;
218 /* Helper for qsort comparison callbacks - return a positive integer if
219 X > Y, or a negative value otherwise. Use a conditional expression
220 instead of a difference computation to insulate from possible overflow
221 issues, e.g. X - Y < 0 for some X > 0 and Y < 0. */
222 #define SORTGT(x,y) (((x) > (y)) ? 1 : -1)
226 /* Definition of vector of allocno hard registers. */
228 /* Vector of unique allocno hard registers. */
229 static vec<allocno_hard_regs_t> allocno_hard_regs_vec;
231 struct allocno_hard_regs_hasher : typed_noop_remove <allocno_hard_regs>
233 typedef allocno_hard_regs *value_type;
234 typedef allocno_hard_regs *compare_type;
235 static inline hashval_t hash (const allocno_hard_regs *);
236 static inline bool equal (const allocno_hard_regs *,
237 const allocno_hard_regs *);
240 /* Returns hash value for allocno hard registers V. */
241 inline hashval_t
242 allocno_hard_regs_hasher::hash (const allocno_hard_regs *hv)
244 return iterative_hash (&hv->set, sizeof (HARD_REG_SET), 0);
247 /* Compares allocno hard registers V1 and V2. */
248 inline bool
249 allocno_hard_regs_hasher::equal (const allocno_hard_regs *hv1,
250 const allocno_hard_regs *hv2)
252 return hard_reg_set_equal_p (hv1->set, hv2->set);
255 /* Hash table of unique allocno hard registers. */
256 static hash_table<allocno_hard_regs_hasher> *allocno_hard_regs_htab;
258 /* Return allocno hard registers in the hash table equal to HV. */
259 static allocno_hard_regs_t
260 find_hard_regs (allocno_hard_regs_t hv)
262 return allocno_hard_regs_htab->find (hv);
265 /* Insert allocno hard registers HV in the hash table (if it is not
266 there yet) and return the value which in the table. */
267 static allocno_hard_regs_t
268 insert_hard_regs (allocno_hard_regs_t hv)
270 allocno_hard_regs **slot = allocno_hard_regs_htab->find_slot (hv, INSERT);
272 if (*slot == NULL)
273 *slot = hv;
274 return *slot;
277 /* Initialize data concerning allocno hard registers. */
278 static void
279 init_allocno_hard_regs (void)
281 allocno_hard_regs_vec.create (200);
282 allocno_hard_regs_htab
283 = new hash_table<allocno_hard_regs_hasher> (200);
286 /* Add (or update info about) allocno hard registers with SET and
287 COST. */
288 static allocno_hard_regs_t
289 add_allocno_hard_regs (HARD_REG_SET set, int64_t cost)
291 struct allocno_hard_regs temp;
292 allocno_hard_regs_t hv;
294 gcc_assert (! hard_reg_set_empty_p (set));
295 COPY_HARD_REG_SET (temp.set, set);
296 if ((hv = find_hard_regs (&temp)) != NULL)
297 hv->cost += cost;
298 else
300 hv = ((struct allocno_hard_regs *)
301 ira_allocate (sizeof (struct allocno_hard_regs)));
302 COPY_HARD_REG_SET (hv->set, set);
303 hv->cost = cost;
304 allocno_hard_regs_vec.safe_push (hv);
305 insert_hard_regs (hv);
307 return hv;
310 /* Finalize data concerning allocno hard registers. */
311 static void
312 finish_allocno_hard_regs (void)
314 int i;
315 allocno_hard_regs_t hv;
317 for (i = 0;
318 allocno_hard_regs_vec.iterate (i, &hv);
319 i++)
320 ira_free (hv);
321 delete allocno_hard_regs_htab;
322 allocno_hard_regs_htab = NULL;
323 allocno_hard_regs_vec.release ();
326 /* Sort hard regs according to their frequency of usage. */
327 static int
328 allocno_hard_regs_compare (const void *v1p, const void *v2p)
330 allocno_hard_regs_t hv1 = *(const allocno_hard_regs_t *) v1p;
331 allocno_hard_regs_t hv2 = *(const allocno_hard_regs_t *) v2p;
333 if (hv2->cost > hv1->cost)
334 return 1;
335 else if (hv2->cost < hv1->cost)
336 return -1;
337 else
338 return 0;
343 /* Used for finding a common ancestor of two allocno hard registers
344 nodes in the forest. We use the current value of
345 'node_check_tick' to mark all nodes from one node to the top and
346 then walking up from another node until we find a marked node.
348 It is also used to figure out allocno colorability as a mark that
349 we already reset value of member 'conflict_size' for the forest
350 node corresponding to the processed allocno. */
351 static int node_check_tick;
353 /* Roots of the forest containing hard register sets can be assigned
354 to allocnos. */
355 static allocno_hard_regs_node_t hard_regs_roots;
357 /* Definition of vector of allocno hard register nodes. */
359 /* Vector used to create the forest. */
360 static vec<allocno_hard_regs_node_t> hard_regs_node_vec;
362 /* Create and return allocno hard registers node containing allocno
363 hard registers HV. */
364 static allocno_hard_regs_node_t
365 create_new_allocno_hard_regs_node (allocno_hard_regs_t hv)
367 allocno_hard_regs_node_t new_node;
369 new_node = ((struct allocno_hard_regs_node *)
370 ira_allocate (sizeof (struct allocno_hard_regs_node)));
371 new_node->check = 0;
372 new_node->hard_regs = hv;
373 new_node->hard_regs_num = hard_reg_set_size (hv->set);
374 new_node->first = NULL;
375 new_node->used_p = false;
376 return new_node;
379 /* Add allocno hard registers node NEW_NODE to the forest on its level
380 given by ROOTS. */
381 static void
382 add_new_allocno_hard_regs_node_to_forest (allocno_hard_regs_node_t *roots,
383 allocno_hard_regs_node_t new_node)
385 new_node->next = *roots;
386 if (new_node->next != NULL)
387 new_node->next->prev = new_node;
388 new_node->prev = NULL;
389 *roots = new_node;
392 /* Add allocno hard registers HV (or its best approximation if it is
393 not possible) to the forest on its level given by ROOTS. */
394 static void
395 add_allocno_hard_regs_to_forest (allocno_hard_regs_node_t *roots,
396 allocno_hard_regs_t hv)
398 unsigned int i, start;
399 allocno_hard_regs_node_t node, prev, new_node;
400 HARD_REG_SET temp_set;
401 allocno_hard_regs_t hv2;
403 start = hard_regs_node_vec.length ();
404 for (node = *roots; node != NULL; node = node->next)
406 if (hard_reg_set_equal_p (hv->set, node->hard_regs->set))
407 return;
408 if (hard_reg_set_subset_p (hv->set, node->hard_regs->set))
410 add_allocno_hard_regs_to_forest (&node->first, hv);
411 return;
413 if (hard_reg_set_subset_p (node->hard_regs->set, hv->set))
414 hard_regs_node_vec.safe_push (node);
415 else if (hard_reg_set_intersect_p (hv->set, node->hard_regs->set))
417 COPY_HARD_REG_SET (temp_set, hv->set);
418 AND_HARD_REG_SET (temp_set, node->hard_regs->set);
419 hv2 = add_allocno_hard_regs (temp_set, hv->cost);
420 add_allocno_hard_regs_to_forest (&node->first, hv2);
423 if (hard_regs_node_vec.length ()
424 > start + 1)
426 /* Create a new node which contains nodes in hard_regs_node_vec. */
427 CLEAR_HARD_REG_SET (temp_set);
428 for (i = start;
429 i < hard_regs_node_vec.length ();
430 i++)
432 node = hard_regs_node_vec[i];
433 IOR_HARD_REG_SET (temp_set, node->hard_regs->set);
435 hv = add_allocno_hard_regs (temp_set, hv->cost);
436 new_node = create_new_allocno_hard_regs_node (hv);
437 prev = NULL;
438 for (i = start;
439 i < hard_regs_node_vec.length ();
440 i++)
442 node = hard_regs_node_vec[i];
443 if (node->prev == NULL)
444 *roots = node->next;
445 else
446 node->prev->next = node->next;
447 if (node->next != NULL)
448 node->next->prev = node->prev;
449 if (prev == NULL)
450 new_node->first = node;
451 else
452 prev->next = node;
453 node->prev = prev;
454 node->next = NULL;
455 prev = node;
457 add_new_allocno_hard_regs_node_to_forest (roots, new_node);
459 hard_regs_node_vec.truncate (start);
462 /* Add allocno hard registers nodes starting with the forest level
463 given by FIRST which contains biggest set inside SET. */
464 static void
465 collect_allocno_hard_regs_cover (allocno_hard_regs_node_t first,
466 HARD_REG_SET set)
468 allocno_hard_regs_node_t node;
470 ira_assert (first != NULL);
471 for (node = first; node != NULL; node = node->next)
472 if (hard_reg_set_subset_p (node->hard_regs->set, set))
473 hard_regs_node_vec.safe_push (node);
474 else if (hard_reg_set_intersect_p (set, node->hard_regs->set))
475 collect_allocno_hard_regs_cover (node->first, set);
478 /* Set up field parent as PARENT in all allocno hard registers nodes
479 in forest given by FIRST. */
480 static void
481 setup_allocno_hard_regs_nodes_parent (allocno_hard_regs_node_t first,
482 allocno_hard_regs_node_t parent)
484 allocno_hard_regs_node_t node;
486 for (node = first; node != NULL; node = node->next)
488 node->parent = parent;
489 setup_allocno_hard_regs_nodes_parent (node->first, node);
493 /* Return allocno hard registers node which is a first common ancestor
494 node of FIRST and SECOND in the forest. */
495 static allocno_hard_regs_node_t
496 first_common_ancestor_node (allocno_hard_regs_node_t first,
497 allocno_hard_regs_node_t second)
499 allocno_hard_regs_node_t node;
501 node_check_tick++;
502 for (node = first; node != NULL; node = node->parent)
503 node->check = node_check_tick;
504 for (node = second; node != NULL; node = node->parent)
505 if (node->check == node_check_tick)
506 return node;
507 return first_common_ancestor_node (second, first);
510 /* Print hard reg set SET to F. */
511 static void
512 print_hard_reg_set (FILE *f, HARD_REG_SET set, bool new_line_p)
514 int i, start;
516 for (start = -1, i = 0; i < FIRST_PSEUDO_REGISTER; i++)
518 if (TEST_HARD_REG_BIT (set, i))
520 if (i == 0 || ! TEST_HARD_REG_BIT (set, i - 1))
521 start = i;
523 if (start >= 0
524 && (i == FIRST_PSEUDO_REGISTER - 1 || ! TEST_HARD_REG_BIT (set, i)))
526 if (start == i - 1)
527 fprintf (f, " %d", start);
528 else if (start == i - 2)
529 fprintf (f, " %d %d", start, start + 1);
530 else
531 fprintf (f, " %d-%d", start, i - 1);
532 start = -1;
535 if (new_line_p)
536 fprintf (f, "\n");
539 /* Print allocno hard register subforest given by ROOTS and its LEVEL
540 to F. */
541 static void
542 print_hard_regs_subforest (FILE *f, allocno_hard_regs_node_t roots,
543 int level)
545 int i;
546 allocno_hard_regs_node_t node;
548 for (node = roots; node != NULL; node = node->next)
550 fprintf (f, " ");
551 for (i = 0; i < level * 2; i++)
552 fprintf (f, " ");
553 fprintf (f, "%d:(", node->preorder_num);
554 print_hard_reg_set (f, node->hard_regs->set, false);
555 fprintf (f, ")@%" PRId64"\n", node->hard_regs->cost);
556 print_hard_regs_subforest (f, node->first, level + 1);
560 /* Print the allocno hard register forest to F. */
561 static void
562 print_hard_regs_forest (FILE *f)
564 fprintf (f, " Hard reg set forest:\n");
565 print_hard_regs_subforest (f, hard_regs_roots, 1);
568 /* Print the allocno hard register forest to stderr. */
569 void
570 ira_debug_hard_regs_forest (void)
572 print_hard_regs_forest (stderr);
575 /* Remove unused allocno hard registers nodes from forest given by its
576 *ROOTS. */
577 static void
578 remove_unused_allocno_hard_regs_nodes (allocno_hard_regs_node_t *roots)
580 allocno_hard_regs_node_t node, prev, next, last;
582 for (prev = NULL, node = *roots; node != NULL; node = next)
584 next = node->next;
585 if (node->used_p)
587 remove_unused_allocno_hard_regs_nodes (&node->first);
588 prev = node;
590 else
592 for (last = node->first;
593 last != NULL && last->next != NULL;
594 last = last->next)
596 if (last != NULL)
598 if (prev == NULL)
599 *roots = node->first;
600 else
601 prev->next = node->first;
602 if (next != NULL)
603 next->prev = last;
604 last->next = next;
605 next = node->first;
607 else
609 if (prev == NULL)
610 *roots = next;
611 else
612 prev->next = next;
613 if (next != NULL)
614 next->prev = prev;
616 ira_free (node);
621 /* Set up fields preorder_num starting with START_NUM in all allocno
622 hard registers nodes in forest given by FIRST. Return biggest set
623 PREORDER_NUM increased by 1. */
624 static int
625 enumerate_allocno_hard_regs_nodes (allocno_hard_regs_node_t first,
626 allocno_hard_regs_node_t parent,
627 int start_num)
629 allocno_hard_regs_node_t node;
631 for (node = first; node != NULL; node = node->next)
633 node->preorder_num = start_num++;
634 node->parent = parent;
635 start_num = enumerate_allocno_hard_regs_nodes (node->first, node,
636 start_num);
638 return start_num;
641 /* Number of allocno hard registers nodes in the forest. */
642 static int allocno_hard_regs_nodes_num;
644 /* Table preorder number of allocno hard registers node in the forest
645 -> the allocno hard registers node. */
646 static allocno_hard_regs_node_t *allocno_hard_regs_nodes;
648 /* See below. */
649 typedef struct allocno_hard_regs_subnode *allocno_hard_regs_subnode_t;
651 /* The structure is used to describes all subnodes (not only immediate
652 ones) in the mentioned above tree for given allocno hard register
653 node. The usage of such data accelerates calculation of
654 colorability of given allocno. */
655 struct allocno_hard_regs_subnode
657 /* The conflict size of conflicting allocnos whose hard register
658 sets are equal sets (plus supersets if given node is given
659 allocno hard registers node) of one in the given node. */
660 int left_conflict_size;
661 /* The summary conflict size of conflicting allocnos whose hard
662 register sets are strict subsets of one in the given node.
663 Overall conflict size is
664 left_conflict_subnodes_size
665 + MIN (max_node_impact - left_conflict_subnodes_size,
666 left_conflict_size)
668 short left_conflict_subnodes_size;
669 short max_node_impact;
672 /* Container for hard regs subnodes of all allocnos. */
673 static allocno_hard_regs_subnode_t allocno_hard_regs_subnodes;
675 /* Table (preorder number of allocno hard registers node in the
676 forest, preorder number of allocno hard registers subnode) -> index
677 of the subnode relative to the node. -1 if it is not a
678 subnode. */
679 static int *allocno_hard_regs_subnode_index;
681 /* Setup arrays ALLOCNO_HARD_REGS_NODES and
682 ALLOCNO_HARD_REGS_SUBNODE_INDEX. */
683 static void
684 setup_allocno_hard_regs_subnode_index (allocno_hard_regs_node_t first)
686 allocno_hard_regs_node_t node, parent;
687 int index;
689 for (node = first; node != NULL; node = node->next)
691 allocno_hard_regs_nodes[node->preorder_num] = node;
692 for (parent = node; parent != NULL; parent = parent->parent)
694 index = parent->preorder_num * allocno_hard_regs_nodes_num;
695 allocno_hard_regs_subnode_index[index + node->preorder_num]
696 = node->preorder_num - parent->preorder_num;
698 setup_allocno_hard_regs_subnode_index (node->first);
702 /* Count all allocno hard registers nodes in tree ROOT. */
703 static int
704 get_allocno_hard_regs_subnodes_num (allocno_hard_regs_node_t root)
706 int len = 1;
708 for (root = root->first; root != NULL; root = root->next)
709 len += get_allocno_hard_regs_subnodes_num (root);
710 return len;
713 /* Build the forest of allocno hard registers nodes and assign each
714 allocno a node from the forest. */
715 static void
716 form_allocno_hard_regs_nodes_forest (void)
718 unsigned int i, j, size, len;
719 int start;
720 ira_allocno_t a;
721 allocno_hard_regs_t hv;
722 bitmap_iterator bi;
723 HARD_REG_SET temp;
724 allocno_hard_regs_node_t node, allocno_hard_regs_node;
725 allocno_color_data_t allocno_data;
727 node_check_tick = 0;
728 init_allocno_hard_regs ();
729 hard_regs_roots = NULL;
730 hard_regs_node_vec.create (100);
731 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
732 if (! TEST_HARD_REG_BIT (ira_no_alloc_regs, i))
734 CLEAR_HARD_REG_SET (temp);
735 SET_HARD_REG_BIT (temp, i);
736 hv = add_allocno_hard_regs (temp, 0);
737 node = create_new_allocno_hard_regs_node (hv);
738 add_new_allocno_hard_regs_node_to_forest (&hard_regs_roots, node);
740 start = allocno_hard_regs_vec.length ();
741 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
743 a = ira_allocnos[i];
744 allocno_data = ALLOCNO_COLOR_DATA (a);
746 if (hard_reg_set_empty_p (allocno_data->profitable_hard_regs))
747 continue;
748 hv = (add_allocno_hard_regs
749 (allocno_data->profitable_hard_regs,
750 ALLOCNO_MEMORY_COST (a) - ALLOCNO_CLASS_COST (a)));
752 SET_HARD_REG_SET (temp);
753 AND_COMPL_HARD_REG_SET (temp, ira_no_alloc_regs);
754 add_allocno_hard_regs (temp, 0);
755 qsort (allocno_hard_regs_vec.address () + start,
756 allocno_hard_regs_vec.length () - start,
757 sizeof (allocno_hard_regs_t), allocno_hard_regs_compare);
758 for (i = start;
759 allocno_hard_regs_vec.iterate (i, &hv);
760 i++)
762 add_allocno_hard_regs_to_forest (&hard_regs_roots, hv);
763 ira_assert (hard_regs_node_vec.length () == 0);
765 /* We need to set up parent fields for right work of
766 first_common_ancestor_node. */
767 setup_allocno_hard_regs_nodes_parent (hard_regs_roots, NULL);
768 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
770 a = ira_allocnos[i];
771 allocno_data = ALLOCNO_COLOR_DATA (a);
772 if (hard_reg_set_empty_p (allocno_data->profitable_hard_regs))
773 continue;
774 hard_regs_node_vec.truncate (0);
775 collect_allocno_hard_regs_cover (hard_regs_roots,
776 allocno_data->profitable_hard_regs);
777 allocno_hard_regs_node = NULL;
778 for (j = 0; hard_regs_node_vec.iterate (j, &node); j++)
779 allocno_hard_regs_node
780 = (j == 0
781 ? node
782 : first_common_ancestor_node (node, allocno_hard_regs_node));
783 /* That is a temporary storage. */
784 allocno_hard_regs_node->used_p = true;
785 allocno_data->hard_regs_node = allocno_hard_regs_node;
787 ira_assert (hard_regs_roots->next == NULL);
788 hard_regs_roots->used_p = true;
789 remove_unused_allocno_hard_regs_nodes (&hard_regs_roots);
790 allocno_hard_regs_nodes_num
791 = enumerate_allocno_hard_regs_nodes (hard_regs_roots, NULL, 0);
792 allocno_hard_regs_nodes
793 = ((allocno_hard_regs_node_t *)
794 ira_allocate (allocno_hard_regs_nodes_num
795 * sizeof (allocno_hard_regs_node_t)));
796 size = allocno_hard_regs_nodes_num * allocno_hard_regs_nodes_num;
797 allocno_hard_regs_subnode_index
798 = (int *) ira_allocate (size * sizeof (int));
799 for (i = 0; i < size; i++)
800 allocno_hard_regs_subnode_index[i] = -1;
801 setup_allocno_hard_regs_subnode_index (hard_regs_roots);
802 start = 0;
803 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
805 a = ira_allocnos[i];
806 allocno_data = ALLOCNO_COLOR_DATA (a);
807 if (hard_reg_set_empty_p (allocno_data->profitable_hard_regs))
808 continue;
809 len = get_allocno_hard_regs_subnodes_num (allocno_data->hard_regs_node);
810 allocno_data->hard_regs_subnodes_start = start;
811 allocno_data->hard_regs_subnodes_num = len;
812 start += len;
814 allocno_hard_regs_subnodes
815 = ((allocno_hard_regs_subnode_t)
816 ira_allocate (sizeof (struct allocno_hard_regs_subnode) * start));
817 hard_regs_node_vec.release ();
820 /* Free tree of allocno hard registers nodes given by its ROOT. */
821 static void
822 finish_allocno_hard_regs_nodes_tree (allocno_hard_regs_node_t root)
824 allocno_hard_regs_node_t child, next;
826 for (child = root->first; child != NULL; child = next)
828 next = child->next;
829 finish_allocno_hard_regs_nodes_tree (child);
831 ira_free (root);
834 /* Finish work with the forest of allocno hard registers nodes. */
835 static void
836 finish_allocno_hard_regs_nodes_forest (void)
838 allocno_hard_regs_node_t node, next;
840 ira_free (allocno_hard_regs_subnodes);
841 for (node = hard_regs_roots; node != NULL; node = next)
843 next = node->next;
844 finish_allocno_hard_regs_nodes_tree (node);
846 ira_free (allocno_hard_regs_nodes);
847 ira_free (allocno_hard_regs_subnode_index);
848 finish_allocno_hard_regs ();
851 /* Set up left conflict sizes and left conflict subnodes sizes of hard
852 registers subnodes of allocno A. Return TRUE if allocno A is
853 trivially colorable. */
854 static bool
855 setup_left_conflict_sizes_p (ira_allocno_t a)
857 int i, k, nobj, start;
858 int conflict_size, left_conflict_subnodes_size, node_preorder_num;
859 allocno_color_data_t data;
860 HARD_REG_SET profitable_hard_regs;
861 allocno_hard_regs_subnode_t subnodes;
862 allocno_hard_regs_node_t node;
863 HARD_REG_SET node_set;
865 nobj = ALLOCNO_NUM_OBJECTS (a);
866 data = ALLOCNO_COLOR_DATA (a);
867 subnodes = allocno_hard_regs_subnodes + data->hard_regs_subnodes_start;
868 COPY_HARD_REG_SET (profitable_hard_regs, data->profitable_hard_regs);
869 node = data->hard_regs_node;
870 node_preorder_num = node->preorder_num;
871 COPY_HARD_REG_SET (node_set, node->hard_regs->set);
872 node_check_tick++;
873 for (k = 0; k < nobj; k++)
875 ira_object_t obj = ALLOCNO_OBJECT (a, k);
876 ira_object_t conflict_obj;
877 ira_object_conflict_iterator oci;
879 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
881 int size;
882 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
883 allocno_hard_regs_node_t conflict_node, temp_node;
884 HARD_REG_SET conflict_node_set;
885 allocno_color_data_t conflict_data;
887 conflict_data = ALLOCNO_COLOR_DATA (conflict_a);
888 if (! ALLOCNO_COLOR_DATA (conflict_a)->in_graph_p
889 || ! hard_reg_set_intersect_p (profitable_hard_regs,
890 conflict_data
891 ->profitable_hard_regs))
892 continue;
893 conflict_node = conflict_data->hard_regs_node;
894 COPY_HARD_REG_SET (conflict_node_set, conflict_node->hard_regs->set);
895 if (hard_reg_set_subset_p (node_set, conflict_node_set))
896 temp_node = node;
897 else
899 ira_assert (hard_reg_set_subset_p (conflict_node_set, node_set));
900 temp_node = conflict_node;
902 if (temp_node->check != node_check_tick)
904 temp_node->check = node_check_tick;
905 temp_node->conflict_size = 0;
907 size = (ira_reg_class_max_nregs
908 [ALLOCNO_CLASS (conflict_a)][ALLOCNO_MODE (conflict_a)]);
909 if (ALLOCNO_NUM_OBJECTS (conflict_a) > 1)
910 /* We will deal with the subwords individually. */
911 size = 1;
912 temp_node->conflict_size += size;
915 for (i = 0; i < data->hard_regs_subnodes_num; i++)
917 allocno_hard_regs_node_t temp_node;
919 temp_node = allocno_hard_regs_nodes[i + node_preorder_num];
920 ira_assert (temp_node->preorder_num == i + node_preorder_num);
921 subnodes[i].left_conflict_size = (temp_node->check != node_check_tick
922 ? 0 : temp_node->conflict_size);
923 if (hard_reg_set_subset_p (temp_node->hard_regs->set,
924 profitable_hard_regs))
925 subnodes[i].max_node_impact = temp_node->hard_regs_num;
926 else
928 HARD_REG_SET temp_set;
929 int j, n, hard_regno;
930 enum reg_class aclass;
932 COPY_HARD_REG_SET (temp_set, temp_node->hard_regs->set);
933 AND_HARD_REG_SET (temp_set, profitable_hard_regs);
934 aclass = ALLOCNO_CLASS (a);
935 for (n = 0, j = ira_class_hard_regs_num[aclass] - 1; j >= 0; j--)
937 hard_regno = ira_class_hard_regs[aclass][j];
938 if (TEST_HARD_REG_BIT (temp_set, hard_regno))
939 n++;
941 subnodes[i].max_node_impact = n;
943 subnodes[i].left_conflict_subnodes_size = 0;
945 start = node_preorder_num * allocno_hard_regs_nodes_num;
946 for (i = data->hard_regs_subnodes_num - 1; i > 0; i--)
948 int size, parent_i;
949 allocno_hard_regs_node_t parent;
951 size = (subnodes[i].left_conflict_subnodes_size
952 + MIN (subnodes[i].max_node_impact
953 - subnodes[i].left_conflict_subnodes_size,
954 subnodes[i].left_conflict_size));
955 parent = allocno_hard_regs_nodes[i + node_preorder_num]->parent;
956 gcc_checking_assert(parent);
957 parent_i
958 = allocno_hard_regs_subnode_index[start + parent->preorder_num];
959 gcc_checking_assert(parent_i >= 0);
960 subnodes[parent_i].left_conflict_subnodes_size += size;
962 left_conflict_subnodes_size = subnodes[0].left_conflict_subnodes_size;
963 conflict_size
964 = (left_conflict_subnodes_size
965 + MIN (subnodes[0].max_node_impact - left_conflict_subnodes_size,
966 subnodes[0].left_conflict_size));
967 conflict_size += ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)];
968 data->colorable_p = conflict_size <= data->available_regs_num;
969 return data->colorable_p;
972 /* Update left conflict sizes of hard registers subnodes of allocno A
973 after removing allocno REMOVED_A with SIZE from the conflict graph.
974 Return TRUE if A is trivially colorable. */
975 static bool
976 update_left_conflict_sizes_p (ira_allocno_t a,
977 ira_allocno_t removed_a, int size)
979 int i, conflict_size, before_conflict_size, diff, start;
980 int node_preorder_num, parent_i;
981 allocno_hard_regs_node_t node, removed_node, parent;
982 allocno_hard_regs_subnode_t subnodes;
983 allocno_color_data_t data = ALLOCNO_COLOR_DATA (a);
985 ira_assert (! data->colorable_p);
986 node = data->hard_regs_node;
987 node_preorder_num = node->preorder_num;
988 removed_node = ALLOCNO_COLOR_DATA (removed_a)->hard_regs_node;
989 ira_assert (hard_reg_set_subset_p (removed_node->hard_regs->set,
990 node->hard_regs->set)
991 || hard_reg_set_subset_p (node->hard_regs->set,
992 removed_node->hard_regs->set));
993 start = node_preorder_num * allocno_hard_regs_nodes_num;
994 i = allocno_hard_regs_subnode_index[start + removed_node->preorder_num];
995 if (i < 0)
996 i = 0;
997 subnodes = allocno_hard_regs_subnodes + data->hard_regs_subnodes_start;
998 before_conflict_size
999 = (subnodes[i].left_conflict_subnodes_size
1000 + MIN (subnodes[i].max_node_impact
1001 - subnodes[i].left_conflict_subnodes_size,
1002 subnodes[i].left_conflict_size));
1003 subnodes[i].left_conflict_size -= size;
1004 for (;;)
1006 conflict_size
1007 = (subnodes[i].left_conflict_subnodes_size
1008 + MIN (subnodes[i].max_node_impact
1009 - subnodes[i].left_conflict_subnodes_size,
1010 subnodes[i].left_conflict_size));
1011 if ((diff = before_conflict_size - conflict_size) == 0)
1012 break;
1013 ira_assert (conflict_size < before_conflict_size);
1014 parent = allocno_hard_regs_nodes[i + node_preorder_num]->parent;
1015 if (parent == NULL)
1016 break;
1017 parent_i
1018 = allocno_hard_regs_subnode_index[start + parent->preorder_num];
1019 if (parent_i < 0)
1020 break;
1021 i = parent_i;
1022 before_conflict_size
1023 = (subnodes[i].left_conflict_subnodes_size
1024 + MIN (subnodes[i].max_node_impact
1025 - subnodes[i].left_conflict_subnodes_size,
1026 subnodes[i].left_conflict_size));
1027 subnodes[i].left_conflict_subnodes_size -= diff;
1029 if (i != 0
1030 || (conflict_size
1031 + ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]
1032 > data->available_regs_num))
1033 return false;
1034 data->colorable_p = true;
1035 return true;
1038 /* Return true if allocno A has empty profitable hard regs. */
1039 static bool
1040 empty_profitable_hard_regs (ira_allocno_t a)
1042 allocno_color_data_t data = ALLOCNO_COLOR_DATA (a);
1044 return hard_reg_set_empty_p (data->profitable_hard_regs);
1047 /* Set up profitable hard registers for each allocno being
1048 colored. */
1049 static void
1050 setup_profitable_hard_regs (void)
1052 unsigned int i;
1053 int j, k, nobj, hard_regno, nregs, class_size;
1054 ira_allocno_t a;
1055 bitmap_iterator bi;
1056 enum reg_class aclass;
1057 machine_mode mode;
1058 allocno_color_data_t data;
1060 /* Initial set up from allocno classes and explicitly conflicting
1061 hard regs. */
1062 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
1064 a = ira_allocnos[i];
1065 if ((aclass = ALLOCNO_CLASS (a)) == NO_REGS)
1066 continue;
1067 data = ALLOCNO_COLOR_DATA (a);
1068 if (ALLOCNO_UPDATED_HARD_REG_COSTS (a) == NULL
1069 && ALLOCNO_CLASS_COST (a) > ALLOCNO_MEMORY_COST (a))
1070 CLEAR_HARD_REG_SET (data->profitable_hard_regs);
1071 else
1073 mode = ALLOCNO_MODE (a);
1074 COPY_HARD_REG_SET (data->profitable_hard_regs,
1075 ira_useful_class_mode_regs[aclass][mode]);
1076 nobj = ALLOCNO_NUM_OBJECTS (a);
1077 for (k = 0; k < nobj; k++)
1079 ira_object_t obj = ALLOCNO_OBJECT (a, k);
1081 AND_COMPL_HARD_REG_SET (data->profitable_hard_regs,
1082 OBJECT_TOTAL_CONFLICT_HARD_REGS (obj));
1086 /* Exclude hard regs already assigned for conflicting objects. */
1087 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, i, bi)
1089 a = ira_allocnos[i];
1090 if ((aclass = ALLOCNO_CLASS (a)) == NO_REGS
1091 || ! ALLOCNO_ASSIGNED_P (a)
1092 || (hard_regno = ALLOCNO_HARD_REGNO (a)) < 0)
1093 continue;
1094 mode = ALLOCNO_MODE (a);
1095 nregs = hard_regno_nregs[hard_regno][mode];
1096 nobj = ALLOCNO_NUM_OBJECTS (a);
1097 for (k = 0; k < nobj; k++)
1099 ira_object_t obj = ALLOCNO_OBJECT (a, k);
1100 ira_object_t conflict_obj;
1101 ira_object_conflict_iterator oci;
1103 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
1105 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
1107 /* We can process the conflict allocno repeatedly with
1108 the same result. */
1109 if (nregs == nobj && nregs > 1)
1111 int num = OBJECT_SUBWORD (conflict_obj);
1113 if (REG_WORDS_BIG_ENDIAN)
1114 CLEAR_HARD_REG_BIT
1115 (ALLOCNO_COLOR_DATA (conflict_a)->profitable_hard_regs,
1116 hard_regno + nobj - num - 1);
1117 else
1118 CLEAR_HARD_REG_BIT
1119 (ALLOCNO_COLOR_DATA (conflict_a)->profitable_hard_regs,
1120 hard_regno + num);
1122 else
1123 AND_COMPL_HARD_REG_SET
1124 (ALLOCNO_COLOR_DATA (conflict_a)->profitable_hard_regs,
1125 ira_reg_mode_hard_regset[hard_regno][mode]);
1129 /* Exclude too costly hard regs. */
1130 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
1132 int min_cost = INT_MAX;
1133 int *costs;
1135 a = ira_allocnos[i];
1136 if ((aclass = ALLOCNO_CLASS (a)) == NO_REGS
1137 || empty_profitable_hard_regs (a))
1138 continue;
1139 data = ALLOCNO_COLOR_DATA (a);
1140 mode = ALLOCNO_MODE (a);
1141 if ((costs = ALLOCNO_UPDATED_HARD_REG_COSTS (a)) != NULL
1142 || (costs = ALLOCNO_HARD_REG_COSTS (a)) != NULL)
1144 class_size = ira_class_hard_regs_num[aclass];
1145 for (j = 0; j < class_size; j++)
1147 hard_regno = ira_class_hard_regs[aclass][j];
1148 if (! TEST_HARD_REG_BIT (data->profitable_hard_regs,
1149 hard_regno))
1150 continue;
1151 if (ALLOCNO_UPDATED_MEMORY_COST (a) < costs[j])
1152 CLEAR_HARD_REG_BIT (data->profitable_hard_regs,
1153 hard_regno);
1154 else if (min_cost > costs[j])
1155 min_cost = costs[j];
1158 else if (ALLOCNO_UPDATED_MEMORY_COST (a)
1159 < ALLOCNO_UPDATED_CLASS_COST (a))
1160 CLEAR_HARD_REG_SET (data->profitable_hard_regs);
1161 if (ALLOCNO_UPDATED_CLASS_COST (a) > min_cost)
1162 ALLOCNO_UPDATED_CLASS_COST (a) = min_cost;
1168 /* This page contains functions used to choose hard registers for
1169 allocnos. */
1171 /* Pool for update cost records. */
1172 static pool_allocator<update_cost_record> update_cost_record_pool
1173 ("update cost records", 100);
1175 /* Return new update cost record with given params. */
1176 static struct update_cost_record *
1177 get_update_cost_record (int hard_regno, int divisor,
1178 struct update_cost_record *next)
1180 struct update_cost_record *record;
1182 record = update_cost_record_pool.allocate ();
1183 record->hard_regno = hard_regno;
1184 record->divisor = divisor;
1185 record->next = next;
1186 return record;
1189 /* Free memory for all records in LIST. */
1190 static void
1191 free_update_cost_record_list (struct update_cost_record *list)
1193 struct update_cost_record *next;
1195 while (list != NULL)
1197 next = list->next;
1198 update_cost_record_pool.remove (list);
1199 list = next;
1203 /* Free memory allocated for all update cost records. */
1204 static void
1205 finish_update_cost_records (void)
1207 update_cost_record_pool.release ();
1210 /* Array whose element value is TRUE if the corresponding hard
1211 register was already allocated for an allocno. */
1212 static bool allocated_hardreg_p[FIRST_PSEUDO_REGISTER];
1214 /* Describes one element in a queue of allocnos whose costs need to be
1215 updated. Each allocno in the queue is known to have an allocno
1216 class. */
1217 struct update_cost_queue_elem
1219 /* This element is in the queue iff CHECK == update_cost_check. */
1220 int check;
1222 /* COST_HOP_DIVISOR**N, where N is the length of the shortest path
1223 connecting this allocno to the one being allocated. */
1224 int divisor;
1226 /* Allocno from which we are chaining costs of connected allocnos.
1227 It is used not go back in graph of allocnos connected by
1228 copies. */
1229 ira_allocno_t from;
1231 /* The next allocno in the queue, or null if this is the last element. */
1232 ira_allocno_t next;
1235 /* The first element in a queue of allocnos whose copy costs need to be
1236 updated. Null if the queue is empty. */
1237 static ira_allocno_t update_cost_queue;
1239 /* The last element in the queue described by update_cost_queue.
1240 Not valid if update_cost_queue is null. */
1241 static struct update_cost_queue_elem *update_cost_queue_tail;
1243 /* A pool of elements in the queue described by update_cost_queue.
1244 Elements are indexed by ALLOCNO_NUM. */
1245 static struct update_cost_queue_elem *update_cost_queue_elems;
1247 /* The current value of update_costs_from_copies call count. */
1248 static int update_cost_check;
1250 /* Allocate and initialize data necessary for function
1251 update_costs_from_copies. */
1252 static void
1253 initiate_cost_update (void)
1255 size_t size;
1257 size = ira_allocnos_num * sizeof (struct update_cost_queue_elem);
1258 update_cost_queue_elems
1259 = (struct update_cost_queue_elem *) ira_allocate (size);
1260 memset (update_cost_queue_elems, 0, size);
1261 update_cost_check = 0;
1264 /* Deallocate data used by function update_costs_from_copies. */
1265 static void
1266 finish_cost_update (void)
1268 ira_free (update_cost_queue_elems);
1269 finish_update_cost_records ();
1272 /* When we traverse allocnos to update hard register costs, the cost
1273 divisor will be multiplied by the following macro value for each
1274 hop from given allocno to directly connected allocnos. */
1275 #define COST_HOP_DIVISOR 4
1277 /* Start a new cost-updating pass. */
1278 static void
1279 start_update_cost (void)
1281 update_cost_check++;
1282 update_cost_queue = NULL;
1285 /* Add (ALLOCNO, FROM, DIVISOR) to the end of update_cost_queue, unless
1286 ALLOCNO is already in the queue, or has NO_REGS class. */
1287 static inline void
1288 queue_update_cost (ira_allocno_t allocno, ira_allocno_t from, int divisor)
1290 struct update_cost_queue_elem *elem;
1292 elem = &update_cost_queue_elems[ALLOCNO_NUM (allocno)];
1293 if (elem->check != update_cost_check
1294 && ALLOCNO_CLASS (allocno) != NO_REGS)
1296 elem->check = update_cost_check;
1297 elem->from = from;
1298 elem->divisor = divisor;
1299 elem->next = NULL;
1300 if (update_cost_queue == NULL)
1301 update_cost_queue = allocno;
1302 else
1303 update_cost_queue_tail->next = allocno;
1304 update_cost_queue_tail = elem;
1308 /* Try to remove the first element from update_cost_queue. Return
1309 false if the queue was empty, otherwise make (*ALLOCNO, *FROM,
1310 *DIVISOR) describe the removed element. */
1311 static inline bool
1312 get_next_update_cost (ira_allocno_t *allocno, ira_allocno_t *from, int *divisor)
1314 struct update_cost_queue_elem *elem;
1316 if (update_cost_queue == NULL)
1317 return false;
1319 *allocno = update_cost_queue;
1320 elem = &update_cost_queue_elems[ALLOCNO_NUM (*allocno)];
1321 *from = elem->from;
1322 *divisor = elem->divisor;
1323 update_cost_queue = elem->next;
1324 return true;
1327 /* Increase costs of HARD_REGNO by UPDATE_COST for ALLOCNO. Return
1328 true if we really modified the cost. */
1329 static bool
1330 update_allocno_cost (ira_allocno_t allocno, int hard_regno, int update_cost)
1332 int i;
1333 enum reg_class aclass = ALLOCNO_CLASS (allocno);
1335 i = ira_class_hard_reg_index[aclass][hard_regno];
1336 if (i < 0)
1337 return false;
1338 ira_allocate_and_set_or_copy_costs
1339 (&ALLOCNO_UPDATED_HARD_REG_COSTS (allocno), aclass,
1340 ALLOCNO_UPDATED_CLASS_COST (allocno),
1341 ALLOCNO_HARD_REG_COSTS (allocno));
1342 ira_allocate_and_set_or_copy_costs
1343 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (allocno),
1344 aclass, 0, ALLOCNO_CONFLICT_HARD_REG_COSTS (allocno));
1345 ALLOCNO_UPDATED_HARD_REG_COSTS (allocno)[i] += update_cost;
1346 ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (allocno)[i] += update_cost;
1347 return true;
1350 /* Update (decrease if DECR_P) HARD_REGNO cost of allocnos connected
1351 by copies to ALLOCNO to increase chances to remove some copies as
1352 the result of subsequent assignment. Record cost updates if
1353 RECORD_P is true. */
1354 static void
1355 update_costs_from_allocno (ira_allocno_t allocno, int hard_regno,
1356 int divisor, bool decr_p, bool record_p)
1358 int cost, update_cost;
1359 machine_mode mode;
1360 enum reg_class rclass, aclass;
1361 ira_allocno_t another_allocno, from = NULL;
1362 ira_copy_t cp, next_cp;
1364 rclass = REGNO_REG_CLASS (hard_regno);
1367 mode = ALLOCNO_MODE (allocno);
1368 ira_init_register_move_cost_if_necessary (mode);
1369 for (cp = ALLOCNO_COPIES (allocno); cp != NULL; cp = next_cp)
1371 if (cp->first == allocno)
1373 next_cp = cp->next_first_allocno_copy;
1374 another_allocno = cp->second;
1376 else if (cp->second == allocno)
1378 next_cp = cp->next_second_allocno_copy;
1379 another_allocno = cp->first;
1381 else
1382 gcc_unreachable ();
1384 if (another_allocno == from)
1385 continue;
1387 aclass = ALLOCNO_CLASS (another_allocno);
1388 if (! TEST_HARD_REG_BIT (reg_class_contents[aclass],
1389 hard_regno)
1390 || ALLOCNO_ASSIGNED_P (another_allocno))
1391 continue;
1393 cost = (cp->second == allocno
1394 ? ira_register_move_cost[mode][rclass][aclass]
1395 : ira_register_move_cost[mode][aclass][rclass]);
1396 if (decr_p)
1397 cost = -cost;
1399 update_cost = cp->freq * cost / divisor;
1400 if (update_cost == 0)
1401 continue;
1403 if (! update_allocno_cost (another_allocno, hard_regno, update_cost))
1404 continue;
1405 queue_update_cost (another_allocno, allocno, divisor * COST_HOP_DIVISOR);
1406 if (record_p && ALLOCNO_COLOR_DATA (another_allocno) != NULL)
1407 ALLOCNO_COLOR_DATA (another_allocno)->update_cost_records
1408 = get_update_cost_record (hard_regno, divisor,
1409 ALLOCNO_COLOR_DATA (another_allocno)
1410 ->update_cost_records);
1413 while (get_next_update_cost (&allocno, &from, &divisor));
1416 /* Decrease preferred ALLOCNO hard register costs and costs of
1417 allocnos connected to ALLOCNO through copy. */
1418 static void
1419 update_costs_from_prefs (ira_allocno_t allocno)
1421 ira_pref_t pref;
1423 start_update_cost ();
1424 for (pref = ALLOCNO_PREFS (allocno); pref != NULL; pref = pref->next_pref)
1425 update_costs_from_allocno (allocno, pref->hard_regno,
1426 COST_HOP_DIVISOR, true, true);
1429 /* Update (decrease if DECR_P) the cost of allocnos connected to
1430 ALLOCNO through copies to increase chances to remove some copies as
1431 the result of subsequent assignment. ALLOCNO was just assigned to
1432 a hard register. Record cost updates if RECORD_P is true. */
1433 static void
1434 update_costs_from_copies (ira_allocno_t allocno, bool decr_p, bool record_p)
1436 int hard_regno;
1438 hard_regno = ALLOCNO_HARD_REGNO (allocno);
1439 ira_assert (hard_regno >= 0 && ALLOCNO_CLASS (allocno) != NO_REGS);
1440 start_update_cost ();
1441 update_costs_from_allocno (allocno, hard_regno, 1, decr_p, record_p);
1444 /* Restore costs of allocnos connected to ALLOCNO by copies as it was
1445 before updating costs of these allocnos from given allocno. This
1446 is a wise thing to do as if given allocno did not get an expected
1447 hard reg, using smaller cost of the hard reg for allocnos connected
1448 by copies to given allocno becomes actually misleading. Free all
1449 update cost records for ALLOCNO as we don't need them anymore. */
1450 static void
1451 restore_costs_from_copies (ira_allocno_t allocno)
1453 struct update_cost_record *records, *curr;
1455 if (ALLOCNO_COLOR_DATA (allocno) == NULL)
1456 return;
1457 records = ALLOCNO_COLOR_DATA (allocno)->update_cost_records;
1458 start_update_cost ();
1459 for (curr = records; curr != NULL; curr = curr->next)
1460 update_costs_from_allocno (allocno, curr->hard_regno,
1461 curr->divisor, true, false);
1462 free_update_cost_record_list (records);
1463 ALLOCNO_COLOR_DATA (allocno)->update_cost_records = NULL;
1466 /* This function updates COSTS (decrease if DECR_P) for hard_registers
1467 of ACLASS by conflict costs of the unassigned allocnos
1468 connected by copies with allocnos in update_cost_queue. This
1469 update increases chances to remove some copies. */
1470 static void
1471 update_conflict_hard_regno_costs (int *costs, enum reg_class aclass,
1472 bool decr_p)
1474 int i, cost, class_size, freq, mult, div, divisor;
1475 int index, hard_regno;
1476 int *conflict_costs;
1477 bool cont_p;
1478 enum reg_class another_aclass;
1479 ira_allocno_t allocno, another_allocno, from;
1480 ira_copy_t cp, next_cp;
1482 while (get_next_update_cost (&allocno, &from, &divisor))
1483 for (cp = ALLOCNO_COPIES (allocno); cp != NULL; cp = next_cp)
1485 if (cp->first == allocno)
1487 next_cp = cp->next_first_allocno_copy;
1488 another_allocno = cp->second;
1490 else if (cp->second == allocno)
1492 next_cp = cp->next_second_allocno_copy;
1493 another_allocno = cp->first;
1495 else
1496 gcc_unreachable ();
1498 if (another_allocno == from)
1499 continue;
1501 another_aclass = ALLOCNO_CLASS (another_allocno);
1502 if (! ira_reg_classes_intersect_p[aclass][another_aclass]
1503 || ALLOCNO_ASSIGNED_P (another_allocno)
1504 || ALLOCNO_COLOR_DATA (another_allocno)->may_be_spilled_p)
1505 continue;
1506 class_size = ira_class_hard_regs_num[another_aclass];
1507 ira_allocate_and_copy_costs
1508 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (another_allocno),
1509 another_aclass, ALLOCNO_CONFLICT_HARD_REG_COSTS (another_allocno));
1510 conflict_costs
1511 = ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (another_allocno);
1512 if (conflict_costs == NULL)
1513 cont_p = true;
1514 else
1516 mult = cp->freq;
1517 freq = ALLOCNO_FREQ (another_allocno);
1518 if (freq == 0)
1519 freq = 1;
1520 div = freq * divisor;
1521 cont_p = false;
1522 for (i = class_size - 1; i >= 0; i--)
1524 hard_regno = ira_class_hard_regs[another_aclass][i];
1525 ira_assert (hard_regno >= 0);
1526 index = ira_class_hard_reg_index[aclass][hard_regno];
1527 if (index < 0)
1528 continue;
1529 cost = (int) ((unsigned) conflict_costs [i] * mult) / div;
1530 if (cost == 0)
1531 continue;
1532 cont_p = true;
1533 if (decr_p)
1534 cost = -cost;
1535 costs[index] += cost;
1538 /* Probably 5 hops will be enough. */
1539 if (cont_p
1540 && divisor <= (COST_HOP_DIVISOR
1541 * COST_HOP_DIVISOR
1542 * COST_HOP_DIVISOR
1543 * COST_HOP_DIVISOR))
1544 queue_update_cost (another_allocno, allocno, divisor * COST_HOP_DIVISOR);
1548 /* Set up conflicting (through CONFLICT_REGS) for each object of
1549 allocno A and the start allocno profitable regs (through
1550 START_PROFITABLE_REGS). Remember that the start profitable regs
1551 exclude hard regs which can not hold value of mode of allocno A.
1552 This covers mostly cases when multi-register value should be
1553 aligned. */
1554 static inline void
1555 get_conflict_and_start_profitable_regs (ira_allocno_t a, bool retry_p,
1556 HARD_REG_SET *conflict_regs,
1557 HARD_REG_SET *start_profitable_regs)
1559 int i, nwords;
1560 ira_object_t obj;
1562 nwords = ALLOCNO_NUM_OBJECTS (a);
1563 for (i = 0; i < nwords; i++)
1565 obj = ALLOCNO_OBJECT (a, i);
1566 COPY_HARD_REG_SET (conflict_regs[i],
1567 OBJECT_TOTAL_CONFLICT_HARD_REGS (obj));
1569 if (retry_p)
1571 COPY_HARD_REG_SET (*start_profitable_regs,
1572 reg_class_contents[ALLOCNO_CLASS (a)]);
1573 AND_COMPL_HARD_REG_SET (*start_profitable_regs,
1574 ira_prohibited_class_mode_regs
1575 [ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]);
1577 else
1578 COPY_HARD_REG_SET (*start_profitable_regs,
1579 ALLOCNO_COLOR_DATA (a)->profitable_hard_regs);
1582 /* Return true if HARD_REGNO is ok for assigning to allocno A with
1583 PROFITABLE_REGS and whose objects have CONFLICT_REGS. */
1584 static inline bool
1585 check_hard_reg_p (ira_allocno_t a, int hard_regno,
1586 HARD_REG_SET *conflict_regs, HARD_REG_SET profitable_regs)
1588 int j, nwords, nregs;
1589 enum reg_class aclass;
1590 machine_mode mode;
1592 aclass = ALLOCNO_CLASS (a);
1593 mode = ALLOCNO_MODE (a);
1594 if (TEST_HARD_REG_BIT (ira_prohibited_class_mode_regs[aclass][mode],
1595 hard_regno))
1596 return false;
1597 /* Checking only profitable hard regs. */
1598 if (! TEST_HARD_REG_BIT (profitable_regs, hard_regno))
1599 return false;
1600 nregs = hard_regno_nregs[hard_regno][mode];
1601 nwords = ALLOCNO_NUM_OBJECTS (a);
1602 for (j = 0; j < nregs; j++)
1604 int k;
1605 int set_to_test_start = 0, set_to_test_end = nwords;
1607 if (nregs == nwords)
1609 if (REG_WORDS_BIG_ENDIAN)
1610 set_to_test_start = nwords - j - 1;
1611 else
1612 set_to_test_start = j;
1613 set_to_test_end = set_to_test_start + 1;
1615 for (k = set_to_test_start; k < set_to_test_end; k++)
1616 if (TEST_HARD_REG_BIT (conflict_regs[k], hard_regno + j))
1617 break;
1618 if (k != set_to_test_end)
1619 break;
1621 return j == nregs;
1624 /* Return number of registers needed to be saved and restored at
1625 function prologue/epilogue if we allocate HARD_REGNO to hold value
1626 of MODE. */
1627 static int
1628 calculate_saved_nregs (int hard_regno, machine_mode mode)
1630 int i;
1631 int nregs = 0;
1633 ira_assert (hard_regno >= 0);
1634 for (i = hard_regno_nregs[hard_regno][mode] - 1; i >= 0; i--)
1635 if (!allocated_hardreg_p[hard_regno + i]
1636 && !TEST_HARD_REG_BIT (call_used_reg_set, hard_regno + i)
1637 && !LOCAL_REGNO (hard_regno + i))
1638 nregs++;
1639 return nregs;
1642 /* Choose a hard register for allocno A. If RETRY_P is TRUE, it means
1643 that the function called from function
1644 `ira_reassign_conflict_allocnos' and `allocno_reload_assign'. In
1645 this case some allocno data are not defined or updated and we
1646 should not touch these data. The function returns true if we
1647 managed to assign a hard register to the allocno.
1649 To assign a hard register, first of all we calculate all conflict
1650 hard registers which can come from conflicting allocnos with
1651 already assigned hard registers. After that we find first free
1652 hard register with the minimal cost. During hard register cost
1653 calculation we take conflict hard register costs into account to
1654 give a chance for conflicting allocnos to get a better hard
1655 register in the future.
1657 If the best hard register cost is bigger than cost of memory usage
1658 for the allocno, we don't assign a hard register to given allocno
1659 at all.
1661 If we assign a hard register to the allocno, we update costs of the
1662 hard register for allocnos connected by copies to improve a chance
1663 to coalesce insns represented by the copies when we assign hard
1664 registers to the allocnos connected by the copies. */
1665 static bool
1666 assign_hard_reg (ira_allocno_t a, bool retry_p)
1668 HARD_REG_SET conflicting_regs[2], profitable_hard_regs;
1669 int i, j, hard_regno, best_hard_regno, class_size;
1670 int cost, mem_cost, min_cost, full_cost, min_full_cost, nwords, word;
1671 int *a_costs;
1672 enum reg_class aclass;
1673 machine_mode mode;
1674 static int costs[FIRST_PSEUDO_REGISTER], full_costs[FIRST_PSEUDO_REGISTER];
1675 int saved_nregs;
1676 enum reg_class rclass;
1677 int add_cost;
1678 #ifdef STACK_REGS
1679 bool no_stack_reg_p;
1680 #endif
1682 ira_assert (! ALLOCNO_ASSIGNED_P (a));
1683 get_conflict_and_start_profitable_regs (a, retry_p,
1684 conflicting_regs,
1685 &profitable_hard_regs);
1686 aclass = ALLOCNO_CLASS (a);
1687 class_size = ira_class_hard_regs_num[aclass];
1688 best_hard_regno = -1;
1689 memset (full_costs, 0, sizeof (int) * class_size);
1690 mem_cost = 0;
1691 memset (costs, 0, sizeof (int) * class_size);
1692 memset (full_costs, 0, sizeof (int) * class_size);
1693 #ifdef STACK_REGS
1694 no_stack_reg_p = false;
1695 #endif
1696 if (! retry_p)
1697 start_update_cost ();
1698 mem_cost += ALLOCNO_UPDATED_MEMORY_COST (a);
1700 ira_allocate_and_copy_costs (&ALLOCNO_UPDATED_HARD_REG_COSTS (a),
1701 aclass, ALLOCNO_HARD_REG_COSTS (a));
1702 a_costs = ALLOCNO_UPDATED_HARD_REG_COSTS (a);
1703 #ifdef STACK_REGS
1704 no_stack_reg_p = no_stack_reg_p || ALLOCNO_TOTAL_NO_STACK_REG_P (a);
1705 #endif
1706 cost = ALLOCNO_UPDATED_CLASS_COST (a);
1707 for (i = 0; i < class_size; i++)
1708 if (a_costs != NULL)
1710 costs[i] += a_costs[i];
1711 full_costs[i] += a_costs[i];
1713 else
1715 costs[i] += cost;
1716 full_costs[i] += cost;
1718 nwords = ALLOCNO_NUM_OBJECTS (a);
1719 curr_allocno_process++;
1720 for (word = 0; word < nwords; word++)
1722 ira_object_t conflict_obj;
1723 ira_object_t obj = ALLOCNO_OBJECT (a, word);
1724 ira_object_conflict_iterator oci;
1726 /* Take preferences of conflicting allocnos into account. */
1727 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
1729 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
1730 enum reg_class conflict_aclass;
1731 allocno_color_data_t data = ALLOCNO_COLOR_DATA (conflict_a);
1733 /* Reload can give another class so we need to check all
1734 allocnos. */
1735 if (!retry_p
1736 && ((!ALLOCNO_ASSIGNED_P (conflict_a)
1737 || ALLOCNO_HARD_REGNO (conflict_a) < 0)
1738 && !(hard_reg_set_intersect_p
1739 (profitable_hard_regs,
1740 ALLOCNO_COLOR_DATA
1741 (conflict_a)->profitable_hard_regs))))
1743 /* All conflict allocnos are in consideration bitmap
1744 when retry_p is false. It might change in future and
1745 if it happens the assert will be broken. It means
1746 the code should be modified for the new
1747 assumptions. */
1748 ira_assert (bitmap_bit_p (consideration_allocno_bitmap,
1749 ALLOCNO_NUM (conflict_a)));
1750 continue;
1752 conflict_aclass = ALLOCNO_CLASS (conflict_a);
1753 ira_assert (ira_reg_classes_intersect_p
1754 [aclass][conflict_aclass]);
1755 if (ALLOCNO_ASSIGNED_P (conflict_a))
1757 hard_regno = ALLOCNO_HARD_REGNO (conflict_a);
1758 if (hard_regno >= 0
1759 && (ira_hard_reg_set_intersection_p
1760 (hard_regno, ALLOCNO_MODE (conflict_a),
1761 reg_class_contents[aclass])))
1763 int n_objects = ALLOCNO_NUM_OBJECTS (conflict_a);
1764 int conflict_nregs;
1766 mode = ALLOCNO_MODE (conflict_a);
1767 conflict_nregs = hard_regno_nregs[hard_regno][mode];
1768 if (conflict_nregs == n_objects && conflict_nregs > 1)
1770 int num = OBJECT_SUBWORD (conflict_obj);
1772 if (REG_WORDS_BIG_ENDIAN)
1773 SET_HARD_REG_BIT (conflicting_regs[word],
1774 hard_regno + n_objects - num - 1);
1775 else
1776 SET_HARD_REG_BIT (conflicting_regs[word],
1777 hard_regno + num);
1779 else
1780 IOR_HARD_REG_SET
1781 (conflicting_regs[word],
1782 ira_reg_mode_hard_regset[hard_regno][mode]);
1783 if (hard_reg_set_subset_p (profitable_hard_regs,
1784 conflicting_regs[word]))
1785 goto fail;
1788 else if (! retry_p
1789 && ! ALLOCNO_COLOR_DATA (conflict_a)->may_be_spilled_p
1790 /* Don't process the conflict allocno twice. */
1791 && (ALLOCNO_COLOR_DATA (conflict_a)->last_process
1792 != curr_allocno_process))
1794 int k, *conflict_costs;
1796 ALLOCNO_COLOR_DATA (conflict_a)->last_process
1797 = curr_allocno_process;
1798 ira_allocate_and_copy_costs
1799 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (conflict_a),
1800 conflict_aclass,
1801 ALLOCNO_CONFLICT_HARD_REG_COSTS (conflict_a));
1802 conflict_costs
1803 = ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (conflict_a);
1804 if (conflict_costs != NULL)
1805 for (j = class_size - 1; j >= 0; j--)
1807 hard_regno = ira_class_hard_regs[aclass][j];
1808 ira_assert (hard_regno >= 0);
1809 k = ira_class_hard_reg_index[conflict_aclass][hard_regno];
1810 if (k < 0
1811 /* If HARD_REGNO is not available for CONFLICT_A,
1812 the conflict would be ignored, since HARD_REGNO
1813 will never be assigned to CONFLICT_A. */
1814 || !TEST_HARD_REG_BIT (data->profitable_hard_regs,
1815 hard_regno))
1816 continue;
1817 full_costs[j] -= conflict_costs[k];
1819 queue_update_cost (conflict_a, NULL, COST_HOP_DIVISOR);
1824 if (! retry_p)
1825 /* Take into account preferences of allocnos connected by copies to
1826 the conflict allocnos. */
1827 update_conflict_hard_regno_costs (full_costs, aclass, true);
1829 /* Take preferences of allocnos connected by copies into
1830 account. */
1831 if (! retry_p)
1833 start_update_cost ();
1834 queue_update_cost (a, NULL, COST_HOP_DIVISOR);
1835 update_conflict_hard_regno_costs (full_costs, aclass, false);
1837 min_cost = min_full_cost = INT_MAX;
1838 /* We don't care about giving callee saved registers to allocnos no
1839 living through calls because call clobbered registers are
1840 allocated first (it is usual practice to put them first in
1841 REG_ALLOC_ORDER). */
1842 mode = ALLOCNO_MODE (a);
1843 for (i = 0; i < class_size; i++)
1845 hard_regno = ira_class_hard_regs[aclass][i];
1846 #ifdef STACK_REGS
1847 if (no_stack_reg_p
1848 && FIRST_STACK_REG <= hard_regno && hard_regno <= LAST_STACK_REG)
1849 continue;
1850 #endif
1851 if (! check_hard_reg_p (a, hard_regno,
1852 conflicting_regs, profitable_hard_regs))
1853 continue;
1854 cost = costs[i];
1855 full_cost = full_costs[i];
1856 if (!HONOR_REG_ALLOC_ORDER)
1858 if ((saved_nregs = calculate_saved_nregs (hard_regno, mode)) != 0)
1859 /* We need to save/restore the hard register in
1860 epilogue/prologue. Therefore we increase the cost. */
1862 rclass = REGNO_REG_CLASS (hard_regno);
1863 add_cost = ((ira_memory_move_cost[mode][rclass][0]
1864 + ira_memory_move_cost[mode][rclass][1])
1865 * saved_nregs / hard_regno_nregs[hard_regno][mode] - 1);
1866 cost += add_cost;
1867 full_cost += add_cost;
1870 if (min_cost > cost)
1871 min_cost = cost;
1872 if (min_full_cost > full_cost)
1874 min_full_cost = full_cost;
1875 best_hard_regno = hard_regno;
1876 ira_assert (hard_regno >= 0);
1879 if (min_full_cost > mem_cost)
1881 if (! retry_p && internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
1882 fprintf (ira_dump_file, "(memory is more profitable %d vs %d) ",
1883 mem_cost, min_full_cost);
1884 best_hard_regno = -1;
1886 fail:
1887 if (best_hard_regno >= 0)
1889 for (i = hard_regno_nregs[best_hard_regno][mode] - 1; i >= 0; i--)
1890 allocated_hardreg_p[best_hard_regno + i] = true;
1892 if (! retry_p)
1893 restore_costs_from_copies (a);
1894 ALLOCNO_HARD_REGNO (a) = best_hard_regno;
1895 ALLOCNO_ASSIGNED_P (a) = true;
1896 if (best_hard_regno >= 0)
1897 update_costs_from_copies (a, true, ! retry_p);
1898 ira_assert (ALLOCNO_CLASS (a) == aclass);
1899 /* We don't need updated costs anymore. */
1900 ira_free_allocno_updated_costs (a);
1901 return best_hard_regno >= 0;
1906 /* An array used to sort copies. */
1907 static ira_copy_t *sorted_copies;
1909 /* Return TRUE if live ranges of allocnos A1 and A2 intersect. It is
1910 used to find a conflict for new allocnos or allocnos with the
1911 different allocno classes. */
1912 static bool
1913 allocnos_conflict_by_live_ranges_p (ira_allocno_t a1, ira_allocno_t a2)
1915 rtx reg1, reg2;
1916 int i, j;
1917 int n1 = ALLOCNO_NUM_OBJECTS (a1);
1918 int n2 = ALLOCNO_NUM_OBJECTS (a2);
1920 if (a1 == a2)
1921 return false;
1922 reg1 = regno_reg_rtx[ALLOCNO_REGNO (a1)];
1923 reg2 = regno_reg_rtx[ALLOCNO_REGNO (a2)];
1924 if (reg1 != NULL && reg2 != NULL
1925 && ORIGINAL_REGNO (reg1) == ORIGINAL_REGNO (reg2))
1926 return false;
1928 for (i = 0; i < n1; i++)
1930 ira_object_t c1 = ALLOCNO_OBJECT (a1, i);
1932 for (j = 0; j < n2; j++)
1934 ira_object_t c2 = ALLOCNO_OBJECT (a2, j);
1936 if (ira_live_ranges_intersect_p (OBJECT_LIVE_RANGES (c1),
1937 OBJECT_LIVE_RANGES (c2)))
1938 return true;
1941 return false;
1944 /* The function is used to sort copies according to their execution
1945 frequencies. */
1946 static int
1947 copy_freq_compare_func (const void *v1p, const void *v2p)
1949 ira_copy_t cp1 = *(const ira_copy_t *) v1p, cp2 = *(const ira_copy_t *) v2p;
1950 int pri1, pri2;
1952 pri1 = cp1->freq;
1953 pri2 = cp2->freq;
1954 if (pri2 - pri1)
1955 return pri2 - pri1;
1957 /* If frequencies are equal, sort by copies, so that the results of
1958 qsort leave nothing to chance. */
1959 return cp1->num - cp2->num;
1964 /* Return true if any allocno from thread of A1 conflicts with any
1965 allocno from thread A2. */
1966 static bool
1967 allocno_thread_conflict_p (ira_allocno_t a1, ira_allocno_t a2)
1969 ira_allocno_t a, conflict_a;
1971 for (a = ALLOCNO_COLOR_DATA (a2)->next_thread_allocno;;
1972 a = ALLOCNO_COLOR_DATA (a)->next_thread_allocno)
1974 for (conflict_a = ALLOCNO_COLOR_DATA (a1)->next_thread_allocno;;
1975 conflict_a = ALLOCNO_COLOR_DATA (conflict_a)->next_thread_allocno)
1977 if (allocnos_conflict_by_live_ranges_p (a, conflict_a))
1978 return true;
1979 if (conflict_a == a1)
1980 break;
1982 if (a == a2)
1983 break;
1985 return false;
1988 /* Merge two threads given correspondingly by their first allocnos T1
1989 and T2 (more accurately merging T2 into T1). */
1990 static void
1991 merge_threads (ira_allocno_t t1, ira_allocno_t t2)
1993 ira_allocno_t a, next, last;
1995 gcc_assert (t1 != t2
1996 && ALLOCNO_COLOR_DATA (t1)->first_thread_allocno == t1
1997 && ALLOCNO_COLOR_DATA (t2)->first_thread_allocno == t2);
1998 for (last = t2, a = ALLOCNO_COLOR_DATA (t2)->next_thread_allocno;;
1999 a = ALLOCNO_COLOR_DATA (a)->next_thread_allocno)
2001 ALLOCNO_COLOR_DATA (a)->first_thread_allocno = t1;
2002 if (a == t2)
2003 break;
2004 last = a;
2006 next = ALLOCNO_COLOR_DATA (t1)->next_thread_allocno;
2007 ALLOCNO_COLOR_DATA (t1)->next_thread_allocno = t2;
2008 ALLOCNO_COLOR_DATA (last)->next_thread_allocno = next;
2009 ALLOCNO_COLOR_DATA (t1)->thread_freq += ALLOCNO_COLOR_DATA (t2)->thread_freq;
2012 /* Create threads by processing CP_NUM copies from sorted copies. We
2013 process the most expensive copies first. */
2014 static void
2015 form_threads_from_copies (int cp_num)
2017 ira_allocno_t a, thread1, thread2;
2018 ira_copy_t cp;
2019 int i, n;
2021 qsort (sorted_copies, cp_num, sizeof (ira_copy_t), copy_freq_compare_func);
2022 /* Form threads processing copies, most frequently executed
2023 first. */
2024 for (; cp_num != 0;)
2026 for (i = 0; i < cp_num; i++)
2028 cp = sorted_copies[i];
2029 thread1 = ALLOCNO_COLOR_DATA (cp->first)->first_thread_allocno;
2030 thread2 = ALLOCNO_COLOR_DATA (cp->second)->first_thread_allocno;
2031 if (thread1 == thread2)
2032 continue;
2033 if (! allocno_thread_conflict_p (thread1, thread2))
2035 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2036 fprintf
2037 (ira_dump_file,
2038 " Forming thread by copy %d:a%dr%d-a%dr%d (freq=%d):\n",
2039 cp->num, ALLOCNO_NUM (cp->first), ALLOCNO_REGNO (cp->first),
2040 ALLOCNO_NUM (cp->second), ALLOCNO_REGNO (cp->second),
2041 cp->freq);
2042 merge_threads (thread1, thread2);
2043 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2045 thread1 = ALLOCNO_COLOR_DATA (thread1)->first_thread_allocno;
2046 fprintf (ira_dump_file, " Result (freq=%d): a%dr%d(%d)",
2047 ALLOCNO_COLOR_DATA (thread1)->thread_freq,
2048 ALLOCNO_NUM (thread1), ALLOCNO_REGNO (thread1),
2049 ALLOCNO_FREQ (thread1));
2050 for (a = ALLOCNO_COLOR_DATA (thread1)->next_thread_allocno;
2051 a != thread1;
2052 a = ALLOCNO_COLOR_DATA (a)->next_thread_allocno)
2053 fprintf (ira_dump_file, " a%dr%d(%d)",
2054 ALLOCNO_NUM (a), ALLOCNO_REGNO (a),
2055 ALLOCNO_FREQ (a));
2056 fprintf (ira_dump_file, "\n");
2058 i++;
2059 break;
2062 /* Collect the rest of copies. */
2063 for (n = 0; i < cp_num; i++)
2065 cp = sorted_copies[i];
2066 if (ALLOCNO_COLOR_DATA (cp->first)->first_thread_allocno
2067 != ALLOCNO_COLOR_DATA (cp->second)->first_thread_allocno)
2068 sorted_copies[n++] = cp;
2070 cp_num = n;
2074 /* Create threads by processing copies of all alocnos from BUCKET. We
2075 process the most expensive copies first. */
2076 static void
2077 form_threads_from_bucket (ira_allocno_t bucket)
2079 ira_allocno_t a;
2080 ira_copy_t cp, next_cp;
2081 int cp_num = 0;
2083 for (a = bucket; a != NULL; a = ALLOCNO_COLOR_DATA (a)->next_bucket_allocno)
2085 for (cp = ALLOCNO_COPIES (a); cp != NULL; cp = next_cp)
2087 if (cp->first == a)
2089 next_cp = cp->next_first_allocno_copy;
2090 sorted_copies[cp_num++] = cp;
2092 else if (cp->second == a)
2093 next_cp = cp->next_second_allocno_copy;
2094 else
2095 gcc_unreachable ();
2098 form_threads_from_copies (cp_num);
2101 /* Create threads by processing copies of colorable allocno A. We
2102 process most expensive copies first. */
2103 static void
2104 form_threads_from_colorable_allocno (ira_allocno_t a)
2106 ira_allocno_t another_a;
2107 ira_copy_t cp, next_cp;
2108 int cp_num = 0;
2110 for (cp = ALLOCNO_COPIES (a); cp != NULL; cp = next_cp)
2112 if (cp->first == a)
2114 next_cp = cp->next_first_allocno_copy;
2115 another_a = cp->second;
2117 else if (cp->second == a)
2119 next_cp = cp->next_second_allocno_copy;
2120 another_a = cp->first;
2122 else
2123 gcc_unreachable ();
2124 if ((! ALLOCNO_COLOR_DATA (another_a)->in_graph_p
2125 && !ALLOCNO_COLOR_DATA (another_a)->may_be_spilled_p)
2126 || ALLOCNO_COLOR_DATA (another_a)->colorable_p)
2127 sorted_copies[cp_num++] = cp;
2129 form_threads_from_copies (cp_num);
2132 /* Form initial threads which contain only one allocno. */
2133 static void
2134 init_allocno_threads (void)
2136 ira_allocno_t a;
2137 unsigned int j;
2138 bitmap_iterator bi;
2140 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
2142 a = ira_allocnos[j];
2143 /* Set up initial thread data: */
2144 ALLOCNO_COLOR_DATA (a)->first_thread_allocno
2145 = ALLOCNO_COLOR_DATA (a)->next_thread_allocno = a;
2146 ALLOCNO_COLOR_DATA (a)->thread_freq = ALLOCNO_FREQ (a);
2152 /* This page contains the allocator based on the Chaitin-Briggs algorithm. */
2154 /* Bucket of allocnos that can colored currently without spilling. */
2155 static ira_allocno_t colorable_allocno_bucket;
2157 /* Bucket of allocnos that might be not colored currently without
2158 spilling. */
2159 static ira_allocno_t uncolorable_allocno_bucket;
2161 /* The current number of allocnos in the uncolorable_bucket. */
2162 static int uncolorable_allocnos_num;
2164 /* Return the current spill priority of allocno A. The less the
2165 number, the more preferable the allocno for spilling. */
2166 static inline int
2167 allocno_spill_priority (ira_allocno_t a)
2169 allocno_color_data_t data = ALLOCNO_COLOR_DATA (a);
2171 return (data->temp
2172 / (ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a)
2173 * ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]
2174 + 1));
2177 /* Add allocno A to bucket *BUCKET_PTR. A should be not in a bucket
2178 before the call. */
2179 static void
2180 add_allocno_to_bucket (ira_allocno_t a, ira_allocno_t *bucket_ptr)
2182 ira_allocno_t first_a;
2183 allocno_color_data_t data;
2185 if (bucket_ptr == &uncolorable_allocno_bucket
2186 && ALLOCNO_CLASS (a) != NO_REGS)
2188 uncolorable_allocnos_num++;
2189 ira_assert (uncolorable_allocnos_num > 0);
2191 first_a = *bucket_ptr;
2192 data = ALLOCNO_COLOR_DATA (a);
2193 data->next_bucket_allocno = first_a;
2194 data->prev_bucket_allocno = NULL;
2195 if (first_a != NULL)
2196 ALLOCNO_COLOR_DATA (first_a)->prev_bucket_allocno = a;
2197 *bucket_ptr = a;
2200 /* Compare two allocnos to define which allocno should be pushed first
2201 into the coloring stack. If the return is a negative number, the
2202 allocno given by the first parameter will be pushed first. In this
2203 case such allocno has less priority than the second one and the
2204 hard register will be assigned to it after assignment to the second
2205 one. As the result of such assignment order, the second allocno
2206 has a better chance to get the best hard register. */
2207 static int
2208 bucket_allocno_compare_func (const void *v1p, const void *v2p)
2210 ira_allocno_t a1 = *(const ira_allocno_t *) v1p;
2211 ira_allocno_t a2 = *(const ira_allocno_t *) v2p;
2212 int diff, freq1, freq2, a1_num, a2_num;
2213 ira_allocno_t t1 = ALLOCNO_COLOR_DATA (a1)->first_thread_allocno;
2214 ira_allocno_t t2 = ALLOCNO_COLOR_DATA (a2)->first_thread_allocno;
2215 int cl1 = ALLOCNO_CLASS (a1), cl2 = ALLOCNO_CLASS (a2);
2217 freq1 = ALLOCNO_COLOR_DATA (t1)->thread_freq;
2218 freq2 = ALLOCNO_COLOR_DATA (t2)->thread_freq;
2219 if ((diff = freq1 - freq2) != 0)
2220 return diff;
2222 if ((diff = ALLOCNO_NUM (t2) - ALLOCNO_NUM (t1)) != 0)
2223 return diff;
2225 /* Push pseudos requiring less hard registers first. It means that
2226 we will assign pseudos requiring more hard registers first
2227 avoiding creation small holes in free hard register file into
2228 which the pseudos requiring more hard registers can not fit. */
2229 if ((diff = (ira_reg_class_max_nregs[cl1][ALLOCNO_MODE (a1)]
2230 - ira_reg_class_max_nregs[cl2][ALLOCNO_MODE (a2)])) != 0)
2231 return diff;
2233 freq1 = ALLOCNO_FREQ (a1);
2234 freq2 = ALLOCNO_FREQ (a2);
2235 if ((diff = freq1 - freq2) != 0)
2236 return diff;
2238 a1_num = ALLOCNO_COLOR_DATA (a1)->available_regs_num;
2239 a2_num = ALLOCNO_COLOR_DATA (a2)->available_regs_num;
2240 if ((diff = a2_num - a1_num) != 0)
2241 return diff;
2242 return ALLOCNO_NUM (a2) - ALLOCNO_NUM (a1);
2245 /* Sort bucket *BUCKET_PTR and return the result through
2246 BUCKET_PTR. */
2247 static void
2248 sort_bucket (ira_allocno_t *bucket_ptr,
2249 int (*compare_func) (const void *, const void *))
2251 ira_allocno_t a, head;
2252 int n;
2254 for (n = 0, a = *bucket_ptr;
2255 a != NULL;
2256 a = ALLOCNO_COLOR_DATA (a)->next_bucket_allocno)
2257 sorted_allocnos[n++] = a;
2258 if (n <= 1)
2259 return;
2260 qsort (sorted_allocnos, n, sizeof (ira_allocno_t), compare_func);
2261 head = NULL;
2262 for (n--; n >= 0; n--)
2264 a = sorted_allocnos[n];
2265 ALLOCNO_COLOR_DATA (a)->next_bucket_allocno = head;
2266 ALLOCNO_COLOR_DATA (a)->prev_bucket_allocno = NULL;
2267 if (head != NULL)
2268 ALLOCNO_COLOR_DATA (head)->prev_bucket_allocno = a;
2269 head = a;
2271 *bucket_ptr = head;
2274 /* Add ALLOCNO to colorable bucket maintaining the order according
2275 their priority. ALLOCNO should be not in a bucket before the
2276 call. */
2277 static void
2278 add_allocno_to_ordered_colorable_bucket (ira_allocno_t allocno)
2280 ira_allocno_t before, after;
2282 form_threads_from_colorable_allocno (allocno);
2283 for (before = colorable_allocno_bucket, after = NULL;
2284 before != NULL;
2285 after = before,
2286 before = ALLOCNO_COLOR_DATA (before)->next_bucket_allocno)
2287 if (bucket_allocno_compare_func (&allocno, &before) < 0)
2288 break;
2289 ALLOCNO_COLOR_DATA (allocno)->next_bucket_allocno = before;
2290 ALLOCNO_COLOR_DATA (allocno)->prev_bucket_allocno = after;
2291 if (after == NULL)
2292 colorable_allocno_bucket = allocno;
2293 else
2294 ALLOCNO_COLOR_DATA (after)->next_bucket_allocno = allocno;
2295 if (before != NULL)
2296 ALLOCNO_COLOR_DATA (before)->prev_bucket_allocno = allocno;
2299 /* Delete ALLOCNO from bucket *BUCKET_PTR. It should be there before
2300 the call. */
2301 static void
2302 delete_allocno_from_bucket (ira_allocno_t allocno, ira_allocno_t *bucket_ptr)
2304 ira_allocno_t prev_allocno, next_allocno;
2306 if (bucket_ptr == &uncolorable_allocno_bucket
2307 && ALLOCNO_CLASS (allocno) != NO_REGS)
2309 uncolorable_allocnos_num--;
2310 ira_assert (uncolorable_allocnos_num >= 0);
2312 prev_allocno = ALLOCNO_COLOR_DATA (allocno)->prev_bucket_allocno;
2313 next_allocno = ALLOCNO_COLOR_DATA (allocno)->next_bucket_allocno;
2314 if (prev_allocno != NULL)
2315 ALLOCNO_COLOR_DATA (prev_allocno)->next_bucket_allocno = next_allocno;
2316 else
2318 ira_assert (*bucket_ptr == allocno);
2319 *bucket_ptr = next_allocno;
2321 if (next_allocno != NULL)
2322 ALLOCNO_COLOR_DATA (next_allocno)->prev_bucket_allocno = prev_allocno;
2325 /* Put allocno A onto the coloring stack without removing it from its
2326 bucket. Pushing allocno to the coloring stack can result in moving
2327 conflicting allocnos from the uncolorable bucket to the colorable
2328 one. */
2329 static void
2330 push_allocno_to_stack (ira_allocno_t a)
2332 enum reg_class aclass;
2333 allocno_color_data_t data, conflict_data;
2334 int size, i, n = ALLOCNO_NUM_OBJECTS (a);
2336 data = ALLOCNO_COLOR_DATA (a);
2337 data->in_graph_p = false;
2338 allocno_stack_vec.safe_push (a);
2339 aclass = ALLOCNO_CLASS (a);
2340 if (aclass == NO_REGS)
2341 return;
2342 size = ira_reg_class_max_nregs[aclass][ALLOCNO_MODE (a)];
2343 if (n > 1)
2345 /* We will deal with the subwords individually. */
2346 gcc_assert (size == ALLOCNO_NUM_OBJECTS (a));
2347 size = 1;
2349 for (i = 0; i < n; i++)
2351 ira_object_t obj = ALLOCNO_OBJECT (a, i);
2352 ira_object_t conflict_obj;
2353 ira_object_conflict_iterator oci;
2355 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
2357 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
2359 conflict_data = ALLOCNO_COLOR_DATA (conflict_a);
2360 if (conflict_data->colorable_p
2361 || ! conflict_data->in_graph_p
2362 || ALLOCNO_ASSIGNED_P (conflict_a)
2363 || !(hard_reg_set_intersect_p
2364 (ALLOCNO_COLOR_DATA (a)->profitable_hard_regs,
2365 conflict_data->profitable_hard_regs)))
2366 continue;
2367 ira_assert (bitmap_bit_p (coloring_allocno_bitmap,
2368 ALLOCNO_NUM (conflict_a)));
2369 if (update_left_conflict_sizes_p (conflict_a, a, size))
2371 delete_allocno_from_bucket
2372 (conflict_a, &uncolorable_allocno_bucket);
2373 add_allocno_to_ordered_colorable_bucket (conflict_a);
2374 if (internal_flag_ira_verbose > 4 && ira_dump_file != NULL)
2376 fprintf (ira_dump_file, " Making");
2377 ira_print_expanded_allocno (conflict_a);
2378 fprintf (ira_dump_file, " colorable\n");
2386 /* Put ALLOCNO onto the coloring stack and remove it from its bucket.
2387 The allocno is in the colorable bucket if COLORABLE_P is TRUE. */
2388 static void
2389 remove_allocno_from_bucket_and_push (ira_allocno_t allocno, bool colorable_p)
2391 if (colorable_p)
2392 delete_allocno_from_bucket (allocno, &colorable_allocno_bucket);
2393 else
2394 delete_allocno_from_bucket (allocno, &uncolorable_allocno_bucket);
2395 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2397 fprintf (ira_dump_file, " Pushing");
2398 ira_print_expanded_allocno (allocno);
2399 if (colorable_p)
2400 fprintf (ira_dump_file, "(cost %d)\n",
2401 ALLOCNO_COLOR_DATA (allocno)->temp);
2402 else
2403 fprintf (ira_dump_file, "(potential spill: %spri=%d, cost=%d)\n",
2404 ALLOCNO_BAD_SPILL_P (allocno) ? "bad spill, " : "",
2405 allocno_spill_priority (allocno),
2406 ALLOCNO_COLOR_DATA (allocno)->temp);
2408 if (! colorable_p)
2409 ALLOCNO_COLOR_DATA (allocno)->may_be_spilled_p = true;
2410 push_allocno_to_stack (allocno);
2413 /* Put all allocnos from colorable bucket onto the coloring stack. */
2414 static void
2415 push_only_colorable (void)
2417 form_threads_from_bucket (colorable_allocno_bucket);
2418 sort_bucket (&colorable_allocno_bucket, bucket_allocno_compare_func);
2419 for (;colorable_allocno_bucket != NULL;)
2420 remove_allocno_from_bucket_and_push (colorable_allocno_bucket, true);
2423 /* Return the frequency of exit edges (if EXIT_P) or entry from/to the
2424 loop given by its LOOP_NODE. */
2426 ira_loop_edge_freq (ira_loop_tree_node_t loop_node, int regno, bool exit_p)
2428 int freq, i;
2429 edge_iterator ei;
2430 edge e;
2431 vec<edge> edges;
2433 ira_assert (current_loops != NULL && loop_node->loop != NULL
2434 && (regno < 0 || regno >= FIRST_PSEUDO_REGISTER));
2435 freq = 0;
2436 if (! exit_p)
2438 FOR_EACH_EDGE (e, ei, loop_node->loop->header->preds)
2439 if (e->src != loop_node->loop->latch
2440 && (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);
2445 else
2447 edges = get_loop_exit_edges (loop_node->loop);
2448 FOR_EACH_VEC_ELT (edges, i, e)
2449 if (regno < 0
2450 || (bitmap_bit_p (df_get_live_out (e->src), regno)
2451 && bitmap_bit_p (df_get_live_in (e->dest), regno)))
2452 freq += EDGE_FREQUENCY (e);
2453 edges.release ();
2456 return REG_FREQ_FROM_EDGE_FREQ (freq);
2459 /* Calculate and return the cost of putting allocno A into memory. */
2460 static int
2461 calculate_allocno_spill_cost (ira_allocno_t a)
2463 int regno, cost;
2464 machine_mode mode;
2465 enum reg_class rclass;
2466 ira_allocno_t parent_allocno;
2467 ira_loop_tree_node_t parent_node, loop_node;
2469 regno = ALLOCNO_REGNO (a);
2470 cost = ALLOCNO_UPDATED_MEMORY_COST (a) - ALLOCNO_UPDATED_CLASS_COST (a);
2471 if (ALLOCNO_CAP (a) != NULL)
2472 return cost;
2473 loop_node = ALLOCNO_LOOP_TREE_NODE (a);
2474 if ((parent_node = loop_node->parent) == NULL)
2475 return cost;
2476 if ((parent_allocno = parent_node->regno_allocno_map[regno]) == NULL)
2477 return cost;
2478 mode = ALLOCNO_MODE (a);
2479 rclass = ALLOCNO_CLASS (a);
2480 if (ALLOCNO_HARD_REGNO (parent_allocno) < 0)
2481 cost -= (ira_memory_move_cost[mode][rclass][0]
2482 * ira_loop_edge_freq (loop_node, regno, true)
2483 + ira_memory_move_cost[mode][rclass][1]
2484 * ira_loop_edge_freq (loop_node, regno, false));
2485 else
2487 ira_init_register_move_cost_if_necessary (mode);
2488 cost += ((ira_memory_move_cost[mode][rclass][1]
2489 * ira_loop_edge_freq (loop_node, regno, true)
2490 + ira_memory_move_cost[mode][rclass][0]
2491 * ira_loop_edge_freq (loop_node, regno, false))
2492 - (ira_register_move_cost[mode][rclass][rclass]
2493 * (ira_loop_edge_freq (loop_node, regno, false)
2494 + ira_loop_edge_freq (loop_node, regno, true))));
2496 return cost;
2499 /* Used for sorting allocnos for spilling. */
2500 static inline int
2501 allocno_spill_priority_compare (ira_allocno_t a1, ira_allocno_t a2)
2503 int pri1, pri2, diff;
2505 if (ALLOCNO_BAD_SPILL_P (a1) && ! ALLOCNO_BAD_SPILL_P (a2))
2506 return 1;
2507 if (ALLOCNO_BAD_SPILL_P (a2) && ! ALLOCNO_BAD_SPILL_P (a1))
2508 return -1;
2509 pri1 = allocno_spill_priority (a1);
2510 pri2 = allocno_spill_priority (a2);
2511 if ((diff = pri1 - pri2) != 0)
2512 return diff;
2513 if ((diff
2514 = ALLOCNO_COLOR_DATA (a1)->temp - ALLOCNO_COLOR_DATA (a2)->temp) != 0)
2515 return diff;
2516 return ALLOCNO_NUM (a1) - ALLOCNO_NUM (a2);
2519 /* Used for sorting allocnos for spilling. */
2520 static int
2521 allocno_spill_sort_compare (const void *v1p, const void *v2p)
2523 ira_allocno_t p1 = *(const ira_allocno_t *) v1p;
2524 ira_allocno_t p2 = *(const ira_allocno_t *) v2p;
2526 return allocno_spill_priority_compare (p1, p2);
2529 /* Push allocnos to the coloring stack. The order of allocnos in the
2530 stack defines the order for the subsequent coloring. */
2531 static void
2532 push_allocnos_to_stack (void)
2534 ira_allocno_t a;
2535 int cost;
2537 /* Calculate uncolorable allocno spill costs. */
2538 for (a = uncolorable_allocno_bucket;
2539 a != NULL;
2540 a = ALLOCNO_COLOR_DATA (a)->next_bucket_allocno)
2541 if (ALLOCNO_CLASS (a) != NO_REGS)
2543 cost = calculate_allocno_spill_cost (a);
2544 /* ??? Remove cost of copies between the coalesced
2545 allocnos. */
2546 ALLOCNO_COLOR_DATA (a)->temp = cost;
2548 sort_bucket (&uncolorable_allocno_bucket, allocno_spill_sort_compare);
2549 for (;;)
2551 push_only_colorable ();
2552 a = uncolorable_allocno_bucket;
2553 if (a == NULL)
2554 break;
2555 remove_allocno_from_bucket_and_push (a, false);
2557 ira_assert (colorable_allocno_bucket == NULL
2558 && uncolorable_allocno_bucket == NULL);
2559 ira_assert (uncolorable_allocnos_num == 0);
2562 /* Pop the coloring stack and assign hard registers to the popped
2563 allocnos. */
2564 static void
2565 pop_allocnos_from_stack (void)
2567 ira_allocno_t allocno;
2568 enum reg_class aclass;
2570 for (;allocno_stack_vec.length () != 0;)
2572 allocno = allocno_stack_vec.pop ();
2573 aclass = ALLOCNO_CLASS (allocno);
2574 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2576 fprintf (ira_dump_file, " Popping");
2577 ira_print_expanded_allocno (allocno);
2578 fprintf (ira_dump_file, " -- ");
2580 if (aclass == NO_REGS)
2582 ALLOCNO_HARD_REGNO (allocno) = -1;
2583 ALLOCNO_ASSIGNED_P (allocno) = true;
2584 ira_assert (ALLOCNO_UPDATED_HARD_REG_COSTS (allocno) == NULL);
2585 ira_assert
2586 (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (allocno) == NULL);
2587 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2588 fprintf (ira_dump_file, "assign memory\n");
2590 else if (assign_hard_reg (allocno, false))
2592 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2593 fprintf (ira_dump_file, "assign reg %d\n",
2594 ALLOCNO_HARD_REGNO (allocno));
2596 else if (ALLOCNO_ASSIGNED_P (allocno))
2598 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2599 fprintf (ira_dump_file, "spill%s\n",
2600 ALLOCNO_COLOR_DATA (allocno)->may_be_spilled_p
2601 ? "" : "!");
2603 ALLOCNO_COLOR_DATA (allocno)->in_graph_p = true;
2607 /* Set up number of available hard registers for allocno A. */
2608 static void
2609 setup_allocno_available_regs_num (ira_allocno_t a)
2611 int i, n, hard_regno, hard_regs_num, nwords;
2612 enum reg_class aclass;
2613 allocno_color_data_t data;
2615 aclass = ALLOCNO_CLASS (a);
2616 data = ALLOCNO_COLOR_DATA (a);
2617 data->available_regs_num = 0;
2618 if (aclass == NO_REGS)
2619 return;
2620 hard_regs_num = ira_class_hard_regs_num[aclass];
2621 nwords = ALLOCNO_NUM_OBJECTS (a);
2622 for (n = 0, i = hard_regs_num - 1; i >= 0; i--)
2624 hard_regno = ira_class_hard_regs[aclass][i];
2625 /* Checking only profitable hard regs. */
2626 if (TEST_HARD_REG_BIT (data->profitable_hard_regs, hard_regno))
2627 n++;
2629 data->available_regs_num = n;
2630 if (internal_flag_ira_verbose <= 2 || ira_dump_file == NULL)
2631 return;
2632 fprintf
2633 (ira_dump_file,
2634 " Allocno a%dr%d of %s(%d) has %d avail. regs ",
2635 ALLOCNO_NUM (a), ALLOCNO_REGNO (a),
2636 reg_class_names[aclass], ira_class_hard_regs_num[aclass], n);
2637 print_hard_reg_set (ira_dump_file, data->profitable_hard_regs, false);
2638 fprintf (ira_dump_file, ", %snode: ",
2639 hard_reg_set_equal_p (data->profitable_hard_regs,
2640 data->hard_regs_node->hard_regs->set)
2641 ? "" : "^");
2642 print_hard_reg_set (ira_dump_file,
2643 data->hard_regs_node->hard_regs->set, false);
2644 for (i = 0; i < nwords; i++)
2646 ira_object_t obj = ALLOCNO_OBJECT (a, i);
2648 if (nwords != 1)
2650 if (i != 0)
2651 fprintf (ira_dump_file, ", ");
2652 fprintf (ira_dump_file, " obj %d", i);
2654 fprintf (ira_dump_file, " (confl regs = ");
2655 print_hard_reg_set (ira_dump_file, OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
2656 false);
2657 fprintf (ira_dump_file, ")");
2659 fprintf (ira_dump_file, "\n");
2662 /* Put ALLOCNO in a bucket corresponding to its number and size of its
2663 conflicting allocnos and hard registers. */
2664 static void
2665 put_allocno_into_bucket (ira_allocno_t allocno)
2667 ALLOCNO_COLOR_DATA (allocno)->in_graph_p = true;
2668 setup_allocno_available_regs_num (allocno);
2669 if (setup_left_conflict_sizes_p (allocno))
2670 add_allocno_to_bucket (allocno, &colorable_allocno_bucket);
2671 else
2672 add_allocno_to_bucket (allocno, &uncolorable_allocno_bucket);
2675 /* Map: allocno number -> allocno priority. */
2676 static int *allocno_priorities;
2678 /* Set up priorities for N allocnos in array
2679 CONSIDERATION_ALLOCNOS. */
2680 static void
2681 setup_allocno_priorities (ira_allocno_t *consideration_allocnos, int n)
2683 int i, length, nrefs, priority, max_priority, mult;
2684 ira_allocno_t a;
2686 max_priority = 0;
2687 for (i = 0; i < n; i++)
2689 a = consideration_allocnos[i];
2690 nrefs = ALLOCNO_NREFS (a);
2691 ira_assert (nrefs >= 0);
2692 mult = floor_log2 (ALLOCNO_NREFS (a)) + 1;
2693 ira_assert (mult >= 0);
2694 allocno_priorities[ALLOCNO_NUM (a)]
2695 = priority
2696 = (mult
2697 * (ALLOCNO_MEMORY_COST (a) - ALLOCNO_CLASS_COST (a))
2698 * ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]);
2699 if (priority < 0)
2700 priority = -priority;
2701 if (max_priority < priority)
2702 max_priority = priority;
2704 mult = max_priority == 0 ? 1 : INT_MAX / max_priority;
2705 for (i = 0; i < n; i++)
2707 a = consideration_allocnos[i];
2708 length = ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a);
2709 if (ALLOCNO_NUM_OBJECTS (a) > 1)
2710 length /= ALLOCNO_NUM_OBJECTS (a);
2711 if (length <= 0)
2712 length = 1;
2713 allocno_priorities[ALLOCNO_NUM (a)]
2714 = allocno_priorities[ALLOCNO_NUM (a)] * mult / length;
2718 /* Sort allocnos according to the profit of usage of a hard register
2719 instead of memory for them. */
2720 static int
2721 allocno_cost_compare_func (const void *v1p, const void *v2p)
2723 ira_allocno_t p1 = *(const ira_allocno_t *) v1p;
2724 ira_allocno_t p2 = *(const ira_allocno_t *) v2p;
2725 int c1, c2;
2727 c1 = ALLOCNO_UPDATED_MEMORY_COST (p1) - ALLOCNO_UPDATED_CLASS_COST (p1);
2728 c2 = ALLOCNO_UPDATED_MEMORY_COST (p2) - ALLOCNO_UPDATED_CLASS_COST (p2);
2729 if (c1 - c2)
2730 return c1 - c2;
2732 /* If regs are equally good, sort by allocno numbers, so that the
2733 results of qsort leave nothing to chance. */
2734 return ALLOCNO_NUM (p1) - ALLOCNO_NUM (p2);
2737 /* We used Chaitin-Briggs coloring to assign as many pseudos as
2738 possible to hard registers. Let us try to improve allocation with
2739 cost point of view. This function improves the allocation by
2740 spilling some allocnos and assigning the freed hard registers to
2741 other allocnos if it decreases the overall allocation cost. */
2742 static void
2743 improve_allocation (void)
2745 unsigned int i;
2746 int j, k, n, hregno, conflict_hregno, base_cost, class_size, word, nwords;
2747 int check, spill_cost, min_cost, nregs, conflict_nregs, r, best;
2748 bool try_p;
2749 enum reg_class aclass;
2750 machine_mode mode;
2751 int *allocno_costs;
2752 int costs[FIRST_PSEUDO_REGISTER];
2753 HARD_REG_SET conflicting_regs[2], profitable_hard_regs;
2754 ira_allocno_t a;
2755 bitmap_iterator bi;
2757 /* Clear counts used to process conflicting allocnos only once for
2758 each allocno. */
2759 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
2760 ALLOCNO_COLOR_DATA (ira_allocnos[i])->temp = 0;
2761 check = n = 0;
2762 /* Process each allocno and try to assign a hard register to it by
2763 spilling some its conflicting allocnos. */
2764 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
2766 a = ira_allocnos[i];
2767 ALLOCNO_COLOR_DATA (a)->temp = 0;
2768 if (empty_profitable_hard_regs (a))
2769 continue;
2770 check++;
2771 aclass = ALLOCNO_CLASS (a);
2772 allocno_costs = ALLOCNO_UPDATED_HARD_REG_COSTS (a);
2773 if (allocno_costs == NULL)
2774 allocno_costs = ALLOCNO_HARD_REG_COSTS (a);
2775 if ((hregno = ALLOCNO_HARD_REGNO (a)) < 0)
2776 base_cost = ALLOCNO_UPDATED_MEMORY_COST (a);
2777 else if (allocno_costs == NULL)
2778 /* It means that assigning a hard register is not profitable
2779 (we don't waste memory for hard register costs in this
2780 case). */
2781 continue;
2782 else
2783 base_cost = allocno_costs[ira_class_hard_reg_index[aclass][hregno]];
2784 try_p = false;
2785 get_conflict_and_start_profitable_regs (a, false,
2786 conflicting_regs,
2787 &profitable_hard_regs);
2788 class_size = ira_class_hard_regs_num[aclass];
2789 /* Set up cost improvement for usage of each profitable hard
2790 register for allocno A. */
2791 for (j = 0; j < class_size; j++)
2793 hregno = ira_class_hard_regs[aclass][j];
2794 if (! check_hard_reg_p (a, hregno,
2795 conflicting_regs, profitable_hard_regs))
2796 continue;
2797 ira_assert (ira_class_hard_reg_index[aclass][hregno] == j);
2798 k = allocno_costs == NULL ? 0 : j;
2799 costs[hregno] = (allocno_costs == NULL
2800 ? ALLOCNO_UPDATED_CLASS_COST (a) : allocno_costs[k]);
2801 costs[hregno] -= base_cost;
2802 if (costs[hregno] < 0)
2803 try_p = true;
2805 if (! try_p)
2806 /* There is no chance to improve the allocation cost by
2807 assigning hard register to allocno A even without spilling
2808 conflicting allocnos. */
2809 continue;
2810 mode = ALLOCNO_MODE (a);
2811 nwords = ALLOCNO_NUM_OBJECTS (a);
2812 /* Process each allocno conflicting with A and update the cost
2813 improvement for profitable hard registers of A. To use a
2814 hard register for A we need to spill some conflicting
2815 allocnos and that creates penalty for the cost
2816 improvement. */
2817 for (word = 0; word < nwords; word++)
2819 ira_object_t conflict_obj;
2820 ira_object_t obj = ALLOCNO_OBJECT (a, word);
2821 ira_object_conflict_iterator oci;
2823 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
2825 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
2827 if (ALLOCNO_COLOR_DATA (conflict_a)->temp == check)
2828 /* We already processed this conflicting allocno
2829 because we processed earlier another object of the
2830 conflicting allocno. */
2831 continue;
2832 ALLOCNO_COLOR_DATA (conflict_a)->temp = check;
2833 if ((conflict_hregno = ALLOCNO_HARD_REGNO (conflict_a)) < 0)
2834 continue;
2835 spill_cost = ALLOCNO_UPDATED_MEMORY_COST (conflict_a);
2836 k = (ira_class_hard_reg_index
2837 [ALLOCNO_CLASS (conflict_a)][conflict_hregno]);
2838 ira_assert (k >= 0);
2839 if ((allocno_costs = ALLOCNO_UPDATED_HARD_REG_COSTS (conflict_a))
2840 != NULL)
2841 spill_cost -= allocno_costs[k];
2842 else if ((allocno_costs = ALLOCNO_HARD_REG_COSTS (conflict_a))
2843 != NULL)
2844 spill_cost -= allocno_costs[k];
2845 else
2846 spill_cost -= ALLOCNO_UPDATED_CLASS_COST (conflict_a);
2847 conflict_nregs
2848 = hard_regno_nregs[conflict_hregno][ALLOCNO_MODE (conflict_a)];
2849 for (r = conflict_hregno;
2850 r >= 0 && r + hard_regno_nregs[r][mode] > conflict_hregno;
2851 r--)
2852 if (check_hard_reg_p (a, r,
2853 conflicting_regs, profitable_hard_regs))
2854 costs[r] += spill_cost;
2855 for (r = conflict_hregno + 1;
2856 r < conflict_hregno + conflict_nregs;
2857 r++)
2858 if (check_hard_reg_p (a, r,
2859 conflicting_regs, profitable_hard_regs))
2860 costs[r] += spill_cost;
2863 min_cost = INT_MAX;
2864 best = -1;
2865 /* Now we choose hard register for A which results in highest
2866 allocation cost improvement. */
2867 for (j = 0; j < class_size; j++)
2869 hregno = ira_class_hard_regs[aclass][j];
2870 if (check_hard_reg_p (a, hregno,
2871 conflicting_regs, profitable_hard_regs)
2872 && min_cost > costs[hregno])
2874 best = hregno;
2875 min_cost = costs[hregno];
2878 if (min_cost >= 0)
2879 /* We are in a situation when assigning any hard register to A
2880 by spilling some conflicting allocnos does not improve the
2881 allocation cost. */
2882 continue;
2883 nregs = hard_regno_nregs[best][mode];
2884 /* Now spill conflicting allocnos which contain a hard register
2885 of A when we assign the best chosen hard register to it. */
2886 for (word = 0; word < nwords; word++)
2888 ira_object_t conflict_obj;
2889 ira_object_t obj = ALLOCNO_OBJECT (a, word);
2890 ira_object_conflict_iterator oci;
2892 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
2894 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
2896 if ((conflict_hregno = ALLOCNO_HARD_REGNO (conflict_a)) < 0)
2897 continue;
2898 conflict_nregs
2899 = hard_regno_nregs[conflict_hregno][ALLOCNO_MODE (conflict_a)];
2900 if (best + nregs <= conflict_hregno
2901 || conflict_hregno + conflict_nregs <= best)
2902 /* No intersection. */
2903 continue;
2904 ALLOCNO_HARD_REGNO (conflict_a) = -1;
2905 sorted_allocnos[n++] = conflict_a;
2906 if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
2907 fprintf (ira_dump_file, "Spilling a%dr%d for a%dr%d\n",
2908 ALLOCNO_NUM (conflict_a), ALLOCNO_REGNO (conflict_a),
2909 ALLOCNO_NUM (a), ALLOCNO_REGNO (a));
2912 /* Assign the best chosen hard register to A. */
2913 ALLOCNO_HARD_REGNO (a) = best;
2914 if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
2915 fprintf (ira_dump_file, "Assigning %d to a%dr%d\n",
2916 best, ALLOCNO_NUM (a), ALLOCNO_REGNO (a));
2918 if (n == 0)
2919 return;
2920 /* We spilled some allocnos to assign their hard registers to other
2921 allocnos. The spilled allocnos are now in array
2922 'sorted_allocnos'. There is still a possibility that some of the
2923 spilled allocnos can get hard registers. So let us try assign
2924 them hard registers again (just a reminder -- function
2925 'assign_hard_reg' assigns hard registers only if it is possible
2926 and profitable). We process the spilled allocnos with biggest
2927 benefit to get hard register first -- see function
2928 'allocno_cost_compare_func'. */
2929 qsort (sorted_allocnos, n, sizeof (ira_allocno_t),
2930 allocno_cost_compare_func);
2931 for (j = 0; j < n; j++)
2933 a = sorted_allocnos[j];
2934 ALLOCNO_ASSIGNED_P (a) = false;
2935 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2937 fprintf (ira_dump_file, " ");
2938 ira_print_expanded_allocno (a);
2939 fprintf (ira_dump_file, " -- ");
2941 if (assign_hard_reg (a, false))
2943 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2944 fprintf (ira_dump_file, "assign hard reg %d\n",
2945 ALLOCNO_HARD_REGNO (a));
2947 else
2949 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2950 fprintf (ira_dump_file, "assign memory\n");
2955 /* Sort allocnos according to their priorities. */
2956 static int
2957 allocno_priority_compare_func (const void *v1p, const void *v2p)
2959 ira_allocno_t a1 = *(const ira_allocno_t *) v1p;
2960 ira_allocno_t a2 = *(const ira_allocno_t *) v2p;
2961 int pri1, pri2;
2963 pri1 = allocno_priorities[ALLOCNO_NUM (a1)];
2964 pri2 = allocno_priorities[ALLOCNO_NUM (a2)];
2965 if (pri2 != pri1)
2966 return SORTGT (pri2, pri1);
2968 /* If regs are equally good, sort by allocnos, so that the results of
2969 qsort leave nothing to chance. */
2970 return ALLOCNO_NUM (a1) - ALLOCNO_NUM (a2);
2973 /* Chaitin-Briggs coloring for allocnos in COLORING_ALLOCNO_BITMAP
2974 taking into account allocnos in CONSIDERATION_ALLOCNO_BITMAP. */
2975 static void
2976 color_allocnos (void)
2978 unsigned int i, n;
2979 bitmap_iterator bi;
2980 ira_allocno_t a;
2982 setup_profitable_hard_regs ();
2983 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
2985 int l, nr;
2986 HARD_REG_SET conflict_hard_regs;
2987 allocno_color_data_t data;
2988 ira_pref_t pref, next_pref;
2990 a = ira_allocnos[i];
2991 nr = ALLOCNO_NUM_OBJECTS (a);
2992 CLEAR_HARD_REG_SET (conflict_hard_regs);
2993 for (l = 0; l < nr; l++)
2995 ira_object_t obj = ALLOCNO_OBJECT (a, l);
2996 IOR_HARD_REG_SET (conflict_hard_regs,
2997 OBJECT_CONFLICT_HARD_REGS (obj));
2999 data = ALLOCNO_COLOR_DATA (a);
3000 for (pref = ALLOCNO_PREFS (a); pref != NULL; pref = next_pref)
3002 next_pref = pref->next_pref;
3003 if (! ira_hard_reg_in_set_p (pref->hard_regno,
3004 ALLOCNO_MODE (a),
3005 data->profitable_hard_regs))
3006 ira_remove_pref (pref);
3009 if (flag_ira_algorithm == IRA_ALGORITHM_PRIORITY)
3011 n = 0;
3012 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
3014 a = ira_allocnos[i];
3015 if (ALLOCNO_CLASS (a) == NO_REGS)
3017 ALLOCNO_HARD_REGNO (a) = -1;
3018 ALLOCNO_ASSIGNED_P (a) = true;
3019 ira_assert (ALLOCNO_UPDATED_HARD_REG_COSTS (a) == NULL);
3020 ira_assert (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a) == NULL);
3021 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3023 fprintf (ira_dump_file, " Spill");
3024 ira_print_expanded_allocno (a);
3025 fprintf (ira_dump_file, "\n");
3027 continue;
3029 sorted_allocnos[n++] = a;
3031 if (n != 0)
3033 setup_allocno_priorities (sorted_allocnos, n);
3034 qsort (sorted_allocnos, n, sizeof (ira_allocno_t),
3035 allocno_priority_compare_func);
3036 for (i = 0; i < n; i++)
3038 a = sorted_allocnos[i];
3039 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3041 fprintf (ira_dump_file, " ");
3042 ira_print_expanded_allocno (a);
3043 fprintf (ira_dump_file, " -- ");
3045 if (assign_hard_reg (a, false))
3047 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3048 fprintf (ira_dump_file, "assign hard reg %d\n",
3049 ALLOCNO_HARD_REGNO (a));
3051 else
3053 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3054 fprintf (ira_dump_file, "assign memory\n");
3059 else
3061 form_allocno_hard_regs_nodes_forest ();
3062 if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
3063 print_hard_regs_forest (ira_dump_file);
3064 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
3066 a = ira_allocnos[i];
3067 if (ALLOCNO_CLASS (a) != NO_REGS && ! empty_profitable_hard_regs (a))
3069 ALLOCNO_COLOR_DATA (a)->in_graph_p = true;
3070 update_costs_from_prefs (a);
3072 else
3074 ALLOCNO_HARD_REGNO (a) = -1;
3075 ALLOCNO_ASSIGNED_P (a) = true;
3076 /* We don't need updated costs anymore. */
3077 ira_free_allocno_updated_costs (a);
3078 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3080 fprintf (ira_dump_file, " Spill");
3081 ira_print_expanded_allocno (a);
3082 fprintf (ira_dump_file, "\n");
3086 /* Put the allocnos into the corresponding buckets. */
3087 colorable_allocno_bucket = NULL;
3088 uncolorable_allocno_bucket = NULL;
3089 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
3091 a = ira_allocnos[i];
3092 if (ALLOCNO_COLOR_DATA (a)->in_graph_p)
3093 put_allocno_into_bucket (a);
3095 push_allocnos_to_stack ();
3096 pop_allocnos_from_stack ();
3097 finish_allocno_hard_regs_nodes_forest ();
3099 improve_allocation ();
3104 /* Output information about the loop given by its LOOP_TREE_NODE. */
3105 static void
3106 print_loop_title (ira_loop_tree_node_t loop_tree_node)
3108 unsigned int j;
3109 bitmap_iterator bi;
3110 ira_loop_tree_node_t subloop_node, dest_loop_node;
3111 edge e;
3112 edge_iterator ei;
3114 if (loop_tree_node->parent == NULL)
3115 fprintf (ira_dump_file,
3116 "\n Loop 0 (parent -1, header bb%d, depth 0)\n bbs:",
3117 NUM_FIXED_BLOCKS);
3118 else
3120 ira_assert (current_loops != NULL && loop_tree_node->loop != NULL);
3121 fprintf (ira_dump_file,
3122 "\n Loop %d (parent %d, header bb%d, depth %d)\n bbs:",
3123 loop_tree_node->loop_num, loop_tree_node->parent->loop_num,
3124 loop_tree_node->loop->header->index,
3125 loop_depth (loop_tree_node->loop));
3127 for (subloop_node = loop_tree_node->children;
3128 subloop_node != NULL;
3129 subloop_node = subloop_node->next)
3130 if (subloop_node->bb != NULL)
3132 fprintf (ira_dump_file, " %d", subloop_node->bb->index);
3133 FOR_EACH_EDGE (e, ei, subloop_node->bb->succs)
3134 if (e->dest != EXIT_BLOCK_PTR_FOR_FN (cfun)
3135 && ((dest_loop_node = IRA_BB_NODE (e->dest)->parent)
3136 != loop_tree_node))
3137 fprintf (ira_dump_file, "(->%d:l%d)",
3138 e->dest->index, dest_loop_node->loop_num);
3140 fprintf (ira_dump_file, "\n all:");
3141 EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->all_allocnos, 0, j, bi)
3142 fprintf (ira_dump_file, " %dr%d", j, ALLOCNO_REGNO (ira_allocnos[j]));
3143 fprintf (ira_dump_file, "\n modified regnos:");
3144 EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->modified_regnos, 0, j, bi)
3145 fprintf (ira_dump_file, " %d", j);
3146 fprintf (ira_dump_file, "\n border:");
3147 EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->border_allocnos, 0, j, bi)
3148 fprintf (ira_dump_file, " %dr%d", j, ALLOCNO_REGNO (ira_allocnos[j]));
3149 fprintf (ira_dump_file, "\n Pressure:");
3150 for (j = 0; (int) j < ira_pressure_classes_num; j++)
3152 enum reg_class pclass;
3154 pclass = ira_pressure_classes[j];
3155 if (loop_tree_node->reg_pressure[pclass] == 0)
3156 continue;
3157 fprintf (ira_dump_file, " %s=%d", reg_class_names[pclass],
3158 loop_tree_node->reg_pressure[pclass]);
3160 fprintf (ira_dump_file, "\n");
3163 /* Color the allocnos inside loop (in the extreme case it can be all
3164 of the function) given the corresponding LOOP_TREE_NODE. The
3165 function is called for each loop during top-down traverse of the
3166 loop tree. */
3167 static void
3168 color_pass (ira_loop_tree_node_t loop_tree_node)
3170 int regno, hard_regno, index = -1, n;
3171 int cost, exit_freq, enter_freq;
3172 unsigned int j;
3173 bitmap_iterator bi;
3174 machine_mode mode;
3175 enum reg_class rclass, aclass, pclass;
3176 ira_allocno_t a, subloop_allocno;
3177 ira_loop_tree_node_t subloop_node;
3179 ira_assert (loop_tree_node->bb == NULL);
3180 if (internal_flag_ira_verbose > 1 && ira_dump_file != NULL)
3181 print_loop_title (loop_tree_node);
3183 bitmap_copy (coloring_allocno_bitmap, loop_tree_node->all_allocnos);
3184 bitmap_copy (consideration_allocno_bitmap, coloring_allocno_bitmap);
3185 n = 0;
3186 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
3188 a = ira_allocnos[j];
3189 n++;
3190 if (! ALLOCNO_ASSIGNED_P (a))
3191 continue;
3192 bitmap_clear_bit (coloring_allocno_bitmap, ALLOCNO_NUM (a));
3194 allocno_color_data
3195 = (allocno_color_data_t) ira_allocate (sizeof (struct allocno_color_data)
3196 * n);
3197 memset (allocno_color_data, 0, sizeof (struct allocno_color_data) * n);
3198 curr_allocno_process = 0;
3199 n = 0;
3200 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
3202 a = ira_allocnos[j];
3203 ALLOCNO_ADD_DATA (a) = allocno_color_data + n;
3204 n++;
3206 init_allocno_threads ();
3207 /* Color all mentioned allocnos including transparent ones. */
3208 color_allocnos ();
3209 /* Process caps. They are processed just once. */
3210 if (flag_ira_region == IRA_REGION_MIXED
3211 || flag_ira_region == IRA_REGION_ALL)
3212 EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->all_allocnos, 0, j, bi)
3214 a = ira_allocnos[j];
3215 if (ALLOCNO_CAP_MEMBER (a) == NULL)
3216 continue;
3217 /* Remove from processing in the next loop. */
3218 bitmap_clear_bit (consideration_allocno_bitmap, j);
3219 rclass = ALLOCNO_CLASS (a);
3220 pclass = ira_pressure_class_translate[rclass];
3221 if (flag_ira_region == IRA_REGION_MIXED
3222 && (loop_tree_node->reg_pressure[pclass]
3223 <= ira_class_hard_regs_num[pclass]))
3225 mode = ALLOCNO_MODE (a);
3226 hard_regno = ALLOCNO_HARD_REGNO (a);
3227 if (hard_regno >= 0)
3229 index = ira_class_hard_reg_index[rclass][hard_regno];
3230 ira_assert (index >= 0);
3232 regno = ALLOCNO_REGNO (a);
3233 subloop_allocno = ALLOCNO_CAP_MEMBER (a);
3234 subloop_node = ALLOCNO_LOOP_TREE_NODE (subloop_allocno);
3235 ira_assert (!ALLOCNO_ASSIGNED_P (subloop_allocno));
3236 ALLOCNO_HARD_REGNO (subloop_allocno) = hard_regno;
3237 ALLOCNO_ASSIGNED_P (subloop_allocno) = true;
3238 if (hard_regno >= 0)
3239 update_costs_from_copies (subloop_allocno, true, true);
3240 /* We don't need updated costs anymore. */
3241 ira_free_allocno_updated_costs (subloop_allocno);
3244 /* Update costs of the corresponding allocnos (not caps) in the
3245 subloops. */
3246 for (subloop_node = loop_tree_node->subloops;
3247 subloop_node != NULL;
3248 subloop_node = subloop_node->subloop_next)
3250 ira_assert (subloop_node->bb == NULL);
3251 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
3253 a = ira_allocnos[j];
3254 ira_assert (ALLOCNO_CAP_MEMBER (a) == NULL);
3255 mode = ALLOCNO_MODE (a);
3256 rclass = ALLOCNO_CLASS (a);
3257 pclass = ira_pressure_class_translate[rclass];
3258 hard_regno = ALLOCNO_HARD_REGNO (a);
3259 /* Use hard register class here. ??? */
3260 if (hard_regno >= 0)
3262 index = ira_class_hard_reg_index[rclass][hard_regno];
3263 ira_assert (index >= 0);
3265 regno = ALLOCNO_REGNO (a);
3266 /* ??? conflict costs */
3267 subloop_allocno = subloop_node->regno_allocno_map[regno];
3268 if (subloop_allocno == NULL
3269 || ALLOCNO_CAP (subloop_allocno) != NULL)
3270 continue;
3271 ira_assert (ALLOCNO_CLASS (subloop_allocno) == rclass);
3272 ira_assert (bitmap_bit_p (subloop_node->all_allocnos,
3273 ALLOCNO_NUM (subloop_allocno)));
3274 if ((flag_ira_region == IRA_REGION_MIXED
3275 && (loop_tree_node->reg_pressure[pclass]
3276 <= ira_class_hard_regs_num[pclass]))
3277 || (pic_offset_table_rtx != NULL
3278 && regno == (int) REGNO (pic_offset_table_rtx))
3279 /* Avoid overlapped multi-registers. Moves between them
3280 might result in wrong code generation. */
3281 || (hard_regno >= 0
3282 && ira_reg_class_max_nregs[pclass][mode] > 1))
3284 if (! ALLOCNO_ASSIGNED_P (subloop_allocno))
3286 ALLOCNO_HARD_REGNO (subloop_allocno) = hard_regno;
3287 ALLOCNO_ASSIGNED_P (subloop_allocno) = true;
3288 if (hard_regno >= 0)
3289 update_costs_from_copies (subloop_allocno, true, true);
3290 /* We don't need updated costs anymore. */
3291 ira_free_allocno_updated_costs (subloop_allocno);
3293 continue;
3295 exit_freq = ira_loop_edge_freq (subloop_node, regno, true);
3296 enter_freq = ira_loop_edge_freq (subloop_node, regno, false);
3297 ira_assert (regno < ira_reg_equiv_len);
3298 if (ira_equiv_no_lvalue_p (regno))
3300 if (! ALLOCNO_ASSIGNED_P (subloop_allocno))
3302 ALLOCNO_HARD_REGNO (subloop_allocno) = hard_regno;
3303 ALLOCNO_ASSIGNED_P (subloop_allocno) = true;
3304 if (hard_regno >= 0)
3305 update_costs_from_copies (subloop_allocno, true, true);
3306 /* We don't need updated costs anymore. */
3307 ira_free_allocno_updated_costs (subloop_allocno);
3310 else if (hard_regno < 0)
3312 ALLOCNO_UPDATED_MEMORY_COST (subloop_allocno)
3313 -= ((ira_memory_move_cost[mode][rclass][1] * enter_freq)
3314 + (ira_memory_move_cost[mode][rclass][0] * exit_freq));
3316 else
3318 aclass = ALLOCNO_CLASS (subloop_allocno);
3319 ira_init_register_move_cost_if_necessary (mode);
3320 cost = (ira_register_move_cost[mode][rclass][rclass]
3321 * (exit_freq + enter_freq));
3322 ira_allocate_and_set_or_copy_costs
3323 (&ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno), aclass,
3324 ALLOCNO_UPDATED_CLASS_COST (subloop_allocno),
3325 ALLOCNO_HARD_REG_COSTS (subloop_allocno));
3326 ira_allocate_and_set_or_copy_costs
3327 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (subloop_allocno),
3328 aclass, 0, ALLOCNO_CONFLICT_HARD_REG_COSTS (subloop_allocno));
3329 ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno)[index] -= cost;
3330 ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (subloop_allocno)[index]
3331 -= cost;
3332 if (ALLOCNO_UPDATED_CLASS_COST (subloop_allocno)
3333 > ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno)[index])
3334 ALLOCNO_UPDATED_CLASS_COST (subloop_allocno)
3335 = ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno)[index];
3336 ALLOCNO_UPDATED_MEMORY_COST (subloop_allocno)
3337 += (ira_memory_move_cost[mode][rclass][0] * enter_freq
3338 + ira_memory_move_cost[mode][rclass][1] * exit_freq);
3342 ira_free (allocno_color_data);
3343 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
3345 a = ira_allocnos[j];
3346 ALLOCNO_ADD_DATA (a) = NULL;
3350 /* Initialize the common data for coloring and calls functions to do
3351 Chaitin-Briggs and regional coloring. */
3352 static void
3353 do_coloring (void)
3355 coloring_allocno_bitmap = ira_allocate_bitmap ();
3356 if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
3357 fprintf (ira_dump_file, "\n**** Allocnos coloring:\n\n");
3359 ira_traverse_loop_tree (false, ira_loop_tree_root, color_pass, NULL);
3361 if (internal_flag_ira_verbose > 1 && ira_dump_file != NULL)
3362 ira_print_disposition (ira_dump_file);
3364 ira_free_bitmap (coloring_allocno_bitmap);
3369 /* Move spill/restore code, which are to be generated in ira-emit.c,
3370 to less frequent points (if it is profitable) by reassigning some
3371 allocnos (in loop with subloops containing in another loop) to
3372 memory which results in longer live-range where the corresponding
3373 pseudo-registers will be in memory. */
3374 static void
3375 move_spill_restore (void)
3377 int cost, regno, hard_regno, hard_regno2, index;
3378 bool changed_p;
3379 int enter_freq, exit_freq;
3380 machine_mode mode;
3381 enum reg_class rclass;
3382 ira_allocno_t a, parent_allocno, subloop_allocno;
3383 ira_loop_tree_node_t parent, loop_node, subloop_node;
3384 ira_allocno_iterator ai;
3386 for (;;)
3388 changed_p = false;
3389 if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
3390 fprintf (ira_dump_file, "New iteration of spill/restore move\n");
3391 FOR_EACH_ALLOCNO (a, ai)
3393 regno = ALLOCNO_REGNO (a);
3394 loop_node = ALLOCNO_LOOP_TREE_NODE (a);
3395 if (ALLOCNO_CAP_MEMBER (a) != NULL
3396 || ALLOCNO_CAP (a) != NULL
3397 || (hard_regno = ALLOCNO_HARD_REGNO (a)) < 0
3398 || loop_node->children == NULL
3399 /* don't do the optimization because it can create
3400 copies and the reload pass can spill the allocno set
3401 by copy although the allocno will not get memory
3402 slot. */
3403 || ira_equiv_no_lvalue_p (regno)
3404 || !bitmap_bit_p (loop_node->border_allocnos, ALLOCNO_NUM (a)))
3405 continue;
3406 mode = ALLOCNO_MODE (a);
3407 rclass = ALLOCNO_CLASS (a);
3408 index = ira_class_hard_reg_index[rclass][hard_regno];
3409 ira_assert (index >= 0);
3410 cost = (ALLOCNO_MEMORY_COST (a)
3411 - (ALLOCNO_HARD_REG_COSTS (a) == NULL
3412 ? ALLOCNO_CLASS_COST (a)
3413 : ALLOCNO_HARD_REG_COSTS (a)[index]));
3414 ira_init_register_move_cost_if_necessary (mode);
3415 for (subloop_node = loop_node->subloops;
3416 subloop_node != NULL;
3417 subloop_node = subloop_node->subloop_next)
3419 ira_assert (subloop_node->bb == NULL);
3420 subloop_allocno = subloop_node->regno_allocno_map[regno];
3421 if (subloop_allocno == NULL)
3422 continue;
3423 ira_assert (rclass == ALLOCNO_CLASS (subloop_allocno));
3424 /* We have accumulated cost. To get the real cost of
3425 allocno usage in the loop we should subtract costs of
3426 the subloop allocnos. */
3427 cost -= (ALLOCNO_MEMORY_COST (subloop_allocno)
3428 - (ALLOCNO_HARD_REG_COSTS (subloop_allocno) == NULL
3429 ? ALLOCNO_CLASS_COST (subloop_allocno)
3430 : ALLOCNO_HARD_REG_COSTS (subloop_allocno)[index]));
3431 exit_freq = ira_loop_edge_freq (subloop_node, regno, true);
3432 enter_freq = ira_loop_edge_freq (subloop_node, regno, false);
3433 if ((hard_regno2 = ALLOCNO_HARD_REGNO (subloop_allocno)) < 0)
3434 cost -= (ira_memory_move_cost[mode][rclass][0] * exit_freq
3435 + ira_memory_move_cost[mode][rclass][1] * enter_freq);
3436 else
3438 cost
3439 += (ira_memory_move_cost[mode][rclass][0] * exit_freq
3440 + ira_memory_move_cost[mode][rclass][1] * enter_freq);
3441 if (hard_regno2 != hard_regno)
3442 cost -= (ira_register_move_cost[mode][rclass][rclass]
3443 * (exit_freq + enter_freq));
3446 if ((parent = loop_node->parent) != NULL
3447 && (parent_allocno = parent->regno_allocno_map[regno]) != NULL)
3449 ira_assert (rclass == ALLOCNO_CLASS (parent_allocno));
3450 exit_freq = ira_loop_edge_freq (loop_node, regno, true);
3451 enter_freq = ira_loop_edge_freq (loop_node, regno, false);
3452 if ((hard_regno2 = ALLOCNO_HARD_REGNO (parent_allocno)) < 0)
3453 cost -= (ira_memory_move_cost[mode][rclass][0] * exit_freq
3454 + ira_memory_move_cost[mode][rclass][1] * enter_freq);
3455 else
3457 cost
3458 += (ira_memory_move_cost[mode][rclass][1] * exit_freq
3459 + ira_memory_move_cost[mode][rclass][0] * enter_freq);
3460 if (hard_regno2 != hard_regno)
3461 cost -= (ira_register_move_cost[mode][rclass][rclass]
3462 * (exit_freq + enter_freq));
3465 if (cost < 0)
3467 ALLOCNO_HARD_REGNO (a) = -1;
3468 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3470 fprintf
3471 (ira_dump_file,
3472 " Moving spill/restore for a%dr%d up from loop %d",
3473 ALLOCNO_NUM (a), regno, loop_node->loop_num);
3474 fprintf (ira_dump_file, " - profit %d\n", -cost);
3476 changed_p = true;
3479 if (! changed_p)
3480 break;
3486 /* Update current hard reg costs and current conflict hard reg costs
3487 for allocno A. It is done by processing its copies containing
3488 other allocnos already assigned. */
3489 static void
3490 update_curr_costs (ira_allocno_t a)
3492 int i, hard_regno, cost;
3493 machine_mode mode;
3494 enum reg_class aclass, rclass;
3495 ira_allocno_t another_a;
3496 ira_copy_t cp, next_cp;
3498 ira_free_allocno_updated_costs (a);
3499 ira_assert (! ALLOCNO_ASSIGNED_P (a));
3500 aclass = ALLOCNO_CLASS (a);
3501 if (aclass == NO_REGS)
3502 return;
3503 mode = ALLOCNO_MODE (a);
3504 ira_init_register_move_cost_if_necessary (mode);
3505 for (cp = ALLOCNO_COPIES (a); cp != NULL; cp = next_cp)
3507 if (cp->first == a)
3509 next_cp = cp->next_first_allocno_copy;
3510 another_a = cp->second;
3512 else if (cp->second == a)
3514 next_cp = cp->next_second_allocno_copy;
3515 another_a = cp->first;
3517 else
3518 gcc_unreachable ();
3519 if (! ira_reg_classes_intersect_p[aclass][ALLOCNO_CLASS (another_a)]
3520 || ! ALLOCNO_ASSIGNED_P (another_a)
3521 || (hard_regno = ALLOCNO_HARD_REGNO (another_a)) < 0)
3522 continue;
3523 rclass = REGNO_REG_CLASS (hard_regno);
3524 i = ira_class_hard_reg_index[aclass][hard_regno];
3525 if (i < 0)
3526 continue;
3527 cost = (cp->first == a
3528 ? ira_register_move_cost[mode][rclass][aclass]
3529 : ira_register_move_cost[mode][aclass][rclass]);
3530 ira_allocate_and_set_or_copy_costs
3531 (&ALLOCNO_UPDATED_HARD_REG_COSTS (a), aclass, ALLOCNO_CLASS_COST (a),
3532 ALLOCNO_HARD_REG_COSTS (a));
3533 ira_allocate_and_set_or_copy_costs
3534 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a),
3535 aclass, 0, ALLOCNO_CONFLICT_HARD_REG_COSTS (a));
3536 ALLOCNO_UPDATED_HARD_REG_COSTS (a)[i] -= cp->freq * cost;
3537 ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a)[i] -= cp->freq * cost;
3541 /* Try to assign hard registers to the unassigned allocnos and
3542 allocnos conflicting with them or conflicting with allocnos whose
3543 regno >= START_REGNO. The function is called after ira_flattening,
3544 so more allocnos (including ones created in ira-emit.c) will have a
3545 chance to get a hard register. We use simple assignment algorithm
3546 based on priorities. */
3547 void
3548 ira_reassign_conflict_allocnos (int start_regno)
3550 int i, allocnos_to_color_num;
3551 ira_allocno_t a;
3552 enum reg_class aclass;
3553 bitmap allocnos_to_color;
3554 ira_allocno_iterator ai;
3556 allocnos_to_color = ira_allocate_bitmap ();
3557 allocnos_to_color_num = 0;
3558 FOR_EACH_ALLOCNO (a, ai)
3560 int n = ALLOCNO_NUM_OBJECTS (a);
3562 if (! ALLOCNO_ASSIGNED_P (a)
3563 && ! bitmap_bit_p (allocnos_to_color, ALLOCNO_NUM (a)))
3565 if (ALLOCNO_CLASS (a) != NO_REGS)
3566 sorted_allocnos[allocnos_to_color_num++] = a;
3567 else
3569 ALLOCNO_ASSIGNED_P (a) = true;
3570 ALLOCNO_HARD_REGNO (a) = -1;
3571 ira_assert (ALLOCNO_UPDATED_HARD_REG_COSTS (a) == NULL);
3572 ira_assert (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a) == NULL);
3574 bitmap_set_bit (allocnos_to_color, ALLOCNO_NUM (a));
3576 if (ALLOCNO_REGNO (a) < start_regno
3577 || (aclass = ALLOCNO_CLASS (a)) == NO_REGS)
3578 continue;
3579 for (i = 0; i < n; i++)
3581 ira_object_t obj = ALLOCNO_OBJECT (a, i);
3582 ira_object_t conflict_obj;
3583 ira_object_conflict_iterator oci;
3585 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
3587 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
3589 ira_assert (ira_reg_classes_intersect_p
3590 [aclass][ALLOCNO_CLASS (conflict_a)]);
3591 if (!bitmap_set_bit (allocnos_to_color, ALLOCNO_NUM (conflict_a)))
3592 continue;
3593 sorted_allocnos[allocnos_to_color_num++] = conflict_a;
3597 ira_free_bitmap (allocnos_to_color);
3598 if (allocnos_to_color_num > 1)
3600 setup_allocno_priorities (sorted_allocnos, allocnos_to_color_num);
3601 qsort (sorted_allocnos, allocnos_to_color_num, sizeof (ira_allocno_t),
3602 allocno_priority_compare_func);
3604 for (i = 0; i < allocnos_to_color_num; i++)
3606 a = sorted_allocnos[i];
3607 ALLOCNO_ASSIGNED_P (a) = false;
3608 update_curr_costs (a);
3610 for (i = 0; i < allocnos_to_color_num; i++)
3612 a = sorted_allocnos[i];
3613 if (assign_hard_reg (a, true))
3615 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3616 fprintf
3617 (ira_dump_file,
3618 " Secondary allocation: assign hard reg %d to reg %d\n",
3619 ALLOCNO_HARD_REGNO (a), ALLOCNO_REGNO (a));
3626 /* This page contains functions used to find conflicts using allocno
3627 live ranges. */
3629 #ifdef ENABLE_IRA_CHECKING
3631 /* Return TRUE if live ranges of pseudo-registers REGNO1 and REGNO2
3632 intersect. This should be used when there is only one region.
3633 Currently this is used during reload. */
3634 static bool
3635 conflict_by_live_ranges_p (int regno1, int regno2)
3637 ira_allocno_t a1, a2;
3639 ira_assert (regno1 >= FIRST_PSEUDO_REGISTER
3640 && regno2 >= FIRST_PSEUDO_REGISTER);
3641 /* Reg info calculated by dataflow infrastructure can be different
3642 from one calculated by regclass. */
3643 if ((a1 = ira_loop_tree_root->regno_allocno_map[regno1]) == NULL
3644 || (a2 = ira_loop_tree_root->regno_allocno_map[regno2]) == NULL)
3645 return false;
3646 return allocnos_conflict_by_live_ranges_p (a1, a2);
3649 #endif
3653 /* This page contains code to coalesce memory stack slots used by
3654 spilled allocnos. This results in smaller stack frame, better data
3655 locality, and in smaller code for some architectures like
3656 x86/x86_64 where insn size depends on address displacement value.
3657 On the other hand, it can worsen insn scheduling after the RA but
3658 in practice it is less important than smaller stack frames. */
3660 /* TRUE if we coalesced some allocnos. In other words, if we got
3661 loops formed by members first_coalesced_allocno and
3662 next_coalesced_allocno containing more one allocno. */
3663 static bool allocno_coalesced_p;
3665 /* Bitmap used to prevent a repeated allocno processing because of
3666 coalescing. */
3667 static bitmap processed_coalesced_allocno_bitmap;
3669 /* See below. */
3670 typedef struct coalesce_data *coalesce_data_t;
3672 /* To decrease footprint of ira_allocno structure we store all data
3673 needed only for coalescing in the following structure. */
3674 struct coalesce_data
3676 /* Coalesced allocnos form a cyclic list. One allocno given by
3677 FIRST represents all coalesced allocnos. The
3678 list is chained by NEXT. */
3679 ira_allocno_t first;
3680 ira_allocno_t next;
3681 int temp;
3684 /* Container for storing allocno data concerning coalescing. */
3685 static coalesce_data_t allocno_coalesce_data;
3687 /* Macro to access the data concerning coalescing. */
3688 #define ALLOCNO_COALESCE_DATA(a) ((coalesce_data_t) ALLOCNO_ADD_DATA (a))
3690 /* Merge two sets of coalesced allocnos given correspondingly by
3691 allocnos A1 and A2 (more accurately merging A2 set into A1
3692 set). */
3693 static void
3694 merge_allocnos (ira_allocno_t a1, ira_allocno_t a2)
3696 ira_allocno_t a, first, last, next;
3698 first = ALLOCNO_COALESCE_DATA (a1)->first;
3699 a = ALLOCNO_COALESCE_DATA (a2)->first;
3700 if (first == a)
3701 return;
3702 for (last = a2, a = ALLOCNO_COALESCE_DATA (a2)->next;;
3703 a = ALLOCNO_COALESCE_DATA (a)->next)
3705 ALLOCNO_COALESCE_DATA (a)->first = first;
3706 if (a == a2)
3707 break;
3708 last = a;
3710 next = allocno_coalesce_data[ALLOCNO_NUM (first)].next;
3711 allocno_coalesce_data[ALLOCNO_NUM (first)].next = a2;
3712 allocno_coalesce_data[ALLOCNO_NUM (last)].next = next;
3715 /* Return TRUE if there are conflicting allocnos from two sets of
3716 coalesced allocnos given correspondingly by allocnos A1 and A2. We
3717 use live ranges to find conflicts because conflicts are represented
3718 only for allocnos of the same allocno class and during the reload
3719 pass we coalesce allocnos for sharing stack memory slots. */
3720 static bool
3721 coalesced_allocno_conflict_p (ira_allocno_t a1, ira_allocno_t a2)
3723 ira_allocno_t a, conflict_a;
3725 if (allocno_coalesced_p)
3727 bitmap_clear (processed_coalesced_allocno_bitmap);
3728 for (a = ALLOCNO_COALESCE_DATA (a1)->next;;
3729 a = ALLOCNO_COALESCE_DATA (a)->next)
3731 bitmap_set_bit (processed_coalesced_allocno_bitmap, ALLOCNO_NUM (a));
3732 if (a == a1)
3733 break;
3736 for (a = ALLOCNO_COALESCE_DATA (a2)->next;;
3737 a = ALLOCNO_COALESCE_DATA (a)->next)
3739 for (conflict_a = ALLOCNO_COALESCE_DATA (a1)->next;;
3740 conflict_a = ALLOCNO_COALESCE_DATA (conflict_a)->next)
3742 if (allocnos_conflict_by_live_ranges_p (a, conflict_a))
3743 return true;
3744 if (conflict_a == a1)
3745 break;
3747 if (a == a2)
3748 break;
3750 return false;
3753 /* The major function for aggressive allocno coalescing. We coalesce
3754 only spilled allocnos. If some allocnos have been coalesced, we
3755 set up flag allocno_coalesced_p. */
3756 static void
3757 coalesce_allocnos (void)
3759 ira_allocno_t a;
3760 ira_copy_t cp, next_cp;
3761 unsigned int j;
3762 int i, n, cp_num, regno;
3763 bitmap_iterator bi;
3765 cp_num = 0;
3766 /* Collect copies. */
3767 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, j, bi)
3769 a = ira_allocnos[j];
3770 regno = ALLOCNO_REGNO (a);
3771 if (! ALLOCNO_ASSIGNED_P (a) || ALLOCNO_HARD_REGNO (a) >= 0
3772 || ira_equiv_no_lvalue_p (regno))
3773 continue;
3774 for (cp = ALLOCNO_COPIES (a); cp != NULL; cp = next_cp)
3776 if (cp->first == a)
3778 next_cp = cp->next_first_allocno_copy;
3779 regno = ALLOCNO_REGNO (cp->second);
3780 /* For priority coloring we coalesce allocnos only with
3781 the same allocno class not with intersected allocno
3782 classes as it were possible. It is done for
3783 simplicity. */
3784 if ((cp->insn != NULL || cp->constraint_p)
3785 && ALLOCNO_ASSIGNED_P (cp->second)
3786 && ALLOCNO_HARD_REGNO (cp->second) < 0
3787 && ! ira_equiv_no_lvalue_p (regno))
3788 sorted_copies[cp_num++] = cp;
3790 else if (cp->second == a)
3791 next_cp = cp->next_second_allocno_copy;
3792 else
3793 gcc_unreachable ();
3796 qsort (sorted_copies, cp_num, sizeof (ira_copy_t), copy_freq_compare_func);
3797 /* Coalesced copies, most frequently executed first. */
3798 for (; cp_num != 0;)
3800 for (i = 0; i < cp_num; i++)
3802 cp = sorted_copies[i];
3803 if (! coalesced_allocno_conflict_p (cp->first, cp->second))
3805 allocno_coalesced_p = true;
3806 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3807 fprintf
3808 (ira_dump_file,
3809 " Coalescing copy %d:a%dr%d-a%dr%d (freq=%d)\n",
3810 cp->num, ALLOCNO_NUM (cp->first), ALLOCNO_REGNO (cp->first),
3811 ALLOCNO_NUM (cp->second), ALLOCNO_REGNO (cp->second),
3812 cp->freq);
3813 merge_allocnos (cp->first, cp->second);
3814 i++;
3815 break;
3818 /* Collect the rest of copies. */
3819 for (n = 0; i < cp_num; i++)
3821 cp = sorted_copies[i];
3822 if (allocno_coalesce_data[ALLOCNO_NUM (cp->first)].first
3823 != allocno_coalesce_data[ALLOCNO_NUM (cp->second)].first)
3824 sorted_copies[n++] = cp;
3826 cp_num = n;
3830 /* Usage cost and order number of coalesced allocno set to which
3831 given pseudo register belongs to. */
3832 static int *regno_coalesced_allocno_cost;
3833 static int *regno_coalesced_allocno_num;
3835 /* Sort pseudos according frequencies of coalesced allocno sets they
3836 belong to (putting most frequently ones first), and according to
3837 coalesced allocno set order numbers. */
3838 static int
3839 coalesced_pseudo_reg_freq_compare (const void *v1p, const void *v2p)
3841 const int regno1 = *(const int *) v1p;
3842 const int regno2 = *(const int *) v2p;
3843 int diff;
3845 if ((diff = (regno_coalesced_allocno_cost[regno2]
3846 - regno_coalesced_allocno_cost[regno1])) != 0)
3847 return diff;
3848 if ((diff = (regno_coalesced_allocno_num[regno1]
3849 - regno_coalesced_allocno_num[regno2])) != 0)
3850 return diff;
3851 return regno1 - regno2;
3854 /* Widest width in which each pseudo reg is referred to (via subreg).
3855 It is used for sorting pseudo registers. */
3856 static unsigned int *regno_max_ref_width;
3858 /* Sort pseudos according their slot numbers (putting ones with
3859 smaller numbers first, or last when the frame pointer is not
3860 needed). */
3861 static int
3862 coalesced_pseudo_reg_slot_compare (const void *v1p, const void *v2p)
3864 const int regno1 = *(const int *) v1p;
3865 const int regno2 = *(const int *) v2p;
3866 ira_allocno_t a1 = ira_regno_allocno_map[regno1];
3867 ira_allocno_t a2 = ira_regno_allocno_map[regno2];
3868 int diff, slot_num1, slot_num2;
3869 int total_size1, total_size2;
3871 if (a1 == NULL || ALLOCNO_HARD_REGNO (a1) >= 0)
3873 if (a2 == NULL || ALLOCNO_HARD_REGNO (a2) >= 0)
3874 return regno1 - regno2;
3875 return 1;
3877 else if (a2 == NULL || ALLOCNO_HARD_REGNO (a2) >= 0)
3878 return -1;
3879 slot_num1 = -ALLOCNO_HARD_REGNO (a1);
3880 slot_num2 = -ALLOCNO_HARD_REGNO (a2);
3881 if ((diff = slot_num1 - slot_num2) != 0)
3882 return (frame_pointer_needed
3883 || (!FRAME_GROWS_DOWNWARD) == STACK_GROWS_DOWNWARD ? diff : -diff);
3884 total_size1 = MAX (PSEUDO_REGNO_BYTES (regno1),
3885 regno_max_ref_width[regno1]);
3886 total_size2 = MAX (PSEUDO_REGNO_BYTES (regno2),
3887 regno_max_ref_width[regno2]);
3888 if ((diff = total_size2 - total_size1) != 0)
3889 return diff;
3890 return regno1 - regno2;
3893 /* Setup REGNO_COALESCED_ALLOCNO_COST and REGNO_COALESCED_ALLOCNO_NUM
3894 for coalesced allocno sets containing allocnos with their regnos
3895 given in array PSEUDO_REGNOS of length N. */
3896 static void
3897 setup_coalesced_allocno_costs_and_nums (int *pseudo_regnos, int n)
3899 int i, num, regno, cost;
3900 ira_allocno_t allocno, a;
3902 for (num = i = 0; i < n; i++)
3904 regno = pseudo_regnos[i];
3905 allocno = ira_regno_allocno_map[regno];
3906 if (allocno == NULL)
3908 regno_coalesced_allocno_cost[regno] = 0;
3909 regno_coalesced_allocno_num[regno] = ++num;
3910 continue;
3912 if (ALLOCNO_COALESCE_DATA (allocno)->first != allocno)
3913 continue;
3914 num++;
3915 for (cost = 0, a = ALLOCNO_COALESCE_DATA (allocno)->next;;
3916 a = ALLOCNO_COALESCE_DATA (a)->next)
3918 cost += ALLOCNO_FREQ (a);
3919 if (a == allocno)
3920 break;
3922 for (a = ALLOCNO_COALESCE_DATA (allocno)->next;;
3923 a = ALLOCNO_COALESCE_DATA (a)->next)
3925 regno_coalesced_allocno_num[ALLOCNO_REGNO (a)] = num;
3926 regno_coalesced_allocno_cost[ALLOCNO_REGNO (a)] = cost;
3927 if (a == allocno)
3928 break;
3933 /* Collect spilled allocnos representing coalesced allocno sets (the
3934 first coalesced allocno). The collected allocnos are returned
3935 through array SPILLED_COALESCED_ALLOCNOS. The function returns the
3936 number of the collected allocnos. The allocnos are given by their
3937 regnos in array PSEUDO_REGNOS of length N. */
3938 static int
3939 collect_spilled_coalesced_allocnos (int *pseudo_regnos, int n,
3940 ira_allocno_t *spilled_coalesced_allocnos)
3942 int i, num, regno;
3943 ira_allocno_t allocno;
3945 for (num = i = 0; i < n; i++)
3947 regno = pseudo_regnos[i];
3948 allocno = ira_regno_allocno_map[regno];
3949 if (allocno == NULL || ALLOCNO_HARD_REGNO (allocno) >= 0
3950 || ALLOCNO_COALESCE_DATA (allocno)->first != allocno)
3951 continue;
3952 spilled_coalesced_allocnos[num++] = allocno;
3954 return num;
3957 /* Array of live ranges of size IRA_ALLOCNOS_NUM. Live range for
3958 given slot contains live ranges of coalesced allocnos assigned to
3959 given slot. */
3960 static live_range_t *slot_coalesced_allocnos_live_ranges;
3962 /* Return TRUE if coalesced allocnos represented by ALLOCNO has live
3963 ranges intersected with live ranges of coalesced allocnos assigned
3964 to slot with number N. */
3965 static bool
3966 slot_coalesced_allocno_live_ranges_intersect_p (ira_allocno_t allocno, int n)
3968 ira_allocno_t a;
3970 for (a = ALLOCNO_COALESCE_DATA (allocno)->next;;
3971 a = ALLOCNO_COALESCE_DATA (a)->next)
3973 int i;
3974 int nr = ALLOCNO_NUM_OBJECTS (a);
3976 for (i = 0; i < nr; i++)
3978 ira_object_t obj = ALLOCNO_OBJECT (a, i);
3980 if (ira_live_ranges_intersect_p
3981 (slot_coalesced_allocnos_live_ranges[n],
3982 OBJECT_LIVE_RANGES (obj)))
3983 return true;
3985 if (a == allocno)
3986 break;
3988 return false;
3991 /* Update live ranges of slot to which coalesced allocnos represented
3992 by ALLOCNO were assigned. */
3993 static void
3994 setup_slot_coalesced_allocno_live_ranges (ira_allocno_t allocno)
3996 int i, n;
3997 ira_allocno_t a;
3998 live_range_t r;
4000 n = ALLOCNO_COALESCE_DATA (allocno)->temp;
4001 for (a = ALLOCNO_COALESCE_DATA (allocno)->next;;
4002 a = ALLOCNO_COALESCE_DATA (a)->next)
4004 int nr = ALLOCNO_NUM_OBJECTS (a);
4005 for (i = 0; i < nr; i++)
4007 ira_object_t obj = ALLOCNO_OBJECT (a, i);
4009 r = ira_copy_live_range_list (OBJECT_LIVE_RANGES (obj));
4010 slot_coalesced_allocnos_live_ranges[n]
4011 = ira_merge_live_ranges
4012 (slot_coalesced_allocnos_live_ranges[n], r);
4014 if (a == allocno)
4015 break;
4019 /* We have coalesced allocnos involving in copies. Coalesce allocnos
4020 further in order to share the same memory stack slot. Allocnos
4021 representing sets of allocnos coalesced before the call are given
4022 in array SPILLED_COALESCED_ALLOCNOS of length NUM. Return TRUE if
4023 some allocnos were coalesced in the function. */
4024 static bool
4025 coalesce_spill_slots (ira_allocno_t *spilled_coalesced_allocnos, int num)
4027 int i, j, n, last_coalesced_allocno_num;
4028 ira_allocno_t allocno, a;
4029 bool merged_p = false;
4030 bitmap set_jump_crosses = regstat_get_setjmp_crosses ();
4032 slot_coalesced_allocnos_live_ranges
4033 = (live_range_t *) ira_allocate (sizeof (live_range_t) * ira_allocnos_num);
4034 memset (slot_coalesced_allocnos_live_ranges, 0,
4035 sizeof (live_range_t) * ira_allocnos_num);
4036 last_coalesced_allocno_num = 0;
4037 /* Coalesce non-conflicting spilled allocnos preferring most
4038 frequently used. */
4039 for (i = 0; i < num; i++)
4041 allocno = spilled_coalesced_allocnos[i];
4042 if (ALLOCNO_COALESCE_DATA (allocno)->first != allocno
4043 || bitmap_bit_p (set_jump_crosses, ALLOCNO_REGNO (allocno))
4044 || ira_equiv_no_lvalue_p (ALLOCNO_REGNO (allocno)))
4045 continue;
4046 for (j = 0; j < i; j++)
4048 a = spilled_coalesced_allocnos[j];
4049 n = ALLOCNO_COALESCE_DATA (a)->temp;
4050 if (ALLOCNO_COALESCE_DATA (a)->first == a
4051 && ! bitmap_bit_p (set_jump_crosses, ALLOCNO_REGNO (a))
4052 && ! ira_equiv_no_lvalue_p (ALLOCNO_REGNO (a))
4053 && ! slot_coalesced_allocno_live_ranges_intersect_p (allocno, n))
4054 break;
4056 if (j >= i)
4058 /* No coalescing: set up number for coalesced allocnos
4059 represented by ALLOCNO. */
4060 ALLOCNO_COALESCE_DATA (allocno)->temp = last_coalesced_allocno_num++;
4061 setup_slot_coalesced_allocno_live_ranges (allocno);
4063 else
4065 allocno_coalesced_p = true;
4066 merged_p = true;
4067 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4068 fprintf (ira_dump_file,
4069 " Coalescing spilled allocnos a%dr%d->a%dr%d\n",
4070 ALLOCNO_NUM (allocno), ALLOCNO_REGNO (allocno),
4071 ALLOCNO_NUM (a), ALLOCNO_REGNO (a));
4072 ALLOCNO_COALESCE_DATA (allocno)->temp
4073 = ALLOCNO_COALESCE_DATA (a)->temp;
4074 setup_slot_coalesced_allocno_live_ranges (allocno);
4075 merge_allocnos (a, allocno);
4076 ira_assert (ALLOCNO_COALESCE_DATA (a)->first == a);
4079 for (i = 0; i < ira_allocnos_num; i++)
4080 ira_finish_live_range_list (slot_coalesced_allocnos_live_ranges[i]);
4081 ira_free (slot_coalesced_allocnos_live_ranges);
4082 return merged_p;
4085 /* Sort pseudo-register numbers in array PSEUDO_REGNOS of length N for
4086 subsequent assigning stack slots to them in the reload pass. To do
4087 this we coalesce spilled allocnos first to decrease the number of
4088 memory-memory move insns. This function is called by the
4089 reload. */
4090 void
4091 ira_sort_regnos_for_alter_reg (int *pseudo_regnos, int n,
4092 unsigned int *reg_max_ref_width)
4094 int max_regno = max_reg_num ();
4095 int i, regno, num, slot_num;
4096 ira_allocno_t allocno, a;
4097 ira_allocno_iterator ai;
4098 ira_allocno_t *spilled_coalesced_allocnos;
4100 ira_assert (! ira_use_lra_p);
4102 /* Set up allocnos can be coalesced. */
4103 coloring_allocno_bitmap = ira_allocate_bitmap ();
4104 for (i = 0; i < n; i++)
4106 regno = pseudo_regnos[i];
4107 allocno = ira_regno_allocno_map[regno];
4108 if (allocno != NULL)
4109 bitmap_set_bit (coloring_allocno_bitmap, ALLOCNO_NUM (allocno));
4111 allocno_coalesced_p = false;
4112 processed_coalesced_allocno_bitmap = ira_allocate_bitmap ();
4113 allocno_coalesce_data
4114 = (coalesce_data_t) ira_allocate (sizeof (struct coalesce_data)
4115 * ira_allocnos_num);
4116 /* Initialize coalesce data for allocnos. */
4117 FOR_EACH_ALLOCNO (a, ai)
4119 ALLOCNO_ADD_DATA (a) = allocno_coalesce_data + ALLOCNO_NUM (a);
4120 ALLOCNO_COALESCE_DATA (a)->first = a;
4121 ALLOCNO_COALESCE_DATA (a)->next = a;
4123 coalesce_allocnos ();
4124 ira_free_bitmap (coloring_allocno_bitmap);
4125 regno_coalesced_allocno_cost
4126 = (int *) ira_allocate (max_regno * sizeof (int));
4127 regno_coalesced_allocno_num
4128 = (int *) ira_allocate (max_regno * sizeof (int));
4129 memset (regno_coalesced_allocno_num, 0, max_regno * sizeof (int));
4130 setup_coalesced_allocno_costs_and_nums (pseudo_regnos, n);
4131 /* Sort regnos according frequencies of the corresponding coalesced
4132 allocno sets. */
4133 qsort (pseudo_regnos, n, sizeof (int), coalesced_pseudo_reg_freq_compare);
4134 spilled_coalesced_allocnos
4135 = (ira_allocno_t *) ira_allocate (ira_allocnos_num
4136 * sizeof (ira_allocno_t));
4137 /* Collect allocnos representing the spilled coalesced allocno
4138 sets. */
4139 num = collect_spilled_coalesced_allocnos (pseudo_regnos, n,
4140 spilled_coalesced_allocnos);
4141 if (flag_ira_share_spill_slots
4142 && coalesce_spill_slots (spilled_coalesced_allocnos, num))
4144 setup_coalesced_allocno_costs_and_nums (pseudo_regnos, n);
4145 qsort (pseudo_regnos, n, sizeof (int),
4146 coalesced_pseudo_reg_freq_compare);
4147 num = collect_spilled_coalesced_allocnos (pseudo_regnos, n,
4148 spilled_coalesced_allocnos);
4150 ira_free_bitmap (processed_coalesced_allocno_bitmap);
4151 allocno_coalesced_p = false;
4152 /* Assign stack slot numbers to spilled allocno sets, use smaller
4153 numbers for most frequently used coalesced allocnos. -1 is
4154 reserved for dynamic search of stack slots for pseudos spilled by
4155 the reload. */
4156 slot_num = 1;
4157 for (i = 0; i < num; i++)
4159 allocno = spilled_coalesced_allocnos[i];
4160 if (ALLOCNO_COALESCE_DATA (allocno)->first != allocno
4161 || ALLOCNO_HARD_REGNO (allocno) >= 0
4162 || ira_equiv_no_lvalue_p (ALLOCNO_REGNO (allocno)))
4163 continue;
4164 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4165 fprintf (ira_dump_file, " Slot %d (freq,size):", slot_num);
4166 slot_num++;
4167 for (a = ALLOCNO_COALESCE_DATA (allocno)->next;;
4168 a = ALLOCNO_COALESCE_DATA (a)->next)
4170 ira_assert (ALLOCNO_HARD_REGNO (a) < 0);
4171 ALLOCNO_HARD_REGNO (a) = -slot_num;
4172 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4173 fprintf (ira_dump_file, " a%dr%d(%d,%d)",
4174 ALLOCNO_NUM (a), ALLOCNO_REGNO (a), ALLOCNO_FREQ (a),
4175 MAX (PSEUDO_REGNO_BYTES (ALLOCNO_REGNO (a)),
4176 reg_max_ref_width[ALLOCNO_REGNO (a)]));
4178 if (a == allocno)
4179 break;
4181 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4182 fprintf (ira_dump_file, "\n");
4184 ira_spilled_reg_stack_slots_num = slot_num - 1;
4185 ira_free (spilled_coalesced_allocnos);
4186 /* Sort regnos according the slot numbers. */
4187 regno_max_ref_width = reg_max_ref_width;
4188 qsort (pseudo_regnos, n, sizeof (int), coalesced_pseudo_reg_slot_compare);
4189 FOR_EACH_ALLOCNO (a, ai)
4190 ALLOCNO_ADD_DATA (a) = NULL;
4191 ira_free (allocno_coalesce_data);
4192 ira_free (regno_coalesced_allocno_num);
4193 ira_free (regno_coalesced_allocno_cost);
4198 /* This page contains code used by the reload pass to improve the
4199 final code. */
4201 /* The function is called from reload to mark changes in the
4202 allocation of REGNO made by the reload. Remember that reg_renumber
4203 reflects the change result. */
4204 void
4205 ira_mark_allocation_change (int regno)
4207 ira_allocno_t a = ira_regno_allocno_map[regno];
4208 int old_hard_regno, hard_regno, cost;
4209 enum reg_class aclass = ALLOCNO_CLASS (a);
4211 ira_assert (a != NULL);
4212 hard_regno = reg_renumber[regno];
4213 if ((old_hard_regno = ALLOCNO_HARD_REGNO (a)) == hard_regno)
4214 return;
4215 if (old_hard_regno < 0)
4216 cost = -ALLOCNO_MEMORY_COST (a);
4217 else
4219 ira_assert (ira_class_hard_reg_index[aclass][old_hard_regno] >= 0);
4220 cost = -(ALLOCNO_HARD_REG_COSTS (a) == NULL
4221 ? ALLOCNO_CLASS_COST (a)
4222 : ALLOCNO_HARD_REG_COSTS (a)
4223 [ira_class_hard_reg_index[aclass][old_hard_regno]]);
4224 update_costs_from_copies (a, false, false);
4226 ira_overall_cost -= cost;
4227 ALLOCNO_HARD_REGNO (a) = hard_regno;
4228 if (hard_regno < 0)
4230 ALLOCNO_HARD_REGNO (a) = -1;
4231 cost += ALLOCNO_MEMORY_COST (a);
4233 else if (ira_class_hard_reg_index[aclass][hard_regno] >= 0)
4235 cost += (ALLOCNO_HARD_REG_COSTS (a) == NULL
4236 ? ALLOCNO_CLASS_COST (a)
4237 : ALLOCNO_HARD_REG_COSTS (a)
4238 [ira_class_hard_reg_index[aclass][hard_regno]]);
4239 update_costs_from_copies (a, true, false);
4241 else
4242 /* Reload changed class of the allocno. */
4243 cost = 0;
4244 ira_overall_cost += cost;
4247 /* This function is called when reload deletes memory-memory move. In
4248 this case we marks that the allocation of the corresponding
4249 allocnos should be not changed in future. Otherwise we risk to get
4250 a wrong code. */
4251 void
4252 ira_mark_memory_move_deletion (int dst_regno, int src_regno)
4254 ira_allocno_t dst = ira_regno_allocno_map[dst_regno];
4255 ira_allocno_t src = ira_regno_allocno_map[src_regno];
4257 ira_assert (dst != NULL && src != NULL
4258 && ALLOCNO_HARD_REGNO (dst) < 0
4259 && ALLOCNO_HARD_REGNO (src) < 0);
4260 ALLOCNO_DONT_REASSIGN_P (dst) = true;
4261 ALLOCNO_DONT_REASSIGN_P (src) = true;
4264 /* Try to assign a hard register (except for FORBIDDEN_REGS) to
4265 allocno A and return TRUE in the case of success. */
4266 static bool
4267 allocno_reload_assign (ira_allocno_t a, HARD_REG_SET forbidden_regs)
4269 int hard_regno;
4270 enum reg_class aclass;
4271 int regno = ALLOCNO_REGNO (a);
4272 HARD_REG_SET saved[2];
4273 int i, n;
4275 n = ALLOCNO_NUM_OBJECTS (a);
4276 for (i = 0; i < n; i++)
4278 ira_object_t obj = ALLOCNO_OBJECT (a, i);
4279 COPY_HARD_REG_SET (saved[i], OBJECT_TOTAL_CONFLICT_HARD_REGS (obj));
4280 IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), forbidden_regs);
4281 if (! flag_caller_saves && ALLOCNO_CALLS_CROSSED_NUM (a) != 0)
4282 IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
4283 call_used_reg_set);
4285 ALLOCNO_ASSIGNED_P (a) = false;
4286 aclass = ALLOCNO_CLASS (a);
4287 update_curr_costs (a);
4288 assign_hard_reg (a, true);
4289 hard_regno = ALLOCNO_HARD_REGNO (a);
4290 reg_renumber[regno] = hard_regno;
4291 if (hard_regno < 0)
4292 ALLOCNO_HARD_REGNO (a) = -1;
4293 else
4295 ira_assert (ira_class_hard_reg_index[aclass][hard_regno] >= 0);
4296 ira_overall_cost
4297 -= (ALLOCNO_MEMORY_COST (a)
4298 - (ALLOCNO_HARD_REG_COSTS (a) == NULL
4299 ? ALLOCNO_CLASS_COST (a)
4300 : ALLOCNO_HARD_REG_COSTS (a)[ira_class_hard_reg_index
4301 [aclass][hard_regno]]));
4302 if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0
4303 && ira_hard_reg_set_intersection_p (hard_regno, ALLOCNO_MODE (a),
4304 call_used_reg_set))
4306 ira_assert (flag_caller_saves);
4307 caller_save_needed = 1;
4311 /* If we found a hard register, modify the RTL for the pseudo
4312 register to show the hard register, and mark the pseudo register
4313 live. */
4314 if (reg_renumber[regno] >= 0)
4316 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4317 fprintf (ira_dump_file, ": reassign to %d\n", reg_renumber[regno]);
4318 SET_REGNO (regno_reg_rtx[regno], reg_renumber[regno]);
4319 mark_home_live (regno);
4321 else if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4322 fprintf (ira_dump_file, "\n");
4323 for (i = 0; i < n; i++)
4325 ira_object_t obj = ALLOCNO_OBJECT (a, i);
4326 COPY_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), saved[i]);
4328 return reg_renumber[regno] >= 0;
4331 /* Sort pseudos according their usage frequencies (putting most
4332 frequently ones first). */
4333 static int
4334 pseudo_reg_compare (const void *v1p, const void *v2p)
4336 int regno1 = *(const int *) v1p;
4337 int regno2 = *(const int *) v2p;
4338 int diff;
4340 if ((diff = REG_FREQ (regno2) - REG_FREQ (regno1)) != 0)
4341 return diff;
4342 return regno1 - regno2;
4345 /* Try to allocate hard registers to SPILLED_PSEUDO_REGS (there are
4346 NUM of them) or spilled pseudos conflicting with pseudos in
4347 SPILLED_PSEUDO_REGS. Return TRUE and update SPILLED, if the
4348 allocation has been changed. The function doesn't use
4349 BAD_SPILL_REGS and hard registers in PSEUDO_FORBIDDEN_REGS and
4350 PSEUDO_PREVIOUS_REGS for the corresponding pseudos. The function
4351 is called by the reload pass at the end of each reload
4352 iteration. */
4353 bool
4354 ira_reassign_pseudos (int *spilled_pseudo_regs, int num,
4355 HARD_REG_SET bad_spill_regs,
4356 HARD_REG_SET *pseudo_forbidden_regs,
4357 HARD_REG_SET *pseudo_previous_regs,
4358 bitmap spilled)
4360 int i, n, regno;
4361 bool changed_p;
4362 ira_allocno_t a;
4363 HARD_REG_SET forbidden_regs;
4364 bitmap temp = BITMAP_ALLOC (NULL);
4366 /* Add pseudos which conflict with pseudos already in
4367 SPILLED_PSEUDO_REGS to SPILLED_PSEUDO_REGS. This is preferable
4368 to allocating in two steps as some of the conflicts might have
4369 a higher priority than the pseudos passed in SPILLED_PSEUDO_REGS. */
4370 for (i = 0; i < num; i++)
4371 bitmap_set_bit (temp, spilled_pseudo_regs[i]);
4373 for (i = 0, n = num; i < n; i++)
4375 int nr, j;
4376 int regno = spilled_pseudo_regs[i];
4377 bitmap_set_bit (temp, regno);
4379 a = ira_regno_allocno_map[regno];
4380 nr = ALLOCNO_NUM_OBJECTS (a);
4381 for (j = 0; j < nr; j++)
4383 ira_object_t conflict_obj;
4384 ira_object_t obj = ALLOCNO_OBJECT (a, j);
4385 ira_object_conflict_iterator oci;
4387 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
4389 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
4390 if (ALLOCNO_HARD_REGNO (conflict_a) < 0
4391 && ! ALLOCNO_DONT_REASSIGN_P (conflict_a)
4392 && bitmap_set_bit (temp, ALLOCNO_REGNO (conflict_a)))
4394 spilled_pseudo_regs[num++] = ALLOCNO_REGNO (conflict_a);
4395 /* ?!? This seems wrong. */
4396 bitmap_set_bit (consideration_allocno_bitmap,
4397 ALLOCNO_NUM (conflict_a));
4403 if (num > 1)
4404 qsort (spilled_pseudo_regs, num, sizeof (int), pseudo_reg_compare);
4405 changed_p = false;
4406 /* Try to assign hard registers to pseudos from
4407 SPILLED_PSEUDO_REGS. */
4408 for (i = 0; i < num; i++)
4410 regno = spilled_pseudo_regs[i];
4411 COPY_HARD_REG_SET (forbidden_regs, bad_spill_regs);
4412 IOR_HARD_REG_SET (forbidden_regs, pseudo_forbidden_regs[regno]);
4413 IOR_HARD_REG_SET (forbidden_regs, pseudo_previous_regs[regno]);
4414 gcc_assert (reg_renumber[regno] < 0);
4415 a = ira_regno_allocno_map[regno];
4416 ira_mark_allocation_change (regno);
4417 ira_assert (reg_renumber[regno] < 0);
4418 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4419 fprintf (ira_dump_file,
4420 " Try Assign %d(a%d), cost=%d", regno, ALLOCNO_NUM (a),
4421 ALLOCNO_MEMORY_COST (a)
4422 - ALLOCNO_CLASS_COST (a));
4423 allocno_reload_assign (a, forbidden_regs);
4424 if (reg_renumber[regno] >= 0)
4426 CLEAR_REGNO_REG_SET (spilled, regno);
4427 changed_p = true;
4430 BITMAP_FREE (temp);
4431 return changed_p;
4434 /* The function is called by reload and returns already allocated
4435 stack slot (if any) for REGNO with given INHERENT_SIZE and
4436 TOTAL_SIZE. In the case of failure to find a slot which can be
4437 used for REGNO, the function returns NULL. */
4439 ira_reuse_stack_slot (int regno, unsigned int inherent_size,
4440 unsigned int total_size)
4442 unsigned int i;
4443 int slot_num, best_slot_num;
4444 int cost, best_cost;
4445 ira_copy_t cp, next_cp;
4446 ira_allocno_t another_allocno, allocno = ira_regno_allocno_map[regno];
4447 rtx x;
4448 bitmap_iterator bi;
4449 struct ira_spilled_reg_stack_slot *slot = NULL;
4451 ira_assert (! ira_use_lra_p);
4453 ira_assert (inherent_size == PSEUDO_REGNO_BYTES (regno)
4454 && inherent_size <= total_size
4455 && ALLOCNO_HARD_REGNO (allocno) < 0);
4456 if (! flag_ira_share_spill_slots)
4457 return NULL_RTX;
4458 slot_num = -ALLOCNO_HARD_REGNO (allocno) - 2;
4459 if (slot_num != -1)
4461 slot = &ira_spilled_reg_stack_slots[slot_num];
4462 x = slot->mem;
4464 else
4466 best_cost = best_slot_num = -1;
4467 x = NULL_RTX;
4468 /* It means that the pseudo was spilled in the reload pass, try
4469 to reuse a slot. */
4470 for (slot_num = 0;
4471 slot_num < ira_spilled_reg_stack_slots_num;
4472 slot_num++)
4474 slot = &ira_spilled_reg_stack_slots[slot_num];
4475 if (slot->mem == NULL_RTX)
4476 continue;
4477 if (slot->width < total_size
4478 || GET_MODE_SIZE (GET_MODE (slot->mem)) < inherent_size)
4479 continue;
4481 EXECUTE_IF_SET_IN_BITMAP (&slot->spilled_regs,
4482 FIRST_PSEUDO_REGISTER, i, bi)
4484 another_allocno = ira_regno_allocno_map[i];
4485 if (allocnos_conflict_by_live_ranges_p (allocno,
4486 another_allocno))
4487 goto cont;
4489 for (cost = 0, cp = ALLOCNO_COPIES (allocno);
4490 cp != NULL;
4491 cp = next_cp)
4493 if (cp->first == allocno)
4495 next_cp = cp->next_first_allocno_copy;
4496 another_allocno = cp->second;
4498 else if (cp->second == allocno)
4500 next_cp = cp->next_second_allocno_copy;
4501 another_allocno = cp->first;
4503 else
4504 gcc_unreachable ();
4505 if (cp->insn == NULL_RTX)
4506 continue;
4507 if (bitmap_bit_p (&slot->spilled_regs,
4508 ALLOCNO_REGNO (another_allocno)))
4509 cost += cp->freq;
4511 if (cost > best_cost)
4513 best_cost = cost;
4514 best_slot_num = slot_num;
4516 cont:
4519 if (best_cost >= 0)
4521 slot_num = best_slot_num;
4522 slot = &ira_spilled_reg_stack_slots[slot_num];
4523 SET_REGNO_REG_SET (&slot->spilled_regs, regno);
4524 x = slot->mem;
4525 ALLOCNO_HARD_REGNO (allocno) = -slot_num - 2;
4528 if (x != NULL_RTX)
4530 ira_assert (slot->width >= total_size);
4531 #ifdef ENABLE_IRA_CHECKING
4532 EXECUTE_IF_SET_IN_BITMAP (&slot->spilled_regs,
4533 FIRST_PSEUDO_REGISTER, i, bi)
4535 ira_assert (! conflict_by_live_ranges_p (regno, i));
4537 #endif
4538 SET_REGNO_REG_SET (&slot->spilled_regs, regno);
4539 if (internal_flag_ira_verbose > 3 && ira_dump_file)
4541 fprintf (ira_dump_file, " Assigning %d(freq=%d) slot %d of",
4542 regno, REG_FREQ (regno), slot_num);
4543 EXECUTE_IF_SET_IN_BITMAP (&slot->spilled_regs,
4544 FIRST_PSEUDO_REGISTER, i, bi)
4546 if ((unsigned) regno != i)
4547 fprintf (ira_dump_file, " %d", i);
4549 fprintf (ira_dump_file, "\n");
4552 return x;
4555 /* This is called by reload every time a new stack slot X with
4556 TOTAL_SIZE was allocated for REGNO. We store this info for
4557 subsequent ira_reuse_stack_slot calls. */
4558 void
4559 ira_mark_new_stack_slot (rtx x, int regno, unsigned int total_size)
4561 struct ira_spilled_reg_stack_slot *slot;
4562 int slot_num;
4563 ira_allocno_t allocno;
4565 ira_assert (! ira_use_lra_p);
4567 ira_assert (PSEUDO_REGNO_BYTES (regno) <= total_size);
4568 allocno = ira_regno_allocno_map[regno];
4569 slot_num = -ALLOCNO_HARD_REGNO (allocno) - 2;
4570 if (slot_num == -1)
4572 slot_num = ira_spilled_reg_stack_slots_num++;
4573 ALLOCNO_HARD_REGNO (allocno) = -slot_num - 2;
4575 slot = &ira_spilled_reg_stack_slots[slot_num];
4576 INIT_REG_SET (&slot->spilled_regs);
4577 SET_REGNO_REG_SET (&slot->spilled_regs, regno);
4578 slot->mem = x;
4579 slot->width = total_size;
4580 if (internal_flag_ira_verbose > 3 && ira_dump_file)
4581 fprintf (ira_dump_file, " Assigning %d(freq=%d) a new slot %d\n",
4582 regno, REG_FREQ (regno), slot_num);
4586 /* Return spill cost for pseudo-registers whose numbers are in array
4587 REGNOS (with a negative number as an end marker) for reload with
4588 given IN and OUT for INSN. Return also number points (through
4589 EXCESS_PRESSURE_LIVE_LENGTH) where the pseudo-register lives and
4590 the register pressure is high, number of references of the
4591 pseudo-registers (through NREFS), number of callee-clobbered
4592 hard-registers occupied by the pseudo-registers (through
4593 CALL_USED_COUNT), and the first hard regno occupied by the
4594 pseudo-registers (through FIRST_HARD_REGNO). */
4595 static int
4596 calculate_spill_cost (int *regnos, rtx in, rtx out, rtx_insn *insn,
4597 int *excess_pressure_live_length,
4598 int *nrefs, int *call_used_count, int *first_hard_regno)
4600 int i, cost, regno, hard_regno, j, count, saved_cost, nregs;
4601 bool in_p, out_p;
4602 int length;
4603 ira_allocno_t a;
4605 *nrefs = 0;
4606 for (length = count = cost = i = 0;; i++)
4608 regno = regnos[i];
4609 if (regno < 0)
4610 break;
4611 *nrefs += REG_N_REFS (regno);
4612 hard_regno = reg_renumber[regno];
4613 ira_assert (hard_regno >= 0);
4614 a = ira_regno_allocno_map[regno];
4615 length += ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a) / ALLOCNO_NUM_OBJECTS (a);
4616 cost += ALLOCNO_MEMORY_COST (a) - ALLOCNO_CLASS_COST (a);
4617 nregs = hard_regno_nregs[hard_regno][ALLOCNO_MODE (a)];
4618 for (j = 0; j < nregs; j++)
4619 if (! TEST_HARD_REG_BIT (call_used_reg_set, hard_regno + j))
4620 break;
4621 if (j == nregs)
4622 count++;
4623 in_p = in && REG_P (in) && (int) REGNO (in) == hard_regno;
4624 out_p = out && REG_P (out) && (int) REGNO (out) == hard_regno;
4625 if ((in_p || out_p)
4626 && find_regno_note (insn, REG_DEAD, hard_regno) != NULL_RTX)
4628 saved_cost = 0;
4629 if (in_p)
4630 saved_cost += ira_memory_move_cost
4631 [ALLOCNO_MODE (a)][ALLOCNO_CLASS (a)][1];
4632 if (out_p)
4633 saved_cost
4634 += ira_memory_move_cost
4635 [ALLOCNO_MODE (a)][ALLOCNO_CLASS (a)][0];
4636 cost -= REG_FREQ_FROM_BB (BLOCK_FOR_INSN (insn)) * saved_cost;
4639 *excess_pressure_live_length = length;
4640 *call_used_count = count;
4641 hard_regno = -1;
4642 if (regnos[0] >= 0)
4644 hard_regno = reg_renumber[regnos[0]];
4646 *first_hard_regno = hard_regno;
4647 return cost;
4650 /* Return TRUE if spilling pseudo-registers whose numbers are in array
4651 REGNOS is better than spilling pseudo-registers with numbers in
4652 OTHER_REGNOS for reload with given IN and OUT for INSN. The
4653 function used by the reload pass to make better register spilling
4654 decisions. */
4655 bool
4656 ira_better_spill_reload_regno_p (int *regnos, int *other_regnos,
4657 rtx in, rtx out, rtx_insn *insn)
4659 int cost, other_cost;
4660 int length, other_length;
4661 int nrefs, other_nrefs;
4662 int call_used_count, other_call_used_count;
4663 int hard_regno, other_hard_regno;
4665 cost = calculate_spill_cost (regnos, in, out, insn,
4666 &length, &nrefs, &call_used_count, &hard_regno);
4667 other_cost = calculate_spill_cost (other_regnos, in, out, insn,
4668 &other_length, &other_nrefs,
4669 &other_call_used_count,
4670 &other_hard_regno);
4671 if (nrefs == 0 && other_nrefs != 0)
4672 return true;
4673 if (nrefs != 0 && other_nrefs == 0)
4674 return false;
4675 if (cost != other_cost)
4676 return cost < other_cost;
4677 if (length != other_length)
4678 return length > other_length;
4679 #ifdef REG_ALLOC_ORDER
4680 if (hard_regno >= 0 && other_hard_regno >= 0)
4681 return (inv_reg_alloc_order[hard_regno]
4682 < inv_reg_alloc_order[other_hard_regno]);
4683 #else
4684 if (call_used_count != other_call_used_count)
4685 return call_used_count > other_call_used_count;
4686 #endif
4687 return false;
4692 /* Allocate and initialize data necessary for assign_hard_reg. */
4693 void
4694 ira_initiate_assign (void)
4696 sorted_allocnos
4697 = (ira_allocno_t *) ira_allocate (sizeof (ira_allocno_t)
4698 * ira_allocnos_num);
4699 consideration_allocno_bitmap = ira_allocate_bitmap ();
4700 initiate_cost_update ();
4701 allocno_priorities = (int *) ira_allocate (sizeof (int) * ira_allocnos_num);
4702 sorted_copies = (ira_copy_t *) ira_allocate (ira_copies_num
4703 * sizeof (ira_copy_t));
4706 /* Deallocate data used by assign_hard_reg. */
4707 void
4708 ira_finish_assign (void)
4710 ira_free (sorted_allocnos);
4711 ira_free_bitmap (consideration_allocno_bitmap);
4712 finish_cost_update ();
4713 ira_free (allocno_priorities);
4714 ira_free (sorted_copies);
4719 /* Entry function doing color-based register allocation. */
4720 static void
4721 color (void)
4723 allocno_stack_vec.create (ira_allocnos_num);
4724 memset (allocated_hardreg_p, 0, sizeof (allocated_hardreg_p));
4725 ira_initiate_assign ();
4726 do_coloring ();
4727 ira_finish_assign ();
4728 allocno_stack_vec.release ();
4729 move_spill_restore ();
4734 /* This page contains a simple register allocator without usage of
4735 allocno conflicts. This is used for fast allocation for -O0. */
4737 /* Do register allocation by not using allocno conflicts. It uses
4738 only allocno live ranges. The algorithm is close to Chow's
4739 priority coloring. */
4740 static void
4741 fast_allocation (void)
4743 int i, j, k, num, class_size, hard_regno;
4744 #ifdef STACK_REGS
4745 bool no_stack_reg_p;
4746 #endif
4747 enum reg_class aclass;
4748 machine_mode mode;
4749 ira_allocno_t a;
4750 ira_allocno_iterator ai;
4751 live_range_t r;
4752 HARD_REG_SET conflict_hard_regs, *used_hard_regs;
4754 sorted_allocnos = (ira_allocno_t *) ira_allocate (sizeof (ira_allocno_t)
4755 * ira_allocnos_num);
4756 num = 0;
4757 FOR_EACH_ALLOCNO (a, ai)
4758 sorted_allocnos[num++] = a;
4759 allocno_priorities = (int *) ira_allocate (sizeof (int) * ira_allocnos_num);
4760 setup_allocno_priorities (sorted_allocnos, num);
4761 used_hard_regs = (HARD_REG_SET *) ira_allocate (sizeof (HARD_REG_SET)
4762 * ira_max_point);
4763 for (i = 0; i < ira_max_point; i++)
4764 CLEAR_HARD_REG_SET (used_hard_regs[i]);
4765 qsort (sorted_allocnos, num, sizeof (ira_allocno_t),
4766 allocno_priority_compare_func);
4767 for (i = 0; i < num; i++)
4769 int nr, l;
4771 a = sorted_allocnos[i];
4772 nr = ALLOCNO_NUM_OBJECTS (a);
4773 CLEAR_HARD_REG_SET (conflict_hard_regs);
4774 for (l = 0; l < nr; l++)
4776 ira_object_t obj = ALLOCNO_OBJECT (a, l);
4777 IOR_HARD_REG_SET (conflict_hard_regs,
4778 OBJECT_CONFLICT_HARD_REGS (obj));
4779 for (r = OBJECT_LIVE_RANGES (obj); r != NULL; r = r->next)
4780 for (j = r->start; j <= r->finish; j++)
4781 IOR_HARD_REG_SET (conflict_hard_regs, used_hard_regs[j]);
4783 aclass = ALLOCNO_CLASS (a);
4784 ALLOCNO_ASSIGNED_P (a) = true;
4785 ALLOCNO_HARD_REGNO (a) = -1;
4786 if (hard_reg_set_subset_p (reg_class_contents[aclass],
4787 conflict_hard_regs))
4788 continue;
4789 mode = ALLOCNO_MODE (a);
4790 #ifdef STACK_REGS
4791 no_stack_reg_p = ALLOCNO_NO_STACK_REG_P (a);
4792 #endif
4793 class_size = ira_class_hard_regs_num[aclass];
4794 for (j = 0; j < class_size; j++)
4796 hard_regno = ira_class_hard_regs[aclass][j];
4797 #ifdef STACK_REGS
4798 if (no_stack_reg_p && FIRST_STACK_REG <= hard_regno
4799 && hard_regno <= LAST_STACK_REG)
4800 continue;
4801 #endif
4802 if (ira_hard_reg_set_intersection_p (hard_regno, mode, conflict_hard_regs)
4803 || (TEST_HARD_REG_BIT
4804 (ira_prohibited_class_mode_regs[aclass][mode], hard_regno)))
4805 continue;
4806 ALLOCNO_HARD_REGNO (a) = hard_regno;
4807 for (l = 0; l < nr; l++)
4809 ira_object_t obj = ALLOCNO_OBJECT (a, l);
4810 for (r = OBJECT_LIVE_RANGES (obj); r != NULL; r = r->next)
4811 for (k = r->start; k <= r->finish; k++)
4812 IOR_HARD_REG_SET (used_hard_regs[k],
4813 ira_reg_mode_hard_regset[hard_regno][mode]);
4815 break;
4818 ira_free (sorted_allocnos);
4819 ira_free (used_hard_regs);
4820 ira_free (allocno_priorities);
4821 if (internal_flag_ira_verbose > 1 && ira_dump_file != NULL)
4822 ira_print_disposition (ira_dump_file);
4827 /* Entry function doing coloring. */
4828 void
4829 ira_color (void)
4831 ira_allocno_t a;
4832 ira_allocno_iterator ai;
4834 /* Setup updated costs. */
4835 FOR_EACH_ALLOCNO (a, ai)
4837 ALLOCNO_UPDATED_MEMORY_COST (a) = ALLOCNO_MEMORY_COST (a);
4838 ALLOCNO_UPDATED_CLASS_COST (a) = ALLOCNO_CLASS_COST (a);
4840 if (ira_conflicts_p)
4841 color ();
4842 else
4843 fast_allocation ();