mmap.c (MAP_FAILED): Define if not defined.
[official-gcc.git] / gcc / ira-color.c
blob1e4c64fa94001c24502086d416fe3ca1c71ebc43
1 /* IRA allocation based on graph coloring.
2 Copyright (C) 2006-2016 Free Software Foundation, Inc.
3 Contributed by Vladimir Makarov <vmakarov@redhat.com>.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "backend.h"
25 #include "target.h"
26 #include "rtl.h"
27 #include "tree.h"
28 #include "predict.h"
29 #include "df.h"
30 #include "tm_p.h"
31 #include "insn-config.h"
32 #include "regs.h"
33 #include "ira.h"
34 #include "ira-int.h"
35 #include "reload.h"
36 #include "cfgloop.h"
38 typedef struct allocno_hard_regs *allocno_hard_regs_t;
40 /* The structure contains information about hard registers can be
41 assigned to allocnos. Usually it is allocno profitable hard
42 registers but in some cases this set can be a bit different. Major
43 reason of the difference is a requirement to use hard register sets
44 that form a tree or a forest (set of trees), i.e. hard register set
45 of a node should contain hard register sets of its subnodes. */
46 struct allocno_hard_regs
48 /* Hard registers can be assigned to an allocno. */
49 HARD_REG_SET set;
50 /* Overall (spilling) cost of all allocnos with given register
51 set. */
52 int64_t cost;
55 typedef struct allocno_hard_regs_node *allocno_hard_regs_node_t;
57 /* A node representing allocno hard registers. Such nodes form a
58 forest (set of trees). Each subnode of given node in the forest
59 refers for hard register set (usually allocno profitable hard
60 register set) which is a subset of one referred from given
61 node. */
62 struct allocno_hard_regs_node
64 /* Set up number of the node in preorder traversing of the forest. */
65 int preorder_num;
66 /* Used for different calculation like finding conflict size of an
67 allocno. */
68 int check;
69 /* Used for calculation of conflict size of an allocno. The
70 conflict size of the allocno is maximal number of given allocno
71 hard registers needed for allocation of the conflicting allocnos.
72 Given allocno is trivially colored if this number plus the number
73 of hard registers needed for given allocno is not greater than
74 the number of given allocno hard register set. */
75 int conflict_size;
76 /* The number of hard registers given by member hard_regs. */
77 int hard_regs_num;
78 /* The following member is used to form the final forest. */
79 bool used_p;
80 /* Pointer to the corresponding profitable hard registers. */
81 allocno_hard_regs_t hard_regs;
82 /* Parent, first subnode, previous and next node with the same
83 parent in the forest. */
84 allocno_hard_regs_node_t parent, first, prev, next;
87 /* Info about changing hard reg costs of an allocno. */
88 struct update_cost_record
90 /* Hard regno for which we changed the cost. */
91 int hard_regno;
92 /* Divisor used when we changed the cost of HARD_REGNO. */
93 int divisor;
94 /* Next record for given allocno. */
95 struct update_cost_record *next;
98 /* To decrease footprint of ira_allocno structure we store all data
99 needed only for coloring in the following structure. */
100 struct allocno_color_data
102 /* TRUE value means that the allocno was not removed yet from the
103 conflicting graph during coloring. */
104 unsigned int in_graph_p : 1;
105 /* TRUE if it is put on the stack to make other allocnos
106 colorable. */
107 unsigned int may_be_spilled_p : 1;
108 /* TRUE if the allocno is trivially colorable. */
109 unsigned int colorable_p : 1;
110 /* Number of hard registers of the allocno class really
111 available for the allocno allocation. It is number of the
112 profitable hard regs. */
113 int available_regs_num;
114 /* Allocnos in a bucket (used in coloring) chained by the following
115 two members. */
116 ira_allocno_t next_bucket_allocno;
117 ira_allocno_t prev_bucket_allocno;
118 /* Used for temporary purposes. */
119 int temp;
120 /* Used to exclude repeated processing. */
121 int last_process;
122 /* Profitable hard regs available for this pseudo allocation. It
123 means that the set excludes unavailable hard regs and hard regs
124 conflicting with given pseudo. They should be of the allocno
125 class. */
126 HARD_REG_SET profitable_hard_regs;
127 /* The allocno hard registers node. */
128 allocno_hard_regs_node_t hard_regs_node;
129 /* Array of structures allocno_hard_regs_subnode representing
130 given allocno hard registers node (the 1st element in the array)
131 and all its subnodes in the tree (forest) of allocno hard
132 register nodes (see comments above). */
133 int hard_regs_subnodes_start;
134 /* The length of the previous array. */
135 int hard_regs_subnodes_num;
136 /* Records about updating allocno hard reg costs from copies. If
137 the allocno did not get expected hard register, these records are
138 used to restore original hard reg costs of allocnos connected to
139 this allocno by copies. */
140 struct update_cost_record *update_cost_records;
141 /* Threads. We collect allocnos connected by copies into threads
142 and try to assign hard regs to allocnos by threads. */
143 /* Allocno representing all thread. */
144 ira_allocno_t first_thread_allocno;
145 /* Allocnos in thread forms a cycle list through the following
146 member. */
147 ira_allocno_t next_thread_allocno;
148 /* All thread frequency. Defined only for first thread allocno. */
149 int thread_freq;
152 /* See above. */
153 typedef struct allocno_color_data *allocno_color_data_t;
155 /* Container for storing allocno data concerning coloring. */
156 static allocno_color_data_t allocno_color_data;
158 /* Macro to access the data concerning coloring. */
159 #define ALLOCNO_COLOR_DATA(a) ((allocno_color_data_t) ALLOCNO_ADD_DATA (a))
161 /* Used for finding allocno colorability to exclude repeated allocno
162 processing and for updating preferencing to exclude repeated
163 allocno processing during assignment. */
164 static int curr_allocno_process;
166 /* This file contains code for regional graph coloring, spill/restore
167 code placement optimization, and code helping the reload pass to do
168 a better job. */
170 /* Bitmap of allocnos which should be colored. */
171 static bitmap coloring_allocno_bitmap;
173 /* Bitmap of allocnos which should be taken into account during
174 coloring. In general case it contains allocnos from
175 coloring_allocno_bitmap plus other already colored conflicting
176 allocnos. */
177 static bitmap consideration_allocno_bitmap;
179 /* All allocnos sorted according their priorities. */
180 static ira_allocno_t *sorted_allocnos;
182 /* Vec representing the stack of allocnos used during coloring. */
183 static vec<ira_allocno_t> allocno_stack_vec;
185 /* Helper for qsort comparison callbacks - return a positive integer if
186 X > Y, or a negative value otherwise. Use a conditional expression
187 instead of a difference computation to insulate from possible overflow
188 issues, e.g. X - Y < 0 for some X > 0 and Y < 0. */
189 #define SORTGT(x,y) (((x) > (y)) ? 1 : -1)
193 /* Definition of vector of allocno hard registers. */
195 /* Vector of unique allocno hard registers. */
196 static vec<allocno_hard_regs_t> allocno_hard_regs_vec;
198 struct allocno_hard_regs_hasher : nofree_ptr_hash <allocno_hard_regs>
200 static inline hashval_t hash (const allocno_hard_regs *);
201 static inline bool equal (const allocno_hard_regs *,
202 const allocno_hard_regs *);
205 /* Returns hash value for allocno hard registers V. */
206 inline hashval_t
207 allocno_hard_regs_hasher::hash (const allocno_hard_regs *hv)
209 return iterative_hash (&hv->set, sizeof (HARD_REG_SET), 0);
212 /* Compares allocno hard registers V1 and V2. */
213 inline bool
214 allocno_hard_regs_hasher::equal (const allocno_hard_regs *hv1,
215 const allocno_hard_regs *hv2)
217 return hard_reg_set_equal_p (hv1->set, hv2->set);
220 /* Hash table of unique allocno hard registers. */
221 static hash_table<allocno_hard_regs_hasher> *allocno_hard_regs_htab;
223 /* Return allocno hard registers in the hash table equal to HV. */
224 static allocno_hard_regs_t
225 find_hard_regs (allocno_hard_regs_t hv)
227 return allocno_hard_regs_htab->find (hv);
230 /* Insert allocno hard registers HV in the hash table (if it is not
231 there yet) and return the value which in the table. */
232 static allocno_hard_regs_t
233 insert_hard_regs (allocno_hard_regs_t hv)
235 allocno_hard_regs **slot = allocno_hard_regs_htab->find_slot (hv, INSERT);
237 if (*slot == NULL)
238 *slot = hv;
239 return *slot;
242 /* Initialize data concerning allocno hard registers. */
243 static void
244 init_allocno_hard_regs (void)
246 allocno_hard_regs_vec.create (200);
247 allocno_hard_regs_htab
248 = new hash_table<allocno_hard_regs_hasher> (200);
251 /* Add (or update info about) allocno hard registers with SET and
252 COST. */
253 static allocno_hard_regs_t
254 add_allocno_hard_regs (HARD_REG_SET set, int64_t cost)
256 struct allocno_hard_regs temp;
257 allocno_hard_regs_t hv;
259 gcc_assert (! hard_reg_set_empty_p (set));
260 COPY_HARD_REG_SET (temp.set, set);
261 if ((hv = find_hard_regs (&temp)) != NULL)
262 hv->cost += cost;
263 else
265 hv = ((struct allocno_hard_regs *)
266 ira_allocate (sizeof (struct allocno_hard_regs)));
267 COPY_HARD_REG_SET (hv->set, set);
268 hv->cost = cost;
269 allocno_hard_regs_vec.safe_push (hv);
270 insert_hard_regs (hv);
272 return hv;
275 /* Finalize data concerning allocno hard registers. */
276 static void
277 finish_allocno_hard_regs (void)
279 int i;
280 allocno_hard_regs_t hv;
282 for (i = 0;
283 allocno_hard_regs_vec.iterate (i, &hv);
284 i++)
285 ira_free (hv);
286 delete allocno_hard_regs_htab;
287 allocno_hard_regs_htab = NULL;
288 allocno_hard_regs_vec.release ();
291 /* Sort hard regs according to their frequency of usage. */
292 static int
293 allocno_hard_regs_compare (const void *v1p, const void *v2p)
295 allocno_hard_regs_t hv1 = *(const allocno_hard_regs_t *) v1p;
296 allocno_hard_regs_t hv2 = *(const allocno_hard_regs_t *) v2p;
298 if (hv2->cost > hv1->cost)
299 return 1;
300 else if (hv2->cost < hv1->cost)
301 return -1;
302 else
303 return 0;
308 /* Used for finding a common ancestor of two allocno hard registers
309 nodes in the forest. We use the current value of
310 'node_check_tick' to mark all nodes from one node to the top and
311 then walking up from another node until we find a marked node.
313 It is also used to figure out allocno colorability as a mark that
314 we already reset value of member 'conflict_size' for the forest
315 node corresponding to the processed allocno. */
316 static int node_check_tick;
318 /* Roots of the forest containing hard register sets can be assigned
319 to allocnos. */
320 static allocno_hard_regs_node_t hard_regs_roots;
322 /* Definition of vector of allocno hard register nodes. */
324 /* Vector used to create the forest. */
325 static vec<allocno_hard_regs_node_t> hard_regs_node_vec;
327 /* Create and return allocno hard registers node containing allocno
328 hard registers HV. */
329 static allocno_hard_regs_node_t
330 create_new_allocno_hard_regs_node (allocno_hard_regs_t hv)
332 allocno_hard_regs_node_t new_node;
334 new_node = ((struct allocno_hard_regs_node *)
335 ira_allocate (sizeof (struct allocno_hard_regs_node)));
336 new_node->check = 0;
337 new_node->hard_regs = hv;
338 new_node->hard_regs_num = hard_reg_set_size (hv->set);
339 new_node->first = NULL;
340 new_node->used_p = false;
341 return new_node;
344 /* Add allocno hard registers node NEW_NODE to the forest on its level
345 given by ROOTS. */
346 static void
347 add_new_allocno_hard_regs_node_to_forest (allocno_hard_regs_node_t *roots,
348 allocno_hard_regs_node_t new_node)
350 new_node->next = *roots;
351 if (new_node->next != NULL)
352 new_node->next->prev = new_node;
353 new_node->prev = NULL;
354 *roots = new_node;
357 /* Add allocno hard registers HV (or its best approximation if it is
358 not possible) to the forest on its level given by ROOTS. */
359 static void
360 add_allocno_hard_regs_to_forest (allocno_hard_regs_node_t *roots,
361 allocno_hard_regs_t hv)
363 unsigned int i, start;
364 allocno_hard_regs_node_t node, prev, new_node;
365 HARD_REG_SET temp_set;
366 allocno_hard_regs_t hv2;
368 start = hard_regs_node_vec.length ();
369 for (node = *roots; node != NULL; node = node->next)
371 if (hard_reg_set_equal_p (hv->set, node->hard_regs->set))
372 return;
373 if (hard_reg_set_subset_p (hv->set, node->hard_regs->set))
375 add_allocno_hard_regs_to_forest (&node->first, hv);
376 return;
378 if (hard_reg_set_subset_p (node->hard_regs->set, hv->set))
379 hard_regs_node_vec.safe_push (node);
380 else if (hard_reg_set_intersect_p (hv->set, node->hard_regs->set))
382 COPY_HARD_REG_SET (temp_set, hv->set);
383 AND_HARD_REG_SET (temp_set, node->hard_regs->set);
384 hv2 = add_allocno_hard_regs (temp_set, hv->cost);
385 add_allocno_hard_regs_to_forest (&node->first, hv2);
388 if (hard_regs_node_vec.length ()
389 > start + 1)
391 /* Create a new node which contains nodes in hard_regs_node_vec. */
392 CLEAR_HARD_REG_SET (temp_set);
393 for (i = start;
394 i < hard_regs_node_vec.length ();
395 i++)
397 node = hard_regs_node_vec[i];
398 IOR_HARD_REG_SET (temp_set, node->hard_regs->set);
400 hv = add_allocno_hard_regs (temp_set, hv->cost);
401 new_node = create_new_allocno_hard_regs_node (hv);
402 prev = NULL;
403 for (i = start;
404 i < hard_regs_node_vec.length ();
405 i++)
407 node = hard_regs_node_vec[i];
408 if (node->prev == NULL)
409 *roots = node->next;
410 else
411 node->prev->next = node->next;
412 if (node->next != NULL)
413 node->next->prev = node->prev;
414 if (prev == NULL)
415 new_node->first = node;
416 else
417 prev->next = node;
418 node->prev = prev;
419 node->next = NULL;
420 prev = node;
422 add_new_allocno_hard_regs_node_to_forest (roots, new_node);
424 hard_regs_node_vec.truncate (start);
427 /* Add allocno hard registers nodes starting with the forest level
428 given by FIRST which contains biggest set inside SET. */
429 static void
430 collect_allocno_hard_regs_cover (allocno_hard_regs_node_t first,
431 HARD_REG_SET set)
433 allocno_hard_regs_node_t node;
435 ira_assert (first != NULL);
436 for (node = first; node != NULL; node = node->next)
437 if (hard_reg_set_subset_p (node->hard_regs->set, set))
438 hard_regs_node_vec.safe_push (node);
439 else if (hard_reg_set_intersect_p (set, node->hard_regs->set))
440 collect_allocno_hard_regs_cover (node->first, set);
443 /* Set up field parent as PARENT in all allocno hard registers nodes
444 in forest given by FIRST. */
445 static void
446 setup_allocno_hard_regs_nodes_parent (allocno_hard_regs_node_t first,
447 allocno_hard_regs_node_t parent)
449 allocno_hard_regs_node_t node;
451 for (node = first; node != NULL; node = node->next)
453 node->parent = parent;
454 setup_allocno_hard_regs_nodes_parent (node->first, node);
458 /* Return allocno hard registers node which is a first common ancestor
459 node of FIRST and SECOND in the forest. */
460 static allocno_hard_regs_node_t
461 first_common_ancestor_node (allocno_hard_regs_node_t first,
462 allocno_hard_regs_node_t second)
464 allocno_hard_regs_node_t node;
466 node_check_tick++;
467 for (node = first; node != NULL; node = node->parent)
468 node->check = node_check_tick;
469 for (node = second; node != NULL; node = node->parent)
470 if (node->check == node_check_tick)
471 return node;
472 return first_common_ancestor_node (second, first);
475 /* Print hard reg set SET to F. */
476 static void
477 print_hard_reg_set (FILE *f, HARD_REG_SET set, bool new_line_p)
479 int i, start;
481 for (start = -1, i = 0; i < FIRST_PSEUDO_REGISTER; i++)
483 if (TEST_HARD_REG_BIT (set, i))
485 if (i == 0 || ! TEST_HARD_REG_BIT (set, i - 1))
486 start = i;
488 if (start >= 0
489 && (i == FIRST_PSEUDO_REGISTER - 1 || ! TEST_HARD_REG_BIT (set, i)))
491 if (start == i - 1)
492 fprintf (f, " %d", start);
493 else if (start == i - 2)
494 fprintf (f, " %d %d", start, start + 1);
495 else
496 fprintf (f, " %d-%d", start, i - 1);
497 start = -1;
500 if (new_line_p)
501 fprintf (f, "\n");
504 /* Print allocno hard register subforest given by ROOTS and its LEVEL
505 to F. */
506 static void
507 print_hard_regs_subforest (FILE *f, allocno_hard_regs_node_t roots,
508 int level)
510 int i;
511 allocno_hard_regs_node_t node;
513 for (node = roots; node != NULL; node = node->next)
515 fprintf (f, " ");
516 for (i = 0; i < level * 2; i++)
517 fprintf (f, " ");
518 fprintf (f, "%d:(", node->preorder_num);
519 print_hard_reg_set (f, node->hard_regs->set, false);
520 fprintf (f, ")@%" PRId64"\n", node->hard_regs->cost);
521 print_hard_regs_subforest (f, node->first, level + 1);
525 /* Print the allocno hard register forest to F. */
526 static void
527 print_hard_regs_forest (FILE *f)
529 fprintf (f, " Hard reg set forest:\n");
530 print_hard_regs_subforest (f, hard_regs_roots, 1);
533 /* Print the allocno hard register forest to stderr. */
534 void
535 ira_debug_hard_regs_forest (void)
537 print_hard_regs_forest (stderr);
540 /* Remove unused allocno hard registers nodes from forest given by its
541 *ROOTS. */
542 static void
543 remove_unused_allocno_hard_regs_nodes (allocno_hard_regs_node_t *roots)
545 allocno_hard_regs_node_t node, prev, next, last;
547 for (prev = NULL, node = *roots; node != NULL; node = next)
549 next = node->next;
550 if (node->used_p)
552 remove_unused_allocno_hard_regs_nodes (&node->first);
553 prev = node;
555 else
557 for (last = node->first;
558 last != NULL && last->next != NULL;
559 last = last->next)
561 if (last != NULL)
563 if (prev == NULL)
564 *roots = node->first;
565 else
566 prev->next = node->first;
567 if (next != NULL)
568 next->prev = last;
569 last->next = next;
570 next = node->first;
572 else
574 if (prev == NULL)
575 *roots = next;
576 else
577 prev->next = next;
578 if (next != NULL)
579 next->prev = prev;
581 ira_free (node);
586 /* Set up fields preorder_num starting with START_NUM in all allocno
587 hard registers nodes in forest given by FIRST. Return biggest set
588 PREORDER_NUM increased by 1. */
589 static int
590 enumerate_allocno_hard_regs_nodes (allocno_hard_regs_node_t first,
591 allocno_hard_regs_node_t parent,
592 int start_num)
594 allocno_hard_regs_node_t node;
596 for (node = first; node != NULL; node = node->next)
598 node->preorder_num = start_num++;
599 node->parent = parent;
600 start_num = enumerate_allocno_hard_regs_nodes (node->first, node,
601 start_num);
603 return start_num;
606 /* Number of allocno hard registers nodes in the forest. */
607 static int allocno_hard_regs_nodes_num;
609 /* Table preorder number of allocno hard registers node in the forest
610 -> the allocno hard registers node. */
611 static allocno_hard_regs_node_t *allocno_hard_regs_nodes;
613 /* See below. */
614 typedef struct allocno_hard_regs_subnode *allocno_hard_regs_subnode_t;
616 /* The structure is used to describes all subnodes (not only immediate
617 ones) in the mentioned above tree for given allocno hard register
618 node. The usage of such data accelerates calculation of
619 colorability of given allocno. */
620 struct allocno_hard_regs_subnode
622 /* The conflict size of conflicting allocnos whose hard register
623 sets are equal sets (plus supersets if given node is given
624 allocno hard registers node) of one in the given node. */
625 int left_conflict_size;
626 /* The summary conflict size of conflicting allocnos whose hard
627 register sets are strict subsets of one in the given node.
628 Overall conflict size is
629 left_conflict_subnodes_size
630 + MIN (max_node_impact - left_conflict_subnodes_size,
631 left_conflict_size)
633 short left_conflict_subnodes_size;
634 short max_node_impact;
637 /* Container for hard regs subnodes of all allocnos. */
638 static allocno_hard_regs_subnode_t allocno_hard_regs_subnodes;
640 /* Table (preorder number of allocno hard registers node in the
641 forest, preorder number of allocno hard registers subnode) -> index
642 of the subnode relative to the node. -1 if it is not a
643 subnode. */
644 static int *allocno_hard_regs_subnode_index;
646 /* Setup arrays ALLOCNO_HARD_REGS_NODES and
647 ALLOCNO_HARD_REGS_SUBNODE_INDEX. */
648 static void
649 setup_allocno_hard_regs_subnode_index (allocno_hard_regs_node_t first)
651 allocno_hard_regs_node_t node, parent;
652 int index;
654 for (node = first; node != NULL; node = node->next)
656 allocno_hard_regs_nodes[node->preorder_num] = node;
657 for (parent = node; parent != NULL; parent = parent->parent)
659 index = parent->preorder_num * allocno_hard_regs_nodes_num;
660 allocno_hard_regs_subnode_index[index + node->preorder_num]
661 = node->preorder_num - parent->preorder_num;
663 setup_allocno_hard_regs_subnode_index (node->first);
667 /* Count all allocno hard registers nodes in tree ROOT. */
668 static int
669 get_allocno_hard_regs_subnodes_num (allocno_hard_regs_node_t root)
671 int len = 1;
673 for (root = root->first; root != NULL; root = root->next)
674 len += get_allocno_hard_regs_subnodes_num (root);
675 return len;
678 /* Build the forest of allocno hard registers nodes and assign each
679 allocno a node from the forest. */
680 static void
681 form_allocno_hard_regs_nodes_forest (void)
683 unsigned int i, j, size, len;
684 int start;
685 ira_allocno_t a;
686 allocno_hard_regs_t hv;
687 bitmap_iterator bi;
688 HARD_REG_SET temp;
689 allocno_hard_regs_node_t node, allocno_hard_regs_node;
690 allocno_color_data_t allocno_data;
692 node_check_tick = 0;
693 init_allocno_hard_regs ();
694 hard_regs_roots = NULL;
695 hard_regs_node_vec.create (100);
696 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
697 if (! TEST_HARD_REG_BIT (ira_no_alloc_regs, i))
699 CLEAR_HARD_REG_SET (temp);
700 SET_HARD_REG_BIT (temp, i);
701 hv = add_allocno_hard_regs (temp, 0);
702 node = create_new_allocno_hard_regs_node (hv);
703 add_new_allocno_hard_regs_node_to_forest (&hard_regs_roots, node);
705 start = allocno_hard_regs_vec.length ();
706 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
708 a = ira_allocnos[i];
709 allocno_data = ALLOCNO_COLOR_DATA (a);
711 if (hard_reg_set_empty_p (allocno_data->profitable_hard_regs))
712 continue;
713 hv = (add_allocno_hard_regs
714 (allocno_data->profitable_hard_regs,
715 ALLOCNO_MEMORY_COST (a) - ALLOCNO_CLASS_COST (a)));
717 SET_HARD_REG_SET (temp);
718 AND_COMPL_HARD_REG_SET (temp, ira_no_alloc_regs);
719 add_allocno_hard_regs (temp, 0);
720 qsort (allocno_hard_regs_vec.address () + start,
721 allocno_hard_regs_vec.length () - start,
722 sizeof (allocno_hard_regs_t), allocno_hard_regs_compare);
723 for (i = start;
724 allocno_hard_regs_vec.iterate (i, &hv);
725 i++)
727 add_allocno_hard_regs_to_forest (&hard_regs_roots, hv);
728 ira_assert (hard_regs_node_vec.length () == 0);
730 /* We need to set up parent fields for right work of
731 first_common_ancestor_node. */
732 setup_allocno_hard_regs_nodes_parent (hard_regs_roots, NULL);
733 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
735 a = ira_allocnos[i];
736 allocno_data = ALLOCNO_COLOR_DATA (a);
737 if (hard_reg_set_empty_p (allocno_data->profitable_hard_regs))
738 continue;
739 hard_regs_node_vec.truncate (0);
740 collect_allocno_hard_regs_cover (hard_regs_roots,
741 allocno_data->profitable_hard_regs);
742 allocno_hard_regs_node = NULL;
743 for (j = 0; hard_regs_node_vec.iterate (j, &node); j++)
744 allocno_hard_regs_node
745 = (j == 0
746 ? node
747 : first_common_ancestor_node (node, allocno_hard_regs_node));
748 /* That is a temporary storage. */
749 allocno_hard_regs_node->used_p = true;
750 allocno_data->hard_regs_node = allocno_hard_regs_node;
752 ira_assert (hard_regs_roots->next == NULL);
753 hard_regs_roots->used_p = true;
754 remove_unused_allocno_hard_regs_nodes (&hard_regs_roots);
755 allocno_hard_regs_nodes_num
756 = enumerate_allocno_hard_regs_nodes (hard_regs_roots, NULL, 0);
757 allocno_hard_regs_nodes
758 = ((allocno_hard_regs_node_t *)
759 ira_allocate (allocno_hard_regs_nodes_num
760 * sizeof (allocno_hard_regs_node_t)));
761 size = allocno_hard_regs_nodes_num * allocno_hard_regs_nodes_num;
762 allocno_hard_regs_subnode_index
763 = (int *) ira_allocate (size * sizeof (int));
764 for (i = 0; i < size; i++)
765 allocno_hard_regs_subnode_index[i] = -1;
766 setup_allocno_hard_regs_subnode_index (hard_regs_roots);
767 start = 0;
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 len = get_allocno_hard_regs_subnodes_num (allocno_data->hard_regs_node);
775 allocno_data->hard_regs_subnodes_start = start;
776 allocno_data->hard_regs_subnodes_num = len;
777 start += len;
779 allocno_hard_regs_subnodes
780 = ((allocno_hard_regs_subnode_t)
781 ira_allocate (sizeof (struct allocno_hard_regs_subnode) * start));
782 hard_regs_node_vec.release ();
785 /* Free tree of allocno hard registers nodes given by its ROOT. */
786 static void
787 finish_allocno_hard_regs_nodes_tree (allocno_hard_regs_node_t root)
789 allocno_hard_regs_node_t child, next;
791 for (child = root->first; child != NULL; child = next)
793 next = child->next;
794 finish_allocno_hard_regs_nodes_tree (child);
796 ira_free (root);
799 /* Finish work with the forest of allocno hard registers nodes. */
800 static void
801 finish_allocno_hard_regs_nodes_forest (void)
803 allocno_hard_regs_node_t node, next;
805 ira_free (allocno_hard_regs_subnodes);
806 for (node = hard_regs_roots; node != NULL; node = next)
808 next = node->next;
809 finish_allocno_hard_regs_nodes_tree (node);
811 ira_free (allocno_hard_regs_nodes);
812 ira_free (allocno_hard_regs_subnode_index);
813 finish_allocno_hard_regs ();
816 /* Set up left conflict sizes and left conflict subnodes sizes of hard
817 registers subnodes of allocno A. Return TRUE if allocno A is
818 trivially colorable. */
819 static bool
820 setup_left_conflict_sizes_p (ira_allocno_t a)
822 int i, k, nobj, start;
823 int conflict_size, left_conflict_subnodes_size, node_preorder_num;
824 allocno_color_data_t data;
825 HARD_REG_SET profitable_hard_regs;
826 allocno_hard_regs_subnode_t subnodes;
827 allocno_hard_regs_node_t node;
828 HARD_REG_SET node_set;
830 nobj = ALLOCNO_NUM_OBJECTS (a);
831 data = ALLOCNO_COLOR_DATA (a);
832 subnodes = allocno_hard_regs_subnodes + data->hard_regs_subnodes_start;
833 COPY_HARD_REG_SET (profitable_hard_regs, data->profitable_hard_regs);
834 node = data->hard_regs_node;
835 node_preorder_num = node->preorder_num;
836 COPY_HARD_REG_SET (node_set, node->hard_regs->set);
837 node_check_tick++;
838 for (k = 0; k < nobj; k++)
840 ira_object_t obj = ALLOCNO_OBJECT (a, k);
841 ira_object_t conflict_obj;
842 ira_object_conflict_iterator oci;
844 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
846 int size;
847 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
848 allocno_hard_regs_node_t conflict_node, temp_node;
849 HARD_REG_SET conflict_node_set;
850 allocno_color_data_t conflict_data;
852 conflict_data = ALLOCNO_COLOR_DATA (conflict_a);
853 if (! ALLOCNO_COLOR_DATA (conflict_a)->in_graph_p
854 || ! hard_reg_set_intersect_p (profitable_hard_regs,
855 conflict_data
856 ->profitable_hard_regs))
857 continue;
858 conflict_node = conflict_data->hard_regs_node;
859 COPY_HARD_REG_SET (conflict_node_set, conflict_node->hard_regs->set);
860 if (hard_reg_set_subset_p (node_set, conflict_node_set))
861 temp_node = node;
862 else
864 ira_assert (hard_reg_set_subset_p (conflict_node_set, node_set));
865 temp_node = conflict_node;
867 if (temp_node->check != node_check_tick)
869 temp_node->check = node_check_tick;
870 temp_node->conflict_size = 0;
872 size = (ira_reg_class_max_nregs
873 [ALLOCNO_CLASS (conflict_a)][ALLOCNO_MODE (conflict_a)]);
874 if (ALLOCNO_NUM_OBJECTS (conflict_a) > 1)
875 /* We will deal with the subwords individually. */
876 size = 1;
877 temp_node->conflict_size += size;
880 for (i = 0; i < data->hard_regs_subnodes_num; i++)
882 allocno_hard_regs_node_t temp_node;
884 temp_node = allocno_hard_regs_nodes[i + node_preorder_num];
885 ira_assert (temp_node->preorder_num == i + node_preorder_num);
886 subnodes[i].left_conflict_size = (temp_node->check != node_check_tick
887 ? 0 : temp_node->conflict_size);
888 if (hard_reg_set_subset_p (temp_node->hard_regs->set,
889 profitable_hard_regs))
890 subnodes[i].max_node_impact = temp_node->hard_regs_num;
891 else
893 HARD_REG_SET temp_set;
894 int j, n, hard_regno;
895 enum reg_class aclass;
897 COPY_HARD_REG_SET (temp_set, temp_node->hard_regs->set);
898 AND_HARD_REG_SET (temp_set, profitable_hard_regs);
899 aclass = ALLOCNO_CLASS (a);
900 for (n = 0, j = ira_class_hard_regs_num[aclass] - 1; j >= 0; j--)
902 hard_regno = ira_class_hard_regs[aclass][j];
903 if (TEST_HARD_REG_BIT (temp_set, hard_regno))
904 n++;
906 subnodes[i].max_node_impact = n;
908 subnodes[i].left_conflict_subnodes_size = 0;
910 start = node_preorder_num * allocno_hard_regs_nodes_num;
911 for (i = data->hard_regs_subnodes_num - 1; i > 0; i--)
913 int size, parent_i;
914 allocno_hard_regs_node_t parent;
916 size = (subnodes[i].left_conflict_subnodes_size
917 + MIN (subnodes[i].max_node_impact
918 - subnodes[i].left_conflict_subnodes_size,
919 subnodes[i].left_conflict_size));
920 parent = allocno_hard_regs_nodes[i + node_preorder_num]->parent;
921 gcc_checking_assert(parent);
922 parent_i
923 = allocno_hard_regs_subnode_index[start + parent->preorder_num];
924 gcc_checking_assert(parent_i >= 0);
925 subnodes[parent_i].left_conflict_subnodes_size += size;
927 left_conflict_subnodes_size = subnodes[0].left_conflict_subnodes_size;
928 conflict_size
929 = (left_conflict_subnodes_size
930 + MIN (subnodes[0].max_node_impact - left_conflict_subnodes_size,
931 subnodes[0].left_conflict_size));
932 conflict_size += ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)];
933 data->colorable_p = conflict_size <= data->available_regs_num;
934 return data->colorable_p;
937 /* Update left conflict sizes of hard registers subnodes of allocno A
938 after removing allocno REMOVED_A with SIZE from the conflict graph.
939 Return TRUE if A is trivially colorable. */
940 static bool
941 update_left_conflict_sizes_p (ira_allocno_t a,
942 ira_allocno_t removed_a, int size)
944 int i, conflict_size, before_conflict_size, diff, start;
945 int node_preorder_num, parent_i;
946 allocno_hard_regs_node_t node, removed_node, parent;
947 allocno_hard_regs_subnode_t subnodes;
948 allocno_color_data_t data = ALLOCNO_COLOR_DATA (a);
950 ira_assert (! data->colorable_p);
951 node = data->hard_regs_node;
952 node_preorder_num = node->preorder_num;
953 removed_node = ALLOCNO_COLOR_DATA (removed_a)->hard_regs_node;
954 ira_assert (hard_reg_set_subset_p (removed_node->hard_regs->set,
955 node->hard_regs->set)
956 || hard_reg_set_subset_p (node->hard_regs->set,
957 removed_node->hard_regs->set));
958 start = node_preorder_num * allocno_hard_regs_nodes_num;
959 i = allocno_hard_regs_subnode_index[start + removed_node->preorder_num];
960 if (i < 0)
961 i = 0;
962 subnodes = allocno_hard_regs_subnodes + data->hard_regs_subnodes_start;
963 before_conflict_size
964 = (subnodes[i].left_conflict_subnodes_size
965 + MIN (subnodes[i].max_node_impact
966 - subnodes[i].left_conflict_subnodes_size,
967 subnodes[i].left_conflict_size));
968 subnodes[i].left_conflict_size -= size;
969 for (;;)
971 conflict_size
972 = (subnodes[i].left_conflict_subnodes_size
973 + MIN (subnodes[i].max_node_impact
974 - subnodes[i].left_conflict_subnodes_size,
975 subnodes[i].left_conflict_size));
976 if ((diff = before_conflict_size - conflict_size) == 0)
977 break;
978 ira_assert (conflict_size < before_conflict_size);
979 parent = allocno_hard_regs_nodes[i + node_preorder_num]->parent;
980 if (parent == NULL)
981 break;
982 parent_i
983 = allocno_hard_regs_subnode_index[start + parent->preorder_num];
984 if (parent_i < 0)
985 break;
986 i = parent_i;
987 before_conflict_size
988 = (subnodes[i].left_conflict_subnodes_size
989 + MIN (subnodes[i].max_node_impact
990 - subnodes[i].left_conflict_subnodes_size,
991 subnodes[i].left_conflict_size));
992 subnodes[i].left_conflict_subnodes_size -= diff;
994 if (i != 0
995 || (conflict_size
996 + ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]
997 > data->available_regs_num))
998 return false;
999 data->colorable_p = true;
1000 return true;
1003 /* Return true if allocno A has empty profitable hard regs. */
1004 static bool
1005 empty_profitable_hard_regs (ira_allocno_t a)
1007 allocno_color_data_t data = ALLOCNO_COLOR_DATA (a);
1009 return hard_reg_set_empty_p (data->profitable_hard_regs);
1012 /* Set up profitable hard registers for each allocno being
1013 colored. */
1014 static void
1015 setup_profitable_hard_regs (void)
1017 unsigned int i;
1018 int j, k, nobj, hard_regno, nregs, class_size;
1019 ira_allocno_t a;
1020 bitmap_iterator bi;
1021 enum reg_class aclass;
1022 machine_mode mode;
1023 allocno_color_data_t data;
1025 /* Initial set up from allocno classes and explicitly conflicting
1026 hard regs. */
1027 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
1029 a = ira_allocnos[i];
1030 if ((aclass = ALLOCNO_CLASS (a)) == NO_REGS)
1031 continue;
1032 data = ALLOCNO_COLOR_DATA (a);
1033 if (ALLOCNO_UPDATED_HARD_REG_COSTS (a) == NULL
1034 && ALLOCNO_CLASS_COST (a) > ALLOCNO_MEMORY_COST (a)
1035 /* Do not empty profitable regs for static chain pointer
1036 pseudo when non-local goto is used. */
1037 && ! non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a)))
1038 CLEAR_HARD_REG_SET (data->profitable_hard_regs);
1039 else
1041 mode = ALLOCNO_MODE (a);
1042 COPY_HARD_REG_SET (data->profitable_hard_regs,
1043 ira_useful_class_mode_regs[aclass][mode]);
1044 nobj = ALLOCNO_NUM_OBJECTS (a);
1045 for (k = 0; k < nobj; k++)
1047 ira_object_t obj = ALLOCNO_OBJECT (a, k);
1049 AND_COMPL_HARD_REG_SET (data->profitable_hard_regs,
1050 OBJECT_TOTAL_CONFLICT_HARD_REGS (obj));
1054 /* Exclude hard regs already assigned for conflicting objects. */
1055 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, i, bi)
1057 a = ira_allocnos[i];
1058 if ((aclass = ALLOCNO_CLASS (a)) == NO_REGS
1059 || ! ALLOCNO_ASSIGNED_P (a)
1060 || (hard_regno = ALLOCNO_HARD_REGNO (a)) < 0)
1061 continue;
1062 mode = ALLOCNO_MODE (a);
1063 nregs = hard_regno_nregs[hard_regno][mode];
1064 nobj = ALLOCNO_NUM_OBJECTS (a);
1065 for (k = 0; k < nobj; k++)
1067 ira_object_t obj = ALLOCNO_OBJECT (a, k);
1068 ira_object_t conflict_obj;
1069 ira_object_conflict_iterator oci;
1071 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
1073 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
1075 /* We can process the conflict allocno repeatedly with
1076 the same result. */
1077 if (nregs == nobj && nregs > 1)
1079 int num = OBJECT_SUBWORD (conflict_obj);
1081 if (REG_WORDS_BIG_ENDIAN)
1082 CLEAR_HARD_REG_BIT
1083 (ALLOCNO_COLOR_DATA (conflict_a)->profitable_hard_regs,
1084 hard_regno + nobj - num - 1);
1085 else
1086 CLEAR_HARD_REG_BIT
1087 (ALLOCNO_COLOR_DATA (conflict_a)->profitable_hard_regs,
1088 hard_regno + num);
1090 else
1091 AND_COMPL_HARD_REG_SET
1092 (ALLOCNO_COLOR_DATA (conflict_a)->profitable_hard_regs,
1093 ira_reg_mode_hard_regset[hard_regno][mode]);
1097 /* Exclude too costly hard regs. */
1098 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
1100 int min_cost = INT_MAX;
1101 int *costs;
1103 a = ira_allocnos[i];
1104 if ((aclass = ALLOCNO_CLASS (a)) == NO_REGS
1105 || empty_profitable_hard_regs (a))
1106 continue;
1107 data = ALLOCNO_COLOR_DATA (a);
1108 mode = ALLOCNO_MODE (a);
1109 if ((costs = ALLOCNO_UPDATED_HARD_REG_COSTS (a)) != NULL
1110 || (costs = ALLOCNO_HARD_REG_COSTS (a)) != NULL)
1112 class_size = ira_class_hard_regs_num[aclass];
1113 for (j = 0; j < class_size; j++)
1115 hard_regno = ira_class_hard_regs[aclass][j];
1116 if (! TEST_HARD_REG_BIT (data->profitable_hard_regs,
1117 hard_regno))
1118 continue;
1119 if (ALLOCNO_UPDATED_MEMORY_COST (a) < costs[j]
1120 /* Do not remove HARD_REGNO for static chain pointer
1121 pseudo when non-local goto is used. */
1122 && ! non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a)))
1123 CLEAR_HARD_REG_BIT (data->profitable_hard_regs,
1124 hard_regno);
1125 else if (min_cost > costs[j])
1126 min_cost = costs[j];
1129 else if (ALLOCNO_UPDATED_MEMORY_COST (a)
1130 < ALLOCNO_UPDATED_CLASS_COST (a)
1131 /* Do not empty profitable regs for static chain
1132 pointer pseudo when non-local goto is used. */
1133 && ! non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a)))
1134 CLEAR_HARD_REG_SET (data->profitable_hard_regs);
1135 if (ALLOCNO_UPDATED_CLASS_COST (a) > min_cost)
1136 ALLOCNO_UPDATED_CLASS_COST (a) = min_cost;
1142 /* This page contains functions used to choose hard registers for
1143 allocnos. */
1145 /* Pool for update cost records. */
1146 static object_allocator<update_cost_record> update_cost_record_pool
1147 ("update cost records");
1149 /* Return new update cost record with given params. */
1150 static struct update_cost_record *
1151 get_update_cost_record (int hard_regno, int divisor,
1152 struct update_cost_record *next)
1154 struct update_cost_record *record;
1156 record = update_cost_record_pool.allocate ();
1157 record->hard_regno = hard_regno;
1158 record->divisor = divisor;
1159 record->next = next;
1160 return record;
1163 /* Free memory for all records in LIST. */
1164 static void
1165 free_update_cost_record_list (struct update_cost_record *list)
1167 struct update_cost_record *next;
1169 while (list != NULL)
1171 next = list->next;
1172 update_cost_record_pool.remove (list);
1173 list = next;
1177 /* Free memory allocated for all update cost records. */
1178 static void
1179 finish_update_cost_records (void)
1181 update_cost_record_pool.release ();
1184 /* Array whose element value is TRUE if the corresponding hard
1185 register was already allocated for an allocno. */
1186 static bool allocated_hardreg_p[FIRST_PSEUDO_REGISTER];
1188 /* Describes one element in a queue of allocnos whose costs need to be
1189 updated. Each allocno in the queue is known to have an allocno
1190 class. */
1191 struct update_cost_queue_elem
1193 /* This element is in the queue iff CHECK == update_cost_check. */
1194 int check;
1196 /* COST_HOP_DIVISOR**N, where N is the length of the shortest path
1197 connecting this allocno to the one being allocated. */
1198 int divisor;
1200 /* Allocno from which we are chaining costs of connected allocnos.
1201 It is used not go back in graph of allocnos connected by
1202 copies. */
1203 ira_allocno_t from;
1205 /* The next allocno in the queue, or null if this is the last element. */
1206 ira_allocno_t next;
1209 /* The first element in a queue of allocnos whose copy costs need to be
1210 updated. Null if the queue is empty. */
1211 static ira_allocno_t update_cost_queue;
1213 /* The last element in the queue described by update_cost_queue.
1214 Not valid if update_cost_queue is null. */
1215 static struct update_cost_queue_elem *update_cost_queue_tail;
1217 /* A pool of elements in the queue described by update_cost_queue.
1218 Elements are indexed by ALLOCNO_NUM. */
1219 static struct update_cost_queue_elem *update_cost_queue_elems;
1221 /* The current value of update_costs_from_copies call count. */
1222 static int update_cost_check;
1224 /* Allocate and initialize data necessary for function
1225 update_costs_from_copies. */
1226 static void
1227 initiate_cost_update (void)
1229 size_t size;
1231 size = ira_allocnos_num * sizeof (struct update_cost_queue_elem);
1232 update_cost_queue_elems
1233 = (struct update_cost_queue_elem *) ira_allocate (size);
1234 memset (update_cost_queue_elems, 0, size);
1235 update_cost_check = 0;
1238 /* Deallocate data used by function update_costs_from_copies. */
1239 static void
1240 finish_cost_update (void)
1242 ira_free (update_cost_queue_elems);
1243 finish_update_cost_records ();
1246 /* When we traverse allocnos to update hard register costs, the cost
1247 divisor will be multiplied by the following macro value for each
1248 hop from given allocno to directly connected allocnos. */
1249 #define COST_HOP_DIVISOR 4
1251 /* Start a new cost-updating pass. */
1252 static void
1253 start_update_cost (void)
1255 update_cost_check++;
1256 update_cost_queue = NULL;
1259 /* Add (ALLOCNO, FROM, DIVISOR) to the end of update_cost_queue, unless
1260 ALLOCNO is already in the queue, or has NO_REGS class. */
1261 static inline void
1262 queue_update_cost (ira_allocno_t allocno, ira_allocno_t from, int divisor)
1264 struct update_cost_queue_elem *elem;
1266 elem = &update_cost_queue_elems[ALLOCNO_NUM (allocno)];
1267 if (elem->check != update_cost_check
1268 && ALLOCNO_CLASS (allocno) != NO_REGS)
1270 elem->check = update_cost_check;
1271 elem->from = from;
1272 elem->divisor = divisor;
1273 elem->next = NULL;
1274 if (update_cost_queue == NULL)
1275 update_cost_queue = allocno;
1276 else
1277 update_cost_queue_tail->next = allocno;
1278 update_cost_queue_tail = elem;
1282 /* Try to remove the first element from update_cost_queue. Return
1283 false if the queue was empty, otherwise make (*ALLOCNO, *FROM,
1284 *DIVISOR) describe the removed element. */
1285 static inline bool
1286 get_next_update_cost (ira_allocno_t *allocno, ira_allocno_t *from, int *divisor)
1288 struct update_cost_queue_elem *elem;
1290 if (update_cost_queue == NULL)
1291 return false;
1293 *allocno = update_cost_queue;
1294 elem = &update_cost_queue_elems[ALLOCNO_NUM (*allocno)];
1295 *from = elem->from;
1296 *divisor = elem->divisor;
1297 update_cost_queue = elem->next;
1298 return true;
1301 /* Increase costs of HARD_REGNO by UPDATE_COST and conflict cost by
1302 UPDATE_CONFLICT_COST for ALLOCNO. Return true if we really
1303 modified the cost. */
1304 static bool
1305 update_allocno_cost (ira_allocno_t allocno, int hard_regno,
1306 int update_cost, int update_conflict_cost)
1308 int i;
1309 enum reg_class aclass = ALLOCNO_CLASS (allocno);
1311 i = ira_class_hard_reg_index[aclass][hard_regno];
1312 if (i < 0)
1313 return false;
1314 ira_allocate_and_set_or_copy_costs
1315 (&ALLOCNO_UPDATED_HARD_REG_COSTS (allocno), aclass,
1316 ALLOCNO_UPDATED_CLASS_COST (allocno),
1317 ALLOCNO_HARD_REG_COSTS (allocno));
1318 ira_allocate_and_set_or_copy_costs
1319 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (allocno),
1320 aclass, 0, ALLOCNO_CONFLICT_HARD_REG_COSTS (allocno));
1321 ALLOCNO_UPDATED_HARD_REG_COSTS (allocno)[i] += update_cost;
1322 ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (allocno)[i] += update_conflict_cost;
1323 return true;
1326 /* Update (decrease if DECR_P) HARD_REGNO cost of allocnos connected
1327 by copies to ALLOCNO to increase chances to remove some copies as
1328 the result of subsequent assignment. Record cost updates if
1329 RECORD_P is true. */
1330 static void
1331 update_costs_from_allocno (ira_allocno_t allocno, int hard_regno,
1332 int divisor, bool decr_p, bool record_p)
1334 int cost, update_cost, update_conflict_cost;
1335 machine_mode mode;
1336 enum reg_class rclass, aclass;
1337 ira_allocno_t another_allocno, from = NULL;
1338 ira_copy_t cp, next_cp;
1340 rclass = REGNO_REG_CLASS (hard_regno);
1343 mode = ALLOCNO_MODE (allocno);
1344 ira_init_register_move_cost_if_necessary (mode);
1345 for (cp = ALLOCNO_COPIES (allocno); cp != NULL; cp = next_cp)
1347 if (cp->first == allocno)
1349 next_cp = cp->next_first_allocno_copy;
1350 another_allocno = cp->second;
1352 else if (cp->second == allocno)
1354 next_cp = cp->next_second_allocno_copy;
1355 another_allocno = cp->first;
1357 else
1358 gcc_unreachable ();
1360 if (another_allocno == from)
1361 continue;
1363 aclass = ALLOCNO_CLASS (another_allocno);
1364 if (! TEST_HARD_REG_BIT (reg_class_contents[aclass],
1365 hard_regno)
1366 || ALLOCNO_ASSIGNED_P (another_allocno))
1367 continue;
1369 cost = (cp->second == allocno
1370 ? ira_register_move_cost[mode][rclass][aclass]
1371 : ira_register_move_cost[mode][aclass][rclass]);
1372 if (decr_p)
1373 cost = -cost;
1375 update_conflict_cost = update_cost = cp->freq * cost / divisor;
1377 if (ALLOCNO_COLOR_DATA (another_allocno) != NULL
1378 && (ALLOCNO_COLOR_DATA (allocno)->first_thread_allocno
1379 != ALLOCNO_COLOR_DATA (another_allocno)->first_thread_allocno))
1380 /* Decrease conflict cost of ANOTHER_ALLOCNO if it is not
1381 in the same allocation thread. */
1382 update_conflict_cost /= COST_HOP_DIVISOR;
1384 if (update_cost == 0)
1385 continue;
1387 if (! update_allocno_cost (another_allocno, hard_regno,
1388 update_cost, update_conflict_cost))
1389 continue;
1390 queue_update_cost (another_allocno, allocno, divisor * COST_HOP_DIVISOR);
1391 if (record_p && ALLOCNO_COLOR_DATA (another_allocno) != NULL)
1392 ALLOCNO_COLOR_DATA (another_allocno)->update_cost_records
1393 = get_update_cost_record (hard_regno, divisor,
1394 ALLOCNO_COLOR_DATA (another_allocno)
1395 ->update_cost_records);
1398 while (get_next_update_cost (&allocno, &from, &divisor));
1401 /* Decrease preferred ALLOCNO hard register costs and costs of
1402 allocnos connected to ALLOCNO through copy. */
1403 static void
1404 update_costs_from_prefs (ira_allocno_t allocno)
1406 ira_pref_t pref;
1408 start_update_cost ();
1409 for (pref = ALLOCNO_PREFS (allocno); pref != NULL; pref = pref->next_pref)
1410 update_costs_from_allocno (allocno, pref->hard_regno,
1411 COST_HOP_DIVISOR, true, true);
1414 /* Update (decrease if DECR_P) the cost of allocnos connected to
1415 ALLOCNO through copies to increase chances to remove some copies as
1416 the result of subsequent assignment. ALLOCNO was just assigned to
1417 a hard register. Record cost updates if RECORD_P is true. */
1418 static void
1419 update_costs_from_copies (ira_allocno_t allocno, bool decr_p, bool record_p)
1421 int hard_regno;
1423 hard_regno = ALLOCNO_HARD_REGNO (allocno);
1424 ira_assert (hard_regno >= 0 && ALLOCNO_CLASS (allocno) != NO_REGS);
1425 start_update_cost ();
1426 update_costs_from_allocno (allocno, hard_regno, 1, decr_p, record_p);
1429 /* Restore costs of allocnos connected to ALLOCNO by copies as it was
1430 before updating costs of these allocnos from given allocno. This
1431 is a wise thing to do as if given allocno did not get an expected
1432 hard reg, using smaller cost of the hard reg for allocnos connected
1433 by copies to given allocno becomes actually misleading. Free all
1434 update cost records for ALLOCNO as we don't need them anymore. */
1435 static void
1436 restore_costs_from_copies (ira_allocno_t allocno)
1438 struct update_cost_record *records, *curr;
1440 if (ALLOCNO_COLOR_DATA (allocno) == NULL)
1441 return;
1442 records = ALLOCNO_COLOR_DATA (allocno)->update_cost_records;
1443 start_update_cost ();
1444 for (curr = records; curr != NULL; curr = curr->next)
1445 update_costs_from_allocno (allocno, curr->hard_regno,
1446 curr->divisor, true, false);
1447 free_update_cost_record_list (records);
1448 ALLOCNO_COLOR_DATA (allocno)->update_cost_records = NULL;
1451 /* This function updates COSTS (decrease if DECR_P) for hard_registers
1452 of ACLASS by conflict costs of the unassigned allocnos
1453 connected by copies with allocnos in update_cost_queue. This
1454 update increases chances to remove some copies. */
1455 static void
1456 update_conflict_hard_regno_costs (int *costs, enum reg_class aclass,
1457 bool decr_p)
1459 int i, cost, class_size, freq, mult, div, divisor;
1460 int index, hard_regno;
1461 int *conflict_costs;
1462 bool cont_p;
1463 enum reg_class another_aclass;
1464 ira_allocno_t allocno, another_allocno, from;
1465 ira_copy_t cp, next_cp;
1467 while (get_next_update_cost (&allocno, &from, &divisor))
1468 for (cp = ALLOCNO_COPIES (allocno); cp != NULL; cp = next_cp)
1470 if (cp->first == allocno)
1472 next_cp = cp->next_first_allocno_copy;
1473 another_allocno = cp->second;
1475 else if (cp->second == allocno)
1477 next_cp = cp->next_second_allocno_copy;
1478 another_allocno = cp->first;
1480 else
1481 gcc_unreachable ();
1483 if (another_allocno == from)
1484 continue;
1486 another_aclass = ALLOCNO_CLASS (another_allocno);
1487 if (! ira_reg_classes_intersect_p[aclass][another_aclass]
1488 || ALLOCNO_ASSIGNED_P (another_allocno)
1489 || ALLOCNO_COLOR_DATA (another_allocno)->may_be_spilled_p)
1490 continue;
1491 class_size = ira_class_hard_regs_num[another_aclass];
1492 ira_allocate_and_copy_costs
1493 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (another_allocno),
1494 another_aclass, ALLOCNO_CONFLICT_HARD_REG_COSTS (another_allocno));
1495 conflict_costs
1496 = ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (another_allocno);
1497 if (conflict_costs == NULL)
1498 cont_p = true;
1499 else
1501 mult = cp->freq;
1502 freq = ALLOCNO_FREQ (another_allocno);
1503 if (freq == 0)
1504 freq = 1;
1505 div = freq * divisor;
1506 cont_p = false;
1507 for (i = class_size - 1; i >= 0; i--)
1509 hard_regno = ira_class_hard_regs[another_aclass][i];
1510 ira_assert (hard_regno >= 0);
1511 index = ira_class_hard_reg_index[aclass][hard_regno];
1512 if (index < 0)
1513 continue;
1514 cost = (int) ((unsigned) conflict_costs [i] * mult) / div;
1515 if (cost == 0)
1516 continue;
1517 cont_p = true;
1518 if (decr_p)
1519 cost = -cost;
1520 costs[index] += cost;
1523 /* Probably 5 hops will be enough. */
1524 if (cont_p
1525 && divisor <= (COST_HOP_DIVISOR
1526 * COST_HOP_DIVISOR
1527 * COST_HOP_DIVISOR
1528 * COST_HOP_DIVISOR))
1529 queue_update_cost (another_allocno, allocno, divisor * COST_HOP_DIVISOR);
1533 /* Set up conflicting (through CONFLICT_REGS) for each object of
1534 allocno A and the start allocno profitable regs (through
1535 START_PROFITABLE_REGS). Remember that the start profitable regs
1536 exclude hard regs which can not hold value of mode of allocno A.
1537 This covers mostly cases when multi-register value should be
1538 aligned. */
1539 static inline void
1540 get_conflict_and_start_profitable_regs (ira_allocno_t a, bool retry_p,
1541 HARD_REG_SET *conflict_regs,
1542 HARD_REG_SET *start_profitable_regs)
1544 int i, nwords;
1545 ira_object_t obj;
1547 nwords = ALLOCNO_NUM_OBJECTS (a);
1548 for (i = 0; i < nwords; i++)
1550 obj = ALLOCNO_OBJECT (a, i);
1551 COPY_HARD_REG_SET (conflict_regs[i],
1552 OBJECT_TOTAL_CONFLICT_HARD_REGS (obj));
1554 if (retry_p)
1556 COPY_HARD_REG_SET (*start_profitable_regs,
1557 reg_class_contents[ALLOCNO_CLASS (a)]);
1558 AND_COMPL_HARD_REG_SET (*start_profitable_regs,
1559 ira_prohibited_class_mode_regs
1560 [ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]);
1562 else
1563 COPY_HARD_REG_SET (*start_profitable_regs,
1564 ALLOCNO_COLOR_DATA (a)->profitable_hard_regs);
1567 /* Return true if HARD_REGNO is ok for assigning to allocno A with
1568 PROFITABLE_REGS and whose objects have CONFLICT_REGS. */
1569 static inline bool
1570 check_hard_reg_p (ira_allocno_t a, int hard_regno,
1571 HARD_REG_SET *conflict_regs, HARD_REG_SET profitable_regs)
1573 int j, nwords, nregs;
1574 enum reg_class aclass;
1575 machine_mode mode;
1577 aclass = ALLOCNO_CLASS (a);
1578 mode = ALLOCNO_MODE (a);
1579 if (TEST_HARD_REG_BIT (ira_prohibited_class_mode_regs[aclass][mode],
1580 hard_regno))
1581 return false;
1582 /* Checking only profitable hard regs. */
1583 if (! TEST_HARD_REG_BIT (profitable_regs, hard_regno))
1584 return false;
1585 nregs = hard_regno_nregs[hard_regno][mode];
1586 nwords = ALLOCNO_NUM_OBJECTS (a);
1587 for (j = 0; j < nregs; j++)
1589 int k;
1590 int set_to_test_start = 0, set_to_test_end = nwords;
1592 if (nregs == nwords)
1594 if (REG_WORDS_BIG_ENDIAN)
1595 set_to_test_start = nwords - j - 1;
1596 else
1597 set_to_test_start = j;
1598 set_to_test_end = set_to_test_start + 1;
1600 for (k = set_to_test_start; k < set_to_test_end; k++)
1601 if (TEST_HARD_REG_BIT (conflict_regs[k], hard_regno + j))
1602 break;
1603 if (k != set_to_test_end)
1604 break;
1606 return j == nregs;
1609 /* Return number of registers needed to be saved and restored at
1610 function prologue/epilogue if we allocate HARD_REGNO to hold value
1611 of MODE. */
1612 static int
1613 calculate_saved_nregs (int hard_regno, machine_mode mode)
1615 int i;
1616 int nregs = 0;
1618 ira_assert (hard_regno >= 0);
1619 for (i = hard_regno_nregs[hard_regno][mode] - 1; i >= 0; i--)
1620 if (!allocated_hardreg_p[hard_regno + i]
1621 && !TEST_HARD_REG_BIT (call_used_reg_set, hard_regno + i)
1622 && !LOCAL_REGNO (hard_regno + i))
1623 nregs++;
1624 return nregs;
1627 /* Choose a hard register for allocno A. If RETRY_P is TRUE, it means
1628 that the function called from function
1629 `ira_reassign_conflict_allocnos' and `allocno_reload_assign'. In
1630 this case some allocno data are not defined or updated and we
1631 should not touch these data. The function returns true if we
1632 managed to assign a hard register to the allocno.
1634 To assign a hard register, first of all we calculate all conflict
1635 hard registers which can come from conflicting allocnos with
1636 already assigned hard registers. After that we find first free
1637 hard register with the minimal cost. During hard register cost
1638 calculation we take conflict hard register costs into account to
1639 give a chance for conflicting allocnos to get a better hard
1640 register in the future.
1642 If the best hard register cost is bigger than cost of memory usage
1643 for the allocno, we don't assign a hard register to given allocno
1644 at all.
1646 If we assign a hard register to the allocno, we update costs of the
1647 hard register for allocnos connected by copies to improve a chance
1648 to coalesce insns represented by the copies when we assign hard
1649 registers to the allocnos connected by the copies. */
1650 static bool
1651 assign_hard_reg (ira_allocno_t a, bool retry_p)
1653 HARD_REG_SET conflicting_regs[2], profitable_hard_regs;
1654 int i, j, hard_regno, best_hard_regno, class_size;
1655 int cost, mem_cost, min_cost, full_cost, min_full_cost, nwords, word;
1656 int *a_costs;
1657 enum reg_class aclass;
1658 machine_mode mode;
1659 static int costs[FIRST_PSEUDO_REGISTER], full_costs[FIRST_PSEUDO_REGISTER];
1660 int saved_nregs;
1661 enum reg_class rclass;
1662 int add_cost;
1663 #ifdef STACK_REGS
1664 bool no_stack_reg_p;
1665 #endif
1667 ira_assert (! ALLOCNO_ASSIGNED_P (a));
1668 get_conflict_and_start_profitable_regs (a, retry_p,
1669 conflicting_regs,
1670 &profitable_hard_regs);
1671 aclass = ALLOCNO_CLASS (a);
1672 class_size = ira_class_hard_regs_num[aclass];
1673 best_hard_regno = -1;
1674 memset (full_costs, 0, sizeof (int) * class_size);
1675 mem_cost = 0;
1676 memset (costs, 0, sizeof (int) * class_size);
1677 memset (full_costs, 0, sizeof (int) * class_size);
1678 #ifdef STACK_REGS
1679 no_stack_reg_p = false;
1680 #endif
1681 if (! retry_p)
1682 start_update_cost ();
1683 mem_cost += ALLOCNO_UPDATED_MEMORY_COST (a);
1685 ira_allocate_and_copy_costs (&ALLOCNO_UPDATED_HARD_REG_COSTS (a),
1686 aclass, ALLOCNO_HARD_REG_COSTS (a));
1687 a_costs = ALLOCNO_UPDATED_HARD_REG_COSTS (a);
1688 #ifdef STACK_REGS
1689 no_stack_reg_p = no_stack_reg_p || ALLOCNO_TOTAL_NO_STACK_REG_P (a);
1690 #endif
1691 cost = ALLOCNO_UPDATED_CLASS_COST (a);
1692 for (i = 0; i < class_size; i++)
1693 if (a_costs != NULL)
1695 costs[i] += a_costs[i];
1696 full_costs[i] += a_costs[i];
1698 else
1700 costs[i] += cost;
1701 full_costs[i] += cost;
1703 nwords = ALLOCNO_NUM_OBJECTS (a);
1704 curr_allocno_process++;
1705 for (word = 0; word < nwords; word++)
1707 ira_object_t conflict_obj;
1708 ira_object_t obj = ALLOCNO_OBJECT (a, word);
1709 ira_object_conflict_iterator oci;
1711 /* Take preferences of conflicting allocnos into account. */
1712 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
1714 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
1715 enum reg_class conflict_aclass;
1716 allocno_color_data_t data = ALLOCNO_COLOR_DATA (conflict_a);
1718 /* Reload can give another class so we need to check all
1719 allocnos. */
1720 if (!retry_p
1721 && ((!ALLOCNO_ASSIGNED_P (conflict_a)
1722 || ALLOCNO_HARD_REGNO (conflict_a) < 0)
1723 && !(hard_reg_set_intersect_p
1724 (profitable_hard_regs,
1725 ALLOCNO_COLOR_DATA
1726 (conflict_a)->profitable_hard_regs))))
1728 /* All conflict allocnos are in consideration bitmap
1729 when retry_p is false. It might change in future and
1730 if it happens the assert will be broken. It means
1731 the code should be modified for the new
1732 assumptions. */
1733 ira_assert (bitmap_bit_p (consideration_allocno_bitmap,
1734 ALLOCNO_NUM (conflict_a)));
1735 continue;
1737 conflict_aclass = ALLOCNO_CLASS (conflict_a);
1738 ira_assert (ira_reg_classes_intersect_p
1739 [aclass][conflict_aclass]);
1740 if (ALLOCNO_ASSIGNED_P (conflict_a))
1742 hard_regno = ALLOCNO_HARD_REGNO (conflict_a);
1743 if (hard_regno >= 0
1744 && (ira_hard_reg_set_intersection_p
1745 (hard_regno, ALLOCNO_MODE (conflict_a),
1746 reg_class_contents[aclass])))
1748 int n_objects = ALLOCNO_NUM_OBJECTS (conflict_a);
1749 int conflict_nregs;
1751 mode = ALLOCNO_MODE (conflict_a);
1752 conflict_nregs = hard_regno_nregs[hard_regno][mode];
1753 if (conflict_nregs == n_objects && conflict_nregs > 1)
1755 int num = OBJECT_SUBWORD (conflict_obj);
1757 if (REG_WORDS_BIG_ENDIAN)
1758 SET_HARD_REG_BIT (conflicting_regs[word],
1759 hard_regno + n_objects - num - 1);
1760 else
1761 SET_HARD_REG_BIT (conflicting_regs[word],
1762 hard_regno + num);
1764 else
1765 IOR_HARD_REG_SET
1766 (conflicting_regs[word],
1767 ira_reg_mode_hard_regset[hard_regno][mode]);
1768 if (hard_reg_set_subset_p (profitable_hard_regs,
1769 conflicting_regs[word]))
1770 goto fail;
1773 else if (! retry_p
1774 && ! ALLOCNO_COLOR_DATA (conflict_a)->may_be_spilled_p
1775 /* Don't process the conflict allocno twice. */
1776 && (ALLOCNO_COLOR_DATA (conflict_a)->last_process
1777 != curr_allocno_process))
1779 int k, *conflict_costs;
1781 ALLOCNO_COLOR_DATA (conflict_a)->last_process
1782 = curr_allocno_process;
1783 ira_allocate_and_copy_costs
1784 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (conflict_a),
1785 conflict_aclass,
1786 ALLOCNO_CONFLICT_HARD_REG_COSTS (conflict_a));
1787 conflict_costs
1788 = ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (conflict_a);
1789 if (conflict_costs != NULL)
1790 for (j = class_size - 1; j >= 0; j--)
1792 hard_regno = ira_class_hard_regs[aclass][j];
1793 ira_assert (hard_regno >= 0);
1794 k = ira_class_hard_reg_index[conflict_aclass][hard_regno];
1795 if (k < 0
1796 /* If HARD_REGNO is not available for CONFLICT_A,
1797 the conflict would be ignored, since HARD_REGNO
1798 will never be assigned to CONFLICT_A. */
1799 || !TEST_HARD_REG_BIT (data->profitable_hard_regs,
1800 hard_regno))
1801 continue;
1802 full_costs[j] -= conflict_costs[k];
1804 queue_update_cost (conflict_a, NULL, COST_HOP_DIVISOR);
1809 if (! retry_p)
1810 /* Take into account preferences of allocnos connected by copies to
1811 the conflict allocnos. */
1812 update_conflict_hard_regno_costs (full_costs, aclass, true);
1814 /* Take preferences of allocnos connected by copies into
1815 account. */
1816 if (! retry_p)
1818 start_update_cost ();
1819 queue_update_cost (a, NULL, COST_HOP_DIVISOR);
1820 update_conflict_hard_regno_costs (full_costs, aclass, false);
1822 min_cost = min_full_cost = INT_MAX;
1823 /* We don't care about giving callee saved registers to allocnos no
1824 living through calls because call clobbered registers are
1825 allocated first (it is usual practice to put them first in
1826 REG_ALLOC_ORDER). */
1827 mode = ALLOCNO_MODE (a);
1828 for (i = 0; i < class_size; i++)
1830 hard_regno = ira_class_hard_regs[aclass][i];
1831 #ifdef STACK_REGS
1832 if (no_stack_reg_p
1833 && FIRST_STACK_REG <= hard_regno && hard_regno <= LAST_STACK_REG)
1834 continue;
1835 #endif
1836 if (! check_hard_reg_p (a, hard_regno,
1837 conflicting_regs, profitable_hard_regs))
1838 continue;
1839 cost = costs[i];
1840 full_cost = full_costs[i];
1841 if (!HONOR_REG_ALLOC_ORDER)
1843 if ((saved_nregs = calculate_saved_nregs (hard_regno, mode)) != 0)
1844 /* We need to save/restore the hard register in
1845 epilogue/prologue. Therefore we increase the cost. */
1847 rclass = REGNO_REG_CLASS (hard_regno);
1848 add_cost = ((ira_memory_move_cost[mode][rclass][0]
1849 + ira_memory_move_cost[mode][rclass][1])
1850 * saved_nregs / hard_regno_nregs[hard_regno][mode] - 1);
1851 cost += add_cost;
1852 full_cost += add_cost;
1855 if (min_cost > cost)
1856 min_cost = cost;
1857 if (min_full_cost > full_cost)
1859 min_full_cost = full_cost;
1860 best_hard_regno = hard_regno;
1861 ira_assert (hard_regno >= 0);
1864 if (min_full_cost > mem_cost
1865 /* Do not spill static chain pointer pseudo when non-local goto
1866 is used. */
1867 && ! non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a)))
1869 if (! retry_p && internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
1870 fprintf (ira_dump_file, "(memory is more profitable %d vs %d) ",
1871 mem_cost, min_full_cost);
1872 best_hard_regno = -1;
1874 fail:
1875 if (best_hard_regno >= 0)
1877 for (i = hard_regno_nregs[best_hard_regno][mode] - 1; i >= 0; i--)
1878 allocated_hardreg_p[best_hard_regno + i] = true;
1880 if (! retry_p)
1881 restore_costs_from_copies (a);
1882 ALLOCNO_HARD_REGNO (a) = best_hard_regno;
1883 ALLOCNO_ASSIGNED_P (a) = true;
1884 if (best_hard_regno >= 0)
1885 update_costs_from_copies (a, true, ! retry_p);
1886 ira_assert (ALLOCNO_CLASS (a) == aclass);
1887 /* We don't need updated costs anymore. */
1888 ira_free_allocno_updated_costs (a);
1889 return best_hard_regno >= 0;
1894 /* An array used to sort copies. */
1895 static ira_copy_t *sorted_copies;
1897 /* Return TRUE if live ranges of allocnos A1 and A2 intersect. It is
1898 used to find a conflict for new allocnos or allocnos with the
1899 different allocno classes. */
1900 static bool
1901 allocnos_conflict_by_live_ranges_p (ira_allocno_t a1, ira_allocno_t a2)
1903 rtx reg1, reg2;
1904 int i, j;
1905 int n1 = ALLOCNO_NUM_OBJECTS (a1);
1906 int n2 = ALLOCNO_NUM_OBJECTS (a2);
1908 if (a1 == a2)
1909 return false;
1910 reg1 = regno_reg_rtx[ALLOCNO_REGNO (a1)];
1911 reg2 = regno_reg_rtx[ALLOCNO_REGNO (a2)];
1912 if (reg1 != NULL && reg2 != NULL
1913 && ORIGINAL_REGNO (reg1) == ORIGINAL_REGNO (reg2))
1914 return false;
1916 for (i = 0; i < n1; i++)
1918 ira_object_t c1 = ALLOCNO_OBJECT (a1, i);
1920 for (j = 0; j < n2; j++)
1922 ira_object_t c2 = ALLOCNO_OBJECT (a2, j);
1924 if (ira_live_ranges_intersect_p (OBJECT_LIVE_RANGES (c1),
1925 OBJECT_LIVE_RANGES (c2)))
1926 return true;
1929 return false;
1932 /* The function is used to sort copies according to their execution
1933 frequencies. */
1934 static int
1935 copy_freq_compare_func (const void *v1p, const void *v2p)
1937 ira_copy_t cp1 = *(const ira_copy_t *) v1p, cp2 = *(const ira_copy_t *) v2p;
1938 int pri1, pri2;
1940 pri1 = cp1->freq;
1941 pri2 = cp2->freq;
1942 if (pri2 - pri1)
1943 return pri2 - pri1;
1945 /* If frequencies are equal, sort by copies, so that the results of
1946 qsort leave nothing to chance. */
1947 return cp1->num - cp2->num;
1952 /* Return true if any allocno from thread of A1 conflicts with any
1953 allocno from thread A2. */
1954 static bool
1955 allocno_thread_conflict_p (ira_allocno_t a1, ira_allocno_t a2)
1957 ira_allocno_t a, conflict_a;
1959 for (a = ALLOCNO_COLOR_DATA (a2)->next_thread_allocno;;
1960 a = ALLOCNO_COLOR_DATA (a)->next_thread_allocno)
1962 for (conflict_a = ALLOCNO_COLOR_DATA (a1)->next_thread_allocno;;
1963 conflict_a = ALLOCNO_COLOR_DATA (conflict_a)->next_thread_allocno)
1965 if (allocnos_conflict_by_live_ranges_p (a, conflict_a))
1966 return true;
1967 if (conflict_a == a1)
1968 break;
1970 if (a == a2)
1971 break;
1973 return false;
1976 /* Merge two threads given correspondingly by their first allocnos T1
1977 and T2 (more accurately merging T2 into T1). */
1978 static void
1979 merge_threads (ira_allocno_t t1, ira_allocno_t t2)
1981 ira_allocno_t a, next, last;
1983 gcc_assert (t1 != t2
1984 && ALLOCNO_COLOR_DATA (t1)->first_thread_allocno == t1
1985 && ALLOCNO_COLOR_DATA (t2)->first_thread_allocno == t2);
1986 for (last = t2, a = ALLOCNO_COLOR_DATA (t2)->next_thread_allocno;;
1987 a = ALLOCNO_COLOR_DATA (a)->next_thread_allocno)
1989 ALLOCNO_COLOR_DATA (a)->first_thread_allocno = t1;
1990 if (a == t2)
1991 break;
1992 last = a;
1994 next = ALLOCNO_COLOR_DATA (t1)->next_thread_allocno;
1995 ALLOCNO_COLOR_DATA (t1)->next_thread_allocno = t2;
1996 ALLOCNO_COLOR_DATA (last)->next_thread_allocno = next;
1997 ALLOCNO_COLOR_DATA (t1)->thread_freq += ALLOCNO_COLOR_DATA (t2)->thread_freq;
2000 /* Create threads by processing CP_NUM copies from sorted copies. We
2001 process the most expensive copies first. */
2002 static void
2003 form_threads_from_copies (int cp_num)
2005 ira_allocno_t a, thread1, thread2;
2006 ira_copy_t cp;
2007 int i, n;
2009 qsort (sorted_copies, cp_num, sizeof (ira_copy_t), copy_freq_compare_func);
2010 /* Form threads processing copies, most frequently executed
2011 first. */
2012 for (; cp_num != 0;)
2014 for (i = 0; i < cp_num; i++)
2016 cp = sorted_copies[i];
2017 thread1 = ALLOCNO_COLOR_DATA (cp->first)->first_thread_allocno;
2018 thread2 = ALLOCNO_COLOR_DATA (cp->second)->first_thread_allocno;
2019 if (thread1 == thread2)
2020 continue;
2021 if (! allocno_thread_conflict_p (thread1, thread2))
2023 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2024 fprintf
2025 (ira_dump_file,
2026 " Forming thread by copy %d:a%dr%d-a%dr%d (freq=%d):\n",
2027 cp->num, ALLOCNO_NUM (cp->first), ALLOCNO_REGNO (cp->first),
2028 ALLOCNO_NUM (cp->second), ALLOCNO_REGNO (cp->second),
2029 cp->freq);
2030 merge_threads (thread1, thread2);
2031 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2033 thread1 = ALLOCNO_COLOR_DATA (thread1)->first_thread_allocno;
2034 fprintf (ira_dump_file, " Result (freq=%d): a%dr%d(%d)",
2035 ALLOCNO_COLOR_DATA (thread1)->thread_freq,
2036 ALLOCNO_NUM (thread1), ALLOCNO_REGNO (thread1),
2037 ALLOCNO_FREQ (thread1));
2038 for (a = ALLOCNO_COLOR_DATA (thread1)->next_thread_allocno;
2039 a != thread1;
2040 a = ALLOCNO_COLOR_DATA (a)->next_thread_allocno)
2041 fprintf (ira_dump_file, " a%dr%d(%d)",
2042 ALLOCNO_NUM (a), ALLOCNO_REGNO (a),
2043 ALLOCNO_FREQ (a));
2044 fprintf (ira_dump_file, "\n");
2046 i++;
2047 break;
2050 /* Collect the rest of copies. */
2051 for (n = 0; i < cp_num; i++)
2053 cp = sorted_copies[i];
2054 if (ALLOCNO_COLOR_DATA (cp->first)->first_thread_allocno
2055 != ALLOCNO_COLOR_DATA (cp->second)->first_thread_allocno)
2056 sorted_copies[n++] = cp;
2058 cp_num = n;
2062 /* Create threads by processing copies of all alocnos from BUCKET. We
2063 process the most expensive copies first. */
2064 static void
2065 form_threads_from_bucket (ira_allocno_t bucket)
2067 ira_allocno_t a;
2068 ira_copy_t cp, next_cp;
2069 int cp_num = 0;
2071 for (a = bucket; a != NULL; a = ALLOCNO_COLOR_DATA (a)->next_bucket_allocno)
2073 for (cp = ALLOCNO_COPIES (a); cp != NULL; cp = next_cp)
2075 if (cp->first == a)
2077 next_cp = cp->next_first_allocno_copy;
2078 sorted_copies[cp_num++] = cp;
2080 else if (cp->second == a)
2081 next_cp = cp->next_second_allocno_copy;
2082 else
2083 gcc_unreachable ();
2086 form_threads_from_copies (cp_num);
2089 /* Create threads by processing copies of colorable allocno A. We
2090 process most expensive copies first. */
2091 static void
2092 form_threads_from_colorable_allocno (ira_allocno_t a)
2094 ira_allocno_t another_a;
2095 ira_copy_t cp, next_cp;
2096 int cp_num = 0;
2098 for (cp = ALLOCNO_COPIES (a); cp != NULL; cp = next_cp)
2100 if (cp->first == a)
2102 next_cp = cp->next_first_allocno_copy;
2103 another_a = cp->second;
2105 else if (cp->second == a)
2107 next_cp = cp->next_second_allocno_copy;
2108 another_a = cp->first;
2110 else
2111 gcc_unreachable ();
2112 if ((! ALLOCNO_COLOR_DATA (another_a)->in_graph_p
2113 && !ALLOCNO_COLOR_DATA (another_a)->may_be_spilled_p)
2114 || ALLOCNO_COLOR_DATA (another_a)->colorable_p)
2115 sorted_copies[cp_num++] = cp;
2117 form_threads_from_copies (cp_num);
2120 /* Form initial threads which contain only one allocno. */
2121 static void
2122 init_allocno_threads (void)
2124 ira_allocno_t a;
2125 unsigned int j;
2126 bitmap_iterator bi;
2128 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
2130 a = ira_allocnos[j];
2131 /* Set up initial thread data: */
2132 ALLOCNO_COLOR_DATA (a)->first_thread_allocno
2133 = ALLOCNO_COLOR_DATA (a)->next_thread_allocno = a;
2134 ALLOCNO_COLOR_DATA (a)->thread_freq = ALLOCNO_FREQ (a);
2140 /* This page contains the allocator based on the Chaitin-Briggs algorithm. */
2142 /* Bucket of allocnos that can colored currently without spilling. */
2143 static ira_allocno_t colorable_allocno_bucket;
2145 /* Bucket of allocnos that might be not colored currently without
2146 spilling. */
2147 static ira_allocno_t uncolorable_allocno_bucket;
2149 /* The current number of allocnos in the uncolorable_bucket. */
2150 static int uncolorable_allocnos_num;
2152 /* Return the current spill priority of allocno A. The less the
2153 number, the more preferable the allocno for spilling. */
2154 static inline int
2155 allocno_spill_priority (ira_allocno_t a)
2157 allocno_color_data_t data = ALLOCNO_COLOR_DATA (a);
2159 return (data->temp
2160 / (ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a)
2161 * ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]
2162 + 1));
2165 /* Add allocno A to bucket *BUCKET_PTR. A should be not in a bucket
2166 before the call. */
2167 static void
2168 add_allocno_to_bucket (ira_allocno_t a, ira_allocno_t *bucket_ptr)
2170 ira_allocno_t first_a;
2171 allocno_color_data_t data;
2173 if (bucket_ptr == &uncolorable_allocno_bucket
2174 && ALLOCNO_CLASS (a) != NO_REGS)
2176 uncolorable_allocnos_num++;
2177 ira_assert (uncolorable_allocnos_num > 0);
2179 first_a = *bucket_ptr;
2180 data = ALLOCNO_COLOR_DATA (a);
2181 data->next_bucket_allocno = first_a;
2182 data->prev_bucket_allocno = NULL;
2183 if (first_a != NULL)
2184 ALLOCNO_COLOR_DATA (first_a)->prev_bucket_allocno = a;
2185 *bucket_ptr = a;
2188 /* Compare two allocnos to define which allocno should be pushed first
2189 into the coloring stack. If the return is a negative number, the
2190 allocno given by the first parameter will be pushed first. In this
2191 case such allocno has less priority than the second one and the
2192 hard register will be assigned to it after assignment to the second
2193 one. As the result of such assignment order, the second allocno
2194 has a better chance to get the best hard register. */
2195 static int
2196 bucket_allocno_compare_func (const void *v1p, const void *v2p)
2198 ira_allocno_t a1 = *(const ira_allocno_t *) v1p;
2199 ira_allocno_t a2 = *(const ira_allocno_t *) v2p;
2200 int diff, freq1, freq2, a1_num, a2_num;
2201 ira_allocno_t t1 = ALLOCNO_COLOR_DATA (a1)->first_thread_allocno;
2202 ira_allocno_t t2 = ALLOCNO_COLOR_DATA (a2)->first_thread_allocno;
2203 int cl1 = ALLOCNO_CLASS (a1), cl2 = ALLOCNO_CLASS (a2);
2205 freq1 = ALLOCNO_COLOR_DATA (t1)->thread_freq;
2206 freq2 = ALLOCNO_COLOR_DATA (t2)->thread_freq;
2207 if ((diff = freq1 - freq2) != 0)
2208 return diff;
2210 if ((diff = ALLOCNO_NUM (t2) - ALLOCNO_NUM (t1)) != 0)
2211 return diff;
2213 /* Push pseudos requiring less hard registers first. It means that
2214 we will assign pseudos requiring more hard registers first
2215 avoiding creation small holes in free hard register file into
2216 which the pseudos requiring more hard registers can not fit. */
2217 if ((diff = (ira_reg_class_max_nregs[cl1][ALLOCNO_MODE (a1)]
2218 - ira_reg_class_max_nregs[cl2][ALLOCNO_MODE (a2)])) != 0)
2219 return diff;
2221 freq1 = ALLOCNO_FREQ (a1);
2222 freq2 = ALLOCNO_FREQ (a2);
2223 if ((diff = freq1 - freq2) != 0)
2224 return diff;
2226 a1_num = ALLOCNO_COLOR_DATA (a1)->available_regs_num;
2227 a2_num = ALLOCNO_COLOR_DATA (a2)->available_regs_num;
2228 if ((diff = a2_num - a1_num) != 0)
2229 return diff;
2230 return ALLOCNO_NUM (a2) - ALLOCNO_NUM (a1);
2233 /* Sort bucket *BUCKET_PTR and return the result through
2234 BUCKET_PTR. */
2235 static void
2236 sort_bucket (ira_allocno_t *bucket_ptr,
2237 int (*compare_func) (const void *, const void *))
2239 ira_allocno_t a, head;
2240 int n;
2242 for (n = 0, a = *bucket_ptr;
2243 a != NULL;
2244 a = ALLOCNO_COLOR_DATA (a)->next_bucket_allocno)
2245 sorted_allocnos[n++] = a;
2246 if (n <= 1)
2247 return;
2248 qsort (sorted_allocnos, n, sizeof (ira_allocno_t), compare_func);
2249 head = NULL;
2250 for (n--; n >= 0; n--)
2252 a = sorted_allocnos[n];
2253 ALLOCNO_COLOR_DATA (a)->next_bucket_allocno = head;
2254 ALLOCNO_COLOR_DATA (a)->prev_bucket_allocno = NULL;
2255 if (head != NULL)
2256 ALLOCNO_COLOR_DATA (head)->prev_bucket_allocno = a;
2257 head = a;
2259 *bucket_ptr = head;
2262 /* Add ALLOCNO to colorable bucket maintaining the order according
2263 their priority. ALLOCNO should be not in a bucket before the
2264 call. */
2265 static void
2266 add_allocno_to_ordered_colorable_bucket (ira_allocno_t allocno)
2268 ira_allocno_t before, after;
2270 form_threads_from_colorable_allocno (allocno);
2271 for (before = colorable_allocno_bucket, after = NULL;
2272 before != NULL;
2273 after = before,
2274 before = ALLOCNO_COLOR_DATA (before)->next_bucket_allocno)
2275 if (bucket_allocno_compare_func (&allocno, &before) < 0)
2276 break;
2277 ALLOCNO_COLOR_DATA (allocno)->next_bucket_allocno = before;
2278 ALLOCNO_COLOR_DATA (allocno)->prev_bucket_allocno = after;
2279 if (after == NULL)
2280 colorable_allocno_bucket = allocno;
2281 else
2282 ALLOCNO_COLOR_DATA (after)->next_bucket_allocno = allocno;
2283 if (before != NULL)
2284 ALLOCNO_COLOR_DATA (before)->prev_bucket_allocno = allocno;
2287 /* Delete ALLOCNO from bucket *BUCKET_PTR. It should be there before
2288 the call. */
2289 static void
2290 delete_allocno_from_bucket (ira_allocno_t allocno, ira_allocno_t *bucket_ptr)
2292 ira_allocno_t prev_allocno, next_allocno;
2294 if (bucket_ptr == &uncolorable_allocno_bucket
2295 && ALLOCNO_CLASS (allocno) != NO_REGS)
2297 uncolorable_allocnos_num--;
2298 ira_assert (uncolorable_allocnos_num >= 0);
2300 prev_allocno = ALLOCNO_COLOR_DATA (allocno)->prev_bucket_allocno;
2301 next_allocno = ALLOCNO_COLOR_DATA (allocno)->next_bucket_allocno;
2302 if (prev_allocno != NULL)
2303 ALLOCNO_COLOR_DATA (prev_allocno)->next_bucket_allocno = next_allocno;
2304 else
2306 ira_assert (*bucket_ptr == allocno);
2307 *bucket_ptr = next_allocno;
2309 if (next_allocno != NULL)
2310 ALLOCNO_COLOR_DATA (next_allocno)->prev_bucket_allocno = prev_allocno;
2313 /* Put allocno A onto the coloring stack without removing it from its
2314 bucket. Pushing allocno to the coloring stack can result in moving
2315 conflicting allocnos from the uncolorable bucket to the colorable
2316 one. */
2317 static void
2318 push_allocno_to_stack (ira_allocno_t a)
2320 enum reg_class aclass;
2321 allocno_color_data_t data, conflict_data;
2322 int size, i, n = ALLOCNO_NUM_OBJECTS (a);
2324 data = ALLOCNO_COLOR_DATA (a);
2325 data->in_graph_p = false;
2326 allocno_stack_vec.safe_push (a);
2327 aclass = ALLOCNO_CLASS (a);
2328 if (aclass == NO_REGS)
2329 return;
2330 size = ira_reg_class_max_nregs[aclass][ALLOCNO_MODE (a)];
2331 if (n > 1)
2333 /* We will deal with the subwords individually. */
2334 gcc_assert (size == ALLOCNO_NUM_OBJECTS (a));
2335 size = 1;
2337 for (i = 0; i < n; i++)
2339 ira_object_t obj = ALLOCNO_OBJECT (a, i);
2340 ira_object_t conflict_obj;
2341 ira_object_conflict_iterator oci;
2343 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
2345 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
2347 conflict_data = ALLOCNO_COLOR_DATA (conflict_a);
2348 if (conflict_data->colorable_p
2349 || ! conflict_data->in_graph_p
2350 || ALLOCNO_ASSIGNED_P (conflict_a)
2351 || !(hard_reg_set_intersect_p
2352 (ALLOCNO_COLOR_DATA (a)->profitable_hard_regs,
2353 conflict_data->profitable_hard_regs)))
2354 continue;
2355 ira_assert (bitmap_bit_p (coloring_allocno_bitmap,
2356 ALLOCNO_NUM (conflict_a)));
2357 if (update_left_conflict_sizes_p (conflict_a, a, size))
2359 delete_allocno_from_bucket
2360 (conflict_a, &uncolorable_allocno_bucket);
2361 add_allocno_to_ordered_colorable_bucket (conflict_a);
2362 if (internal_flag_ira_verbose > 4 && ira_dump_file != NULL)
2364 fprintf (ira_dump_file, " Making");
2365 ira_print_expanded_allocno (conflict_a);
2366 fprintf (ira_dump_file, " colorable\n");
2374 /* Put ALLOCNO onto the coloring stack and remove it from its bucket.
2375 The allocno is in the colorable bucket if COLORABLE_P is TRUE. */
2376 static void
2377 remove_allocno_from_bucket_and_push (ira_allocno_t allocno, bool colorable_p)
2379 if (colorable_p)
2380 delete_allocno_from_bucket (allocno, &colorable_allocno_bucket);
2381 else
2382 delete_allocno_from_bucket (allocno, &uncolorable_allocno_bucket);
2383 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2385 fprintf (ira_dump_file, " Pushing");
2386 ira_print_expanded_allocno (allocno);
2387 if (colorable_p)
2388 fprintf (ira_dump_file, "(cost %d)\n",
2389 ALLOCNO_COLOR_DATA (allocno)->temp);
2390 else
2391 fprintf (ira_dump_file, "(potential spill: %spri=%d, cost=%d)\n",
2392 ALLOCNO_BAD_SPILL_P (allocno) ? "bad spill, " : "",
2393 allocno_spill_priority (allocno),
2394 ALLOCNO_COLOR_DATA (allocno)->temp);
2396 if (! colorable_p)
2397 ALLOCNO_COLOR_DATA (allocno)->may_be_spilled_p = true;
2398 push_allocno_to_stack (allocno);
2401 /* Put all allocnos from colorable bucket onto the coloring stack. */
2402 static void
2403 push_only_colorable (void)
2405 form_threads_from_bucket (colorable_allocno_bucket);
2406 sort_bucket (&colorable_allocno_bucket, bucket_allocno_compare_func);
2407 for (;colorable_allocno_bucket != NULL;)
2408 remove_allocno_from_bucket_and_push (colorable_allocno_bucket, true);
2411 /* Return the frequency of exit edges (if EXIT_P) or entry from/to the
2412 loop given by its LOOP_NODE. */
2414 ira_loop_edge_freq (ira_loop_tree_node_t loop_node, int regno, bool exit_p)
2416 int freq, i;
2417 edge_iterator ei;
2418 edge e;
2419 vec<edge> edges;
2421 ira_assert (current_loops != NULL && loop_node->loop != NULL
2422 && (regno < 0 || regno >= FIRST_PSEUDO_REGISTER));
2423 freq = 0;
2424 if (! exit_p)
2426 FOR_EACH_EDGE (e, ei, loop_node->loop->header->preds)
2427 if (e->src != loop_node->loop->latch
2428 && (regno < 0
2429 || (bitmap_bit_p (df_get_live_out (e->src), regno)
2430 && bitmap_bit_p (df_get_live_in (e->dest), regno))))
2431 freq += EDGE_FREQUENCY (e);
2433 else
2435 edges = get_loop_exit_edges (loop_node->loop);
2436 FOR_EACH_VEC_ELT (edges, i, e)
2437 if (regno < 0
2438 || (bitmap_bit_p (df_get_live_out (e->src), regno)
2439 && bitmap_bit_p (df_get_live_in (e->dest), regno)))
2440 freq += EDGE_FREQUENCY (e);
2441 edges.release ();
2444 return REG_FREQ_FROM_EDGE_FREQ (freq);
2447 /* Calculate and return the cost of putting allocno A into memory. */
2448 static int
2449 calculate_allocno_spill_cost (ira_allocno_t a)
2451 int regno, cost;
2452 machine_mode mode;
2453 enum reg_class rclass;
2454 ira_allocno_t parent_allocno;
2455 ira_loop_tree_node_t parent_node, loop_node;
2457 regno = ALLOCNO_REGNO (a);
2458 cost = ALLOCNO_UPDATED_MEMORY_COST (a) - ALLOCNO_UPDATED_CLASS_COST (a);
2459 if (ALLOCNO_CAP (a) != NULL)
2460 return cost;
2461 loop_node = ALLOCNO_LOOP_TREE_NODE (a);
2462 if ((parent_node = loop_node->parent) == NULL)
2463 return cost;
2464 if ((parent_allocno = parent_node->regno_allocno_map[regno]) == NULL)
2465 return cost;
2466 mode = ALLOCNO_MODE (a);
2467 rclass = ALLOCNO_CLASS (a);
2468 if (ALLOCNO_HARD_REGNO (parent_allocno) < 0)
2469 cost -= (ira_memory_move_cost[mode][rclass][0]
2470 * ira_loop_edge_freq (loop_node, regno, true)
2471 + ira_memory_move_cost[mode][rclass][1]
2472 * ira_loop_edge_freq (loop_node, regno, false));
2473 else
2475 ira_init_register_move_cost_if_necessary (mode);
2476 cost += ((ira_memory_move_cost[mode][rclass][1]
2477 * ira_loop_edge_freq (loop_node, regno, true)
2478 + ira_memory_move_cost[mode][rclass][0]
2479 * ira_loop_edge_freq (loop_node, regno, false))
2480 - (ira_register_move_cost[mode][rclass][rclass]
2481 * (ira_loop_edge_freq (loop_node, regno, false)
2482 + ira_loop_edge_freq (loop_node, regno, true))));
2484 return cost;
2487 /* Used for sorting allocnos for spilling. */
2488 static inline int
2489 allocno_spill_priority_compare (ira_allocno_t a1, ira_allocno_t a2)
2491 int pri1, pri2, diff;
2493 /* Avoid spilling static chain pointer pseudo when non-local goto is
2494 used. */
2495 if (non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a1)))
2496 return 1;
2497 else if (non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a2)))
2498 return -1;
2499 if (ALLOCNO_BAD_SPILL_P (a1) && ! ALLOCNO_BAD_SPILL_P (a2))
2500 return 1;
2501 if (ALLOCNO_BAD_SPILL_P (a2) && ! ALLOCNO_BAD_SPILL_P (a1))
2502 return -1;
2503 pri1 = allocno_spill_priority (a1);
2504 pri2 = allocno_spill_priority (a2);
2505 if ((diff = pri1 - pri2) != 0)
2506 return diff;
2507 if ((diff
2508 = ALLOCNO_COLOR_DATA (a1)->temp - ALLOCNO_COLOR_DATA (a2)->temp) != 0)
2509 return diff;
2510 return ALLOCNO_NUM (a1) - ALLOCNO_NUM (a2);
2513 /* Used for sorting allocnos for spilling. */
2514 static int
2515 allocno_spill_sort_compare (const void *v1p, const void *v2p)
2517 ira_allocno_t p1 = *(const ira_allocno_t *) v1p;
2518 ira_allocno_t p2 = *(const ira_allocno_t *) v2p;
2520 return allocno_spill_priority_compare (p1, p2);
2523 /* Push allocnos to the coloring stack. The order of allocnos in the
2524 stack defines the order for the subsequent coloring. */
2525 static void
2526 push_allocnos_to_stack (void)
2528 ira_allocno_t a;
2529 int cost;
2531 /* Calculate uncolorable allocno spill costs. */
2532 for (a = uncolorable_allocno_bucket;
2533 a != NULL;
2534 a = ALLOCNO_COLOR_DATA (a)->next_bucket_allocno)
2535 if (ALLOCNO_CLASS (a) != NO_REGS)
2537 cost = calculate_allocno_spill_cost (a);
2538 /* ??? Remove cost of copies between the coalesced
2539 allocnos. */
2540 ALLOCNO_COLOR_DATA (a)->temp = cost;
2542 sort_bucket (&uncolorable_allocno_bucket, allocno_spill_sort_compare);
2543 for (;;)
2545 push_only_colorable ();
2546 a = uncolorable_allocno_bucket;
2547 if (a == NULL)
2548 break;
2549 remove_allocno_from_bucket_and_push (a, false);
2551 ira_assert (colorable_allocno_bucket == NULL
2552 && uncolorable_allocno_bucket == NULL);
2553 ira_assert (uncolorable_allocnos_num == 0);
2556 /* Pop the coloring stack and assign hard registers to the popped
2557 allocnos. */
2558 static void
2559 pop_allocnos_from_stack (void)
2561 ira_allocno_t allocno;
2562 enum reg_class aclass;
2564 for (;allocno_stack_vec.length () != 0;)
2566 allocno = allocno_stack_vec.pop ();
2567 aclass = ALLOCNO_CLASS (allocno);
2568 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2570 fprintf (ira_dump_file, " Popping");
2571 ira_print_expanded_allocno (allocno);
2572 fprintf (ira_dump_file, " -- ");
2574 if (aclass == NO_REGS)
2576 ALLOCNO_HARD_REGNO (allocno) = -1;
2577 ALLOCNO_ASSIGNED_P (allocno) = true;
2578 ira_assert (ALLOCNO_UPDATED_HARD_REG_COSTS (allocno) == NULL);
2579 ira_assert
2580 (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (allocno) == NULL);
2581 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2582 fprintf (ira_dump_file, "assign memory\n");
2584 else if (assign_hard_reg (allocno, false))
2586 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2587 fprintf (ira_dump_file, "assign reg %d\n",
2588 ALLOCNO_HARD_REGNO (allocno));
2590 else if (ALLOCNO_ASSIGNED_P (allocno))
2592 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2593 fprintf (ira_dump_file, "spill%s\n",
2594 ALLOCNO_COLOR_DATA (allocno)->may_be_spilled_p
2595 ? "" : "!");
2597 ALLOCNO_COLOR_DATA (allocno)->in_graph_p = true;
2601 /* Set up number of available hard registers for allocno A. */
2602 static void
2603 setup_allocno_available_regs_num (ira_allocno_t a)
2605 int i, n, hard_regno, hard_regs_num, nwords;
2606 enum reg_class aclass;
2607 allocno_color_data_t data;
2609 aclass = ALLOCNO_CLASS (a);
2610 data = ALLOCNO_COLOR_DATA (a);
2611 data->available_regs_num = 0;
2612 if (aclass == NO_REGS)
2613 return;
2614 hard_regs_num = ira_class_hard_regs_num[aclass];
2615 nwords = ALLOCNO_NUM_OBJECTS (a);
2616 for (n = 0, i = hard_regs_num - 1; i >= 0; i--)
2618 hard_regno = ira_class_hard_regs[aclass][i];
2619 /* Checking only profitable hard regs. */
2620 if (TEST_HARD_REG_BIT (data->profitable_hard_regs, hard_regno))
2621 n++;
2623 data->available_regs_num = n;
2624 if (internal_flag_ira_verbose <= 2 || ira_dump_file == NULL)
2625 return;
2626 fprintf
2627 (ira_dump_file,
2628 " Allocno a%dr%d of %s(%d) has %d avail. regs ",
2629 ALLOCNO_NUM (a), ALLOCNO_REGNO (a),
2630 reg_class_names[aclass], ira_class_hard_regs_num[aclass], n);
2631 print_hard_reg_set (ira_dump_file, data->profitable_hard_regs, false);
2632 fprintf (ira_dump_file, ", %snode: ",
2633 hard_reg_set_equal_p (data->profitable_hard_regs,
2634 data->hard_regs_node->hard_regs->set)
2635 ? "" : "^");
2636 print_hard_reg_set (ira_dump_file,
2637 data->hard_regs_node->hard_regs->set, false);
2638 for (i = 0; i < nwords; i++)
2640 ira_object_t obj = ALLOCNO_OBJECT (a, i);
2642 if (nwords != 1)
2644 if (i != 0)
2645 fprintf (ira_dump_file, ", ");
2646 fprintf (ira_dump_file, " obj %d", i);
2648 fprintf (ira_dump_file, " (confl regs = ");
2649 print_hard_reg_set (ira_dump_file, OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
2650 false);
2651 fprintf (ira_dump_file, ")");
2653 fprintf (ira_dump_file, "\n");
2656 /* Put ALLOCNO in a bucket corresponding to its number and size of its
2657 conflicting allocnos and hard registers. */
2658 static void
2659 put_allocno_into_bucket (ira_allocno_t allocno)
2661 ALLOCNO_COLOR_DATA (allocno)->in_graph_p = true;
2662 setup_allocno_available_regs_num (allocno);
2663 if (setup_left_conflict_sizes_p (allocno))
2664 add_allocno_to_bucket (allocno, &colorable_allocno_bucket);
2665 else
2666 add_allocno_to_bucket (allocno, &uncolorable_allocno_bucket);
2669 /* Map: allocno number -> allocno priority. */
2670 static int *allocno_priorities;
2672 /* Set up priorities for N allocnos in array
2673 CONSIDERATION_ALLOCNOS. */
2674 static void
2675 setup_allocno_priorities (ira_allocno_t *consideration_allocnos, int n)
2677 int i, length, nrefs, priority, max_priority, mult;
2678 ira_allocno_t a;
2680 max_priority = 0;
2681 for (i = 0; i < n; i++)
2683 a = consideration_allocnos[i];
2684 nrefs = ALLOCNO_NREFS (a);
2685 ira_assert (nrefs >= 0);
2686 mult = floor_log2 (ALLOCNO_NREFS (a)) + 1;
2687 ira_assert (mult >= 0);
2688 allocno_priorities[ALLOCNO_NUM (a)]
2689 = priority
2690 = (mult
2691 * (ALLOCNO_MEMORY_COST (a) - ALLOCNO_CLASS_COST (a))
2692 * ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]);
2693 if (priority < 0)
2694 priority = -priority;
2695 if (max_priority < priority)
2696 max_priority = priority;
2698 mult = max_priority == 0 ? 1 : INT_MAX / max_priority;
2699 for (i = 0; i < n; i++)
2701 a = consideration_allocnos[i];
2702 length = ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a);
2703 if (ALLOCNO_NUM_OBJECTS (a) > 1)
2704 length /= ALLOCNO_NUM_OBJECTS (a);
2705 if (length <= 0)
2706 length = 1;
2707 allocno_priorities[ALLOCNO_NUM (a)]
2708 = allocno_priorities[ALLOCNO_NUM (a)] * mult / length;
2712 /* Sort allocnos according to the profit of usage of a hard register
2713 instead of memory for them. */
2714 static int
2715 allocno_cost_compare_func (const void *v1p, const void *v2p)
2717 ira_allocno_t p1 = *(const ira_allocno_t *) v1p;
2718 ira_allocno_t p2 = *(const ira_allocno_t *) v2p;
2719 int c1, c2;
2721 c1 = ALLOCNO_UPDATED_MEMORY_COST (p1) - ALLOCNO_UPDATED_CLASS_COST (p1);
2722 c2 = ALLOCNO_UPDATED_MEMORY_COST (p2) - ALLOCNO_UPDATED_CLASS_COST (p2);
2723 if (c1 - c2)
2724 return c1 - c2;
2726 /* If regs are equally good, sort by allocno numbers, so that the
2727 results of qsort leave nothing to chance. */
2728 return ALLOCNO_NUM (p1) - ALLOCNO_NUM (p2);
2731 /* We used Chaitin-Briggs coloring to assign as many pseudos as
2732 possible to hard registers. Let us try to improve allocation with
2733 cost point of view. This function improves the allocation by
2734 spilling some allocnos and assigning the freed hard registers to
2735 other allocnos if it decreases the overall allocation cost. */
2736 static void
2737 improve_allocation (void)
2739 unsigned int i;
2740 int j, k, n, hregno, conflict_hregno, base_cost, class_size, word, nwords;
2741 int check, spill_cost, min_cost, nregs, conflict_nregs, r, best;
2742 bool try_p;
2743 enum reg_class aclass;
2744 machine_mode mode;
2745 int *allocno_costs;
2746 int costs[FIRST_PSEUDO_REGISTER];
2747 HARD_REG_SET conflicting_regs[2], profitable_hard_regs;
2748 ira_allocno_t a;
2749 bitmap_iterator bi;
2751 /* Don't bother to optimize the code with static chain pointer and
2752 non-local goto in order not to spill the chain pointer
2753 pseudo. */
2754 if (cfun->static_chain_decl && crtl->has_nonlocal_goto)
2755 return;
2756 /* Clear counts used to process conflicting allocnos only once for
2757 each allocno. */
2758 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
2759 ALLOCNO_COLOR_DATA (ira_allocnos[i])->temp = 0;
2760 check = n = 0;
2761 /* Process each allocno and try to assign a hard register to it by
2762 spilling some its conflicting allocnos. */
2763 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
2765 a = ira_allocnos[i];
2766 ALLOCNO_COLOR_DATA (a)->temp = 0;
2767 if (empty_profitable_hard_regs (a))
2768 continue;
2769 check++;
2770 aclass = ALLOCNO_CLASS (a);
2771 allocno_costs = ALLOCNO_UPDATED_HARD_REG_COSTS (a);
2772 if (allocno_costs == NULL)
2773 allocno_costs = ALLOCNO_HARD_REG_COSTS (a);
2774 if ((hregno = ALLOCNO_HARD_REGNO (a)) < 0)
2775 base_cost = ALLOCNO_UPDATED_MEMORY_COST (a);
2776 else if (allocno_costs == NULL)
2777 /* It means that assigning a hard register is not profitable
2778 (we don't waste memory for hard register costs in this
2779 case). */
2780 continue;
2781 else
2782 base_cost = allocno_costs[ira_class_hard_reg_index[aclass][hregno]];
2783 try_p = false;
2784 get_conflict_and_start_profitable_regs (a, false,
2785 conflicting_regs,
2786 &profitable_hard_regs);
2787 class_size = ira_class_hard_regs_num[aclass];
2788 /* Set up cost improvement for usage of each profitable hard
2789 register for allocno A. */
2790 for (j = 0; j < class_size; j++)
2792 hregno = ira_class_hard_regs[aclass][j];
2793 if (! check_hard_reg_p (a, hregno,
2794 conflicting_regs, profitable_hard_regs))
2795 continue;
2796 ira_assert (ira_class_hard_reg_index[aclass][hregno] == j);
2797 k = allocno_costs == NULL ? 0 : j;
2798 costs[hregno] = (allocno_costs == NULL
2799 ? ALLOCNO_UPDATED_CLASS_COST (a) : allocno_costs[k]);
2800 costs[hregno] -= base_cost;
2801 if (costs[hregno] < 0)
2802 try_p = true;
2804 if (! try_p)
2805 /* There is no chance to improve the allocation cost by
2806 assigning hard register to allocno A even without spilling
2807 conflicting allocnos. */
2808 continue;
2809 mode = ALLOCNO_MODE (a);
2810 nwords = ALLOCNO_NUM_OBJECTS (a);
2811 /* Process each allocno conflicting with A and update the cost
2812 improvement for profitable hard registers of A. To use a
2813 hard register for A we need to spill some conflicting
2814 allocnos and that creates penalty for the cost
2815 improvement. */
2816 for (word = 0; word < nwords; word++)
2818 ira_object_t conflict_obj;
2819 ira_object_t obj = ALLOCNO_OBJECT (a, word);
2820 ira_object_conflict_iterator oci;
2822 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
2824 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
2826 if (ALLOCNO_COLOR_DATA (conflict_a)->temp == check)
2827 /* We already processed this conflicting allocno
2828 because we processed earlier another object of the
2829 conflicting allocno. */
2830 continue;
2831 ALLOCNO_COLOR_DATA (conflict_a)->temp = check;
2832 if ((conflict_hregno = ALLOCNO_HARD_REGNO (conflict_a)) < 0)
2833 continue;
2834 spill_cost = ALLOCNO_UPDATED_MEMORY_COST (conflict_a);
2835 k = (ira_class_hard_reg_index
2836 [ALLOCNO_CLASS (conflict_a)][conflict_hregno]);
2837 ira_assert (k >= 0);
2838 if ((allocno_costs = ALLOCNO_UPDATED_HARD_REG_COSTS (conflict_a))
2839 != NULL)
2840 spill_cost -= allocno_costs[k];
2841 else if ((allocno_costs = ALLOCNO_HARD_REG_COSTS (conflict_a))
2842 != NULL)
2843 spill_cost -= allocno_costs[k];
2844 else
2845 spill_cost -= ALLOCNO_UPDATED_CLASS_COST (conflict_a);
2846 conflict_nregs
2847 = hard_regno_nregs[conflict_hregno][ALLOCNO_MODE (conflict_a)];
2848 for (r = conflict_hregno;
2849 r >= 0 && r + hard_regno_nregs[r][mode] > conflict_hregno;
2850 r--)
2851 if (check_hard_reg_p (a, r,
2852 conflicting_regs, profitable_hard_regs))
2853 costs[r] += spill_cost;
2854 for (r = conflict_hregno + 1;
2855 r < conflict_hregno + conflict_nregs;
2856 r++)
2857 if (check_hard_reg_p (a, r,
2858 conflicting_regs, profitable_hard_regs))
2859 costs[r] += spill_cost;
2862 min_cost = INT_MAX;
2863 best = -1;
2864 /* Now we choose hard register for A which results in highest
2865 allocation cost improvement. */
2866 for (j = 0; j < class_size; j++)
2868 hregno = ira_class_hard_regs[aclass][j];
2869 if (check_hard_reg_p (a, hregno,
2870 conflicting_regs, profitable_hard_regs)
2871 && min_cost > costs[hregno])
2873 best = hregno;
2874 min_cost = costs[hregno];
2877 if (min_cost >= 0)
2878 /* We are in a situation when assigning any hard register to A
2879 by spilling some conflicting allocnos does not improve the
2880 allocation cost. */
2881 continue;
2882 nregs = hard_regno_nregs[best][mode];
2883 /* Now spill conflicting allocnos which contain a hard register
2884 of A when we assign the best chosen hard register to it. */
2885 for (word = 0; word < nwords; word++)
2887 ira_object_t conflict_obj;
2888 ira_object_t obj = ALLOCNO_OBJECT (a, word);
2889 ira_object_conflict_iterator oci;
2891 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
2893 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
2895 if ((conflict_hregno = ALLOCNO_HARD_REGNO (conflict_a)) < 0)
2896 continue;
2897 conflict_nregs
2898 = hard_regno_nregs[conflict_hregno][ALLOCNO_MODE (conflict_a)];
2899 if (best + nregs <= conflict_hregno
2900 || conflict_hregno + conflict_nregs <= best)
2901 /* No intersection. */
2902 continue;
2903 ALLOCNO_HARD_REGNO (conflict_a) = -1;
2904 sorted_allocnos[n++] = conflict_a;
2905 if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
2906 fprintf (ira_dump_file, "Spilling a%dr%d for a%dr%d\n",
2907 ALLOCNO_NUM (conflict_a), ALLOCNO_REGNO (conflict_a),
2908 ALLOCNO_NUM (a), ALLOCNO_REGNO (a));
2911 /* Assign the best chosen hard register to A. */
2912 ALLOCNO_HARD_REGNO (a) = best;
2913 if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
2914 fprintf (ira_dump_file, "Assigning %d to a%dr%d\n",
2915 best, ALLOCNO_NUM (a), ALLOCNO_REGNO (a));
2917 if (n == 0)
2918 return;
2919 /* We spilled some allocnos to assign their hard registers to other
2920 allocnos. The spilled allocnos are now in array
2921 'sorted_allocnos'. There is still a possibility that some of the
2922 spilled allocnos can get hard registers. So let us try assign
2923 them hard registers again (just a reminder -- function
2924 'assign_hard_reg' assigns hard registers only if it is possible
2925 and profitable). We process the spilled allocnos with biggest
2926 benefit to get hard register first -- see function
2927 'allocno_cost_compare_func'. */
2928 qsort (sorted_allocnos, n, sizeof (ira_allocno_t),
2929 allocno_cost_compare_func);
2930 for (j = 0; j < n; j++)
2932 a = sorted_allocnos[j];
2933 ALLOCNO_ASSIGNED_P (a) = false;
2934 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2936 fprintf (ira_dump_file, " ");
2937 ira_print_expanded_allocno (a);
2938 fprintf (ira_dump_file, " -- ");
2940 if (assign_hard_reg (a, false))
2942 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2943 fprintf (ira_dump_file, "assign hard reg %d\n",
2944 ALLOCNO_HARD_REGNO (a));
2946 else
2948 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2949 fprintf (ira_dump_file, "assign memory\n");
2954 /* Sort allocnos according to their priorities. */
2955 static int
2956 allocno_priority_compare_func (const void *v1p, const void *v2p)
2958 ira_allocno_t a1 = *(const ira_allocno_t *) v1p;
2959 ira_allocno_t a2 = *(const ira_allocno_t *) v2p;
2960 int pri1, pri2;
2962 /* Assign hard reg to static chain pointer pseudo first when
2963 non-local goto is used. */
2964 if (non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a1)))
2965 return 1;
2966 else if (non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a2)))
2967 return -1;
2968 pri1 = allocno_priorities[ALLOCNO_NUM (a1)];
2969 pri2 = allocno_priorities[ALLOCNO_NUM (a2)];
2970 if (pri2 != pri1)
2971 return SORTGT (pri2, pri1);
2973 /* If regs are equally good, sort by allocnos, so that the results of
2974 qsort leave nothing to chance. */
2975 return ALLOCNO_NUM (a1) - ALLOCNO_NUM (a2);
2978 /* Chaitin-Briggs coloring for allocnos in COLORING_ALLOCNO_BITMAP
2979 taking into account allocnos in CONSIDERATION_ALLOCNO_BITMAP. */
2980 static void
2981 color_allocnos (void)
2983 unsigned int i, n;
2984 bitmap_iterator bi;
2985 ira_allocno_t a;
2987 setup_profitable_hard_regs ();
2988 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
2990 int l, nr;
2991 HARD_REG_SET conflict_hard_regs;
2992 allocno_color_data_t data;
2993 ira_pref_t pref, next_pref;
2995 a = ira_allocnos[i];
2996 nr = ALLOCNO_NUM_OBJECTS (a);
2997 CLEAR_HARD_REG_SET (conflict_hard_regs);
2998 for (l = 0; l < nr; l++)
3000 ira_object_t obj = ALLOCNO_OBJECT (a, l);
3001 IOR_HARD_REG_SET (conflict_hard_regs,
3002 OBJECT_CONFLICT_HARD_REGS (obj));
3004 data = ALLOCNO_COLOR_DATA (a);
3005 for (pref = ALLOCNO_PREFS (a); pref != NULL; pref = next_pref)
3007 next_pref = pref->next_pref;
3008 if (! ira_hard_reg_in_set_p (pref->hard_regno,
3009 ALLOCNO_MODE (a),
3010 data->profitable_hard_regs))
3011 ira_remove_pref (pref);
3014 if (flag_ira_algorithm == IRA_ALGORITHM_PRIORITY)
3016 n = 0;
3017 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
3019 a = ira_allocnos[i];
3020 if (ALLOCNO_CLASS (a) == NO_REGS)
3022 ALLOCNO_HARD_REGNO (a) = -1;
3023 ALLOCNO_ASSIGNED_P (a) = true;
3024 ira_assert (ALLOCNO_UPDATED_HARD_REG_COSTS (a) == NULL);
3025 ira_assert (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a) == NULL);
3026 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3028 fprintf (ira_dump_file, " Spill");
3029 ira_print_expanded_allocno (a);
3030 fprintf (ira_dump_file, "\n");
3032 continue;
3034 sorted_allocnos[n++] = a;
3036 if (n != 0)
3038 setup_allocno_priorities (sorted_allocnos, n);
3039 qsort (sorted_allocnos, n, sizeof (ira_allocno_t),
3040 allocno_priority_compare_func);
3041 for (i = 0; i < n; i++)
3043 a = sorted_allocnos[i];
3044 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3046 fprintf (ira_dump_file, " ");
3047 ira_print_expanded_allocno (a);
3048 fprintf (ira_dump_file, " -- ");
3050 if (assign_hard_reg (a, false))
3052 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3053 fprintf (ira_dump_file, "assign hard reg %d\n",
3054 ALLOCNO_HARD_REGNO (a));
3056 else
3058 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3059 fprintf (ira_dump_file, "assign memory\n");
3064 else
3066 form_allocno_hard_regs_nodes_forest ();
3067 if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
3068 print_hard_regs_forest (ira_dump_file);
3069 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
3071 a = ira_allocnos[i];
3072 if (ALLOCNO_CLASS (a) != NO_REGS && ! empty_profitable_hard_regs (a))
3074 ALLOCNO_COLOR_DATA (a)->in_graph_p = true;
3075 update_costs_from_prefs (a);
3077 else
3079 ALLOCNO_HARD_REGNO (a) = -1;
3080 ALLOCNO_ASSIGNED_P (a) = true;
3081 /* We don't need updated costs anymore. */
3082 ira_free_allocno_updated_costs (a);
3083 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3085 fprintf (ira_dump_file, " Spill");
3086 ira_print_expanded_allocno (a);
3087 fprintf (ira_dump_file, "\n");
3091 /* Put the allocnos into the corresponding buckets. */
3092 colorable_allocno_bucket = NULL;
3093 uncolorable_allocno_bucket = NULL;
3094 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
3096 a = ira_allocnos[i];
3097 if (ALLOCNO_COLOR_DATA (a)->in_graph_p)
3098 put_allocno_into_bucket (a);
3100 push_allocnos_to_stack ();
3101 pop_allocnos_from_stack ();
3102 finish_allocno_hard_regs_nodes_forest ();
3104 improve_allocation ();
3109 /* Output information about the loop given by its LOOP_TREE_NODE. */
3110 static void
3111 print_loop_title (ira_loop_tree_node_t loop_tree_node)
3113 unsigned int j;
3114 bitmap_iterator bi;
3115 ira_loop_tree_node_t subloop_node, dest_loop_node;
3116 edge e;
3117 edge_iterator ei;
3119 if (loop_tree_node->parent == NULL)
3120 fprintf (ira_dump_file,
3121 "\n Loop 0 (parent -1, header bb%d, depth 0)\n bbs:",
3122 NUM_FIXED_BLOCKS);
3123 else
3125 ira_assert (current_loops != NULL && loop_tree_node->loop != NULL);
3126 fprintf (ira_dump_file,
3127 "\n Loop %d (parent %d, header bb%d, depth %d)\n bbs:",
3128 loop_tree_node->loop_num, loop_tree_node->parent->loop_num,
3129 loop_tree_node->loop->header->index,
3130 loop_depth (loop_tree_node->loop));
3132 for (subloop_node = loop_tree_node->children;
3133 subloop_node != NULL;
3134 subloop_node = subloop_node->next)
3135 if (subloop_node->bb != NULL)
3137 fprintf (ira_dump_file, " %d", subloop_node->bb->index);
3138 FOR_EACH_EDGE (e, ei, subloop_node->bb->succs)
3139 if (e->dest != EXIT_BLOCK_PTR_FOR_FN (cfun)
3140 && ((dest_loop_node = IRA_BB_NODE (e->dest)->parent)
3141 != loop_tree_node))
3142 fprintf (ira_dump_file, "(->%d:l%d)",
3143 e->dest->index, dest_loop_node->loop_num);
3145 fprintf (ira_dump_file, "\n all:");
3146 EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->all_allocnos, 0, j, bi)
3147 fprintf (ira_dump_file, " %dr%d", j, ALLOCNO_REGNO (ira_allocnos[j]));
3148 fprintf (ira_dump_file, "\n modified regnos:");
3149 EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->modified_regnos, 0, j, bi)
3150 fprintf (ira_dump_file, " %d", j);
3151 fprintf (ira_dump_file, "\n border:");
3152 EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->border_allocnos, 0, j, bi)
3153 fprintf (ira_dump_file, " %dr%d", j, ALLOCNO_REGNO (ira_allocnos[j]));
3154 fprintf (ira_dump_file, "\n Pressure:");
3155 for (j = 0; (int) j < ira_pressure_classes_num; j++)
3157 enum reg_class pclass;
3159 pclass = ira_pressure_classes[j];
3160 if (loop_tree_node->reg_pressure[pclass] == 0)
3161 continue;
3162 fprintf (ira_dump_file, " %s=%d", reg_class_names[pclass],
3163 loop_tree_node->reg_pressure[pclass]);
3165 fprintf (ira_dump_file, "\n");
3168 /* Color the allocnos inside loop (in the extreme case it can be all
3169 of the function) given the corresponding LOOP_TREE_NODE. The
3170 function is called for each loop during top-down traverse of the
3171 loop tree. */
3172 static void
3173 color_pass (ira_loop_tree_node_t loop_tree_node)
3175 int regno, hard_regno, index = -1, n;
3176 int cost, exit_freq, enter_freq;
3177 unsigned int j;
3178 bitmap_iterator bi;
3179 machine_mode mode;
3180 enum reg_class rclass, aclass, pclass;
3181 ira_allocno_t a, subloop_allocno;
3182 ira_loop_tree_node_t subloop_node;
3184 ira_assert (loop_tree_node->bb == NULL);
3185 if (internal_flag_ira_verbose > 1 && ira_dump_file != NULL)
3186 print_loop_title (loop_tree_node);
3188 bitmap_copy (coloring_allocno_bitmap, loop_tree_node->all_allocnos);
3189 bitmap_copy (consideration_allocno_bitmap, coloring_allocno_bitmap);
3190 n = 0;
3191 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
3193 a = ira_allocnos[j];
3194 n++;
3195 if (! ALLOCNO_ASSIGNED_P (a))
3196 continue;
3197 bitmap_clear_bit (coloring_allocno_bitmap, ALLOCNO_NUM (a));
3199 allocno_color_data
3200 = (allocno_color_data_t) ira_allocate (sizeof (struct allocno_color_data)
3201 * n);
3202 memset (allocno_color_data, 0, sizeof (struct allocno_color_data) * n);
3203 curr_allocno_process = 0;
3204 n = 0;
3205 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
3207 a = ira_allocnos[j];
3208 ALLOCNO_ADD_DATA (a) = allocno_color_data + n;
3209 n++;
3211 init_allocno_threads ();
3212 /* Color all mentioned allocnos including transparent ones. */
3213 color_allocnos ();
3214 /* Process caps. They are processed just once. */
3215 if (flag_ira_region == IRA_REGION_MIXED
3216 || flag_ira_region == IRA_REGION_ALL)
3217 EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->all_allocnos, 0, j, bi)
3219 a = ira_allocnos[j];
3220 if (ALLOCNO_CAP_MEMBER (a) == NULL)
3221 continue;
3222 /* Remove from processing in the next loop. */
3223 bitmap_clear_bit (consideration_allocno_bitmap, j);
3224 rclass = ALLOCNO_CLASS (a);
3225 pclass = ira_pressure_class_translate[rclass];
3226 if (flag_ira_region == IRA_REGION_MIXED
3227 && (loop_tree_node->reg_pressure[pclass]
3228 <= ira_class_hard_regs_num[pclass]))
3230 mode = ALLOCNO_MODE (a);
3231 hard_regno = ALLOCNO_HARD_REGNO (a);
3232 if (hard_regno >= 0)
3234 index = ira_class_hard_reg_index[rclass][hard_regno];
3235 ira_assert (index >= 0);
3237 regno = ALLOCNO_REGNO (a);
3238 subloop_allocno = ALLOCNO_CAP_MEMBER (a);
3239 subloop_node = ALLOCNO_LOOP_TREE_NODE (subloop_allocno);
3240 ira_assert (!ALLOCNO_ASSIGNED_P (subloop_allocno));
3241 ALLOCNO_HARD_REGNO (subloop_allocno) = hard_regno;
3242 ALLOCNO_ASSIGNED_P (subloop_allocno) = true;
3243 if (hard_regno >= 0)
3244 update_costs_from_copies (subloop_allocno, true, true);
3245 /* We don't need updated costs anymore. */
3246 ira_free_allocno_updated_costs (subloop_allocno);
3249 /* Update costs of the corresponding allocnos (not caps) in the
3250 subloops. */
3251 for (subloop_node = loop_tree_node->subloops;
3252 subloop_node != NULL;
3253 subloop_node = subloop_node->subloop_next)
3255 ira_assert (subloop_node->bb == NULL);
3256 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
3258 a = ira_allocnos[j];
3259 ira_assert (ALLOCNO_CAP_MEMBER (a) == NULL);
3260 mode = ALLOCNO_MODE (a);
3261 rclass = ALLOCNO_CLASS (a);
3262 pclass = ira_pressure_class_translate[rclass];
3263 hard_regno = ALLOCNO_HARD_REGNO (a);
3264 /* Use hard register class here. ??? */
3265 if (hard_regno >= 0)
3267 index = ira_class_hard_reg_index[rclass][hard_regno];
3268 ira_assert (index >= 0);
3270 regno = ALLOCNO_REGNO (a);
3271 /* ??? conflict costs */
3272 subloop_allocno = subloop_node->regno_allocno_map[regno];
3273 if (subloop_allocno == NULL
3274 || ALLOCNO_CAP (subloop_allocno) != NULL)
3275 continue;
3276 ira_assert (ALLOCNO_CLASS (subloop_allocno) == rclass);
3277 ira_assert (bitmap_bit_p (subloop_node->all_allocnos,
3278 ALLOCNO_NUM (subloop_allocno)));
3279 if ((flag_ira_region == IRA_REGION_MIXED
3280 && (loop_tree_node->reg_pressure[pclass]
3281 <= ira_class_hard_regs_num[pclass]))
3282 || (pic_offset_table_rtx != NULL
3283 && regno == (int) REGNO (pic_offset_table_rtx))
3284 /* Avoid overlapped multi-registers. Moves between them
3285 might result in wrong code generation. */
3286 || (hard_regno >= 0
3287 && ira_reg_class_max_nregs[pclass][mode] > 1))
3289 if (! ALLOCNO_ASSIGNED_P (subloop_allocno))
3291 ALLOCNO_HARD_REGNO (subloop_allocno) = hard_regno;
3292 ALLOCNO_ASSIGNED_P (subloop_allocno) = true;
3293 if (hard_regno >= 0)
3294 update_costs_from_copies (subloop_allocno, true, true);
3295 /* We don't need updated costs anymore. */
3296 ira_free_allocno_updated_costs (subloop_allocno);
3298 continue;
3300 exit_freq = ira_loop_edge_freq (subloop_node, regno, true);
3301 enter_freq = ira_loop_edge_freq (subloop_node, regno, false);
3302 ira_assert (regno < ira_reg_equiv_len);
3303 if (ira_equiv_no_lvalue_p (regno))
3305 if (! ALLOCNO_ASSIGNED_P (subloop_allocno))
3307 ALLOCNO_HARD_REGNO (subloop_allocno) = hard_regno;
3308 ALLOCNO_ASSIGNED_P (subloop_allocno) = true;
3309 if (hard_regno >= 0)
3310 update_costs_from_copies (subloop_allocno, true, true);
3311 /* We don't need updated costs anymore. */
3312 ira_free_allocno_updated_costs (subloop_allocno);
3315 else if (hard_regno < 0)
3317 ALLOCNO_UPDATED_MEMORY_COST (subloop_allocno)
3318 -= ((ira_memory_move_cost[mode][rclass][1] * enter_freq)
3319 + (ira_memory_move_cost[mode][rclass][0] * exit_freq));
3321 else
3323 aclass = ALLOCNO_CLASS (subloop_allocno);
3324 ira_init_register_move_cost_if_necessary (mode);
3325 cost = (ira_register_move_cost[mode][rclass][rclass]
3326 * (exit_freq + enter_freq));
3327 ira_allocate_and_set_or_copy_costs
3328 (&ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno), aclass,
3329 ALLOCNO_UPDATED_CLASS_COST (subloop_allocno),
3330 ALLOCNO_HARD_REG_COSTS (subloop_allocno));
3331 ira_allocate_and_set_or_copy_costs
3332 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (subloop_allocno),
3333 aclass, 0, ALLOCNO_CONFLICT_HARD_REG_COSTS (subloop_allocno));
3334 ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno)[index] -= cost;
3335 ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (subloop_allocno)[index]
3336 -= cost;
3337 if (ALLOCNO_UPDATED_CLASS_COST (subloop_allocno)
3338 > ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno)[index])
3339 ALLOCNO_UPDATED_CLASS_COST (subloop_allocno)
3340 = ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno)[index];
3341 ALLOCNO_UPDATED_MEMORY_COST (subloop_allocno)
3342 += (ira_memory_move_cost[mode][rclass][0] * enter_freq
3343 + ira_memory_move_cost[mode][rclass][1] * exit_freq);
3347 ira_free (allocno_color_data);
3348 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
3350 a = ira_allocnos[j];
3351 ALLOCNO_ADD_DATA (a) = NULL;
3355 /* Initialize the common data for coloring and calls functions to do
3356 Chaitin-Briggs and regional coloring. */
3357 static void
3358 do_coloring (void)
3360 coloring_allocno_bitmap = ira_allocate_bitmap ();
3361 if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
3362 fprintf (ira_dump_file, "\n**** Allocnos coloring:\n\n");
3364 ira_traverse_loop_tree (false, ira_loop_tree_root, color_pass, NULL);
3366 if (internal_flag_ira_verbose > 1 && ira_dump_file != NULL)
3367 ira_print_disposition (ira_dump_file);
3369 ira_free_bitmap (coloring_allocno_bitmap);
3374 /* Move spill/restore code, which are to be generated in ira-emit.c,
3375 to less frequent points (if it is profitable) by reassigning some
3376 allocnos (in loop with subloops containing in another loop) to
3377 memory which results in longer live-range where the corresponding
3378 pseudo-registers will be in memory. */
3379 static void
3380 move_spill_restore (void)
3382 int cost, regno, hard_regno, hard_regno2, index;
3383 bool changed_p;
3384 int enter_freq, exit_freq;
3385 machine_mode mode;
3386 enum reg_class rclass;
3387 ira_allocno_t a, parent_allocno, subloop_allocno;
3388 ira_loop_tree_node_t parent, loop_node, subloop_node;
3389 ira_allocno_iterator ai;
3391 for (;;)
3393 changed_p = false;
3394 if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
3395 fprintf (ira_dump_file, "New iteration of spill/restore move\n");
3396 FOR_EACH_ALLOCNO (a, ai)
3398 regno = ALLOCNO_REGNO (a);
3399 loop_node = ALLOCNO_LOOP_TREE_NODE (a);
3400 if (ALLOCNO_CAP_MEMBER (a) != NULL
3401 || ALLOCNO_CAP (a) != NULL
3402 || (hard_regno = ALLOCNO_HARD_REGNO (a)) < 0
3403 || loop_node->children == NULL
3404 /* don't do the optimization because it can create
3405 copies and the reload pass can spill the allocno set
3406 by copy although the allocno will not get memory
3407 slot. */
3408 || ira_equiv_no_lvalue_p (regno)
3409 || !bitmap_bit_p (loop_node->border_allocnos, ALLOCNO_NUM (a))
3410 /* Do not spill static chain pointer pseudo when
3411 non-local goto is used. */
3412 || non_spilled_static_chain_regno_p (regno))
3413 continue;
3414 mode = ALLOCNO_MODE (a);
3415 rclass = ALLOCNO_CLASS (a);
3416 index = ira_class_hard_reg_index[rclass][hard_regno];
3417 ira_assert (index >= 0);
3418 cost = (ALLOCNO_MEMORY_COST (a)
3419 - (ALLOCNO_HARD_REG_COSTS (a) == NULL
3420 ? ALLOCNO_CLASS_COST (a)
3421 : ALLOCNO_HARD_REG_COSTS (a)[index]));
3422 ira_init_register_move_cost_if_necessary (mode);
3423 for (subloop_node = loop_node->subloops;
3424 subloop_node != NULL;
3425 subloop_node = subloop_node->subloop_next)
3427 ira_assert (subloop_node->bb == NULL);
3428 subloop_allocno = subloop_node->regno_allocno_map[regno];
3429 if (subloop_allocno == NULL)
3430 continue;
3431 ira_assert (rclass == ALLOCNO_CLASS (subloop_allocno));
3432 /* We have accumulated cost. To get the real cost of
3433 allocno usage in the loop we should subtract costs of
3434 the subloop allocnos. */
3435 cost -= (ALLOCNO_MEMORY_COST (subloop_allocno)
3436 - (ALLOCNO_HARD_REG_COSTS (subloop_allocno) == NULL
3437 ? ALLOCNO_CLASS_COST (subloop_allocno)
3438 : ALLOCNO_HARD_REG_COSTS (subloop_allocno)[index]));
3439 exit_freq = ira_loop_edge_freq (subloop_node, regno, true);
3440 enter_freq = ira_loop_edge_freq (subloop_node, regno, false);
3441 if ((hard_regno2 = ALLOCNO_HARD_REGNO (subloop_allocno)) < 0)
3442 cost -= (ira_memory_move_cost[mode][rclass][0] * exit_freq
3443 + ira_memory_move_cost[mode][rclass][1] * enter_freq);
3444 else
3446 cost
3447 += (ira_memory_move_cost[mode][rclass][0] * exit_freq
3448 + ira_memory_move_cost[mode][rclass][1] * enter_freq);
3449 if (hard_regno2 != hard_regno)
3450 cost -= (ira_register_move_cost[mode][rclass][rclass]
3451 * (exit_freq + enter_freq));
3454 if ((parent = loop_node->parent) != NULL
3455 && (parent_allocno = parent->regno_allocno_map[regno]) != NULL)
3457 ira_assert (rclass == ALLOCNO_CLASS (parent_allocno));
3458 exit_freq = ira_loop_edge_freq (loop_node, regno, true);
3459 enter_freq = ira_loop_edge_freq (loop_node, regno, false);
3460 if ((hard_regno2 = ALLOCNO_HARD_REGNO (parent_allocno)) < 0)
3461 cost -= (ira_memory_move_cost[mode][rclass][0] * exit_freq
3462 + ira_memory_move_cost[mode][rclass][1] * enter_freq);
3463 else
3465 cost
3466 += (ira_memory_move_cost[mode][rclass][1] * exit_freq
3467 + ira_memory_move_cost[mode][rclass][0] * enter_freq);
3468 if (hard_regno2 != hard_regno)
3469 cost -= (ira_register_move_cost[mode][rclass][rclass]
3470 * (exit_freq + enter_freq));
3473 if (cost < 0)
3475 ALLOCNO_HARD_REGNO (a) = -1;
3476 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3478 fprintf
3479 (ira_dump_file,
3480 " Moving spill/restore for a%dr%d up from loop %d",
3481 ALLOCNO_NUM (a), regno, loop_node->loop_num);
3482 fprintf (ira_dump_file, " - profit %d\n", -cost);
3484 changed_p = true;
3487 if (! changed_p)
3488 break;
3494 /* Update current hard reg costs and current conflict hard reg costs
3495 for allocno A. It is done by processing its copies containing
3496 other allocnos already assigned. */
3497 static void
3498 update_curr_costs (ira_allocno_t a)
3500 int i, hard_regno, cost;
3501 machine_mode mode;
3502 enum reg_class aclass, rclass;
3503 ira_allocno_t another_a;
3504 ira_copy_t cp, next_cp;
3506 ira_free_allocno_updated_costs (a);
3507 ira_assert (! ALLOCNO_ASSIGNED_P (a));
3508 aclass = ALLOCNO_CLASS (a);
3509 if (aclass == NO_REGS)
3510 return;
3511 mode = ALLOCNO_MODE (a);
3512 ira_init_register_move_cost_if_necessary (mode);
3513 for (cp = ALLOCNO_COPIES (a); cp != NULL; cp = next_cp)
3515 if (cp->first == a)
3517 next_cp = cp->next_first_allocno_copy;
3518 another_a = cp->second;
3520 else if (cp->second == a)
3522 next_cp = cp->next_second_allocno_copy;
3523 another_a = cp->first;
3525 else
3526 gcc_unreachable ();
3527 if (! ira_reg_classes_intersect_p[aclass][ALLOCNO_CLASS (another_a)]
3528 || ! ALLOCNO_ASSIGNED_P (another_a)
3529 || (hard_regno = ALLOCNO_HARD_REGNO (another_a)) < 0)
3530 continue;
3531 rclass = REGNO_REG_CLASS (hard_regno);
3532 i = ira_class_hard_reg_index[aclass][hard_regno];
3533 if (i < 0)
3534 continue;
3535 cost = (cp->first == a
3536 ? ira_register_move_cost[mode][rclass][aclass]
3537 : ira_register_move_cost[mode][aclass][rclass]);
3538 ira_allocate_and_set_or_copy_costs
3539 (&ALLOCNO_UPDATED_HARD_REG_COSTS (a), aclass, ALLOCNO_CLASS_COST (a),
3540 ALLOCNO_HARD_REG_COSTS (a));
3541 ira_allocate_and_set_or_copy_costs
3542 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a),
3543 aclass, 0, ALLOCNO_CONFLICT_HARD_REG_COSTS (a));
3544 ALLOCNO_UPDATED_HARD_REG_COSTS (a)[i] -= cp->freq * cost;
3545 ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a)[i] -= cp->freq * cost;
3549 /* Try to assign hard registers to the unassigned allocnos and
3550 allocnos conflicting with them or conflicting with allocnos whose
3551 regno >= START_REGNO. The function is called after ira_flattening,
3552 so more allocnos (including ones created in ira-emit.c) will have a
3553 chance to get a hard register. We use simple assignment algorithm
3554 based on priorities. */
3555 void
3556 ira_reassign_conflict_allocnos (int start_regno)
3558 int i, allocnos_to_color_num;
3559 ira_allocno_t a;
3560 enum reg_class aclass;
3561 bitmap allocnos_to_color;
3562 ira_allocno_iterator ai;
3564 allocnos_to_color = ira_allocate_bitmap ();
3565 allocnos_to_color_num = 0;
3566 FOR_EACH_ALLOCNO (a, ai)
3568 int n = ALLOCNO_NUM_OBJECTS (a);
3570 if (! ALLOCNO_ASSIGNED_P (a)
3571 && ! bitmap_bit_p (allocnos_to_color, ALLOCNO_NUM (a)))
3573 if (ALLOCNO_CLASS (a) != NO_REGS)
3574 sorted_allocnos[allocnos_to_color_num++] = a;
3575 else
3577 ALLOCNO_ASSIGNED_P (a) = true;
3578 ALLOCNO_HARD_REGNO (a) = -1;
3579 ira_assert (ALLOCNO_UPDATED_HARD_REG_COSTS (a) == NULL);
3580 ira_assert (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a) == NULL);
3582 bitmap_set_bit (allocnos_to_color, ALLOCNO_NUM (a));
3584 if (ALLOCNO_REGNO (a) < start_regno
3585 || (aclass = ALLOCNO_CLASS (a)) == NO_REGS)
3586 continue;
3587 for (i = 0; i < n; i++)
3589 ira_object_t obj = ALLOCNO_OBJECT (a, i);
3590 ira_object_t conflict_obj;
3591 ira_object_conflict_iterator oci;
3593 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
3595 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
3597 ira_assert (ira_reg_classes_intersect_p
3598 [aclass][ALLOCNO_CLASS (conflict_a)]);
3599 if (!bitmap_set_bit (allocnos_to_color, ALLOCNO_NUM (conflict_a)))
3600 continue;
3601 sorted_allocnos[allocnos_to_color_num++] = conflict_a;
3605 ira_free_bitmap (allocnos_to_color);
3606 if (allocnos_to_color_num > 1)
3608 setup_allocno_priorities (sorted_allocnos, allocnos_to_color_num);
3609 qsort (sorted_allocnos, allocnos_to_color_num, sizeof (ira_allocno_t),
3610 allocno_priority_compare_func);
3612 for (i = 0; i < allocnos_to_color_num; i++)
3614 a = sorted_allocnos[i];
3615 ALLOCNO_ASSIGNED_P (a) = false;
3616 update_curr_costs (a);
3618 for (i = 0; i < allocnos_to_color_num; i++)
3620 a = sorted_allocnos[i];
3621 if (assign_hard_reg (a, true))
3623 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3624 fprintf
3625 (ira_dump_file,
3626 " Secondary allocation: assign hard reg %d to reg %d\n",
3627 ALLOCNO_HARD_REGNO (a), ALLOCNO_REGNO (a));
3634 /* This page contains functions used to find conflicts using allocno
3635 live ranges. */
3637 #ifdef ENABLE_IRA_CHECKING
3639 /* Return TRUE if live ranges of pseudo-registers REGNO1 and REGNO2
3640 intersect. This should be used when there is only one region.
3641 Currently this is used during reload. */
3642 static bool
3643 conflict_by_live_ranges_p (int regno1, int regno2)
3645 ira_allocno_t a1, a2;
3647 ira_assert (regno1 >= FIRST_PSEUDO_REGISTER
3648 && regno2 >= FIRST_PSEUDO_REGISTER);
3649 /* Reg info calculated by dataflow infrastructure can be different
3650 from one calculated by regclass. */
3651 if ((a1 = ira_loop_tree_root->regno_allocno_map[regno1]) == NULL
3652 || (a2 = ira_loop_tree_root->regno_allocno_map[regno2]) == NULL)
3653 return false;
3654 return allocnos_conflict_by_live_ranges_p (a1, a2);
3657 #endif
3661 /* This page contains code to coalesce memory stack slots used by
3662 spilled allocnos. This results in smaller stack frame, better data
3663 locality, and in smaller code for some architectures like
3664 x86/x86_64 where insn size depends on address displacement value.
3665 On the other hand, it can worsen insn scheduling after the RA but
3666 in practice it is less important than smaller stack frames. */
3668 /* TRUE if we coalesced some allocnos. In other words, if we got
3669 loops formed by members first_coalesced_allocno and
3670 next_coalesced_allocno containing more one allocno. */
3671 static bool allocno_coalesced_p;
3673 /* Bitmap used to prevent a repeated allocno processing because of
3674 coalescing. */
3675 static bitmap processed_coalesced_allocno_bitmap;
3677 /* See below. */
3678 typedef struct coalesce_data *coalesce_data_t;
3680 /* To decrease footprint of ira_allocno structure we store all data
3681 needed only for coalescing in the following structure. */
3682 struct coalesce_data
3684 /* Coalesced allocnos form a cyclic list. One allocno given by
3685 FIRST represents all coalesced allocnos. The
3686 list is chained by NEXT. */
3687 ira_allocno_t first;
3688 ira_allocno_t next;
3689 int temp;
3692 /* Container for storing allocno data concerning coalescing. */
3693 static coalesce_data_t allocno_coalesce_data;
3695 /* Macro to access the data concerning coalescing. */
3696 #define ALLOCNO_COALESCE_DATA(a) ((coalesce_data_t) ALLOCNO_ADD_DATA (a))
3698 /* Merge two sets of coalesced allocnos given correspondingly by
3699 allocnos A1 and A2 (more accurately merging A2 set into A1
3700 set). */
3701 static void
3702 merge_allocnos (ira_allocno_t a1, ira_allocno_t a2)
3704 ira_allocno_t a, first, last, next;
3706 first = ALLOCNO_COALESCE_DATA (a1)->first;
3707 a = ALLOCNO_COALESCE_DATA (a2)->first;
3708 if (first == a)
3709 return;
3710 for (last = a2, a = ALLOCNO_COALESCE_DATA (a2)->next;;
3711 a = ALLOCNO_COALESCE_DATA (a)->next)
3713 ALLOCNO_COALESCE_DATA (a)->first = first;
3714 if (a == a2)
3715 break;
3716 last = a;
3718 next = allocno_coalesce_data[ALLOCNO_NUM (first)].next;
3719 allocno_coalesce_data[ALLOCNO_NUM (first)].next = a2;
3720 allocno_coalesce_data[ALLOCNO_NUM (last)].next = next;
3723 /* Return TRUE if there are conflicting allocnos from two sets of
3724 coalesced allocnos given correspondingly by allocnos A1 and A2. We
3725 use live ranges to find conflicts because conflicts are represented
3726 only for allocnos of the same allocno class and during the reload
3727 pass we coalesce allocnos for sharing stack memory slots. */
3728 static bool
3729 coalesced_allocno_conflict_p (ira_allocno_t a1, ira_allocno_t a2)
3731 ira_allocno_t a, conflict_a;
3733 if (allocno_coalesced_p)
3735 bitmap_clear (processed_coalesced_allocno_bitmap);
3736 for (a = ALLOCNO_COALESCE_DATA (a1)->next;;
3737 a = ALLOCNO_COALESCE_DATA (a)->next)
3739 bitmap_set_bit (processed_coalesced_allocno_bitmap, ALLOCNO_NUM (a));
3740 if (a == a1)
3741 break;
3744 for (a = ALLOCNO_COALESCE_DATA (a2)->next;;
3745 a = ALLOCNO_COALESCE_DATA (a)->next)
3747 for (conflict_a = ALLOCNO_COALESCE_DATA (a1)->next;;
3748 conflict_a = ALLOCNO_COALESCE_DATA (conflict_a)->next)
3750 if (allocnos_conflict_by_live_ranges_p (a, conflict_a))
3751 return true;
3752 if (conflict_a == a1)
3753 break;
3755 if (a == a2)
3756 break;
3758 return false;
3761 /* The major function for aggressive allocno coalescing. We coalesce
3762 only spilled allocnos. If some allocnos have been coalesced, we
3763 set up flag allocno_coalesced_p. */
3764 static void
3765 coalesce_allocnos (void)
3767 ira_allocno_t a;
3768 ira_copy_t cp, next_cp;
3769 unsigned int j;
3770 int i, n, cp_num, regno;
3771 bitmap_iterator bi;
3773 cp_num = 0;
3774 /* Collect copies. */
3775 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, j, bi)
3777 a = ira_allocnos[j];
3778 regno = ALLOCNO_REGNO (a);
3779 if (! ALLOCNO_ASSIGNED_P (a) || ALLOCNO_HARD_REGNO (a) >= 0
3780 || ira_equiv_no_lvalue_p (regno))
3781 continue;
3782 for (cp = ALLOCNO_COPIES (a); cp != NULL; cp = next_cp)
3784 if (cp->first == a)
3786 next_cp = cp->next_first_allocno_copy;
3787 regno = ALLOCNO_REGNO (cp->second);
3788 /* For priority coloring we coalesce allocnos only with
3789 the same allocno class not with intersected allocno
3790 classes as it were possible. It is done for
3791 simplicity. */
3792 if ((cp->insn != NULL || cp->constraint_p)
3793 && ALLOCNO_ASSIGNED_P (cp->second)
3794 && ALLOCNO_HARD_REGNO (cp->second) < 0
3795 && ! ira_equiv_no_lvalue_p (regno))
3796 sorted_copies[cp_num++] = cp;
3798 else if (cp->second == a)
3799 next_cp = cp->next_second_allocno_copy;
3800 else
3801 gcc_unreachable ();
3804 qsort (sorted_copies, cp_num, sizeof (ira_copy_t), copy_freq_compare_func);
3805 /* Coalesced copies, most frequently executed first. */
3806 for (; cp_num != 0;)
3808 for (i = 0; i < cp_num; i++)
3810 cp = sorted_copies[i];
3811 if (! coalesced_allocno_conflict_p (cp->first, cp->second))
3813 allocno_coalesced_p = true;
3814 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3815 fprintf
3816 (ira_dump_file,
3817 " Coalescing copy %d:a%dr%d-a%dr%d (freq=%d)\n",
3818 cp->num, ALLOCNO_NUM (cp->first), ALLOCNO_REGNO (cp->first),
3819 ALLOCNO_NUM (cp->second), ALLOCNO_REGNO (cp->second),
3820 cp->freq);
3821 merge_allocnos (cp->first, cp->second);
3822 i++;
3823 break;
3826 /* Collect the rest of copies. */
3827 for (n = 0; i < cp_num; i++)
3829 cp = sorted_copies[i];
3830 if (allocno_coalesce_data[ALLOCNO_NUM (cp->first)].first
3831 != allocno_coalesce_data[ALLOCNO_NUM (cp->second)].first)
3832 sorted_copies[n++] = cp;
3834 cp_num = n;
3838 /* Usage cost and order number of coalesced allocno set to which
3839 given pseudo register belongs to. */
3840 static int *regno_coalesced_allocno_cost;
3841 static int *regno_coalesced_allocno_num;
3843 /* Sort pseudos according frequencies of coalesced allocno sets they
3844 belong to (putting most frequently ones first), and according to
3845 coalesced allocno set order numbers. */
3846 static int
3847 coalesced_pseudo_reg_freq_compare (const void *v1p, const void *v2p)
3849 const int regno1 = *(const int *) v1p;
3850 const int regno2 = *(const int *) v2p;
3851 int diff;
3853 if ((diff = (regno_coalesced_allocno_cost[regno2]
3854 - regno_coalesced_allocno_cost[regno1])) != 0)
3855 return diff;
3856 if ((diff = (regno_coalesced_allocno_num[regno1]
3857 - regno_coalesced_allocno_num[regno2])) != 0)
3858 return diff;
3859 return regno1 - regno2;
3862 /* Widest width in which each pseudo reg is referred to (via subreg).
3863 It is used for sorting pseudo registers. */
3864 static unsigned int *regno_max_ref_width;
3866 /* Sort pseudos according their slot numbers (putting ones with
3867 smaller numbers first, or last when the frame pointer is not
3868 needed). */
3869 static int
3870 coalesced_pseudo_reg_slot_compare (const void *v1p, const void *v2p)
3872 const int regno1 = *(const int *) v1p;
3873 const int regno2 = *(const int *) v2p;
3874 ira_allocno_t a1 = ira_regno_allocno_map[regno1];
3875 ira_allocno_t a2 = ira_regno_allocno_map[regno2];
3876 int diff, slot_num1, slot_num2;
3877 int total_size1, total_size2;
3879 if (a1 == NULL || ALLOCNO_HARD_REGNO (a1) >= 0)
3881 if (a2 == NULL || ALLOCNO_HARD_REGNO (a2) >= 0)
3882 return regno1 - regno2;
3883 return 1;
3885 else if (a2 == NULL || ALLOCNO_HARD_REGNO (a2) >= 0)
3886 return -1;
3887 slot_num1 = -ALLOCNO_HARD_REGNO (a1);
3888 slot_num2 = -ALLOCNO_HARD_REGNO (a2);
3889 if ((diff = slot_num1 - slot_num2) != 0)
3890 return (frame_pointer_needed
3891 || (!FRAME_GROWS_DOWNWARD) == STACK_GROWS_DOWNWARD ? diff : -diff);
3892 total_size1 = MAX (PSEUDO_REGNO_BYTES (regno1),
3893 regno_max_ref_width[regno1]);
3894 total_size2 = MAX (PSEUDO_REGNO_BYTES (regno2),
3895 regno_max_ref_width[regno2]);
3896 if ((diff = total_size2 - total_size1) != 0)
3897 return diff;
3898 return regno1 - regno2;
3901 /* Setup REGNO_COALESCED_ALLOCNO_COST and REGNO_COALESCED_ALLOCNO_NUM
3902 for coalesced allocno sets containing allocnos with their regnos
3903 given in array PSEUDO_REGNOS of length N. */
3904 static void
3905 setup_coalesced_allocno_costs_and_nums (int *pseudo_regnos, int n)
3907 int i, num, regno, cost;
3908 ira_allocno_t allocno, a;
3910 for (num = i = 0; i < n; i++)
3912 regno = pseudo_regnos[i];
3913 allocno = ira_regno_allocno_map[regno];
3914 if (allocno == NULL)
3916 regno_coalesced_allocno_cost[regno] = 0;
3917 regno_coalesced_allocno_num[regno] = ++num;
3918 continue;
3920 if (ALLOCNO_COALESCE_DATA (allocno)->first != allocno)
3921 continue;
3922 num++;
3923 for (cost = 0, a = ALLOCNO_COALESCE_DATA (allocno)->next;;
3924 a = ALLOCNO_COALESCE_DATA (a)->next)
3926 cost += ALLOCNO_FREQ (a);
3927 if (a == allocno)
3928 break;
3930 for (a = ALLOCNO_COALESCE_DATA (allocno)->next;;
3931 a = ALLOCNO_COALESCE_DATA (a)->next)
3933 regno_coalesced_allocno_num[ALLOCNO_REGNO (a)] = num;
3934 regno_coalesced_allocno_cost[ALLOCNO_REGNO (a)] = cost;
3935 if (a == allocno)
3936 break;
3941 /* Collect spilled allocnos representing coalesced allocno sets (the
3942 first coalesced allocno). The collected allocnos are returned
3943 through array SPILLED_COALESCED_ALLOCNOS. The function returns the
3944 number of the collected allocnos. The allocnos are given by their
3945 regnos in array PSEUDO_REGNOS of length N. */
3946 static int
3947 collect_spilled_coalesced_allocnos (int *pseudo_regnos, int n,
3948 ira_allocno_t *spilled_coalesced_allocnos)
3950 int i, num, regno;
3951 ira_allocno_t allocno;
3953 for (num = i = 0; i < n; i++)
3955 regno = pseudo_regnos[i];
3956 allocno = ira_regno_allocno_map[regno];
3957 if (allocno == NULL || ALLOCNO_HARD_REGNO (allocno) >= 0
3958 || ALLOCNO_COALESCE_DATA (allocno)->first != allocno)
3959 continue;
3960 spilled_coalesced_allocnos[num++] = allocno;
3962 return num;
3965 /* Array of live ranges of size IRA_ALLOCNOS_NUM. Live range for
3966 given slot contains live ranges of coalesced allocnos assigned to
3967 given slot. */
3968 static live_range_t *slot_coalesced_allocnos_live_ranges;
3970 /* Return TRUE if coalesced allocnos represented by ALLOCNO has live
3971 ranges intersected with live ranges of coalesced allocnos assigned
3972 to slot with number N. */
3973 static bool
3974 slot_coalesced_allocno_live_ranges_intersect_p (ira_allocno_t allocno, int n)
3976 ira_allocno_t a;
3978 for (a = ALLOCNO_COALESCE_DATA (allocno)->next;;
3979 a = ALLOCNO_COALESCE_DATA (a)->next)
3981 int i;
3982 int nr = ALLOCNO_NUM_OBJECTS (a);
3984 for (i = 0; i < nr; i++)
3986 ira_object_t obj = ALLOCNO_OBJECT (a, i);
3988 if (ira_live_ranges_intersect_p
3989 (slot_coalesced_allocnos_live_ranges[n],
3990 OBJECT_LIVE_RANGES (obj)))
3991 return true;
3993 if (a == allocno)
3994 break;
3996 return false;
3999 /* Update live ranges of slot to which coalesced allocnos represented
4000 by ALLOCNO were assigned. */
4001 static void
4002 setup_slot_coalesced_allocno_live_ranges (ira_allocno_t allocno)
4004 int i, n;
4005 ira_allocno_t a;
4006 live_range_t r;
4008 n = ALLOCNO_COALESCE_DATA (allocno)->temp;
4009 for (a = ALLOCNO_COALESCE_DATA (allocno)->next;;
4010 a = ALLOCNO_COALESCE_DATA (a)->next)
4012 int nr = ALLOCNO_NUM_OBJECTS (a);
4013 for (i = 0; i < nr; i++)
4015 ira_object_t obj = ALLOCNO_OBJECT (a, i);
4017 r = ira_copy_live_range_list (OBJECT_LIVE_RANGES (obj));
4018 slot_coalesced_allocnos_live_ranges[n]
4019 = ira_merge_live_ranges
4020 (slot_coalesced_allocnos_live_ranges[n], r);
4022 if (a == allocno)
4023 break;
4027 /* We have coalesced allocnos involving in copies. Coalesce allocnos
4028 further in order to share the same memory stack slot. Allocnos
4029 representing sets of allocnos coalesced before the call are given
4030 in array SPILLED_COALESCED_ALLOCNOS of length NUM. Return TRUE if
4031 some allocnos were coalesced in the function. */
4032 static bool
4033 coalesce_spill_slots (ira_allocno_t *spilled_coalesced_allocnos, int num)
4035 int i, j, n, last_coalesced_allocno_num;
4036 ira_allocno_t allocno, a;
4037 bool merged_p = false;
4038 bitmap set_jump_crosses = regstat_get_setjmp_crosses ();
4040 slot_coalesced_allocnos_live_ranges
4041 = (live_range_t *) ira_allocate (sizeof (live_range_t) * ira_allocnos_num);
4042 memset (slot_coalesced_allocnos_live_ranges, 0,
4043 sizeof (live_range_t) * ira_allocnos_num);
4044 last_coalesced_allocno_num = 0;
4045 /* Coalesce non-conflicting spilled allocnos preferring most
4046 frequently used. */
4047 for (i = 0; i < num; i++)
4049 allocno = spilled_coalesced_allocnos[i];
4050 if (ALLOCNO_COALESCE_DATA (allocno)->first != allocno
4051 || bitmap_bit_p (set_jump_crosses, ALLOCNO_REGNO (allocno))
4052 || ira_equiv_no_lvalue_p (ALLOCNO_REGNO (allocno)))
4053 continue;
4054 for (j = 0; j < i; j++)
4056 a = spilled_coalesced_allocnos[j];
4057 n = ALLOCNO_COALESCE_DATA (a)->temp;
4058 if (ALLOCNO_COALESCE_DATA (a)->first == a
4059 && ! bitmap_bit_p (set_jump_crosses, ALLOCNO_REGNO (a))
4060 && ! ira_equiv_no_lvalue_p (ALLOCNO_REGNO (a))
4061 && ! slot_coalesced_allocno_live_ranges_intersect_p (allocno, n))
4062 break;
4064 if (j >= i)
4066 /* No coalescing: set up number for coalesced allocnos
4067 represented by ALLOCNO. */
4068 ALLOCNO_COALESCE_DATA (allocno)->temp = last_coalesced_allocno_num++;
4069 setup_slot_coalesced_allocno_live_ranges (allocno);
4071 else
4073 allocno_coalesced_p = true;
4074 merged_p = true;
4075 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4076 fprintf (ira_dump_file,
4077 " Coalescing spilled allocnos a%dr%d->a%dr%d\n",
4078 ALLOCNO_NUM (allocno), ALLOCNO_REGNO (allocno),
4079 ALLOCNO_NUM (a), ALLOCNO_REGNO (a));
4080 ALLOCNO_COALESCE_DATA (allocno)->temp
4081 = ALLOCNO_COALESCE_DATA (a)->temp;
4082 setup_slot_coalesced_allocno_live_ranges (allocno);
4083 merge_allocnos (a, allocno);
4084 ira_assert (ALLOCNO_COALESCE_DATA (a)->first == a);
4087 for (i = 0; i < ira_allocnos_num; i++)
4088 ira_finish_live_range_list (slot_coalesced_allocnos_live_ranges[i]);
4089 ira_free (slot_coalesced_allocnos_live_ranges);
4090 return merged_p;
4093 /* Sort pseudo-register numbers in array PSEUDO_REGNOS of length N for
4094 subsequent assigning stack slots to them in the reload pass. To do
4095 this we coalesce spilled allocnos first to decrease the number of
4096 memory-memory move insns. This function is called by the
4097 reload. */
4098 void
4099 ira_sort_regnos_for_alter_reg (int *pseudo_regnos, int n,
4100 unsigned int *reg_max_ref_width)
4102 int max_regno = max_reg_num ();
4103 int i, regno, num, slot_num;
4104 ira_allocno_t allocno, a;
4105 ira_allocno_iterator ai;
4106 ira_allocno_t *spilled_coalesced_allocnos;
4108 ira_assert (! ira_use_lra_p);
4110 /* Set up allocnos can be coalesced. */
4111 coloring_allocno_bitmap = ira_allocate_bitmap ();
4112 for (i = 0; i < n; i++)
4114 regno = pseudo_regnos[i];
4115 allocno = ira_regno_allocno_map[regno];
4116 if (allocno != NULL)
4117 bitmap_set_bit (coloring_allocno_bitmap, ALLOCNO_NUM (allocno));
4119 allocno_coalesced_p = false;
4120 processed_coalesced_allocno_bitmap = ira_allocate_bitmap ();
4121 allocno_coalesce_data
4122 = (coalesce_data_t) ira_allocate (sizeof (struct coalesce_data)
4123 * ira_allocnos_num);
4124 /* Initialize coalesce data for allocnos. */
4125 FOR_EACH_ALLOCNO (a, ai)
4127 ALLOCNO_ADD_DATA (a) = allocno_coalesce_data + ALLOCNO_NUM (a);
4128 ALLOCNO_COALESCE_DATA (a)->first = a;
4129 ALLOCNO_COALESCE_DATA (a)->next = a;
4131 coalesce_allocnos ();
4132 ira_free_bitmap (coloring_allocno_bitmap);
4133 regno_coalesced_allocno_cost
4134 = (int *) ira_allocate (max_regno * sizeof (int));
4135 regno_coalesced_allocno_num
4136 = (int *) ira_allocate (max_regno * sizeof (int));
4137 memset (regno_coalesced_allocno_num, 0, max_regno * sizeof (int));
4138 setup_coalesced_allocno_costs_and_nums (pseudo_regnos, n);
4139 /* Sort regnos according frequencies of the corresponding coalesced
4140 allocno sets. */
4141 qsort (pseudo_regnos, n, sizeof (int), coalesced_pseudo_reg_freq_compare);
4142 spilled_coalesced_allocnos
4143 = (ira_allocno_t *) ira_allocate (ira_allocnos_num
4144 * sizeof (ira_allocno_t));
4145 /* Collect allocnos representing the spilled coalesced allocno
4146 sets. */
4147 num = collect_spilled_coalesced_allocnos (pseudo_regnos, n,
4148 spilled_coalesced_allocnos);
4149 if (flag_ira_share_spill_slots
4150 && coalesce_spill_slots (spilled_coalesced_allocnos, num))
4152 setup_coalesced_allocno_costs_and_nums (pseudo_regnos, n);
4153 qsort (pseudo_regnos, n, sizeof (int),
4154 coalesced_pseudo_reg_freq_compare);
4155 num = collect_spilled_coalesced_allocnos (pseudo_regnos, n,
4156 spilled_coalesced_allocnos);
4158 ira_free_bitmap (processed_coalesced_allocno_bitmap);
4159 allocno_coalesced_p = false;
4160 /* Assign stack slot numbers to spilled allocno sets, use smaller
4161 numbers for most frequently used coalesced allocnos. -1 is
4162 reserved for dynamic search of stack slots for pseudos spilled by
4163 the reload. */
4164 slot_num = 1;
4165 for (i = 0; i < num; i++)
4167 allocno = spilled_coalesced_allocnos[i];
4168 if (ALLOCNO_COALESCE_DATA (allocno)->first != allocno
4169 || ALLOCNO_HARD_REGNO (allocno) >= 0
4170 || ira_equiv_no_lvalue_p (ALLOCNO_REGNO (allocno)))
4171 continue;
4172 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4173 fprintf (ira_dump_file, " Slot %d (freq,size):", slot_num);
4174 slot_num++;
4175 for (a = ALLOCNO_COALESCE_DATA (allocno)->next;;
4176 a = ALLOCNO_COALESCE_DATA (a)->next)
4178 ira_assert (ALLOCNO_HARD_REGNO (a) < 0);
4179 ALLOCNO_HARD_REGNO (a) = -slot_num;
4180 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4181 fprintf (ira_dump_file, " a%dr%d(%d,%d)",
4182 ALLOCNO_NUM (a), ALLOCNO_REGNO (a), ALLOCNO_FREQ (a),
4183 MAX (PSEUDO_REGNO_BYTES (ALLOCNO_REGNO (a)),
4184 reg_max_ref_width[ALLOCNO_REGNO (a)]));
4186 if (a == allocno)
4187 break;
4189 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4190 fprintf (ira_dump_file, "\n");
4192 ira_spilled_reg_stack_slots_num = slot_num - 1;
4193 ira_free (spilled_coalesced_allocnos);
4194 /* Sort regnos according the slot numbers. */
4195 regno_max_ref_width = reg_max_ref_width;
4196 qsort (pseudo_regnos, n, sizeof (int), coalesced_pseudo_reg_slot_compare);
4197 FOR_EACH_ALLOCNO (a, ai)
4198 ALLOCNO_ADD_DATA (a) = NULL;
4199 ira_free (allocno_coalesce_data);
4200 ira_free (regno_coalesced_allocno_num);
4201 ira_free (regno_coalesced_allocno_cost);
4206 /* This page contains code used by the reload pass to improve the
4207 final code. */
4209 /* The function is called from reload to mark changes in the
4210 allocation of REGNO made by the reload. Remember that reg_renumber
4211 reflects the change result. */
4212 void
4213 ira_mark_allocation_change (int regno)
4215 ira_allocno_t a = ira_regno_allocno_map[regno];
4216 int old_hard_regno, hard_regno, cost;
4217 enum reg_class aclass = ALLOCNO_CLASS (a);
4219 ira_assert (a != NULL);
4220 hard_regno = reg_renumber[regno];
4221 if ((old_hard_regno = ALLOCNO_HARD_REGNO (a)) == hard_regno)
4222 return;
4223 if (old_hard_regno < 0)
4224 cost = -ALLOCNO_MEMORY_COST (a);
4225 else
4227 ira_assert (ira_class_hard_reg_index[aclass][old_hard_regno] >= 0);
4228 cost = -(ALLOCNO_HARD_REG_COSTS (a) == NULL
4229 ? ALLOCNO_CLASS_COST (a)
4230 : ALLOCNO_HARD_REG_COSTS (a)
4231 [ira_class_hard_reg_index[aclass][old_hard_regno]]);
4232 update_costs_from_copies (a, false, false);
4234 ira_overall_cost -= cost;
4235 ALLOCNO_HARD_REGNO (a) = hard_regno;
4236 if (hard_regno < 0)
4238 ALLOCNO_HARD_REGNO (a) = -1;
4239 cost += ALLOCNO_MEMORY_COST (a);
4241 else if (ira_class_hard_reg_index[aclass][hard_regno] >= 0)
4243 cost += (ALLOCNO_HARD_REG_COSTS (a) == NULL
4244 ? ALLOCNO_CLASS_COST (a)
4245 : ALLOCNO_HARD_REG_COSTS (a)
4246 [ira_class_hard_reg_index[aclass][hard_regno]]);
4247 update_costs_from_copies (a, true, false);
4249 else
4250 /* Reload changed class of the allocno. */
4251 cost = 0;
4252 ira_overall_cost += cost;
4255 /* This function is called when reload deletes memory-memory move. In
4256 this case we marks that the allocation of the corresponding
4257 allocnos should be not changed in future. Otherwise we risk to get
4258 a wrong code. */
4259 void
4260 ira_mark_memory_move_deletion (int dst_regno, int src_regno)
4262 ira_allocno_t dst = ira_regno_allocno_map[dst_regno];
4263 ira_allocno_t src = ira_regno_allocno_map[src_regno];
4265 ira_assert (dst != NULL && src != NULL
4266 && ALLOCNO_HARD_REGNO (dst) < 0
4267 && ALLOCNO_HARD_REGNO (src) < 0);
4268 ALLOCNO_DONT_REASSIGN_P (dst) = true;
4269 ALLOCNO_DONT_REASSIGN_P (src) = true;
4272 /* Try to assign a hard register (except for FORBIDDEN_REGS) to
4273 allocno A and return TRUE in the case of success. */
4274 static bool
4275 allocno_reload_assign (ira_allocno_t a, HARD_REG_SET forbidden_regs)
4277 int hard_regno;
4278 enum reg_class aclass;
4279 int regno = ALLOCNO_REGNO (a);
4280 HARD_REG_SET saved[2];
4281 int i, n;
4283 n = ALLOCNO_NUM_OBJECTS (a);
4284 for (i = 0; i < n; i++)
4286 ira_object_t obj = ALLOCNO_OBJECT (a, i);
4287 COPY_HARD_REG_SET (saved[i], OBJECT_TOTAL_CONFLICT_HARD_REGS (obj));
4288 IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), forbidden_regs);
4289 if (! flag_caller_saves && ALLOCNO_CALLS_CROSSED_NUM (a) != 0)
4290 IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
4291 call_used_reg_set);
4293 ALLOCNO_ASSIGNED_P (a) = false;
4294 aclass = ALLOCNO_CLASS (a);
4295 update_curr_costs (a);
4296 assign_hard_reg (a, true);
4297 hard_regno = ALLOCNO_HARD_REGNO (a);
4298 reg_renumber[regno] = hard_regno;
4299 if (hard_regno < 0)
4300 ALLOCNO_HARD_REGNO (a) = -1;
4301 else
4303 ira_assert (ira_class_hard_reg_index[aclass][hard_regno] >= 0);
4304 ira_overall_cost
4305 -= (ALLOCNO_MEMORY_COST (a)
4306 - (ALLOCNO_HARD_REG_COSTS (a) == NULL
4307 ? ALLOCNO_CLASS_COST (a)
4308 : ALLOCNO_HARD_REG_COSTS (a)[ira_class_hard_reg_index
4309 [aclass][hard_regno]]));
4310 if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0
4311 && ira_hard_reg_set_intersection_p (hard_regno, ALLOCNO_MODE (a),
4312 call_used_reg_set))
4314 ira_assert (flag_caller_saves);
4315 caller_save_needed = 1;
4319 /* If we found a hard register, modify the RTL for the pseudo
4320 register to show the hard register, and mark the pseudo register
4321 live. */
4322 if (reg_renumber[regno] >= 0)
4324 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4325 fprintf (ira_dump_file, ": reassign to %d\n", reg_renumber[regno]);
4326 SET_REGNO (regno_reg_rtx[regno], reg_renumber[regno]);
4327 mark_home_live (regno);
4329 else if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4330 fprintf (ira_dump_file, "\n");
4331 for (i = 0; i < n; i++)
4333 ira_object_t obj = ALLOCNO_OBJECT (a, i);
4334 COPY_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), saved[i]);
4336 return reg_renumber[regno] >= 0;
4339 /* Sort pseudos according their usage frequencies (putting most
4340 frequently ones first). */
4341 static int
4342 pseudo_reg_compare (const void *v1p, const void *v2p)
4344 int regno1 = *(const int *) v1p;
4345 int regno2 = *(const int *) v2p;
4346 int diff;
4348 if ((diff = REG_FREQ (regno2) - REG_FREQ (regno1)) != 0)
4349 return diff;
4350 return regno1 - regno2;
4353 /* Try to allocate hard registers to SPILLED_PSEUDO_REGS (there are
4354 NUM of them) or spilled pseudos conflicting with pseudos in
4355 SPILLED_PSEUDO_REGS. Return TRUE and update SPILLED, if the
4356 allocation has been changed. The function doesn't use
4357 BAD_SPILL_REGS and hard registers in PSEUDO_FORBIDDEN_REGS and
4358 PSEUDO_PREVIOUS_REGS for the corresponding pseudos. The function
4359 is called by the reload pass at the end of each reload
4360 iteration. */
4361 bool
4362 ira_reassign_pseudos (int *spilled_pseudo_regs, int num,
4363 HARD_REG_SET bad_spill_regs,
4364 HARD_REG_SET *pseudo_forbidden_regs,
4365 HARD_REG_SET *pseudo_previous_regs,
4366 bitmap spilled)
4368 int i, n, regno;
4369 bool changed_p;
4370 ira_allocno_t a;
4371 HARD_REG_SET forbidden_regs;
4372 bitmap temp = BITMAP_ALLOC (NULL);
4374 /* Add pseudos which conflict with pseudos already in
4375 SPILLED_PSEUDO_REGS to SPILLED_PSEUDO_REGS. This is preferable
4376 to allocating in two steps as some of the conflicts might have
4377 a higher priority than the pseudos passed in SPILLED_PSEUDO_REGS. */
4378 for (i = 0; i < num; i++)
4379 bitmap_set_bit (temp, spilled_pseudo_regs[i]);
4381 for (i = 0, n = num; i < n; i++)
4383 int nr, j;
4384 int regno = spilled_pseudo_regs[i];
4385 bitmap_set_bit (temp, regno);
4387 a = ira_regno_allocno_map[regno];
4388 nr = ALLOCNO_NUM_OBJECTS (a);
4389 for (j = 0; j < nr; j++)
4391 ira_object_t conflict_obj;
4392 ira_object_t obj = ALLOCNO_OBJECT (a, j);
4393 ira_object_conflict_iterator oci;
4395 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
4397 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
4398 if (ALLOCNO_HARD_REGNO (conflict_a) < 0
4399 && ! ALLOCNO_DONT_REASSIGN_P (conflict_a)
4400 && bitmap_set_bit (temp, ALLOCNO_REGNO (conflict_a)))
4402 spilled_pseudo_regs[num++] = ALLOCNO_REGNO (conflict_a);
4403 /* ?!? This seems wrong. */
4404 bitmap_set_bit (consideration_allocno_bitmap,
4405 ALLOCNO_NUM (conflict_a));
4411 if (num > 1)
4412 qsort (spilled_pseudo_regs, num, sizeof (int), pseudo_reg_compare);
4413 changed_p = false;
4414 /* Try to assign hard registers to pseudos from
4415 SPILLED_PSEUDO_REGS. */
4416 for (i = 0; i < num; i++)
4418 regno = spilled_pseudo_regs[i];
4419 COPY_HARD_REG_SET (forbidden_regs, bad_spill_regs);
4420 IOR_HARD_REG_SET (forbidden_regs, pseudo_forbidden_regs[regno]);
4421 IOR_HARD_REG_SET (forbidden_regs, pseudo_previous_regs[regno]);
4422 gcc_assert (reg_renumber[regno] < 0);
4423 a = ira_regno_allocno_map[regno];
4424 ira_mark_allocation_change (regno);
4425 ira_assert (reg_renumber[regno] < 0);
4426 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4427 fprintf (ira_dump_file,
4428 " Try Assign %d(a%d), cost=%d", regno, ALLOCNO_NUM (a),
4429 ALLOCNO_MEMORY_COST (a)
4430 - ALLOCNO_CLASS_COST (a));
4431 allocno_reload_assign (a, forbidden_regs);
4432 if (reg_renumber[regno] >= 0)
4434 CLEAR_REGNO_REG_SET (spilled, regno);
4435 changed_p = true;
4438 BITMAP_FREE (temp);
4439 return changed_p;
4442 /* The function is called by reload and returns already allocated
4443 stack slot (if any) for REGNO with given INHERENT_SIZE and
4444 TOTAL_SIZE. In the case of failure to find a slot which can be
4445 used for REGNO, the function returns NULL. */
4447 ira_reuse_stack_slot (int regno, unsigned int inherent_size,
4448 unsigned int total_size)
4450 unsigned int i;
4451 int slot_num, best_slot_num;
4452 int cost, best_cost;
4453 ira_copy_t cp, next_cp;
4454 ira_allocno_t another_allocno, allocno = ira_regno_allocno_map[regno];
4455 rtx x;
4456 bitmap_iterator bi;
4457 struct ira_spilled_reg_stack_slot *slot = NULL;
4459 ira_assert (! ira_use_lra_p);
4461 ira_assert (inherent_size == PSEUDO_REGNO_BYTES (regno)
4462 && inherent_size <= total_size
4463 && ALLOCNO_HARD_REGNO (allocno) < 0);
4464 if (! flag_ira_share_spill_slots)
4465 return NULL_RTX;
4466 slot_num = -ALLOCNO_HARD_REGNO (allocno) - 2;
4467 if (slot_num != -1)
4469 slot = &ira_spilled_reg_stack_slots[slot_num];
4470 x = slot->mem;
4472 else
4474 best_cost = best_slot_num = -1;
4475 x = NULL_RTX;
4476 /* It means that the pseudo was spilled in the reload pass, try
4477 to reuse a slot. */
4478 for (slot_num = 0;
4479 slot_num < ira_spilled_reg_stack_slots_num;
4480 slot_num++)
4482 slot = &ira_spilled_reg_stack_slots[slot_num];
4483 if (slot->mem == NULL_RTX)
4484 continue;
4485 if (slot->width < total_size
4486 || GET_MODE_SIZE (GET_MODE (slot->mem)) < inherent_size)
4487 continue;
4489 EXECUTE_IF_SET_IN_BITMAP (&slot->spilled_regs,
4490 FIRST_PSEUDO_REGISTER, i, bi)
4492 another_allocno = ira_regno_allocno_map[i];
4493 if (allocnos_conflict_by_live_ranges_p (allocno,
4494 another_allocno))
4495 goto cont;
4497 for (cost = 0, cp = ALLOCNO_COPIES (allocno);
4498 cp != NULL;
4499 cp = next_cp)
4501 if (cp->first == allocno)
4503 next_cp = cp->next_first_allocno_copy;
4504 another_allocno = cp->second;
4506 else if (cp->second == allocno)
4508 next_cp = cp->next_second_allocno_copy;
4509 another_allocno = cp->first;
4511 else
4512 gcc_unreachable ();
4513 if (cp->insn == NULL_RTX)
4514 continue;
4515 if (bitmap_bit_p (&slot->spilled_regs,
4516 ALLOCNO_REGNO (another_allocno)))
4517 cost += cp->freq;
4519 if (cost > best_cost)
4521 best_cost = cost;
4522 best_slot_num = slot_num;
4524 cont:
4527 if (best_cost >= 0)
4529 slot_num = best_slot_num;
4530 slot = &ira_spilled_reg_stack_slots[slot_num];
4531 SET_REGNO_REG_SET (&slot->spilled_regs, regno);
4532 x = slot->mem;
4533 ALLOCNO_HARD_REGNO (allocno) = -slot_num - 2;
4536 if (x != NULL_RTX)
4538 ira_assert (slot->width >= total_size);
4539 #ifdef ENABLE_IRA_CHECKING
4540 EXECUTE_IF_SET_IN_BITMAP (&slot->spilled_regs,
4541 FIRST_PSEUDO_REGISTER, i, bi)
4543 ira_assert (! conflict_by_live_ranges_p (regno, i));
4545 #endif
4546 SET_REGNO_REG_SET (&slot->spilled_regs, regno);
4547 if (internal_flag_ira_verbose > 3 && ira_dump_file)
4549 fprintf (ira_dump_file, " Assigning %d(freq=%d) slot %d of",
4550 regno, REG_FREQ (regno), slot_num);
4551 EXECUTE_IF_SET_IN_BITMAP (&slot->spilled_regs,
4552 FIRST_PSEUDO_REGISTER, i, bi)
4554 if ((unsigned) regno != i)
4555 fprintf (ira_dump_file, " %d", i);
4557 fprintf (ira_dump_file, "\n");
4560 return x;
4563 /* This is called by reload every time a new stack slot X with
4564 TOTAL_SIZE was allocated for REGNO. We store this info for
4565 subsequent ira_reuse_stack_slot calls. */
4566 void
4567 ira_mark_new_stack_slot (rtx x, int regno, unsigned int total_size)
4569 struct ira_spilled_reg_stack_slot *slot;
4570 int slot_num;
4571 ira_allocno_t allocno;
4573 ira_assert (! ira_use_lra_p);
4575 ira_assert (PSEUDO_REGNO_BYTES (regno) <= total_size);
4576 allocno = ira_regno_allocno_map[regno];
4577 slot_num = -ALLOCNO_HARD_REGNO (allocno) - 2;
4578 if (slot_num == -1)
4580 slot_num = ira_spilled_reg_stack_slots_num++;
4581 ALLOCNO_HARD_REGNO (allocno) = -slot_num - 2;
4583 slot = &ira_spilled_reg_stack_slots[slot_num];
4584 INIT_REG_SET (&slot->spilled_regs);
4585 SET_REGNO_REG_SET (&slot->spilled_regs, regno);
4586 slot->mem = x;
4587 slot->width = total_size;
4588 if (internal_flag_ira_verbose > 3 && ira_dump_file)
4589 fprintf (ira_dump_file, " Assigning %d(freq=%d) a new slot %d\n",
4590 regno, REG_FREQ (regno), slot_num);
4594 /* Return spill cost for pseudo-registers whose numbers are in array
4595 REGNOS (with a negative number as an end marker) for reload with
4596 given IN and OUT for INSN. Return also number points (through
4597 EXCESS_PRESSURE_LIVE_LENGTH) where the pseudo-register lives and
4598 the register pressure is high, number of references of the
4599 pseudo-registers (through NREFS), number of callee-clobbered
4600 hard-registers occupied by the pseudo-registers (through
4601 CALL_USED_COUNT), and the first hard regno occupied by the
4602 pseudo-registers (through FIRST_HARD_REGNO). */
4603 static int
4604 calculate_spill_cost (int *regnos, rtx in, rtx out, rtx_insn *insn,
4605 int *excess_pressure_live_length,
4606 int *nrefs, int *call_used_count, int *first_hard_regno)
4608 int i, cost, regno, hard_regno, j, count, saved_cost, nregs;
4609 bool in_p, out_p;
4610 int length;
4611 ira_allocno_t a;
4613 *nrefs = 0;
4614 for (length = count = cost = i = 0;; i++)
4616 regno = regnos[i];
4617 if (regno < 0)
4618 break;
4619 *nrefs += REG_N_REFS (regno);
4620 hard_regno = reg_renumber[regno];
4621 ira_assert (hard_regno >= 0);
4622 a = ira_regno_allocno_map[regno];
4623 length += ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a) / ALLOCNO_NUM_OBJECTS (a);
4624 cost += ALLOCNO_MEMORY_COST (a) - ALLOCNO_CLASS_COST (a);
4625 nregs = hard_regno_nregs[hard_regno][ALLOCNO_MODE (a)];
4626 for (j = 0; j < nregs; j++)
4627 if (! TEST_HARD_REG_BIT (call_used_reg_set, hard_regno + j))
4628 break;
4629 if (j == nregs)
4630 count++;
4631 in_p = in && REG_P (in) && (int) REGNO (in) == hard_regno;
4632 out_p = out && REG_P (out) && (int) REGNO (out) == hard_regno;
4633 if ((in_p || out_p)
4634 && find_regno_note (insn, REG_DEAD, hard_regno) != NULL_RTX)
4636 saved_cost = 0;
4637 if (in_p)
4638 saved_cost += ira_memory_move_cost
4639 [ALLOCNO_MODE (a)][ALLOCNO_CLASS (a)][1];
4640 if (out_p)
4641 saved_cost
4642 += ira_memory_move_cost
4643 [ALLOCNO_MODE (a)][ALLOCNO_CLASS (a)][0];
4644 cost -= REG_FREQ_FROM_BB (BLOCK_FOR_INSN (insn)) * saved_cost;
4647 *excess_pressure_live_length = length;
4648 *call_used_count = count;
4649 hard_regno = -1;
4650 if (regnos[0] >= 0)
4652 hard_regno = reg_renumber[regnos[0]];
4654 *first_hard_regno = hard_regno;
4655 return cost;
4658 /* Return TRUE if spilling pseudo-registers whose numbers are in array
4659 REGNOS is better than spilling pseudo-registers with numbers in
4660 OTHER_REGNOS for reload with given IN and OUT for INSN. The
4661 function used by the reload pass to make better register spilling
4662 decisions. */
4663 bool
4664 ira_better_spill_reload_regno_p (int *regnos, int *other_regnos,
4665 rtx in, rtx out, rtx_insn *insn)
4667 int cost, other_cost;
4668 int length, other_length;
4669 int nrefs, other_nrefs;
4670 int call_used_count, other_call_used_count;
4671 int hard_regno, other_hard_regno;
4673 cost = calculate_spill_cost (regnos, in, out, insn,
4674 &length, &nrefs, &call_used_count, &hard_regno);
4675 other_cost = calculate_spill_cost (other_regnos, in, out, insn,
4676 &other_length, &other_nrefs,
4677 &other_call_used_count,
4678 &other_hard_regno);
4679 if (nrefs == 0 && other_nrefs != 0)
4680 return true;
4681 if (nrefs != 0 && other_nrefs == 0)
4682 return false;
4683 if (cost != other_cost)
4684 return cost < other_cost;
4685 if (length != other_length)
4686 return length > other_length;
4687 #ifdef REG_ALLOC_ORDER
4688 if (hard_regno >= 0 && other_hard_regno >= 0)
4689 return (inv_reg_alloc_order[hard_regno]
4690 < inv_reg_alloc_order[other_hard_regno]);
4691 #else
4692 if (call_used_count != other_call_used_count)
4693 return call_used_count > other_call_used_count;
4694 #endif
4695 return false;
4700 /* Allocate and initialize data necessary for assign_hard_reg. */
4701 void
4702 ira_initiate_assign (void)
4704 sorted_allocnos
4705 = (ira_allocno_t *) ira_allocate (sizeof (ira_allocno_t)
4706 * ira_allocnos_num);
4707 consideration_allocno_bitmap = ira_allocate_bitmap ();
4708 initiate_cost_update ();
4709 allocno_priorities = (int *) ira_allocate (sizeof (int) * ira_allocnos_num);
4710 sorted_copies = (ira_copy_t *) ira_allocate (ira_copies_num
4711 * sizeof (ira_copy_t));
4714 /* Deallocate data used by assign_hard_reg. */
4715 void
4716 ira_finish_assign (void)
4718 ira_free (sorted_allocnos);
4719 ira_free_bitmap (consideration_allocno_bitmap);
4720 finish_cost_update ();
4721 ira_free (allocno_priorities);
4722 ira_free (sorted_copies);
4727 /* Entry function doing color-based register allocation. */
4728 static void
4729 color (void)
4731 allocno_stack_vec.create (ira_allocnos_num);
4732 memset (allocated_hardreg_p, 0, sizeof (allocated_hardreg_p));
4733 ira_initiate_assign ();
4734 do_coloring ();
4735 ira_finish_assign ();
4736 allocno_stack_vec.release ();
4737 move_spill_restore ();
4742 /* This page contains a simple register allocator without usage of
4743 allocno conflicts. This is used for fast allocation for -O0. */
4745 /* Do register allocation by not using allocno conflicts. It uses
4746 only allocno live ranges. The algorithm is close to Chow's
4747 priority coloring. */
4748 static void
4749 fast_allocation (void)
4751 int i, j, k, num, class_size, hard_regno;
4752 #ifdef STACK_REGS
4753 bool no_stack_reg_p;
4754 #endif
4755 enum reg_class aclass;
4756 machine_mode mode;
4757 ira_allocno_t a;
4758 ira_allocno_iterator ai;
4759 live_range_t r;
4760 HARD_REG_SET conflict_hard_regs, *used_hard_regs;
4762 sorted_allocnos = (ira_allocno_t *) ira_allocate (sizeof (ira_allocno_t)
4763 * ira_allocnos_num);
4764 num = 0;
4765 FOR_EACH_ALLOCNO (a, ai)
4766 sorted_allocnos[num++] = a;
4767 allocno_priorities = (int *) ira_allocate (sizeof (int) * ira_allocnos_num);
4768 setup_allocno_priorities (sorted_allocnos, num);
4769 used_hard_regs = (HARD_REG_SET *) ira_allocate (sizeof (HARD_REG_SET)
4770 * ira_max_point);
4771 for (i = 0; i < ira_max_point; i++)
4772 CLEAR_HARD_REG_SET (used_hard_regs[i]);
4773 qsort (sorted_allocnos, num, sizeof (ira_allocno_t),
4774 allocno_priority_compare_func);
4775 for (i = 0; i < num; i++)
4777 int nr, l;
4779 a = sorted_allocnos[i];
4780 nr = ALLOCNO_NUM_OBJECTS (a);
4781 CLEAR_HARD_REG_SET (conflict_hard_regs);
4782 for (l = 0; l < nr; l++)
4784 ira_object_t obj = ALLOCNO_OBJECT (a, l);
4785 IOR_HARD_REG_SET (conflict_hard_regs,
4786 OBJECT_CONFLICT_HARD_REGS (obj));
4787 for (r = OBJECT_LIVE_RANGES (obj); r != NULL; r = r->next)
4788 for (j = r->start; j <= r->finish; j++)
4789 IOR_HARD_REG_SET (conflict_hard_regs, used_hard_regs[j]);
4791 aclass = ALLOCNO_CLASS (a);
4792 ALLOCNO_ASSIGNED_P (a) = true;
4793 ALLOCNO_HARD_REGNO (a) = -1;
4794 if (hard_reg_set_subset_p (reg_class_contents[aclass],
4795 conflict_hard_regs))
4796 continue;
4797 mode = ALLOCNO_MODE (a);
4798 #ifdef STACK_REGS
4799 no_stack_reg_p = ALLOCNO_NO_STACK_REG_P (a);
4800 #endif
4801 class_size = ira_class_hard_regs_num[aclass];
4802 for (j = 0; j < class_size; j++)
4804 hard_regno = ira_class_hard_regs[aclass][j];
4805 #ifdef STACK_REGS
4806 if (no_stack_reg_p && FIRST_STACK_REG <= hard_regno
4807 && hard_regno <= LAST_STACK_REG)
4808 continue;
4809 #endif
4810 if (ira_hard_reg_set_intersection_p (hard_regno, mode, conflict_hard_regs)
4811 || (TEST_HARD_REG_BIT
4812 (ira_prohibited_class_mode_regs[aclass][mode], hard_regno)))
4813 continue;
4814 ALLOCNO_HARD_REGNO (a) = hard_regno;
4815 for (l = 0; l < nr; l++)
4817 ira_object_t obj = ALLOCNO_OBJECT (a, l);
4818 for (r = OBJECT_LIVE_RANGES (obj); r != NULL; r = r->next)
4819 for (k = r->start; k <= r->finish; k++)
4820 IOR_HARD_REG_SET (used_hard_regs[k],
4821 ira_reg_mode_hard_regset[hard_regno][mode]);
4823 break;
4826 ira_free (sorted_allocnos);
4827 ira_free (used_hard_regs);
4828 ira_free (allocno_priorities);
4829 if (internal_flag_ira_verbose > 1 && ira_dump_file != NULL)
4830 ira_print_disposition (ira_dump_file);
4835 /* Entry function doing coloring. */
4836 void
4837 ira_color (void)
4839 ira_allocno_t a;
4840 ira_allocno_iterator ai;
4842 /* Setup updated costs. */
4843 FOR_EACH_ALLOCNO (a, ai)
4845 ALLOCNO_UPDATED_MEMORY_COST (a) = ALLOCNO_MEMORY_COST (a);
4846 ALLOCNO_UPDATED_CLASS_COST (a) = ALLOCNO_CLASS_COST (a);
4848 if (ira_conflicts_p)
4849 color ();
4850 else
4851 fast_allocation ();