2018-02-09 Sebastian Perta <sebastian.perta@renesas.com>
[official-gcc.git] / gcc / ira-color.c
blob26b18f3b15de80f0f67f25435b0f285a5d70503f
1 /* IRA allocation based on graph coloring.
2 Copyright (C) 2006-2018 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 "memmodel.h"
31 #include "tm_p.h"
32 #include "insn-config.h"
33 #include "regs.h"
34 #include "ira.h"
35 #include "ira-int.h"
36 #include "reload.h"
37 #include "cfgloop.h"
39 typedef struct allocno_hard_regs *allocno_hard_regs_t;
41 /* The structure contains information about hard registers can be
42 assigned to allocnos. Usually it is allocno profitable hard
43 registers but in some cases this set can be a bit different. Major
44 reason of the difference is a requirement to use hard register sets
45 that form a tree or a forest (set of trees), i.e. hard register set
46 of a node should contain hard register sets of its subnodes. */
47 struct allocno_hard_regs
49 /* Hard registers can be assigned to an allocno. */
50 HARD_REG_SET set;
51 /* Overall (spilling) cost of all allocnos with given register
52 set. */
53 int64_t cost;
56 typedef struct allocno_hard_regs_node *allocno_hard_regs_node_t;
58 /* A node representing allocno hard registers. Such nodes form a
59 forest (set of trees). Each subnode of given node in the forest
60 refers for hard register set (usually allocno profitable hard
61 register set) which is a subset of one referred from given
62 node. */
63 struct allocno_hard_regs_node
65 /* Set up number of the node in preorder traversing of the forest. */
66 int preorder_num;
67 /* Used for different calculation like finding conflict size of an
68 allocno. */
69 int check;
70 /* Used for calculation of conflict size of an allocno. The
71 conflict size of the allocno is maximal number of given allocno
72 hard registers needed for allocation of the conflicting allocnos.
73 Given allocno is trivially colored if this number plus the number
74 of hard registers needed for given allocno is not greater than
75 the number of given allocno hard register set. */
76 int conflict_size;
77 /* The number of hard registers given by member hard_regs. */
78 int hard_regs_num;
79 /* The following member is used to form the final forest. */
80 bool used_p;
81 /* Pointer to the corresponding profitable hard registers. */
82 allocno_hard_regs_t hard_regs;
83 /* Parent, first subnode, previous and next node with the same
84 parent in the forest. */
85 allocno_hard_regs_node_t parent, first, prev, next;
88 /* Info about changing hard reg costs of an allocno. */
89 struct update_cost_record
91 /* Hard regno for which we changed the cost. */
92 int hard_regno;
93 /* Divisor used when we changed the cost of HARD_REGNO. */
94 int divisor;
95 /* Next record for given allocno. */
96 struct update_cost_record *next;
99 /* To decrease footprint of ira_allocno structure we store all data
100 needed only for coloring in the following structure. */
101 struct allocno_color_data
103 /* TRUE value means that the allocno was not removed yet from the
104 conflicting graph during coloring. */
105 unsigned int in_graph_p : 1;
106 /* TRUE if it is put on the stack to make other allocnos
107 colorable. */
108 unsigned int may_be_spilled_p : 1;
109 /* TRUE if the allocno is trivially colorable. */
110 unsigned int colorable_p : 1;
111 /* Number of hard registers of the allocno class really
112 available for the allocno allocation. It is number of the
113 profitable hard regs. */
114 int available_regs_num;
115 /* Allocnos in a bucket (used in coloring) chained by the following
116 two members. */
117 ira_allocno_t next_bucket_allocno;
118 ira_allocno_t prev_bucket_allocno;
119 /* Used for temporary purposes. */
120 int temp;
121 /* Used to exclude repeated processing. */
122 int last_process;
123 /* Profitable hard regs available for this pseudo allocation. It
124 means that the set excludes unavailable hard regs and hard regs
125 conflicting with given pseudo. They should be of the allocno
126 class. */
127 HARD_REG_SET profitable_hard_regs;
128 /* The allocno hard registers node. */
129 allocno_hard_regs_node_t hard_regs_node;
130 /* Array of structures allocno_hard_regs_subnode representing
131 given allocno hard registers node (the 1st element in the array)
132 and all its subnodes in the tree (forest) of allocno hard
133 register nodes (see comments above). */
134 int hard_regs_subnodes_start;
135 /* The length of the previous array. */
136 int hard_regs_subnodes_num;
137 /* Records about updating allocno hard reg costs from copies. If
138 the allocno did not get expected hard register, these records are
139 used to restore original hard reg costs of allocnos connected to
140 this allocno by copies. */
141 struct update_cost_record *update_cost_records;
142 /* Threads. We collect allocnos connected by copies into threads
143 and try to assign hard regs to allocnos by threads. */
144 /* Allocno representing all thread. */
145 ira_allocno_t first_thread_allocno;
146 /* Allocnos in thread forms a cycle list through the following
147 member. */
148 ira_allocno_t next_thread_allocno;
149 /* All thread frequency. Defined only for first thread allocno. */
150 int thread_freq;
153 /* See above. */
154 typedef struct allocno_color_data *allocno_color_data_t;
156 /* Container for storing allocno data concerning coloring. */
157 static allocno_color_data_t allocno_color_data;
159 /* Macro to access the data concerning coloring. */
160 #define ALLOCNO_COLOR_DATA(a) ((allocno_color_data_t) ALLOCNO_ADD_DATA (a))
162 /* Used for finding allocno colorability to exclude repeated allocno
163 processing and for updating preferencing to exclude repeated
164 allocno processing during assignment. */
165 static int curr_allocno_process;
167 /* This file contains code for regional graph coloring, spill/restore
168 code placement optimization, and code helping the reload pass to do
169 a better job. */
171 /* Bitmap of allocnos which should be colored. */
172 static bitmap coloring_allocno_bitmap;
174 /* Bitmap of allocnos which should be taken into account during
175 coloring. In general case it contains allocnos from
176 coloring_allocno_bitmap plus other already colored conflicting
177 allocnos. */
178 static bitmap consideration_allocno_bitmap;
180 /* All allocnos sorted according their priorities. */
181 static ira_allocno_t *sorted_allocnos;
183 /* Vec representing the stack of allocnos used during coloring. */
184 static vec<ira_allocno_t> allocno_stack_vec;
186 /* Helper for qsort comparison callbacks - return a positive integer if
187 X > Y, or a negative value otherwise. Use a conditional expression
188 instead of a difference computation to insulate from possible overflow
189 issues, e.g. X - Y < 0 for some X > 0 and Y < 0. */
190 #define SORTGT(x,y) (((x) > (y)) ? 1 : -1)
194 /* Definition of vector of allocno hard registers. */
196 /* Vector of unique allocno hard registers. */
197 static vec<allocno_hard_regs_t> allocno_hard_regs_vec;
199 struct allocno_hard_regs_hasher : nofree_ptr_hash <allocno_hard_regs>
201 static inline hashval_t hash (const allocno_hard_regs *);
202 static inline bool equal (const allocno_hard_regs *,
203 const allocno_hard_regs *);
206 /* Returns hash value for allocno hard registers V. */
207 inline hashval_t
208 allocno_hard_regs_hasher::hash (const allocno_hard_regs *hv)
210 return iterative_hash (&hv->set, sizeof (HARD_REG_SET), 0);
213 /* Compares allocno hard registers V1 and V2. */
214 inline bool
215 allocno_hard_regs_hasher::equal (const allocno_hard_regs *hv1,
216 const allocno_hard_regs *hv2)
218 return hard_reg_set_equal_p (hv1->set, hv2->set);
221 /* Hash table of unique allocno hard registers. */
222 static hash_table<allocno_hard_regs_hasher> *allocno_hard_regs_htab;
224 /* Return allocno hard registers in the hash table equal to HV. */
225 static allocno_hard_regs_t
226 find_hard_regs (allocno_hard_regs_t hv)
228 return allocno_hard_regs_htab->find (hv);
231 /* Insert allocno hard registers HV in the hash table (if it is not
232 there yet) and return the value which in the table. */
233 static allocno_hard_regs_t
234 insert_hard_regs (allocno_hard_regs_t hv)
236 allocno_hard_regs **slot = allocno_hard_regs_htab->find_slot (hv, INSERT);
238 if (*slot == NULL)
239 *slot = hv;
240 return *slot;
243 /* Initialize data concerning allocno hard registers. */
244 static void
245 init_allocno_hard_regs (void)
247 allocno_hard_regs_vec.create (200);
248 allocno_hard_regs_htab
249 = new hash_table<allocno_hard_regs_hasher> (200);
252 /* Add (or update info about) allocno hard registers with SET and
253 COST. */
254 static allocno_hard_regs_t
255 add_allocno_hard_regs (HARD_REG_SET set, int64_t cost)
257 struct allocno_hard_regs temp;
258 allocno_hard_regs_t hv;
260 gcc_assert (! hard_reg_set_empty_p (set));
261 COPY_HARD_REG_SET (temp.set, set);
262 if ((hv = find_hard_regs (&temp)) != NULL)
263 hv->cost += cost;
264 else
266 hv = ((struct allocno_hard_regs *)
267 ira_allocate (sizeof (struct allocno_hard_regs)));
268 COPY_HARD_REG_SET (hv->set, set);
269 hv->cost = cost;
270 allocno_hard_regs_vec.safe_push (hv);
271 insert_hard_regs (hv);
273 return hv;
276 /* Finalize data concerning allocno hard registers. */
277 static void
278 finish_allocno_hard_regs (void)
280 int i;
281 allocno_hard_regs_t hv;
283 for (i = 0;
284 allocno_hard_regs_vec.iterate (i, &hv);
285 i++)
286 ira_free (hv);
287 delete allocno_hard_regs_htab;
288 allocno_hard_regs_htab = NULL;
289 allocno_hard_regs_vec.release ();
292 /* Sort hard regs according to their frequency of usage. */
293 static int
294 allocno_hard_regs_compare (const void *v1p, const void *v2p)
296 allocno_hard_regs_t hv1 = *(const allocno_hard_regs_t *) v1p;
297 allocno_hard_regs_t hv2 = *(const allocno_hard_regs_t *) v2p;
299 if (hv2->cost > hv1->cost)
300 return 1;
301 else if (hv2->cost < hv1->cost)
302 return -1;
303 return SORTGT (allocno_hard_regs_hasher::hash(hv2), allocno_hard_regs_hasher::hash(hv1));
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 /* If we have different modes use the smallest one. It is
1370 a sub-register move. It is hard to predict what LRA
1371 will reload (the pseudo or its sub-register) but LRA
1372 will try to minimize the data movement. Also for some
1373 register classes bigger modes might be invalid,
1374 e.g. DImode for AREG on x86. For such cases the
1375 register move cost will be maximal. */
1376 mode = narrower_subreg_mode (mode, ALLOCNO_MODE (cp->second));
1378 cost = (cp->second == allocno
1379 ? ira_register_move_cost[mode][rclass][aclass]
1380 : ira_register_move_cost[mode][aclass][rclass]);
1381 if (decr_p)
1382 cost = -cost;
1384 update_conflict_cost = update_cost = cp->freq * cost / divisor;
1386 if (ALLOCNO_COLOR_DATA (another_allocno) != NULL
1387 && (ALLOCNO_COLOR_DATA (allocno)->first_thread_allocno
1388 != ALLOCNO_COLOR_DATA (another_allocno)->first_thread_allocno))
1389 /* Decrease conflict cost of ANOTHER_ALLOCNO if it is not
1390 in the same allocation thread. */
1391 update_conflict_cost /= COST_HOP_DIVISOR;
1393 if (update_cost == 0)
1394 continue;
1396 if (! update_allocno_cost (another_allocno, hard_regno,
1397 update_cost, update_conflict_cost))
1398 continue;
1399 queue_update_cost (another_allocno, allocno, divisor * COST_HOP_DIVISOR);
1400 if (record_p && ALLOCNO_COLOR_DATA (another_allocno) != NULL)
1401 ALLOCNO_COLOR_DATA (another_allocno)->update_cost_records
1402 = get_update_cost_record (hard_regno, divisor,
1403 ALLOCNO_COLOR_DATA (another_allocno)
1404 ->update_cost_records);
1407 while (get_next_update_cost (&allocno, &from, &divisor));
1410 /* Decrease preferred ALLOCNO hard register costs and costs of
1411 allocnos connected to ALLOCNO through copy. */
1412 static void
1413 update_costs_from_prefs (ira_allocno_t allocno)
1415 ira_pref_t pref;
1417 start_update_cost ();
1418 for (pref = ALLOCNO_PREFS (allocno); pref != NULL; pref = pref->next_pref)
1419 update_costs_from_allocno (allocno, pref->hard_regno,
1420 COST_HOP_DIVISOR, true, true);
1423 /* Update (decrease if DECR_P) the cost of allocnos connected to
1424 ALLOCNO through copies to increase chances to remove some copies as
1425 the result of subsequent assignment. ALLOCNO was just assigned to
1426 a hard register. Record cost updates if RECORD_P is true. */
1427 static void
1428 update_costs_from_copies (ira_allocno_t allocno, bool decr_p, bool record_p)
1430 int hard_regno;
1432 hard_regno = ALLOCNO_HARD_REGNO (allocno);
1433 ira_assert (hard_regno >= 0 && ALLOCNO_CLASS (allocno) != NO_REGS);
1434 start_update_cost ();
1435 update_costs_from_allocno (allocno, hard_regno, 1, decr_p, record_p);
1438 /* Restore costs of allocnos connected to ALLOCNO by copies as it was
1439 before updating costs of these allocnos from given allocno. This
1440 is a wise thing to do as if given allocno did not get an expected
1441 hard reg, using smaller cost of the hard reg for allocnos connected
1442 by copies to given allocno becomes actually misleading. Free all
1443 update cost records for ALLOCNO as we don't need them anymore. */
1444 static void
1445 restore_costs_from_copies (ira_allocno_t allocno)
1447 struct update_cost_record *records, *curr;
1449 if (ALLOCNO_COLOR_DATA (allocno) == NULL)
1450 return;
1451 records = ALLOCNO_COLOR_DATA (allocno)->update_cost_records;
1452 start_update_cost ();
1453 for (curr = records; curr != NULL; curr = curr->next)
1454 update_costs_from_allocno (allocno, curr->hard_regno,
1455 curr->divisor, true, false);
1456 free_update_cost_record_list (records);
1457 ALLOCNO_COLOR_DATA (allocno)->update_cost_records = NULL;
1460 /* This function updates COSTS (decrease if DECR_P) for hard_registers
1461 of ACLASS by conflict costs of the unassigned allocnos
1462 connected by copies with allocnos in update_cost_queue. This
1463 update increases chances to remove some copies. */
1464 static void
1465 update_conflict_hard_regno_costs (int *costs, enum reg_class aclass,
1466 bool decr_p)
1468 int i, cost, class_size, freq, mult, div, divisor;
1469 int index, hard_regno;
1470 int *conflict_costs;
1471 bool cont_p;
1472 enum reg_class another_aclass;
1473 ira_allocno_t allocno, another_allocno, from;
1474 ira_copy_t cp, next_cp;
1476 while (get_next_update_cost (&allocno, &from, &divisor))
1477 for (cp = ALLOCNO_COPIES (allocno); cp != NULL; cp = next_cp)
1479 if (cp->first == allocno)
1481 next_cp = cp->next_first_allocno_copy;
1482 another_allocno = cp->second;
1484 else if (cp->second == allocno)
1486 next_cp = cp->next_second_allocno_copy;
1487 another_allocno = cp->first;
1489 else
1490 gcc_unreachable ();
1492 if (another_allocno == from)
1493 continue;
1495 another_aclass = ALLOCNO_CLASS (another_allocno);
1496 if (! ira_reg_classes_intersect_p[aclass][another_aclass]
1497 || ALLOCNO_ASSIGNED_P (another_allocno)
1498 || ALLOCNO_COLOR_DATA (another_allocno)->may_be_spilled_p)
1499 continue;
1500 class_size = ira_class_hard_regs_num[another_aclass];
1501 ira_allocate_and_copy_costs
1502 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (another_allocno),
1503 another_aclass, ALLOCNO_CONFLICT_HARD_REG_COSTS (another_allocno));
1504 conflict_costs
1505 = ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (another_allocno);
1506 if (conflict_costs == NULL)
1507 cont_p = true;
1508 else
1510 mult = cp->freq;
1511 freq = ALLOCNO_FREQ (another_allocno);
1512 if (freq == 0)
1513 freq = 1;
1514 div = freq * divisor;
1515 cont_p = false;
1516 for (i = class_size - 1; i >= 0; i--)
1518 hard_regno = ira_class_hard_regs[another_aclass][i];
1519 ira_assert (hard_regno >= 0);
1520 index = ira_class_hard_reg_index[aclass][hard_regno];
1521 if (index < 0)
1522 continue;
1523 cost = (int) (((int64_t) conflict_costs [i] * mult) / div);
1524 if (cost == 0)
1525 continue;
1526 cont_p = true;
1527 if (decr_p)
1528 cost = -cost;
1529 costs[index] += cost;
1532 /* Probably 5 hops will be enough. */
1533 if (cont_p
1534 && divisor <= (COST_HOP_DIVISOR
1535 * COST_HOP_DIVISOR
1536 * COST_HOP_DIVISOR
1537 * COST_HOP_DIVISOR))
1538 queue_update_cost (another_allocno, allocno, divisor * COST_HOP_DIVISOR);
1542 /* Set up conflicting (through CONFLICT_REGS) for each object of
1543 allocno A and the start allocno profitable regs (through
1544 START_PROFITABLE_REGS). Remember that the start profitable regs
1545 exclude hard regs which can not hold value of mode of allocno A.
1546 This covers mostly cases when multi-register value should be
1547 aligned. */
1548 static inline void
1549 get_conflict_and_start_profitable_regs (ira_allocno_t a, bool retry_p,
1550 HARD_REG_SET *conflict_regs,
1551 HARD_REG_SET *start_profitable_regs)
1553 int i, nwords;
1554 ira_object_t obj;
1556 nwords = ALLOCNO_NUM_OBJECTS (a);
1557 for (i = 0; i < nwords; i++)
1559 obj = ALLOCNO_OBJECT (a, i);
1560 COPY_HARD_REG_SET (conflict_regs[i],
1561 OBJECT_TOTAL_CONFLICT_HARD_REGS (obj));
1563 if (retry_p)
1565 COPY_HARD_REG_SET (*start_profitable_regs,
1566 reg_class_contents[ALLOCNO_CLASS (a)]);
1567 AND_COMPL_HARD_REG_SET (*start_profitable_regs,
1568 ira_prohibited_class_mode_regs
1569 [ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]);
1571 else
1572 COPY_HARD_REG_SET (*start_profitable_regs,
1573 ALLOCNO_COLOR_DATA (a)->profitable_hard_regs);
1576 /* Return true if HARD_REGNO is ok for assigning to allocno A with
1577 PROFITABLE_REGS and whose objects have CONFLICT_REGS. */
1578 static inline bool
1579 check_hard_reg_p (ira_allocno_t a, int hard_regno,
1580 HARD_REG_SET *conflict_regs, HARD_REG_SET profitable_regs)
1582 int j, nwords, nregs;
1583 enum reg_class aclass;
1584 machine_mode mode;
1586 aclass = ALLOCNO_CLASS (a);
1587 mode = ALLOCNO_MODE (a);
1588 if (TEST_HARD_REG_BIT (ira_prohibited_class_mode_regs[aclass][mode],
1589 hard_regno))
1590 return false;
1591 /* Checking only profitable hard regs. */
1592 if (! TEST_HARD_REG_BIT (profitable_regs, hard_regno))
1593 return false;
1594 nregs = hard_regno_nregs (hard_regno, mode);
1595 nwords = ALLOCNO_NUM_OBJECTS (a);
1596 for (j = 0; j < nregs; j++)
1598 int k;
1599 int set_to_test_start = 0, set_to_test_end = nwords;
1601 if (nregs == nwords)
1603 if (REG_WORDS_BIG_ENDIAN)
1604 set_to_test_start = nwords - j - 1;
1605 else
1606 set_to_test_start = j;
1607 set_to_test_end = set_to_test_start + 1;
1609 for (k = set_to_test_start; k < set_to_test_end; k++)
1610 if (TEST_HARD_REG_BIT (conflict_regs[k], hard_regno + j))
1611 break;
1612 if (k != set_to_test_end)
1613 break;
1615 return j == nregs;
1618 /* Return number of registers needed to be saved and restored at
1619 function prologue/epilogue if we allocate HARD_REGNO to hold value
1620 of MODE. */
1621 static int
1622 calculate_saved_nregs (int hard_regno, machine_mode mode)
1624 int i;
1625 int nregs = 0;
1627 ira_assert (hard_regno >= 0);
1628 for (i = hard_regno_nregs (hard_regno, mode) - 1; i >= 0; i--)
1629 if (!allocated_hardreg_p[hard_regno + i]
1630 && !TEST_HARD_REG_BIT (call_used_reg_set, hard_regno + i)
1631 && !LOCAL_REGNO (hard_regno + i))
1632 nregs++;
1633 return nregs;
1636 /* Choose a hard register for allocno A. If RETRY_P is TRUE, it means
1637 that the function called from function
1638 `ira_reassign_conflict_allocnos' and `allocno_reload_assign'. In
1639 this case some allocno data are not defined or updated and we
1640 should not touch these data. The function returns true if we
1641 managed to assign a hard register to the allocno.
1643 To assign a hard register, first of all we calculate all conflict
1644 hard registers which can come from conflicting allocnos with
1645 already assigned hard registers. After that we find first free
1646 hard register with the minimal cost. During hard register cost
1647 calculation we take conflict hard register costs into account to
1648 give a chance for conflicting allocnos to get a better hard
1649 register in the future.
1651 If the best hard register cost is bigger than cost of memory usage
1652 for the allocno, we don't assign a hard register to given allocno
1653 at all.
1655 If we assign a hard register to the allocno, we update costs of the
1656 hard register for allocnos connected by copies to improve a chance
1657 to coalesce insns represented by the copies when we assign hard
1658 registers to the allocnos connected by the copies. */
1659 static bool
1660 assign_hard_reg (ira_allocno_t a, bool retry_p)
1662 HARD_REG_SET conflicting_regs[2], profitable_hard_regs;
1663 int i, j, hard_regno, best_hard_regno, class_size;
1664 int cost, mem_cost, min_cost, full_cost, min_full_cost, nwords, word;
1665 int *a_costs;
1666 enum reg_class aclass;
1667 machine_mode mode;
1668 static int costs[FIRST_PSEUDO_REGISTER], full_costs[FIRST_PSEUDO_REGISTER];
1669 int saved_nregs;
1670 enum reg_class rclass;
1671 int add_cost;
1672 #ifdef STACK_REGS
1673 bool no_stack_reg_p;
1674 #endif
1676 ira_assert (! ALLOCNO_ASSIGNED_P (a));
1677 get_conflict_and_start_profitable_regs (a, retry_p,
1678 conflicting_regs,
1679 &profitable_hard_regs);
1680 aclass = ALLOCNO_CLASS (a);
1681 class_size = ira_class_hard_regs_num[aclass];
1682 best_hard_regno = -1;
1683 memset (full_costs, 0, sizeof (int) * class_size);
1684 mem_cost = 0;
1685 memset (costs, 0, sizeof (int) * class_size);
1686 memset (full_costs, 0, sizeof (int) * class_size);
1687 #ifdef STACK_REGS
1688 no_stack_reg_p = false;
1689 #endif
1690 if (! retry_p)
1691 start_update_cost ();
1692 mem_cost += ALLOCNO_UPDATED_MEMORY_COST (a);
1694 ira_allocate_and_copy_costs (&ALLOCNO_UPDATED_HARD_REG_COSTS (a),
1695 aclass, ALLOCNO_HARD_REG_COSTS (a));
1696 a_costs = ALLOCNO_UPDATED_HARD_REG_COSTS (a);
1697 #ifdef STACK_REGS
1698 no_stack_reg_p = no_stack_reg_p || ALLOCNO_TOTAL_NO_STACK_REG_P (a);
1699 #endif
1700 cost = ALLOCNO_UPDATED_CLASS_COST (a);
1701 for (i = 0; i < class_size; i++)
1702 if (a_costs != NULL)
1704 costs[i] += a_costs[i];
1705 full_costs[i] += a_costs[i];
1707 else
1709 costs[i] += cost;
1710 full_costs[i] += cost;
1712 nwords = ALLOCNO_NUM_OBJECTS (a);
1713 curr_allocno_process++;
1714 for (word = 0; word < nwords; word++)
1716 ira_object_t conflict_obj;
1717 ira_object_t obj = ALLOCNO_OBJECT (a, word);
1718 ira_object_conflict_iterator oci;
1720 /* Take preferences of conflicting allocnos into account. */
1721 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
1723 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
1724 enum reg_class conflict_aclass;
1725 allocno_color_data_t data = ALLOCNO_COLOR_DATA (conflict_a);
1727 /* Reload can give another class so we need to check all
1728 allocnos. */
1729 if (!retry_p
1730 && ((!ALLOCNO_ASSIGNED_P (conflict_a)
1731 || ALLOCNO_HARD_REGNO (conflict_a) < 0)
1732 && !(hard_reg_set_intersect_p
1733 (profitable_hard_regs,
1734 ALLOCNO_COLOR_DATA
1735 (conflict_a)->profitable_hard_regs))))
1737 /* All conflict allocnos are in consideration bitmap
1738 when retry_p is false. It might change in future and
1739 if it happens the assert will be broken. It means
1740 the code should be modified for the new
1741 assumptions. */
1742 ira_assert (bitmap_bit_p (consideration_allocno_bitmap,
1743 ALLOCNO_NUM (conflict_a)));
1744 continue;
1746 conflict_aclass = ALLOCNO_CLASS (conflict_a);
1747 ira_assert (ira_reg_classes_intersect_p
1748 [aclass][conflict_aclass]);
1749 if (ALLOCNO_ASSIGNED_P (conflict_a))
1751 hard_regno = ALLOCNO_HARD_REGNO (conflict_a);
1752 if (hard_regno >= 0
1753 && (ira_hard_reg_set_intersection_p
1754 (hard_regno, ALLOCNO_MODE (conflict_a),
1755 reg_class_contents[aclass])))
1757 int n_objects = ALLOCNO_NUM_OBJECTS (conflict_a);
1758 int conflict_nregs;
1760 mode = ALLOCNO_MODE (conflict_a);
1761 conflict_nregs = hard_regno_nregs (hard_regno, mode);
1762 if (conflict_nregs == n_objects && conflict_nregs > 1)
1764 int num = OBJECT_SUBWORD (conflict_obj);
1766 if (REG_WORDS_BIG_ENDIAN)
1767 SET_HARD_REG_BIT (conflicting_regs[word],
1768 hard_regno + n_objects - num - 1);
1769 else
1770 SET_HARD_REG_BIT (conflicting_regs[word],
1771 hard_regno + num);
1773 else
1774 IOR_HARD_REG_SET
1775 (conflicting_regs[word],
1776 ira_reg_mode_hard_regset[hard_regno][mode]);
1777 if (hard_reg_set_subset_p (profitable_hard_regs,
1778 conflicting_regs[word]))
1779 goto fail;
1782 else if (! retry_p
1783 && ! ALLOCNO_COLOR_DATA (conflict_a)->may_be_spilled_p
1784 /* Don't process the conflict allocno twice. */
1785 && (ALLOCNO_COLOR_DATA (conflict_a)->last_process
1786 != curr_allocno_process))
1788 int k, *conflict_costs;
1790 ALLOCNO_COLOR_DATA (conflict_a)->last_process
1791 = curr_allocno_process;
1792 ira_allocate_and_copy_costs
1793 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (conflict_a),
1794 conflict_aclass,
1795 ALLOCNO_CONFLICT_HARD_REG_COSTS (conflict_a));
1796 conflict_costs
1797 = ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (conflict_a);
1798 if (conflict_costs != NULL)
1799 for (j = class_size - 1; j >= 0; j--)
1801 hard_regno = ira_class_hard_regs[aclass][j];
1802 ira_assert (hard_regno >= 0);
1803 k = ira_class_hard_reg_index[conflict_aclass][hard_regno];
1804 if (k < 0
1805 /* If HARD_REGNO is not available for CONFLICT_A,
1806 the conflict would be ignored, since HARD_REGNO
1807 will never be assigned to CONFLICT_A. */
1808 || !TEST_HARD_REG_BIT (data->profitable_hard_regs,
1809 hard_regno))
1810 continue;
1811 full_costs[j] -= conflict_costs[k];
1813 queue_update_cost (conflict_a, NULL, COST_HOP_DIVISOR);
1818 if (! retry_p)
1819 /* Take into account preferences of allocnos connected by copies to
1820 the conflict allocnos. */
1821 update_conflict_hard_regno_costs (full_costs, aclass, true);
1823 /* Take preferences of allocnos connected by copies into
1824 account. */
1825 if (! retry_p)
1827 start_update_cost ();
1828 queue_update_cost (a, NULL, COST_HOP_DIVISOR);
1829 update_conflict_hard_regno_costs (full_costs, aclass, false);
1831 min_cost = min_full_cost = INT_MAX;
1832 /* We don't care about giving callee saved registers to allocnos no
1833 living through calls because call clobbered registers are
1834 allocated first (it is usual practice to put them first in
1835 REG_ALLOC_ORDER). */
1836 mode = ALLOCNO_MODE (a);
1837 for (i = 0; i < class_size; i++)
1839 hard_regno = ira_class_hard_regs[aclass][i];
1840 #ifdef STACK_REGS
1841 if (no_stack_reg_p
1842 && FIRST_STACK_REG <= hard_regno && hard_regno <= LAST_STACK_REG)
1843 continue;
1844 #endif
1845 if (! check_hard_reg_p (a, hard_regno,
1846 conflicting_regs, profitable_hard_regs))
1847 continue;
1848 cost = costs[i];
1849 full_cost = full_costs[i];
1850 if (!HONOR_REG_ALLOC_ORDER)
1852 if ((saved_nregs = calculate_saved_nregs (hard_regno, mode)) != 0)
1853 /* We need to save/restore the hard register in
1854 epilogue/prologue. Therefore we increase the cost. */
1856 rclass = REGNO_REG_CLASS (hard_regno);
1857 add_cost = ((ira_memory_move_cost[mode][rclass][0]
1858 + ira_memory_move_cost[mode][rclass][1])
1859 * saved_nregs / hard_regno_nregs (hard_regno,
1860 mode) - 1);
1861 cost += add_cost;
1862 full_cost += add_cost;
1865 if (min_cost > cost)
1866 min_cost = cost;
1867 if (min_full_cost > full_cost)
1869 min_full_cost = full_cost;
1870 best_hard_regno = hard_regno;
1871 ira_assert (hard_regno >= 0);
1874 if (min_full_cost > mem_cost
1875 /* Do not spill static chain pointer pseudo when non-local goto
1876 is used. */
1877 && ! non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a)))
1879 if (! retry_p && internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
1880 fprintf (ira_dump_file, "(memory is more profitable %d vs %d) ",
1881 mem_cost, min_full_cost);
1882 best_hard_regno = -1;
1884 fail:
1885 if (best_hard_regno >= 0)
1887 for (i = hard_regno_nregs (best_hard_regno, mode) - 1; i >= 0; i--)
1888 allocated_hardreg_p[best_hard_regno + i] = true;
1890 if (! retry_p)
1891 restore_costs_from_copies (a);
1892 ALLOCNO_HARD_REGNO (a) = best_hard_regno;
1893 ALLOCNO_ASSIGNED_P (a) = true;
1894 if (best_hard_regno >= 0)
1895 update_costs_from_copies (a, true, ! retry_p);
1896 ira_assert (ALLOCNO_CLASS (a) == aclass);
1897 /* We don't need updated costs anymore. */
1898 ira_free_allocno_updated_costs (a);
1899 return best_hard_regno >= 0;
1904 /* An array used to sort copies. */
1905 static ira_copy_t *sorted_copies;
1907 /* If allocno A is a cap, return non-cap allocno from which A is
1908 created. Otherwise, return A. */
1909 static ira_allocno_t
1910 get_cap_member (ira_allocno_t a)
1912 ira_allocno_t member;
1914 while ((member = ALLOCNO_CAP_MEMBER (a)) != NULL)
1915 a = member;
1916 return a;
1919 /* Return TRUE if live ranges of allocnos A1 and A2 intersect. It is
1920 used to find a conflict for new allocnos or allocnos with the
1921 different allocno classes. */
1922 static bool
1923 allocnos_conflict_by_live_ranges_p (ira_allocno_t a1, ira_allocno_t a2)
1925 rtx reg1, reg2;
1926 int i, j;
1927 int n1 = ALLOCNO_NUM_OBJECTS (a1);
1928 int n2 = ALLOCNO_NUM_OBJECTS (a2);
1930 if (a1 == a2)
1931 return false;
1932 reg1 = regno_reg_rtx[ALLOCNO_REGNO (a1)];
1933 reg2 = regno_reg_rtx[ALLOCNO_REGNO (a2)];
1934 if (reg1 != NULL && reg2 != NULL
1935 && ORIGINAL_REGNO (reg1) == ORIGINAL_REGNO (reg2))
1936 return false;
1938 /* We don't keep live ranges for caps because they can be quite big.
1939 Use ranges of non-cap allocno from which caps are created. */
1940 a1 = get_cap_member (a1);
1941 a2 = get_cap_member (a2);
1942 for (i = 0; i < n1; i++)
1944 ira_object_t c1 = ALLOCNO_OBJECT (a1, i);
1946 for (j = 0; j < n2; j++)
1948 ira_object_t c2 = ALLOCNO_OBJECT (a2, j);
1950 if (ira_live_ranges_intersect_p (OBJECT_LIVE_RANGES (c1),
1951 OBJECT_LIVE_RANGES (c2)))
1952 return true;
1955 return false;
1958 /* The function is used to sort copies according to their execution
1959 frequencies. */
1960 static int
1961 copy_freq_compare_func (const void *v1p, const void *v2p)
1963 ira_copy_t cp1 = *(const ira_copy_t *) v1p, cp2 = *(const ira_copy_t *) v2p;
1964 int pri1, pri2;
1966 pri1 = cp1->freq;
1967 pri2 = cp2->freq;
1968 if (pri2 - pri1)
1969 return pri2 - pri1;
1971 /* If frequencies are equal, sort by copies, so that the results of
1972 qsort leave nothing to chance. */
1973 return cp1->num - cp2->num;
1978 /* Return true if any allocno from thread of A1 conflicts with any
1979 allocno from thread A2. */
1980 static bool
1981 allocno_thread_conflict_p (ira_allocno_t a1, ira_allocno_t a2)
1983 ira_allocno_t a, conflict_a;
1985 for (a = ALLOCNO_COLOR_DATA (a2)->next_thread_allocno;;
1986 a = ALLOCNO_COLOR_DATA (a)->next_thread_allocno)
1988 for (conflict_a = ALLOCNO_COLOR_DATA (a1)->next_thread_allocno;;
1989 conflict_a = ALLOCNO_COLOR_DATA (conflict_a)->next_thread_allocno)
1991 if (allocnos_conflict_by_live_ranges_p (a, conflict_a))
1992 return true;
1993 if (conflict_a == a1)
1994 break;
1996 if (a == a2)
1997 break;
1999 return false;
2002 /* Merge two threads given correspondingly by their first allocnos T1
2003 and T2 (more accurately merging T2 into T1). */
2004 static void
2005 merge_threads (ira_allocno_t t1, ira_allocno_t t2)
2007 ira_allocno_t a, next, last;
2009 gcc_assert (t1 != t2
2010 && ALLOCNO_COLOR_DATA (t1)->first_thread_allocno == t1
2011 && ALLOCNO_COLOR_DATA (t2)->first_thread_allocno == t2);
2012 for (last = t2, a = ALLOCNO_COLOR_DATA (t2)->next_thread_allocno;;
2013 a = ALLOCNO_COLOR_DATA (a)->next_thread_allocno)
2015 ALLOCNO_COLOR_DATA (a)->first_thread_allocno = t1;
2016 if (a == t2)
2017 break;
2018 last = a;
2020 next = ALLOCNO_COLOR_DATA (t1)->next_thread_allocno;
2021 ALLOCNO_COLOR_DATA (t1)->next_thread_allocno = t2;
2022 ALLOCNO_COLOR_DATA (last)->next_thread_allocno = next;
2023 ALLOCNO_COLOR_DATA (t1)->thread_freq += ALLOCNO_COLOR_DATA (t2)->thread_freq;
2026 /* Create threads by processing CP_NUM copies from sorted copies. We
2027 process the most expensive copies first. */
2028 static void
2029 form_threads_from_copies (int cp_num)
2031 ira_allocno_t a, thread1, thread2;
2032 ira_copy_t cp;
2033 int i, n;
2035 qsort (sorted_copies, cp_num, sizeof (ira_copy_t), copy_freq_compare_func);
2036 /* Form threads processing copies, most frequently executed
2037 first. */
2038 for (; cp_num != 0;)
2040 for (i = 0; i < cp_num; i++)
2042 cp = sorted_copies[i];
2043 thread1 = ALLOCNO_COLOR_DATA (cp->first)->first_thread_allocno;
2044 thread2 = ALLOCNO_COLOR_DATA (cp->second)->first_thread_allocno;
2045 if (thread1 == thread2)
2046 continue;
2047 if (! allocno_thread_conflict_p (thread1, thread2))
2049 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2050 fprintf
2051 (ira_dump_file,
2052 " Forming thread by copy %d:a%dr%d-a%dr%d (freq=%d):\n",
2053 cp->num, ALLOCNO_NUM (cp->first), ALLOCNO_REGNO (cp->first),
2054 ALLOCNO_NUM (cp->second), ALLOCNO_REGNO (cp->second),
2055 cp->freq);
2056 merge_threads (thread1, thread2);
2057 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2059 thread1 = ALLOCNO_COLOR_DATA (thread1)->first_thread_allocno;
2060 fprintf (ira_dump_file, " Result (freq=%d): a%dr%d(%d)",
2061 ALLOCNO_COLOR_DATA (thread1)->thread_freq,
2062 ALLOCNO_NUM (thread1), ALLOCNO_REGNO (thread1),
2063 ALLOCNO_FREQ (thread1));
2064 for (a = ALLOCNO_COLOR_DATA (thread1)->next_thread_allocno;
2065 a != thread1;
2066 a = ALLOCNO_COLOR_DATA (a)->next_thread_allocno)
2067 fprintf (ira_dump_file, " a%dr%d(%d)",
2068 ALLOCNO_NUM (a), ALLOCNO_REGNO (a),
2069 ALLOCNO_FREQ (a));
2070 fprintf (ira_dump_file, "\n");
2072 i++;
2073 break;
2076 /* Collect the rest of copies. */
2077 for (n = 0; i < cp_num; i++)
2079 cp = sorted_copies[i];
2080 if (ALLOCNO_COLOR_DATA (cp->first)->first_thread_allocno
2081 != ALLOCNO_COLOR_DATA (cp->second)->first_thread_allocno)
2082 sorted_copies[n++] = cp;
2084 cp_num = n;
2088 /* Create threads by processing copies of all alocnos from BUCKET. We
2089 process the most expensive copies first. */
2090 static void
2091 form_threads_from_bucket (ira_allocno_t bucket)
2093 ira_allocno_t a;
2094 ira_copy_t cp, next_cp;
2095 int cp_num = 0;
2097 for (a = bucket; a != NULL; a = ALLOCNO_COLOR_DATA (a)->next_bucket_allocno)
2099 for (cp = ALLOCNO_COPIES (a); cp != NULL; cp = next_cp)
2101 if (cp->first == a)
2103 next_cp = cp->next_first_allocno_copy;
2104 sorted_copies[cp_num++] = cp;
2106 else if (cp->second == a)
2107 next_cp = cp->next_second_allocno_copy;
2108 else
2109 gcc_unreachable ();
2112 form_threads_from_copies (cp_num);
2115 /* Create threads by processing copies of colorable allocno A. We
2116 process most expensive copies first. */
2117 static void
2118 form_threads_from_colorable_allocno (ira_allocno_t a)
2120 ira_allocno_t another_a;
2121 ira_copy_t cp, next_cp;
2122 int cp_num = 0;
2124 for (cp = ALLOCNO_COPIES (a); cp != NULL; cp = next_cp)
2126 if (cp->first == a)
2128 next_cp = cp->next_first_allocno_copy;
2129 another_a = cp->second;
2131 else if (cp->second == a)
2133 next_cp = cp->next_second_allocno_copy;
2134 another_a = cp->first;
2136 else
2137 gcc_unreachable ();
2138 if ((! ALLOCNO_COLOR_DATA (another_a)->in_graph_p
2139 && !ALLOCNO_COLOR_DATA (another_a)->may_be_spilled_p)
2140 || ALLOCNO_COLOR_DATA (another_a)->colorable_p)
2141 sorted_copies[cp_num++] = cp;
2143 form_threads_from_copies (cp_num);
2146 /* Form initial threads which contain only one allocno. */
2147 static void
2148 init_allocno_threads (void)
2150 ira_allocno_t a;
2151 unsigned int j;
2152 bitmap_iterator bi;
2154 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
2156 a = ira_allocnos[j];
2157 /* Set up initial thread data: */
2158 ALLOCNO_COLOR_DATA (a)->first_thread_allocno
2159 = ALLOCNO_COLOR_DATA (a)->next_thread_allocno = a;
2160 ALLOCNO_COLOR_DATA (a)->thread_freq = ALLOCNO_FREQ (a);
2166 /* This page contains the allocator based on the Chaitin-Briggs algorithm. */
2168 /* Bucket of allocnos that can colored currently without spilling. */
2169 static ira_allocno_t colorable_allocno_bucket;
2171 /* Bucket of allocnos that might be not colored currently without
2172 spilling. */
2173 static ira_allocno_t uncolorable_allocno_bucket;
2175 /* The current number of allocnos in the uncolorable_bucket. */
2176 static int uncolorable_allocnos_num;
2178 /* Return the current spill priority of allocno A. The less the
2179 number, the more preferable the allocno for spilling. */
2180 static inline int
2181 allocno_spill_priority (ira_allocno_t a)
2183 allocno_color_data_t data = ALLOCNO_COLOR_DATA (a);
2185 return (data->temp
2186 / (ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a)
2187 * ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]
2188 + 1));
2191 /* Add allocno A to bucket *BUCKET_PTR. A should be not in a bucket
2192 before the call. */
2193 static void
2194 add_allocno_to_bucket (ira_allocno_t a, ira_allocno_t *bucket_ptr)
2196 ira_allocno_t first_a;
2197 allocno_color_data_t data;
2199 if (bucket_ptr == &uncolorable_allocno_bucket
2200 && ALLOCNO_CLASS (a) != NO_REGS)
2202 uncolorable_allocnos_num++;
2203 ira_assert (uncolorable_allocnos_num > 0);
2205 first_a = *bucket_ptr;
2206 data = ALLOCNO_COLOR_DATA (a);
2207 data->next_bucket_allocno = first_a;
2208 data->prev_bucket_allocno = NULL;
2209 if (first_a != NULL)
2210 ALLOCNO_COLOR_DATA (first_a)->prev_bucket_allocno = a;
2211 *bucket_ptr = a;
2214 /* Compare two allocnos to define which allocno should be pushed first
2215 into the coloring stack. If the return is a negative number, the
2216 allocno given by the first parameter will be pushed first. In this
2217 case such allocno has less priority than the second one and the
2218 hard register will be assigned to it after assignment to the second
2219 one. As the result of such assignment order, the second allocno
2220 has a better chance to get the best hard register. */
2221 static int
2222 bucket_allocno_compare_func (const void *v1p, const void *v2p)
2224 ira_allocno_t a1 = *(const ira_allocno_t *) v1p;
2225 ira_allocno_t a2 = *(const ira_allocno_t *) v2p;
2226 int diff, freq1, freq2, a1_num, a2_num;
2227 ira_allocno_t t1 = ALLOCNO_COLOR_DATA (a1)->first_thread_allocno;
2228 ira_allocno_t t2 = ALLOCNO_COLOR_DATA (a2)->first_thread_allocno;
2229 int cl1 = ALLOCNO_CLASS (a1), cl2 = ALLOCNO_CLASS (a2);
2231 freq1 = ALLOCNO_COLOR_DATA (t1)->thread_freq;
2232 freq2 = ALLOCNO_COLOR_DATA (t2)->thread_freq;
2233 if ((diff = freq1 - freq2) != 0)
2234 return diff;
2236 if ((diff = ALLOCNO_NUM (t2) - ALLOCNO_NUM (t1)) != 0)
2237 return diff;
2239 /* Push pseudos requiring less hard registers first. It means that
2240 we will assign pseudos requiring more hard registers first
2241 avoiding creation small holes in free hard register file into
2242 which the pseudos requiring more hard registers can not fit. */
2243 if ((diff = (ira_reg_class_max_nregs[cl1][ALLOCNO_MODE (a1)]
2244 - ira_reg_class_max_nregs[cl2][ALLOCNO_MODE (a2)])) != 0)
2245 return diff;
2247 freq1 = ALLOCNO_FREQ (a1);
2248 freq2 = ALLOCNO_FREQ (a2);
2249 if ((diff = freq1 - freq2) != 0)
2250 return diff;
2252 a1_num = ALLOCNO_COLOR_DATA (a1)->available_regs_num;
2253 a2_num = ALLOCNO_COLOR_DATA (a2)->available_regs_num;
2254 if ((diff = a2_num - a1_num) != 0)
2255 return diff;
2256 return ALLOCNO_NUM (a2) - ALLOCNO_NUM (a1);
2259 /* Sort bucket *BUCKET_PTR and return the result through
2260 BUCKET_PTR. */
2261 static void
2262 sort_bucket (ira_allocno_t *bucket_ptr,
2263 int (*compare_func) (const void *, const void *))
2265 ira_allocno_t a, head;
2266 int n;
2268 for (n = 0, a = *bucket_ptr;
2269 a != NULL;
2270 a = ALLOCNO_COLOR_DATA (a)->next_bucket_allocno)
2271 sorted_allocnos[n++] = a;
2272 if (n <= 1)
2273 return;
2274 qsort (sorted_allocnos, n, sizeof (ira_allocno_t), compare_func);
2275 head = NULL;
2276 for (n--; n >= 0; n--)
2278 a = sorted_allocnos[n];
2279 ALLOCNO_COLOR_DATA (a)->next_bucket_allocno = head;
2280 ALLOCNO_COLOR_DATA (a)->prev_bucket_allocno = NULL;
2281 if (head != NULL)
2282 ALLOCNO_COLOR_DATA (head)->prev_bucket_allocno = a;
2283 head = a;
2285 *bucket_ptr = head;
2288 /* Add ALLOCNO to colorable bucket maintaining the order according
2289 their priority. ALLOCNO should be not in a bucket before the
2290 call. */
2291 static void
2292 add_allocno_to_ordered_colorable_bucket (ira_allocno_t allocno)
2294 ira_allocno_t before, after;
2296 form_threads_from_colorable_allocno (allocno);
2297 for (before = colorable_allocno_bucket, after = NULL;
2298 before != NULL;
2299 after = before,
2300 before = ALLOCNO_COLOR_DATA (before)->next_bucket_allocno)
2301 if (bucket_allocno_compare_func (&allocno, &before) < 0)
2302 break;
2303 ALLOCNO_COLOR_DATA (allocno)->next_bucket_allocno = before;
2304 ALLOCNO_COLOR_DATA (allocno)->prev_bucket_allocno = after;
2305 if (after == NULL)
2306 colorable_allocno_bucket = allocno;
2307 else
2308 ALLOCNO_COLOR_DATA (after)->next_bucket_allocno = allocno;
2309 if (before != NULL)
2310 ALLOCNO_COLOR_DATA (before)->prev_bucket_allocno = allocno;
2313 /* Delete ALLOCNO from bucket *BUCKET_PTR. It should be there before
2314 the call. */
2315 static void
2316 delete_allocno_from_bucket (ira_allocno_t allocno, ira_allocno_t *bucket_ptr)
2318 ira_allocno_t prev_allocno, next_allocno;
2320 if (bucket_ptr == &uncolorable_allocno_bucket
2321 && ALLOCNO_CLASS (allocno) != NO_REGS)
2323 uncolorable_allocnos_num--;
2324 ira_assert (uncolorable_allocnos_num >= 0);
2326 prev_allocno = ALLOCNO_COLOR_DATA (allocno)->prev_bucket_allocno;
2327 next_allocno = ALLOCNO_COLOR_DATA (allocno)->next_bucket_allocno;
2328 if (prev_allocno != NULL)
2329 ALLOCNO_COLOR_DATA (prev_allocno)->next_bucket_allocno = next_allocno;
2330 else
2332 ira_assert (*bucket_ptr == allocno);
2333 *bucket_ptr = next_allocno;
2335 if (next_allocno != NULL)
2336 ALLOCNO_COLOR_DATA (next_allocno)->prev_bucket_allocno = prev_allocno;
2339 /* Put allocno A onto the coloring stack without removing it from its
2340 bucket. Pushing allocno to the coloring stack can result in moving
2341 conflicting allocnos from the uncolorable bucket to the colorable
2342 one. */
2343 static void
2344 push_allocno_to_stack (ira_allocno_t a)
2346 enum reg_class aclass;
2347 allocno_color_data_t data, conflict_data;
2348 int size, i, n = ALLOCNO_NUM_OBJECTS (a);
2350 data = ALLOCNO_COLOR_DATA (a);
2351 data->in_graph_p = false;
2352 allocno_stack_vec.safe_push (a);
2353 aclass = ALLOCNO_CLASS (a);
2354 if (aclass == NO_REGS)
2355 return;
2356 size = ira_reg_class_max_nregs[aclass][ALLOCNO_MODE (a)];
2357 if (n > 1)
2359 /* We will deal with the subwords individually. */
2360 gcc_assert (size == ALLOCNO_NUM_OBJECTS (a));
2361 size = 1;
2363 for (i = 0; i < n; i++)
2365 ira_object_t obj = ALLOCNO_OBJECT (a, i);
2366 ira_object_t conflict_obj;
2367 ira_object_conflict_iterator oci;
2369 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
2371 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
2373 conflict_data = ALLOCNO_COLOR_DATA (conflict_a);
2374 if (conflict_data->colorable_p
2375 || ! conflict_data->in_graph_p
2376 || ALLOCNO_ASSIGNED_P (conflict_a)
2377 || !(hard_reg_set_intersect_p
2378 (ALLOCNO_COLOR_DATA (a)->profitable_hard_regs,
2379 conflict_data->profitable_hard_regs)))
2380 continue;
2381 ira_assert (bitmap_bit_p (coloring_allocno_bitmap,
2382 ALLOCNO_NUM (conflict_a)));
2383 if (update_left_conflict_sizes_p (conflict_a, a, size))
2385 delete_allocno_from_bucket
2386 (conflict_a, &uncolorable_allocno_bucket);
2387 add_allocno_to_ordered_colorable_bucket (conflict_a);
2388 if (internal_flag_ira_verbose > 4 && ira_dump_file != NULL)
2390 fprintf (ira_dump_file, " Making");
2391 ira_print_expanded_allocno (conflict_a);
2392 fprintf (ira_dump_file, " colorable\n");
2400 /* Put ALLOCNO onto the coloring stack and remove it from its bucket.
2401 The allocno is in the colorable bucket if COLORABLE_P is TRUE. */
2402 static void
2403 remove_allocno_from_bucket_and_push (ira_allocno_t allocno, bool colorable_p)
2405 if (colorable_p)
2406 delete_allocno_from_bucket (allocno, &colorable_allocno_bucket);
2407 else
2408 delete_allocno_from_bucket (allocno, &uncolorable_allocno_bucket);
2409 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2411 fprintf (ira_dump_file, " Pushing");
2412 ira_print_expanded_allocno (allocno);
2413 if (colorable_p)
2414 fprintf (ira_dump_file, "(cost %d)\n",
2415 ALLOCNO_COLOR_DATA (allocno)->temp);
2416 else
2417 fprintf (ira_dump_file, "(potential spill: %spri=%d, cost=%d)\n",
2418 ALLOCNO_BAD_SPILL_P (allocno) ? "bad spill, " : "",
2419 allocno_spill_priority (allocno),
2420 ALLOCNO_COLOR_DATA (allocno)->temp);
2422 if (! colorable_p)
2423 ALLOCNO_COLOR_DATA (allocno)->may_be_spilled_p = true;
2424 push_allocno_to_stack (allocno);
2427 /* Put all allocnos from colorable bucket onto the coloring stack. */
2428 static void
2429 push_only_colorable (void)
2431 form_threads_from_bucket (colorable_allocno_bucket);
2432 sort_bucket (&colorable_allocno_bucket, bucket_allocno_compare_func);
2433 for (;colorable_allocno_bucket != NULL;)
2434 remove_allocno_from_bucket_and_push (colorable_allocno_bucket, true);
2437 /* Return the frequency of exit edges (if EXIT_P) or entry from/to the
2438 loop given by its LOOP_NODE. */
2440 ira_loop_edge_freq (ira_loop_tree_node_t loop_node, int regno, bool exit_p)
2442 int freq, i;
2443 edge_iterator ei;
2444 edge e;
2445 vec<edge> edges;
2447 ira_assert (current_loops != NULL && loop_node->loop != NULL
2448 && (regno < 0 || regno >= FIRST_PSEUDO_REGISTER));
2449 freq = 0;
2450 if (! exit_p)
2452 FOR_EACH_EDGE (e, ei, loop_node->loop->header->preds)
2453 if (e->src != loop_node->loop->latch
2454 && (regno < 0
2455 || (bitmap_bit_p (df_get_live_out (e->src), regno)
2456 && bitmap_bit_p (df_get_live_in (e->dest), regno))))
2457 freq += EDGE_FREQUENCY (e);
2459 else
2461 edges = get_loop_exit_edges (loop_node->loop);
2462 FOR_EACH_VEC_ELT (edges, i, e)
2463 if (regno < 0
2464 || (bitmap_bit_p (df_get_live_out (e->src), regno)
2465 && bitmap_bit_p (df_get_live_in (e->dest), regno)))
2466 freq += EDGE_FREQUENCY (e);
2467 edges.release ();
2470 return REG_FREQ_FROM_EDGE_FREQ (freq);
2473 /* Calculate and return the cost of putting allocno A into memory. */
2474 static int
2475 calculate_allocno_spill_cost (ira_allocno_t a)
2477 int regno, cost;
2478 machine_mode mode;
2479 enum reg_class rclass;
2480 ira_allocno_t parent_allocno;
2481 ira_loop_tree_node_t parent_node, loop_node;
2483 regno = ALLOCNO_REGNO (a);
2484 cost = ALLOCNO_UPDATED_MEMORY_COST (a) - ALLOCNO_UPDATED_CLASS_COST (a);
2485 if (ALLOCNO_CAP (a) != NULL)
2486 return cost;
2487 loop_node = ALLOCNO_LOOP_TREE_NODE (a);
2488 if ((parent_node = loop_node->parent) == NULL)
2489 return cost;
2490 if ((parent_allocno = parent_node->regno_allocno_map[regno]) == NULL)
2491 return cost;
2492 mode = ALLOCNO_MODE (a);
2493 rclass = ALLOCNO_CLASS (a);
2494 if (ALLOCNO_HARD_REGNO (parent_allocno) < 0)
2495 cost -= (ira_memory_move_cost[mode][rclass][0]
2496 * ira_loop_edge_freq (loop_node, regno, true)
2497 + ira_memory_move_cost[mode][rclass][1]
2498 * ira_loop_edge_freq (loop_node, regno, false));
2499 else
2501 ira_init_register_move_cost_if_necessary (mode);
2502 cost += ((ira_memory_move_cost[mode][rclass][1]
2503 * ira_loop_edge_freq (loop_node, regno, true)
2504 + ira_memory_move_cost[mode][rclass][0]
2505 * ira_loop_edge_freq (loop_node, regno, false))
2506 - (ira_register_move_cost[mode][rclass][rclass]
2507 * (ira_loop_edge_freq (loop_node, regno, false)
2508 + ira_loop_edge_freq (loop_node, regno, true))));
2510 return cost;
2513 /* Used for sorting allocnos for spilling. */
2514 static inline int
2515 allocno_spill_priority_compare (ira_allocno_t a1, ira_allocno_t a2)
2517 int pri1, pri2, diff;
2519 /* Avoid spilling static chain pointer pseudo when non-local goto is
2520 used. */
2521 if (non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a1)))
2522 return 1;
2523 else if (non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a2)))
2524 return -1;
2525 if (ALLOCNO_BAD_SPILL_P (a1) && ! ALLOCNO_BAD_SPILL_P (a2))
2526 return 1;
2527 if (ALLOCNO_BAD_SPILL_P (a2) && ! ALLOCNO_BAD_SPILL_P (a1))
2528 return -1;
2529 pri1 = allocno_spill_priority (a1);
2530 pri2 = allocno_spill_priority (a2);
2531 if ((diff = pri1 - pri2) != 0)
2532 return diff;
2533 if ((diff
2534 = ALLOCNO_COLOR_DATA (a1)->temp - ALLOCNO_COLOR_DATA (a2)->temp) != 0)
2535 return diff;
2536 return ALLOCNO_NUM (a1) - ALLOCNO_NUM (a2);
2539 /* Used for sorting allocnos for spilling. */
2540 static int
2541 allocno_spill_sort_compare (const void *v1p, const void *v2p)
2543 ira_allocno_t p1 = *(const ira_allocno_t *) v1p;
2544 ira_allocno_t p2 = *(const ira_allocno_t *) v2p;
2546 return allocno_spill_priority_compare (p1, p2);
2549 /* Push allocnos to the coloring stack. The order of allocnos in the
2550 stack defines the order for the subsequent coloring. */
2551 static void
2552 push_allocnos_to_stack (void)
2554 ira_allocno_t a;
2555 int cost;
2557 /* Calculate uncolorable allocno spill costs. */
2558 for (a = uncolorable_allocno_bucket;
2559 a != NULL;
2560 a = ALLOCNO_COLOR_DATA (a)->next_bucket_allocno)
2561 if (ALLOCNO_CLASS (a) != NO_REGS)
2563 cost = calculate_allocno_spill_cost (a);
2564 /* ??? Remove cost of copies between the coalesced
2565 allocnos. */
2566 ALLOCNO_COLOR_DATA (a)->temp = cost;
2568 sort_bucket (&uncolorable_allocno_bucket, allocno_spill_sort_compare);
2569 for (;;)
2571 push_only_colorable ();
2572 a = uncolorable_allocno_bucket;
2573 if (a == NULL)
2574 break;
2575 remove_allocno_from_bucket_and_push (a, false);
2577 ira_assert (colorable_allocno_bucket == NULL
2578 && uncolorable_allocno_bucket == NULL);
2579 ira_assert (uncolorable_allocnos_num == 0);
2582 /* Pop the coloring stack and assign hard registers to the popped
2583 allocnos. */
2584 static void
2585 pop_allocnos_from_stack (void)
2587 ira_allocno_t allocno;
2588 enum reg_class aclass;
2590 for (;allocno_stack_vec.length () != 0;)
2592 allocno = allocno_stack_vec.pop ();
2593 aclass = ALLOCNO_CLASS (allocno);
2594 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2596 fprintf (ira_dump_file, " Popping");
2597 ira_print_expanded_allocno (allocno);
2598 fprintf (ira_dump_file, " -- ");
2600 if (aclass == NO_REGS)
2602 ALLOCNO_HARD_REGNO (allocno) = -1;
2603 ALLOCNO_ASSIGNED_P (allocno) = true;
2604 ira_assert (ALLOCNO_UPDATED_HARD_REG_COSTS (allocno) == NULL);
2605 ira_assert
2606 (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (allocno) == NULL);
2607 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2608 fprintf (ira_dump_file, "assign memory\n");
2610 else if (assign_hard_reg (allocno, false))
2612 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2613 fprintf (ira_dump_file, "assign reg %d\n",
2614 ALLOCNO_HARD_REGNO (allocno));
2616 else if (ALLOCNO_ASSIGNED_P (allocno))
2618 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2619 fprintf (ira_dump_file, "spill%s\n",
2620 ALLOCNO_COLOR_DATA (allocno)->may_be_spilled_p
2621 ? "" : "!");
2623 ALLOCNO_COLOR_DATA (allocno)->in_graph_p = true;
2627 /* Set up number of available hard registers for allocno A. */
2628 static void
2629 setup_allocno_available_regs_num (ira_allocno_t a)
2631 int i, n, hard_regno, hard_regs_num, nwords;
2632 enum reg_class aclass;
2633 allocno_color_data_t data;
2635 aclass = ALLOCNO_CLASS (a);
2636 data = ALLOCNO_COLOR_DATA (a);
2637 data->available_regs_num = 0;
2638 if (aclass == NO_REGS)
2639 return;
2640 hard_regs_num = ira_class_hard_regs_num[aclass];
2641 nwords = ALLOCNO_NUM_OBJECTS (a);
2642 for (n = 0, i = hard_regs_num - 1; i >= 0; i--)
2644 hard_regno = ira_class_hard_regs[aclass][i];
2645 /* Checking only profitable hard regs. */
2646 if (TEST_HARD_REG_BIT (data->profitable_hard_regs, hard_regno))
2647 n++;
2649 data->available_regs_num = n;
2650 if (internal_flag_ira_verbose <= 2 || ira_dump_file == NULL)
2651 return;
2652 fprintf
2653 (ira_dump_file,
2654 " Allocno a%dr%d of %s(%d) has %d avail. regs ",
2655 ALLOCNO_NUM (a), ALLOCNO_REGNO (a),
2656 reg_class_names[aclass], ira_class_hard_regs_num[aclass], n);
2657 print_hard_reg_set (ira_dump_file, data->profitable_hard_regs, false);
2658 fprintf (ira_dump_file, ", %snode: ",
2659 hard_reg_set_equal_p (data->profitable_hard_regs,
2660 data->hard_regs_node->hard_regs->set)
2661 ? "" : "^");
2662 print_hard_reg_set (ira_dump_file,
2663 data->hard_regs_node->hard_regs->set, false);
2664 for (i = 0; i < nwords; i++)
2666 ira_object_t obj = ALLOCNO_OBJECT (a, i);
2668 if (nwords != 1)
2670 if (i != 0)
2671 fprintf (ira_dump_file, ", ");
2672 fprintf (ira_dump_file, " obj %d", i);
2674 fprintf (ira_dump_file, " (confl regs = ");
2675 print_hard_reg_set (ira_dump_file, OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
2676 false);
2677 fprintf (ira_dump_file, ")");
2679 fprintf (ira_dump_file, "\n");
2682 /* Put ALLOCNO in a bucket corresponding to its number and size of its
2683 conflicting allocnos and hard registers. */
2684 static void
2685 put_allocno_into_bucket (ira_allocno_t allocno)
2687 ALLOCNO_COLOR_DATA (allocno)->in_graph_p = true;
2688 setup_allocno_available_regs_num (allocno);
2689 if (setup_left_conflict_sizes_p (allocno))
2690 add_allocno_to_bucket (allocno, &colorable_allocno_bucket);
2691 else
2692 add_allocno_to_bucket (allocno, &uncolorable_allocno_bucket);
2695 /* Map: allocno number -> allocno priority. */
2696 static int *allocno_priorities;
2698 /* Set up priorities for N allocnos in array
2699 CONSIDERATION_ALLOCNOS. */
2700 static void
2701 setup_allocno_priorities (ira_allocno_t *consideration_allocnos, int n)
2703 int i, length, nrefs, priority, max_priority, mult;
2704 ira_allocno_t a;
2706 max_priority = 0;
2707 for (i = 0; i < n; i++)
2709 a = consideration_allocnos[i];
2710 nrefs = ALLOCNO_NREFS (a);
2711 ira_assert (nrefs >= 0);
2712 mult = floor_log2 (ALLOCNO_NREFS (a)) + 1;
2713 ira_assert (mult >= 0);
2714 allocno_priorities[ALLOCNO_NUM (a)]
2715 = priority
2716 = (mult
2717 * (ALLOCNO_MEMORY_COST (a) - ALLOCNO_CLASS_COST (a))
2718 * ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]);
2719 if (priority < 0)
2720 priority = -priority;
2721 if (max_priority < priority)
2722 max_priority = priority;
2724 mult = max_priority == 0 ? 1 : INT_MAX / max_priority;
2725 for (i = 0; i < n; i++)
2727 a = consideration_allocnos[i];
2728 length = ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a);
2729 if (ALLOCNO_NUM_OBJECTS (a) > 1)
2730 length /= ALLOCNO_NUM_OBJECTS (a);
2731 if (length <= 0)
2732 length = 1;
2733 allocno_priorities[ALLOCNO_NUM (a)]
2734 = allocno_priorities[ALLOCNO_NUM (a)] * mult / length;
2738 /* Sort allocnos according to the profit of usage of a hard register
2739 instead of memory for them. */
2740 static int
2741 allocno_cost_compare_func (const void *v1p, const void *v2p)
2743 ira_allocno_t p1 = *(const ira_allocno_t *) v1p;
2744 ira_allocno_t p2 = *(const ira_allocno_t *) v2p;
2745 int c1, c2;
2747 c1 = ALLOCNO_UPDATED_MEMORY_COST (p1) - ALLOCNO_UPDATED_CLASS_COST (p1);
2748 c2 = ALLOCNO_UPDATED_MEMORY_COST (p2) - ALLOCNO_UPDATED_CLASS_COST (p2);
2749 if (c1 - c2)
2750 return c1 - c2;
2752 /* If regs are equally good, sort by allocno numbers, so that the
2753 results of qsort leave nothing to chance. */
2754 return ALLOCNO_NUM (p1) - ALLOCNO_NUM (p2);
2757 /* Return savings on removed copies when ALLOCNO is assigned to
2758 HARD_REGNO. */
2759 static int
2760 allocno_copy_cost_saving (ira_allocno_t allocno, int hard_regno)
2762 int cost = 0;
2763 machine_mode allocno_mode = ALLOCNO_MODE (allocno);
2764 enum reg_class rclass;
2765 ira_copy_t cp, next_cp;
2767 rclass = REGNO_REG_CLASS (hard_regno);
2768 if (ira_reg_class_max_nregs[rclass][allocno_mode]
2769 > ira_class_hard_regs_num[rclass])
2770 /* For the above condition the cost can be wrong. Use the allocno
2771 class in this case. */
2772 rclass = ALLOCNO_CLASS (allocno);
2773 for (cp = ALLOCNO_COPIES (allocno); cp != NULL; cp = next_cp)
2775 if (cp->first == allocno)
2777 next_cp = cp->next_first_allocno_copy;
2778 if (ALLOCNO_HARD_REGNO (cp->second) != hard_regno)
2779 continue;
2781 else if (cp->second == allocno)
2783 next_cp = cp->next_second_allocno_copy;
2784 if (ALLOCNO_HARD_REGNO (cp->first) != hard_regno)
2785 continue;
2787 else
2788 gcc_unreachable ();
2789 cost += cp->freq * ira_register_move_cost[allocno_mode][rclass][rclass];
2791 return cost;
2794 /* We used Chaitin-Briggs coloring to assign as many pseudos as
2795 possible to hard registers. Let us try to improve allocation with
2796 cost point of view. This function improves the allocation by
2797 spilling some allocnos and assigning the freed hard registers to
2798 other allocnos if it decreases the overall allocation cost. */
2799 static void
2800 improve_allocation (void)
2802 unsigned int i;
2803 int j, k, n, hregno, conflict_hregno, base_cost, class_size, word, nwords;
2804 int check, spill_cost, min_cost, nregs, conflict_nregs, r, best;
2805 bool try_p;
2806 enum reg_class aclass;
2807 machine_mode mode;
2808 int *allocno_costs;
2809 int costs[FIRST_PSEUDO_REGISTER];
2810 HARD_REG_SET conflicting_regs[2], profitable_hard_regs;
2811 ira_allocno_t a;
2812 bitmap_iterator bi;
2814 /* Don't bother to optimize the code with static chain pointer and
2815 non-local goto in order not to spill the chain pointer
2816 pseudo. */
2817 if (cfun->static_chain_decl && crtl->has_nonlocal_goto)
2818 return;
2819 /* Clear counts used to process conflicting allocnos only once for
2820 each allocno. */
2821 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
2822 ALLOCNO_COLOR_DATA (ira_allocnos[i])->temp = 0;
2823 check = n = 0;
2824 /* Process each allocno and try to assign a hard register to it by
2825 spilling some its conflicting allocnos. */
2826 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
2828 a = ira_allocnos[i];
2829 ALLOCNO_COLOR_DATA (a)->temp = 0;
2830 if (empty_profitable_hard_regs (a))
2831 continue;
2832 check++;
2833 aclass = ALLOCNO_CLASS (a);
2834 allocno_costs = ALLOCNO_HARD_REG_COSTS (a);
2835 if ((hregno = ALLOCNO_HARD_REGNO (a)) < 0)
2836 base_cost = ALLOCNO_UPDATED_MEMORY_COST (a);
2837 else if (allocno_costs == NULL)
2838 /* It means that assigning a hard register is not profitable
2839 (we don't waste memory for hard register costs in this
2840 case). */
2841 continue;
2842 else
2843 base_cost = (allocno_costs[ira_class_hard_reg_index[aclass][hregno]]
2844 - allocno_copy_cost_saving (a, hregno));
2845 try_p = false;
2846 get_conflict_and_start_profitable_regs (a, false,
2847 conflicting_regs,
2848 &profitable_hard_regs);
2849 class_size = ira_class_hard_regs_num[aclass];
2850 /* Set up cost improvement for usage of each profitable hard
2851 register for allocno A. */
2852 for (j = 0; j < class_size; j++)
2854 hregno = ira_class_hard_regs[aclass][j];
2855 if (! check_hard_reg_p (a, hregno,
2856 conflicting_regs, profitable_hard_regs))
2857 continue;
2858 ira_assert (ira_class_hard_reg_index[aclass][hregno] == j);
2859 k = allocno_costs == NULL ? 0 : j;
2860 costs[hregno] = (allocno_costs == NULL
2861 ? ALLOCNO_UPDATED_CLASS_COST (a) : allocno_costs[k]);
2862 costs[hregno] -= allocno_copy_cost_saving (a, hregno);
2863 costs[hregno] -= base_cost;
2864 if (costs[hregno] < 0)
2865 try_p = true;
2867 if (! try_p)
2868 /* There is no chance to improve the allocation cost by
2869 assigning hard register to allocno A even without spilling
2870 conflicting allocnos. */
2871 continue;
2872 mode = ALLOCNO_MODE (a);
2873 nwords = ALLOCNO_NUM_OBJECTS (a);
2874 /* Process each allocno conflicting with A and update the cost
2875 improvement for profitable hard registers of A. To use a
2876 hard register for A we need to spill some conflicting
2877 allocnos and that creates penalty for the cost
2878 improvement. */
2879 for (word = 0; word < nwords; word++)
2881 ira_object_t conflict_obj;
2882 ira_object_t obj = ALLOCNO_OBJECT (a, word);
2883 ira_object_conflict_iterator oci;
2885 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
2887 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
2889 if (ALLOCNO_COLOR_DATA (conflict_a)->temp == check)
2890 /* We already processed this conflicting allocno
2891 because we processed earlier another object of the
2892 conflicting allocno. */
2893 continue;
2894 ALLOCNO_COLOR_DATA (conflict_a)->temp = check;
2895 if ((conflict_hregno = ALLOCNO_HARD_REGNO (conflict_a)) < 0)
2896 continue;
2897 spill_cost = ALLOCNO_UPDATED_MEMORY_COST (conflict_a);
2898 k = (ira_class_hard_reg_index
2899 [ALLOCNO_CLASS (conflict_a)][conflict_hregno]);
2900 ira_assert (k >= 0);
2901 if ((allocno_costs = ALLOCNO_HARD_REG_COSTS (conflict_a))
2902 != NULL)
2903 spill_cost -= allocno_costs[k];
2904 else
2905 spill_cost -= ALLOCNO_UPDATED_CLASS_COST (conflict_a);
2906 spill_cost
2907 += allocno_copy_cost_saving (conflict_a, conflict_hregno);
2908 conflict_nregs = hard_regno_nregs (conflict_hregno,
2909 ALLOCNO_MODE (conflict_a));
2910 for (r = conflict_hregno;
2911 r >= 0 && (int) end_hard_regno (mode, r) > conflict_hregno;
2912 r--)
2913 if (check_hard_reg_p (a, r,
2914 conflicting_regs, profitable_hard_regs))
2915 costs[r] += spill_cost;
2916 for (r = conflict_hregno + 1;
2917 r < conflict_hregno + conflict_nregs;
2918 r++)
2919 if (check_hard_reg_p (a, r,
2920 conflicting_regs, profitable_hard_regs))
2921 costs[r] += spill_cost;
2924 min_cost = INT_MAX;
2925 best = -1;
2926 /* Now we choose hard register for A which results in highest
2927 allocation cost improvement. */
2928 for (j = 0; j < class_size; j++)
2930 hregno = ira_class_hard_regs[aclass][j];
2931 if (check_hard_reg_p (a, hregno,
2932 conflicting_regs, profitable_hard_regs)
2933 && min_cost > costs[hregno])
2935 best = hregno;
2936 min_cost = costs[hregno];
2939 if (min_cost >= 0)
2940 /* We are in a situation when assigning any hard register to A
2941 by spilling some conflicting allocnos does not improve the
2942 allocation cost. */
2943 continue;
2944 nregs = hard_regno_nregs (best, mode);
2945 /* Now spill conflicting allocnos which contain a hard register
2946 of A when we assign the best chosen hard register to it. */
2947 for (word = 0; word < nwords; word++)
2949 ira_object_t conflict_obj;
2950 ira_object_t obj = ALLOCNO_OBJECT (a, word);
2951 ira_object_conflict_iterator oci;
2953 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
2955 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
2957 if ((conflict_hregno = ALLOCNO_HARD_REGNO (conflict_a)) < 0)
2958 continue;
2959 conflict_nregs = hard_regno_nregs (conflict_hregno,
2960 ALLOCNO_MODE (conflict_a));
2961 if (best + nregs <= conflict_hregno
2962 || conflict_hregno + conflict_nregs <= best)
2963 /* No intersection. */
2964 continue;
2965 ALLOCNO_HARD_REGNO (conflict_a) = -1;
2966 sorted_allocnos[n++] = conflict_a;
2967 if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
2968 fprintf (ira_dump_file, "Spilling a%dr%d for a%dr%d\n",
2969 ALLOCNO_NUM (conflict_a), ALLOCNO_REGNO (conflict_a),
2970 ALLOCNO_NUM (a), ALLOCNO_REGNO (a));
2973 /* Assign the best chosen hard register to A. */
2974 ALLOCNO_HARD_REGNO (a) = best;
2975 if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
2976 fprintf (ira_dump_file, "Assigning %d to a%dr%d\n",
2977 best, ALLOCNO_NUM (a), ALLOCNO_REGNO (a));
2979 if (n == 0)
2980 return;
2981 /* We spilled some allocnos to assign their hard registers to other
2982 allocnos. The spilled allocnos are now in array
2983 'sorted_allocnos'. There is still a possibility that some of the
2984 spilled allocnos can get hard registers. So let us try assign
2985 them hard registers again (just a reminder -- function
2986 'assign_hard_reg' assigns hard registers only if it is possible
2987 and profitable). We process the spilled allocnos with biggest
2988 benefit to get hard register first -- see function
2989 'allocno_cost_compare_func'. */
2990 qsort (sorted_allocnos, n, sizeof (ira_allocno_t),
2991 allocno_cost_compare_func);
2992 for (j = 0; j < n; j++)
2994 a = sorted_allocnos[j];
2995 ALLOCNO_ASSIGNED_P (a) = false;
2996 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2998 fprintf (ira_dump_file, " ");
2999 ira_print_expanded_allocno (a);
3000 fprintf (ira_dump_file, " -- ");
3002 if (assign_hard_reg (a, false))
3004 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3005 fprintf (ira_dump_file, "assign hard reg %d\n",
3006 ALLOCNO_HARD_REGNO (a));
3008 else
3010 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3011 fprintf (ira_dump_file, "assign memory\n");
3016 /* Sort allocnos according to their priorities. */
3017 static int
3018 allocno_priority_compare_func (const void *v1p, const void *v2p)
3020 ira_allocno_t a1 = *(const ira_allocno_t *) v1p;
3021 ira_allocno_t a2 = *(const ira_allocno_t *) v2p;
3022 int pri1, pri2, diff;
3024 /* Assign hard reg to static chain pointer pseudo first when
3025 non-local goto is used. */
3026 if ((diff = (non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a2))
3027 - non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a1)))) != 0)
3028 return diff;
3029 pri1 = allocno_priorities[ALLOCNO_NUM (a1)];
3030 pri2 = allocno_priorities[ALLOCNO_NUM (a2)];
3031 if (pri2 != pri1)
3032 return SORTGT (pri2, pri1);
3034 /* If regs are equally good, sort by allocnos, so that the results of
3035 qsort leave nothing to chance. */
3036 return ALLOCNO_NUM (a1) - ALLOCNO_NUM (a2);
3039 /* Chaitin-Briggs coloring for allocnos in COLORING_ALLOCNO_BITMAP
3040 taking into account allocnos in CONSIDERATION_ALLOCNO_BITMAP. */
3041 static void
3042 color_allocnos (void)
3044 unsigned int i, n;
3045 bitmap_iterator bi;
3046 ira_allocno_t a;
3048 setup_profitable_hard_regs ();
3049 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
3051 int l, nr;
3052 HARD_REG_SET conflict_hard_regs;
3053 allocno_color_data_t data;
3054 ira_pref_t pref, next_pref;
3056 a = ira_allocnos[i];
3057 nr = ALLOCNO_NUM_OBJECTS (a);
3058 CLEAR_HARD_REG_SET (conflict_hard_regs);
3059 for (l = 0; l < nr; l++)
3061 ira_object_t obj = ALLOCNO_OBJECT (a, l);
3062 IOR_HARD_REG_SET (conflict_hard_regs,
3063 OBJECT_CONFLICT_HARD_REGS (obj));
3065 data = ALLOCNO_COLOR_DATA (a);
3066 for (pref = ALLOCNO_PREFS (a); pref != NULL; pref = next_pref)
3068 next_pref = pref->next_pref;
3069 if (! ira_hard_reg_in_set_p (pref->hard_regno,
3070 ALLOCNO_MODE (a),
3071 data->profitable_hard_regs))
3072 ira_remove_pref (pref);
3075 if (flag_ira_algorithm == IRA_ALGORITHM_PRIORITY)
3077 n = 0;
3078 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
3080 a = ira_allocnos[i];
3081 if (ALLOCNO_CLASS (a) == NO_REGS)
3083 ALLOCNO_HARD_REGNO (a) = -1;
3084 ALLOCNO_ASSIGNED_P (a) = true;
3085 ira_assert (ALLOCNO_UPDATED_HARD_REG_COSTS (a) == NULL);
3086 ira_assert (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a) == NULL);
3087 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3089 fprintf (ira_dump_file, " Spill");
3090 ira_print_expanded_allocno (a);
3091 fprintf (ira_dump_file, "\n");
3093 continue;
3095 sorted_allocnos[n++] = a;
3097 if (n != 0)
3099 setup_allocno_priorities (sorted_allocnos, n);
3100 qsort (sorted_allocnos, n, sizeof (ira_allocno_t),
3101 allocno_priority_compare_func);
3102 for (i = 0; i < n; i++)
3104 a = sorted_allocnos[i];
3105 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3107 fprintf (ira_dump_file, " ");
3108 ira_print_expanded_allocno (a);
3109 fprintf (ira_dump_file, " -- ");
3111 if (assign_hard_reg (a, false))
3113 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3114 fprintf (ira_dump_file, "assign hard reg %d\n",
3115 ALLOCNO_HARD_REGNO (a));
3117 else
3119 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3120 fprintf (ira_dump_file, "assign memory\n");
3125 else
3127 form_allocno_hard_regs_nodes_forest ();
3128 if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
3129 print_hard_regs_forest (ira_dump_file);
3130 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
3132 a = ira_allocnos[i];
3133 if (ALLOCNO_CLASS (a) != NO_REGS && ! empty_profitable_hard_regs (a))
3135 ALLOCNO_COLOR_DATA (a)->in_graph_p = true;
3136 update_costs_from_prefs (a);
3138 else
3140 ALLOCNO_HARD_REGNO (a) = -1;
3141 ALLOCNO_ASSIGNED_P (a) = true;
3142 /* We don't need updated costs anymore. */
3143 ira_free_allocno_updated_costs (a);
3144 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3146 fprintf (ira_dump_file, " Spill");
3147 ira_print_expanded_allocno (a);
3148 fprintf (ira_dump_file, "\n");
3152 /* Put the allocnos into the corresponding buckets. */
3153 colorable_allocno_bucket = NULL;
3154 uncolorable_allocno_bucket = NULL;
3155 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
3157 a = ira_allocnos[i];
3158 if (ALLOCNO_COLOR_DATA (a)->in_graph_p)
3159 put_allocno_into_bucket (a);
3161 push_allocnos_to_stack ();
3162 pop_allocnos_from_stack ();
3163 finish_allocno_hard_regs_nodes_forest ();
3165 improve_allocation ();
3170 /* Output information about the loop given by its LOOP_TREE_NODE. */
3171 static void
3172 print_loop_title (ira_loop_tree_node_t loop_tree_node)
3174 unsigned int j;
3175 bitmap_iterator bi;
3176 ira_loop_tree_node_t subloop_node, dest_loop_node;
3177 edge e;
3178 edge_iterator ei;
3180 if (loop_tree_node->parent == NULL)
3181 fprintf (ira_dump_file,
3182 "\n Loop 0 (parent -1, header bb%d, depth 0)\n bbs:",
3183 NUM_FIXED_BLOCKS);
3184 else
3186 ira_assert (current_loops != NULL && loop_tree_node->loop != NULL);
3187 fprintf (ira_dump_file,
3188 "\n Loop %d (parent %d, header bb%d, depth %d)\n bbs:",
3189 loop_tree_node->loop_num, loop_tree_node->parent->loop_num,
3190 loop_tree_node->loop->header->index,
3191 loop_depth (loop_tree_node->loop));
3193 for (subloop_node = loop_tree_node->children;
3194 subloop_node != NULL;
3195 subloop_node = subloop_node->next)
3196 if (subloop_node->bb != NULL)
3198 fprintf (ira_dump_file, " %d", subloop_node->bb->index);
3199 FOR_EACH_EDGE (e, ei, subloop_node->bb->succs)
3200 if (e->dest != EXIT_BLOCK_PTR_FOR_FN (cfun)
3201 && ((dest_loop_node = IRA_BB_NODE (e->dest)->parent)
3202 != loop_tree_node))
3203 fprintf (ira_dump_file, "(->%d:l%d)",
3204 e->dest->index, dest_loop_node->loop_num);
3206 fprintf (ira_dump_file, "\n all:");
3207 EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->all_allocnos, 0, j, bi)
3208 fprintf (ira_dump_file, " %dr%d", j, ALLOCNO_REGNO (ira_allocnos[j]));
3209 fprintf (ira_dump_file, "\n modified regnos:");
3210 EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->modified_regnos, 0, j, bi)
3211 fprintf (ira_dump_file, " %d", j);
3212 fprintf (ira_dump_file, "\n border:");
3213 EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->border_allocnos, 0, j, bi)
3214 fprintf (ira_dump_file, " %dr%d", j, ALLOCNO_REGNO (ira_allocnos[j]));
3215 fprintf (ira_dump_file, "\n Pressure:");
3216 for (j = 0; (int) j < ira_pressure_classes_num; j++)
3218 enum reg_class pclass;
3220 pclass = ira_pressure_classes[j];
3221 if (loop_tree_node->reg_pressure[pclass] == 0)
3222 continue;
3223 fprintf (ira_dump_file, " %s=%d", reg_class_names[pclass],
3224 loop_tree_node->reg_pressure[pclass]);
3226 fprintf (ira_dump_file, "\n");
3229 /* Color the allocnos inside loop (in the extreme case it can be all
3230 of the function) given the corresponding LOOP_TREE_NODE. The
3231 function is called for each loop during top-down traverse of the
3232 loop tree. */
3233 static void
3234 color_pass (ira_loop_tree_node_t loop_tree_node)
3236 int regno, hard_regno, index = -1, n;
3237 int cost, exit_freq, enter_freq;
3238 unsigned int j;
3239 bitmap_iterator bi;
3240 machine_mode mode;
3241 enum reg_class rclass, aclass, pclass;
3242 ira_allocno_t a, subloop_allocno;
3243 ira_loop_tree_node_t subloop_node;
3245 ira_assert (loop_tree_node->bb == NULL);
3246 if (internal_flag_ira_verbose > 1 && ira_dump_file != NULL)
3247 print_loop_title (loop_tree_node);
3249 bitmap_copy (coloring_allocno_bitmap, loop_tree_node->all_allocnos);
3250 bitmap_copy (consideration_allocno_bitmap, coloring_allocno_bitmap);
3251 n = 0;
3252 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
3254 a = ira_allocnos[j];
3255 n++;
3256 if (! ALLOCNO_ASSIGNED_P (a))
3257 continue;
3258 bitmap_clear_bit (coloring_allocno_bitmap, ALLOCNO_NUM (a));
3260 allocno_color_data
3261 = (allocno_color_data_t) ira_allocate (sizeof (struct allocno_color_data)
3262 * n);
3263 memset (allocno_color_data, 0, sizeof (struct allocno_color_data) * n);
3264 curr_allocno_process = 0;
3265 n = 0;
3266 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
3268 a = ira_allocnos[j];
3269 ALLOCNO_ADD_DATA (a) = allocno_color_data + n;
3270 n++;
3272 init_allocno_threads ();
3273 /* Color all mentioned allocnos including transparent ones. */
3274 color_allocnos ();
3275 /* Process caps. They are processed just once. */
3276 if (flag_ira_region == IRA_REGION_MIXED
3277 || flag_ira_region == IRA_REGION_ALL)
3278 EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->all_allocnos, 0, j, bi)
3280 a = ira_allocnos[j];
3281 if (ALLOCNO_CAP_MEMBER (a) == NULL)
3282 continue;
3283 /* Remove from processing in the next loop. */
3284 bitmap_clear_bit (consideration_allocno_bitmap, j);
3285 rclass = ALLOCNO_CLASS (a);
3286 pclass = ira_pressure_class_translate[rclass];
3287 if (flag_ira_region == IRA_REGION_MIXED
3288 && (loop_tree_node->reg_pressure[pclass]
3289 <= ira_class_hard_regs_num[pclass]))
3291 mode = ALLOCNO_MODE (a);
3292 hard_regno = ALLOCNO_HARD_REGNO (a);
3293 if (hard_regno >= 0)
3295 index = ira_class_hard_reg_index[rclass][hard_regno];
3296 ira_assert (index >= 0);
3298 regno = ALLOCNO_REGNO (a);
3299 subloop_allocno = ALLOCNO_CAP_MEMBER (a);
3300 subloop_node = ALLOCNO_LOOP_TREE_NODE (subloop_allocno);
3301 ira_assert (!ALLOCNO_ASSIGNED_P (subloop_allocno));
3302 ALLOCNO_HARD_REGNO (subloop_allocno) = hard_regno;
3303 ALLOCNO_ASSIGNED_P (subloop_allocno) = true;
3304 if (hard_regno >= 0)
3305 update_costs_from_copies (subloop_allocno, true, true);
3306 /* We don't need updated costs anymore. */
3307 ira_free_allocno_updated_costs (subloop_allocno);
3310 /* Update costs of the corresponding allocnos (not caps) in the
3311 subloops. */
3312 for (subloop_node = loop_tree_node->subloops;
3313 subloop_node != NULL;
3314 subloop_node = subloop_node->subloop_next)
3316 ira_assert (subloop_node->bb == NULL);
3317 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
3319 a = ira_allocnos[j];
3320 ira_assert (ALLOCNO_CAP_MEMBER (a) == NULL);
3321 mode = ALLOCNO_MODE (a);
3322 rclass = ALLOCNO_CLASS (a);
3323 pclass = ira_pressure_class_translate[rclass];
3324 hard_regno = ALLOCNO_HARD_REGNO (a);
3325 /* Use hard register class here. ??? */
3326 if (hard_regno >= 0)
3328 index = ira_class_hard_reg_index[rclass][hard_regno];
3329 ira_assert (index >= 0);
3331 regno = ALLOCNO_REGNO (a);
3332 /* ??? conflict costs */
3333 subloop_allocno = subloop_node->regno_allocno_map[regno];
3334 if (subloop_allocno == NULL
3335 || ALLOCNO_CAP (subloop_allocno) != NULL)
3336 continue;
3337 ira_assert (ALLOCNO_CLASS (subloop_allocno) == rclass);
3338 ira_assert (bitmap_bit_p (subloop_node->all_allocnos,
3339 ALLOCNO_NUM (subloop_allocno)));
3340 if ((flag_ira_region == IRA_REGION_MIXED
3341 && (loop_tree_node->reg_pressure[pclass]
3342 <= ira_class_hard_regs_num[pclass]))
3343 || (pic_offset_table_rtx != NULL
3344 && regno == (int) REGNO (pic_offset_table_rtx))
3345 /* Avoid overlapped multi-registers. Moves between them
3346 might result in wrong code generation. */
3347 || (hard_regno >= 0
3348 && ira_reg_class_max_nregs[pclass][mode] > 1))
3350 if (! ALLOCNO_ASSIGNED_P (subloop_allocno))
3352 ALLOCNO_HARD_REGNO (subloop_allocno) = hard_regno;
3353 ALLOCNO_ASSIGNED_P (subloop_allocno) = true;
3354 if (hard_regno >= 0)
3355 update_costs_from_copies (subloop_allocno, true, true);
3356 /* We don't need updated costs anymore. */
3357 ira_free_allocno_updated_costs (subloop_allocno);
3359 continue;
3361 exit_freq = ira_loop_edge_freq (subloop_node, regno, true);
3362 enter_freq = ira_loop_edge_freq (subloop_node, regno, false);
3363 ira_assert (regno < ira_reg_equiv_len);
3364 if (ira_equiv_no_lvalue_p (regno))
3366 if (! ALLOCNO_ASSIGNED_P (subloop_allocno))
3368 ALLOCNO_HARD_REGNO (subloop_allocno) = hard_regno;
3369 ALLOCNO_ASSIGNED_P (subloop_allocno) = true;
3370 if (hard_regno >= 0)
3371 update_costs_from_copies (subloop_allocno, true, true);
3372 /* We don't need updated costs anymore. */
3373 ira_free_allocno_updated_costs (subloop_allocno);
3376 else if (hard_regno < 0)
3378 ALLOCNO_UPDATED_MEMORY_COST (subloop_allocno)
3379 -= ((ira_memory_move_cost[mode][rclass][1] * enter_freq)
3380 + (ira_memory_move_cost[mode][rclass][0] * exit_freq));
3382 else
3384 aclass = ALLOCNO_CLASS (subloop_allocno);
3385 ira_init_register_move_cost_if_necessary (mode);
3386 cost = (ira_register_move_cost[mode][rclass][rclass]
3387 * (exit_freq + enter_freq));
3388 ira_allocate_and_set_or_copy_costs
3389 (&ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno), aclass,
3390 ALLOCNO_UPDATED_CLASS_COST (subloop_allocno),
3391 ALLOCNO_HARD_REG_COSTS (subloop_allocno));
3392 ira_allocate_and_set_or_copy_costs
3393 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (subloop_allocno),
3394 aclass, 0, ALLOCNO_CONFLICT_HARD_REG_COSTS (subloop_allocno));
3395 ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno)[index] -= cost;
3396 ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (subloop_allocno)[index]
3397 -= cost;
3398 if (ALLOCNO_UPDATED_CLASS_COST (subloop_allocno)
3399 > ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno)[index])
3400 ALLOCNO_UPDATED_CLASS_COST (subloop_allocno)
3401 = ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno)[index];
3402 ALLOCNO_UPDATED_MEMORY_COST (subloop_allocno)
3403 += (ira_memory_move_cost[mode][rclass][0] * enter_freq
3404 + ira_memory_move_cost[mode][rclass][1] * exit_freq);
3408 ira_free (allocno_color_data);
3409 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
3411 a = ira_allocnos[j];
3412 ALLOCNO_ADD_DATA (a) = NULL;
3416 /* Initialize the common data for coloring and calls functions to do
3417 Chaitin-Briggs and regional coloring. */
3418 static void
3419 do_coloring (void)
3421 coloring_allocno_bitmap = ira_allocate_bitmap ();
3422 if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
3423 fprintf (ira_dump_file, "\n**** Allocnos coloring:\n\n");
3425 ira_traverse_loop_tree (false, ira_loop_tree_root, color_pass, NULL);
3427 if (internal_flag_ira_verbose > 1 && ira_dump_file != NULL)
3428 ira_print_disposition (ira_dump_file);
3430 ira_free_bitmap (coloring_allocno_bitmap);
3435 /* Move spill/restore code, which are to be generated in ira-emit.c,
3436 to less frequent points (if it is profitable) by reassigning some
3437 allocnos (in loop with subloops containing in another loop) to
3438 memory which results in longer live-range where the corresponding
3439 pseudo-registers will be in memory. */
3440 static void
3441 move_spill_restore (void)
3443 int cost, regno, hard_regno, hard_regno2, index;
3444 bool changed_p;
3445 int enter_freq, exit_freq;
3446 machine_mode mode;
3447 enum reg_class rclass;
3448 ira_allocno_t a, parent_allocno, subloop_allocno;
3449 ira_loop_tree_node_t parent, loop_node, subloop_node;
3450 ira_allocno_iterator ai;
3452 for (;;)
3454 changed_p = false;
3455 if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
3456 fprintf (ira_dump_file, "New iteration of spill/restore move\n");
3457 FOR_EACH_ALLOCNO (a, ai)
3459 regno = ALLOCNO_REGNO (a);
3460 loop_node = ALLOCNO_LOOP_TREE_NODE (a);
3461 if (ALLOCNO_CAP_MEMBER (a) != NULL
3462 || ALLOCNO_CAP (a) != NULL
3463 || (hard_regno = ALLOCNO_HARD_REGNO (a)) < 0
3464 || loop_node->children == NULL
3465 /* don't do the optimization because it can create
3466 copies and the reload pass can spill the allocno set
3467 by copy although the allocno will not get memory
3468 slot. */
3469 || ira_equiv_no_lvalue_p (regno)
3470 || !bitmap_bit_p (loop_node->border_allocnos, ALLOCNO_NUM (a))
3471 /* Do not spill static chain pointer pseudo when
3472 non-local goto is used. */
3473 || non_spilled_static_chain_regno_p (regno))
3474 continue;
3475 mode = ALLOCNO_MODE (a);
3476 rclass = ALLOCNO_CLASS (a);
3477 index = ira_class_hard_reg_index[rclass][hard_regno];
3478 ira_assert (index >= 0);
3479 cost = (ALLOCNO_MEMORY_COST (a)
3480 - (ALLOCNO_HARD_REG_COSTS (a) == NULL
3481 ? ALLOCNO_CLASS_COST (a)
3482 : ALLOCNO_HARD_REG_COSTS (a)[index]));
3483 ira_init_register_move_cost_if_necessary (mode);
3484 for (subloop_node = loop_node->subloops;
3485 subloop_node != NULL;
3486 subloop_node = subloop_node->subloop_next)
3488 ira_assert (subloop_node->bb == NULL);
3489 subloop_allocno = subloop_node->regno_allocno_map[regno];
3490 if (subloop_allocno == NULL)
3491 continue;
3492 ira_assert (rclass == ALLOCNO_CLASS (subloop_allocno));
3493 /* We have accumulated cost. To get the real cost of
3494 allocno usage in the loop we should subtract costs of
3495 the subloop allocnos. */
3496 cost -= (ALLOCNO_MEMORY_COST (subloop_allocno)
3497 - (ALLOCNO_HARD_REG_COSTS (subloop_allocno) == NULL
3498 ? ALLOCNO_CLASS_COST (subloop_allocno)
3499 : ALLOCNO_HARD_REG_COSTS (subloop_allocno)[index]));
3500 exit_freq = ira_loop_edge_freq (subloop_node, regno, true);
3501 enter_freq = ira_loop_edge_freq (subloop_node, regno, false);
3502 if ((hard_regno2 = ALLOCNO_HARD_REGNO (subloop_allocno)) < 0)
3503 cost -= (ira_memory_move_cost[mode][rclass][0] * exit_freq
3504 + ira_memory_move_cost[mode][rclass][1] * enter_freq);
3505 else
3507 cost
3508 += (ira_memory_move_cost[mode][rclass][0] * exit_freq
3509 + ira_memory_move_cost[mode][rclass][1] * enter_freq);
3510 if (hard_regno2 != hard_regno)
3511 cost -= (ira_register_move_cost[mode][rclass][rclass]
3512 * (exit_freq + enter_freq));
3515 if ((parent = loop_node->parent) != NULL
3516 && (parent_allocno = parent->regno_allocno_map[regno]) != NULL)
3518 ira_assert (rclass == ALLOCNO_CLASS (parent_allocno));
3519 exit_freq = ira_loop_edge_freq (loop_node, regno, true);
3520 enter_freq = ira_loop_edge_freq (loop_node, regno, false);
3521 if ((hard_regno2 = ALLOCNO_HARD_REGNO (parent_allocno)) < 0)
3522 cost -= (ira_memory_move_cost[mode][rclass][0] * exit_freq
3523 + ira_memory_move_cost[mode][rclass][1] * enter_freq);
3524 else
3526 cost
3527 += (ira_memory_move_cost[mode][rclass][1] * exit_freq
3528 + ira_memory_move_cost[mode][rclass][0] * enter_freq);
3529 if (hard_regno2 != hard_regno)
3530 cost -= (ira_register_move_cost[mode][rclass][rclass]
3531 * (exit_freq + enter_freq));
3534 if (cost < 0)
3536 ALLOCNO_HARD_REGNO (a) = -1;
3537 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3539 fprintf
3540 (ira_dump_file,
3541 " Moving spill/restore for a%dr%d up from loop %d",
3542 ALLOCNO_NUM (a), regno, loop_node->loop_num);
3543 fprintf (ira_dump_file, " - profit %d\n", -cost);
3545 changed_p = true;
3548 if (! changed_p)
3549 break;
3555 /* Update current hard reg costs and current conflict hard reg costs
3556 for allocno A. It is done by processing its copies containing
3557 other allocnos already assigned. */
3558 static void
3559 update_curr_costs (ira_allocno_t a)
3561 int i, hard_regno, cost;
3562 machine_mode mode;
3563 enum reg_class aclass, rclass;
3564 ira_allocno_t another_a;
3565 ira_copy_t cp, next_cp;
3567 ira_free_allocno_updated_costs (a);
3568 ira_assert (! ALLOCNO_ASSIGNED_P (a));
3569 aclass = ALLOCNO_CLASS (a);
3570 if (aclass == NO_REGS)
3571 return;
3572 mode = ALLOCNO_MODE (a);
3573 ira_init_register_move_cost_if_necessary (mode);
3574 for (cp = ALLOCNO_COPIES (a); cp != NULL; cp = next_cp)
3576 if (cp->first == a)
3578 next_cp = cp->next_first_allocno_copy;
3579 another_a = cp->second;
3581 else if (cp->second == a)
3583 next_cp = cp->next_second_allocno_copy;
3584 another_a = cp->first;
3586 else
3587 gcc_unreachable ();
3588 if (! ira_reg_classes_intersect_p[aclass][ALLOCNO_CLASS (another_a)]
3589 || ! ALLOCNO_ASSIGNED_P (another_a)
3590 || (hard_regno = ALLOCNO_HARD_REGNO (another_a)) < 0)
3591 continue;
3592 rclass = REGNO_REG_CLASS (hard_regno);
3593 i = ira_class_hard_reg_index[aclass][hard_regno];
3594 if (i < 0)
3595 continue;
3596 cost = (cp->first == a
3597 ? ira_register_move_cost[mode][rclass][aclass]
3598 : ira_register_move_cost[mode][aclass][rclass]);
3599 ira_allocate_and_set_or_copy_costs
3600 (&ALLOCNO_UPDATED_HARD_REG_COSTS (a), aclass, ALLOCNO_CLASS_COST (a),
3601 ALLOCNO_HARD_REG_COSTS (a));
3602 ira_allocate_and_set_or_copy_costs
3603 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a),
3604 aclass, 0, ALLOCNO_CONFLICT_HARD_REG_COSTS (a));
3605 ALLOCNO_UPDATED_HARD_REG_COSTS (a)[i] -= cp->freq * cost;
3606 ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a)[i] -= cp->freq * cost;
3610 /* Try to assign hard registers to the unassigned allocnos and
3611 allocnos conflicting with them or conflicting with allocnos whose
3612 regno >= START_REGNO. The function is called after ira_flattening,
3613 so more allocnos (including ones created in ira-emit.c) will have a
3614 chance to get a hard register. We use simple assignment algorithm
3615 based on priorities. */
3616 void
3617 ira_reassign_conflict_allocnos (int start_regno)
3619 int i, allocnos_to_color_num;
3620 ira_allocno_t a;
3621 enum reg_class aclass;
3622 bitmap allocnos_to_color;
3623 ira_allocno_iterator ai;
3625 allocnos_to_color = ira_allocate_bitmap ();
3626 allocnos_to_color_num = 0;
3627 FOR_EACH_ALLOCNO (a, ai)
3629 int n = ALLOCNO_NUM_OBJECTS (a);
3631 if (! ALLOCNO_ASSIGNED_P (a)
3632 && ! bitmap_bit_p (allocnos_to_color, ALLOCNO_NUM (a)))
3634 if (ALLOCNO_CLASS (a) != NO_REGS)
3635 sorted_allocnos[allocnos_to_color_num++] = a;
3636 else
3638 ALLOCNO_ASSIGNED_P (a) = true;
3639 ALLOCNO_HARD_REGNO (a) = -1;
3640 ira_assert (ALLOCNO_UPDATED_HARD_REG_COSTS (a) == NULL);
3641 ira_assert (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a) == NULL);
3643 bitmap_set_bit (allocnos_to_color, ALLOCNO_NUM (a));
3645 if (ALLOCNO_REGNO (a) < start_regno
3646 || (aclass = ALLOCNO_CLASS (a)) == NO_REGS)
3647 continue;
3648 for (i = 0; i < n; i++)
3650 ira_object_t obj = ALLOCNO_OBJECT (a, i);
3651 ira_object_t conflict_obj;
3652 ira_object_conflict_iterator oci;
3654 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
3656 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
3658 ira_assert (ira_reg_classes_intersect_p
3659 [aclass][ALLOCNO_CLASS (conflict_a)]);
3660 if (!bitmap_set_bit (allocnos_to_color, ALLOCNO_NUM (conflict_a)))
3661 continue;
3662 sorted_allocnos[allocnos_to_color_num++] = conflict_a;
3666 ira_free_bitmap (allocnos_to_color);
3667 if (allocnos_to_color_num > 1)
3669 setup_allocno_priorities (sorted_allocnos, allocnos_to_color_num);
3670 qsort (sorted_allocnos, allocnos_to_color_num, sizeof (ira_allocno_t),
3671 allocno_priority_compare_func);
3673 for (i = 0; i < allocnos_to_color_num; i++)
3675 a = sorted_allocnos[i];
3676 ALLOCNO_ASSIGNED_P (a) = false;
3677 update_curr_costs (a);
3679 for (i = 0; i < allocnos_to_color_num; i++)
3681 a = sorted_allocnos[i];
3682 if (assign_hard_reg (a, true))
3684 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3685 fprintf
3686 (ira_dump_file,
3687 " Secondary allocation: assign hard reg %d to reg %d\n",
3688 ALLOCNO_HARD_REGNO (a), ALLOCNO_REGNO (a));
3695 /* This page contains functions used to find conflicts using allocno
3696 live ranges. */
3698 #ifdef ENABLE_IRA_CHECKING
3700 /* Return TRUE if live ranges of pseudo-registers REGNO1 and REGNO2
3701 intersect. This should be used when there is only one region.
3702 Currently this is used during reload. */
3703 static bool
3704 conflict_by_live_ranges_p (int regno1, int regno2)
3706 ira_allocno_t a1, a2;
3708 ira_assert (regno1 >= FIRST_PSEUDO_REGISTER
3709 && regno2 >= FIRST_PSEUDO_REGISTER);
3710 /* Reg info calculated by dataflow infrastructure can be different
3711 from one calculated by regclass. */
3712 if ((a1 = ira_loop_tree_root->regno_allocno_map[regno1]) == NULL
3713 || (a2 = ira_loop_tree_root->regno_allocno_map[regno2]) == NULL)
3714 return false;
3715 return allocnos_conflict_by_live_ranges_p (a1, a2);
3718 #endif
3722 /* This page contains code to coalesce memory stack slots used by
3723 spilled allocnos. This results in smaller stack frame, better data
3724 locality, and in smaller code for some architectures like
3725 x86/x86_64 where insn size depends on address displacement value.
3726 On the other hand, it can worsen insn scheduling after the RA but
3727 in practice it is less important than smaller stack frames. */
3729 /* TRUE if we coalesced some allocnos. In other words, if we got
3730 loops formed by members first_coalesced_allocno and
3731 next_coalesced_allocno containing more one allocno. */
3732 static bool allocno_coalesced_p;
3734 /* Bitmap used to prevent a repeated allocno processing because of
3735 coalescing. */
3736 static bitmap processed_coalesced_allocno_bitmap;
3738 /* See below. */
3739 typedef struct coalesce_data *coalesce_data_t;
3741 /* To decrease footprint of ira_allocno structure we store all data
3742 needed only for coalescing in the following structure. */
3743 struct coalesce_data
3745 /* Coalesced allocnos form a cyclic list. One allocno given by
3746 FIRST represents all coalesced allocnos. The
3747 list is chained by NEXT. */
3748 ira_allocno_t first;
3749 ira_allocno_t next;
3750 int temp;
3753 /* Container for storing allocno data concerning coalescing. */
3754 static coalesce_data_t allocno_coalesce_data;
3756 /* Macro to access the data concerning coalescing. */
3757 #define ALLOCNO_COALESCE_DATA(a) ((coalesce_data_t) ALLOCNO_ADD_DATA (a))
3759 /* Merge two sets of coalesced allocnos given correspondingly by
3760 allocnos A1 and A2 (more accurately merging A2 set into A1
3761 set). */
3762 static void
3763 merge_allocnos (ira_allocno_t a1, ira_allocno_t a2)
3765 ira_allocno_t a, first, last, next;
3767 first = ALLOCNO_COALESCE_DATA (a1)->first;
3768 a = ALLOCNO_COALESCE_DATA (a2)->first;
3769 if (first == a)
3770 return;
3771 for (last = a2, a = ALLOCNO_COALESCE_DATA (a2)->next;;
3772 a = ALLOCNO_COALESCE_DATA (a)->next)
3774 ALLOCNO_COALESCE_DATA (a)->first = first;
3775 if (a == a2)
3776 break;
3777 last = a;
3779 next = allocno_coalesce_data[ALLOCNO_NUM (first)].next;
3780 allocno_coalesce_data[ALLOCNO_NUM (first)].next = a2;
3781 allocno_coalesce_data[ALLOCNO_NUM (last)].next = next;
3784 /* Return TRUE if there are conflicting allocnos from two sets of
3785 coalesced allocnos given correspondingly by allocnos A1 and A2. We
3786 use live ranges to find conflicts because conflicts are represented
3787 only for allocnos of the same allocno class and during the reload
3788 pass we coalesce allocnos for sharing stack memory slots. */
3789 static bool
3790 coalesced_allocno_conflict_p (ira_allocno_t a1, ira_allocno_t a2)
3792 ira_allocno_t a, conflict_a;
3794 if (allocno_coalesced_p)
3796 bitmap_clear (processed_coalesced_allocno_bitmap);
3797 for (a = ALLOCNO_COALESCE_DATA (a1)->next;;
3798 a = ALLOCNO_COALESCE_DATA (a)->next)
3800 bitmap_set_bit (processed_coalesced_allocno_bitmap, ALLOCNO_NUM (a));
3801 if (a == a1)
3802 break;
3805 for (a = ALLOCNO_COALESCE_DATA (a2)->next;;
3806 a = ALLOCNO_COALESCE_DATA (a)->next)
3808 for (conflict_a = ALLOCNO_COALESCE_DATA (a1)->next;;
3809 conflict_a = ALLOCNO_COALESCE_DATA (conflict_a)->next)
3811 if (allocnos_conflict_by_live_ranges_p (a, conflict_a))
3812 return true;
3813 if (conflict_a == a1)
3814 break;
3816 if (a == a2)
3817 break;
3819 return false;
3822 /* The major function for aggressive allocno coalescing. We coalesce
3823 only spilled allocnos. If some allocnos have been coalesced, we
3824 set up flag allocno_coalesced_p. */
3825 static void
3826 coalesce_allocnos (void)
3828 ira_allocno_t a;
3829 ira_copy_t cp, next_cp;
3830 unsigned int j;
3831 int i, n, cp_num, regno;
3832 bitmap_iterator bi;
3834 cp_num = 0;
3835 /* Collect copies. */
3836 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, j, bi)
3838 a = ira_allocnos[j];
3839 regno = ALLOCNO_REGNO (a);
3840 if (! ALLOCNO_ASSIGNED_P (a) || ALLOCNO_HARD_REGNO (a) >= 0
3841 || ira_equiv_no_lvalue_p (regno))
3842 continue;
3843 for (cp = ALLOCNO_COPIES (a); cp != NULL; cp = next_cp)
3845 if (cp->first == a)
3847 next_cp = cp->next_first_allocno_copy;
3848 regno = ALLOCNO_REGNO (cp->second);
3849 /* For priority coloring we coalesce allocnos only with
3850 the same allocno class not with intersected allocno
3851 classes as it were possible. It is done for
3852 simplicity. */
3853 if ((cp->insn != NULL || cp->constraint_p)
3854 && ALLOCNO_ASSIGNED_P (cp->second)
3855 && ALLOCNO_HARD_REGNO (cp->second) < 0
3856 && ! ira_equiv_no_lvalue_p (regno))
3857 sorted_copies[cp_num++] = cp;
3859 else if (cp->second == a)
3860 next_cp = cp->next_second_allocno_copy;
3861 else
3862 gcc_unreachable ();
3865 qsort (sorted_copies, cp_num, sizeof (ira_copy_t), copy_freq_compare_func);
3866 /* Coalesced copies, most frequently executed first. */
3867 for (; cp_num != 0;)
3869 for (i = 0; i < cp_num; i++)
3871 cp = sorted_copies[i];
3872 if (! coalesced_allocno_conflict_p (cp->first, cp->second))
3874 allocno_coalesced_p = true;
3875 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3876 fprintf
3877 (ira_dump_file,
3878 " Coalescing copy %d:a%dr%d-a%dr%d (freq=%d)\n",
3879 cp->num, ALLOCNO_NUM (cp->first), ALLOCNO_REGNO (cp->first),
3880 ALLOCNO_NUM (cp->second), ALLOCNO_REGNO (cp->second),
3881 cp->freq);
3882 merge_allocnos (cp->first, cp->second);
3883 i++;
3884 break;
3887 /* Collect the rest of copies. */
3888 for (n = 0; i < cp_num; i++)
3890 cp = sorted_copies[i];
3891 if (allocno_coalesce_data[ALLOCNO_NUM (cp->first)].first
3892 != allocno_coalesce_data[ALLOCNO_NUM (cp->second)].first)
3893 sorted_copies[n++] = cp;
3895 cp_num = n;
3899 /* Usage cost and order number of coalesced allocno set to which
3900 given pseudo register belongs to. */
3901 static int *regno_coalesced_allocno_cost;
3902 static int *regno_coalesced_allocno_num;
3904 /* Sort pseudos according frequencies of coalesced allocno sets they
3905 belong to (putting most frequently ones first), and according to
3906 coalesced allocno set order numbers. */
3907 static int
3908 coalesced_pseudo_reg_freq_compare (const void *v1p, const void *v2p)
3910 const int regno1 = *(const int *) v1p;
3911 const int regno2 = *(const int *) v2p;
3912 int diff;
3914 if ((diff = (regno_coalesced_allocno_cost[regno2]
3915 - regno_coalesced_allocno_cost[regno1])) != 0)
3916 return diff;
3917 if ((diff = (regno_coalesced_allocno_num[regno1]
3918 - regno_coalesced_allocno_num[regno2])) != 0)
3919 return diff;
3920 return regno1 - regno2;
3923 /* Widest width in which each pseudo reg is referred to (via subreg).
3924 It is used for sorting pseudo registers. */
3925 static machine_mode *regno_max_ref_mode;
3927 /* Sort pseudos according their slot numbers (putting ones with
3928 smaller numbers first, or last when the frame pointer is not
3929 needed). */
3930 static int
3931 coalesced_pseudo_reg_slot_compare (const void *v1p, const void *v2p)
3933 const int regno1 = *(const int *) v1p;
3934 const int regno2 = *(const int *) v2p;
3935 ira_allocno_t a1 = ira_regno_allocno_map[regno1];
3936 ira_allocno_t a2 = ira_regno_allocno_map[regno2];
3937 int diff, slot_num1, slot_num2;
3938 machine_mode mode1, mode2;
3940 if (a1 == NULL || ALLOCNO_HARD_REGNO (a1) >= 0)
3942 if (a2 == NULL || ALLOCNO_HARD_REGNO (a2) >= 0)
3943 return regno1 - regno2;
3944 return 1;
3946 else if (a2 == NULL || ALLOCNO_HARD_REGNO (a2) >= 0)
3947 return -1;
3948 slot_num1 = -ALLOCNO_HARD_REGNO (a1);
3949 slot_num2 = -ALLOCNO_HARD_REGNO (a2);
3950 if ((diff = slot_num1 - slot_num2) != 0)
3951 return (frame_pointer_needed
3952 || (!FRAME_GROWS_DOWNWARD) == STACK_GROWS_DOWNWARD ? diff : -diff);
3953 mode1 = wider_subreg_mode (PSEUDO_REGNO_MODE (regno1),
3954 regno_max_ref_mode[regno1]);
3955 mode2 = wider_subreg_mode (PSEUDO_REGNO_MODE (regno2),
3956 regno_max_ref_mode[regno2]);
3957 if ((diff = compare_sizes_for_sort (GET_MODE_SIZE (mode2),
3958 GET_MODE_SIZE (mode1))) != 0)
3959 return diff;
3960 return regno1 - regno2;
3963 /* Setup REGNO_COALESCED_ALLOCNO_COST and REGNO_COALESCED_ALLOCNO_NUM
3964 for coalesced allocno sets containing allocnos with their regnos
3965 given in array PSEUDO_REGNOS of length N. */
3966 static void
3967 setup_coalesced_allocno_costs_and_nums (int *pseudo_regnos, int n)
3969 int i, num, regno, cost;
3970 ira_allocno_t allocno, a;
3972 for (num = i = 0; i < n; i++)
3974 regno = pseudo_regnos[i];
3975 allocno = ira_regno_allocno_map[regno];
3976 if (allocno == NULL)
3978 regno_coalesced_allocno_cost[regno] = 0;
3979 regno_coalesced_allocno_num[regno] = ++num;
3980 continue;
3982 if (ALLOCNO_COALESCE_DATA (allocno)->first != allocno)
3983 continue;
3984 num++;
3985 for (cost = 0, a = ALLOCNO_COALESCE_DATA (allocno)->next;;
3986 a = ALLOCNO_COALESCE_DATA (a)->next)
3988 cost += ALLOCNO_FREQ (a);
3989 if (a == allocno)
3990 break;
3992 for (a = ALLOCNO_COALESCE_DATA (allocno)->next;;
3993 a = ALLOCNO_COALESCE_DATA (a)->next)
3995 regno_coalesced_allocno_num[ALLOCNO_REGNO (a)] = num;
3996 regno_coalesced_allocno_cost[ALLOCNO_REGNO (a)] = cost;
3997 if (a == allocno)
3998 break;
4003 /* Collect spilled allocnos representing coalesced allocno sets (the
4004 first coalesced allocno). The collected allocnos are returned
4005 through array SPILLED_COALESCED_ALLOCNOS. The function returns the
4006 number of the collected allocnos. The allocnos are given by their
4007 regnos in array PSEUDO_REGNOS of length N. */
4008 static int
4009 collect_spilled_coalesced_allocnos (int *pseudo_regnos, int n,
4010 ira_allocno_t *spilled_coalesced_allocnos)
4012 int i, num, regno;
4013 ira_allocno_t allocno;
4015 for (num = i = 0; i < n; i++)
4017 regno = pseudo_regnos[i];
4018 allocno = ira_regno_allocno_map[regno];
4019 if (allocno == NULL || ALLOCNO_HARD_REGNO (allocno) >= 0
4020 || ALLOCNO_COALESCE_DATA (allocno)->first != allocno)
4021 continue;
4022 spilled_coalesced_allocnos[num++] = allocno;
4024 return num;
4027 /* Array of live ranges of size IRA_ALLOCNOS_NUM. Live range for
4028 given slot contains live ranges of coalesced allocnos assigned to
4029 given slot. */
4030 static live_range_t *slot_coalesced_allocnos_live_ranges;
4032 /* Return TRUE if coalesced allocnos represented by ALLOCNO has live
4033 ranges intersected with live ranges of coalesced allocnos assigned
4034 to slot with number N. */
4035 static bool
4036 slot_coalesced_allocno_live_ranges_intersect_p (ira_allocno_t allocno, int n)
4038 ira_allocno_t a;
4040 for (a = ALLOCNO_COALESCE_DATA (allocno)->next;;
4041 a = ALLOCNO_COALESCE_DATA (a)->next)
4043 int i;
4044 int nr = ALLOCNO_NUM_OBJECTS (a);
4045 gcc_assert (ALLOCNO_CAP_MEMBER (a) == NULL);
4046 for (i = 0; i < nr; i++)
4048 ira_object_t obj = ALLOCNO_OBJECT (a, i);
4050 if (ira_live_ranges_intersect_p
4051 (slot_coalesced_allocnos_live_ranges[n],
4052 OBJECT_LIVE_RANGES (obj)))
4053 return true;
4055 if (a == allocno)
4056 break;
4058 return false;
4061 /* Update live ranges of slot to which coalesced allocnos represented
4062 by ALLOCNO were assigned. */
4063 static void
4064 setup_slot_coalesced_allocno_live_ranges (ira_allocno_t allocno)
4066 int i, n;
4067 ira_allocno_t a;
4068 live_range_t r;
4070 n = ALLOCNO_COALESCE_DATA (allocno)->temp;
4071 for (a = ALLOCNO_COALESCE_DATA (allocno)->next;;
4072 a = ALLOCNO_COALESCE_DATA (a)->next)
4074 int nr = ALLOCNO_NUM_OBJECTS (a);
4075 gcc_assert (ALLOCNO_CAP_MEMBER (a) == NULL);
4076 for (i = 0; i < nr; i++)
4078 ira_object_t obj = ALLOCNO_OBJECT (a, i);
4080 r = ira_copy_live_range_list (OBJECT_LIVE_RANGES (obj));
4081 slot_coalesced_allocnos_live_ranges[n]
4082 = ira_merge_live_ranges
4083 (slot_coalesced_allocnos_live_ranges[n], r);
4085 if (a == allocno)
4086 break;
4090 /* We have coalesced allocnos involving in copies. Coalesce allocnos
4091 further in order to share the same memory stack slot. Allocnos
4092 representing sets of allocnos coalesced before the call are given
4093 in array SPILLED_COALESCED_ALLOCNOS of length NUM. Return TRUE if
4094 some allocnos were coalesced in the function. */
4095 static bool
4096 coalesce_spill_slots (ira_allocno_t *spilled_coalesced_allocnos, int num)
4098 int i, j, n, last_coalesced_allocno_num;
4099 ira_allocno_t allocno, a;
4100 bool merged_p = false;
4101 bitmap set_jump_crosses = regstat_get_setjmp_crosses ();
4103 slot_coalesced_allocnos_live_ranges
4104 = (live_range_t *) ira_allocate (sizeof (live_range_t) * ira_allocnos_num);
4105 memset (slot_coalesced_allocnos_live_ranges, 0,
4106 sizeof (live_range_t) * ira_allocnos_num);
4107 last_coalesced_allocno_num = 0;
4108 /* Coalesce non-conflicting spilled allocnos preferring most
4109 frequently used. */
4110 for (i = 0; i < num; i++)
4112 allocno = spilled_coalesced_allocnos[i];
4113 if (ALLOCNO_COALESCE_DATA (allocno)->first != allocno
4114 || bitmap_bit_p (set_jump_crosses, ALLOCNO_REGNO (allocno))
4115 || ira_equiv_no_lvalue_p (ALLOCNO_REGNO (allocno)))
4116 continue;
4117 for (j = 0; j < i; j++)
4119 a = spilled_coalesced_allocnos[j];
4120 n = ALLOCNO_COALESCE_DATA (a)->temp;
4121 if (ALLOCNO_COALESCE_DATA (a)->first == a
4122 && ! bitmap_bit_p (set_jump_crosses, ALLOCNO_REGNO (a))
4123 && ! ira_equiv_no_lvalue_p (ALLOCNO_REGNO (a))
4124 && ! slot_coalesced_allocno_live_ranges_intersect_p (allocno, n))
4125 break;
4127 if (j >= i)
4129 /* No coalescing: set up number for coalesced allocnos
4130 represented by ALLOCNO. */
4131 ALLOCNO_COALESCE_DATA (allocno)->temp = last_coalesced_allocno_num++;
4132 setup_slot_coalesced_allocno_live_ranges (allocno);
4134 else
4136 allocno_coalesced_p = true;
4137 merged_p = true;
4138 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4139 fprintf (ira_dump_file,
4140 " Coalescing spilled allocnos a%dr%d->a%dr%d\n",
4141 ALLOCNO_NUM (allocno), ALLOCNO_REGNO (allocno),
4142 ALLOCNO_NUM (a), ALLOCNO_REGNO (a));
4143 ALLOCNO_COALESCE_DATA (allocno)->temp
4144 = ALLOCNO_COALESCE_DATA (a)->temp;
4145 setup_slot_coalesced_allocno_live_ranges (allocno);
4146 merge_allocnos (a, allocno);
4147 ira_assert (ALLOCNO_COALESCE_DATA (a)->first == a);
4150 for (i = 0; i < ira_allocnos_num; i++)
4151 ira_finish_live_range_list (slot_coalesced_allocnos_live_ranges[i]);
4152 ira_free (slot_coalesced_allocnos_live_ranges);
4153 return merged_p;
4156 /* Sort pseudo-register numbers in array PSEUDO_REGNOS of length N for
4157 subsequent assigning stack slots to them in the reload pass. To do
4158 this we coalesce spilled allocnos first to decrease the number of
4159 memory-memory move insns. This function is called by the
4160 reload. */
4161 void
4162 ira_sort_regnos_for_alter_reg (int *pseudo_regnos, int n,
4163 machine_mode *reg_max_ref_mode)
4165 int max_regno = max_reg_num ();
4166 int i, regno, num, slot_num;
4167 ira_allocno_t allocno, a;
4168 ira_allocno_iterator ai;
4169 ira_allocno_t *spilled_coalesced_allocnos;
4171 ira_assert (! ira_use_lra_p);
4173 /* Set up allocnos can be coalesced. */
4174 coloring_allocno_bitmap = ira_allocate_bitmap ();
4175 for (i = 0; i < n; i++)
4177 regno = pseudo_regnos[i];
4178 allocno = ira_regno_allocno_map[regno];
4179 if (allocno != NULL)
4180 bitmap_set_bit (coloring_allocno_bitmap, ALLOCNO_NUM (allocno));
4182 allocno_coalesced_p = false;
4183 processed_coalesced_allocno_bitmap = ira_allocate_bitmap ();
4184 allocno_coalesce_data
4185 = (coalesce_data_t) ira_allocate (sizeof (struct coalesce_data)
4186 * ira_allocnos_num);
4187 /* Initialize coalesce data for allocnos. */
4188 FOR_EACH_ALLOCNO (a, ai)
4190 ALLOCNO_ADD_DATA (a) = allocno_coalesce_data + ALLOCNO_NUM (a);
4191 ALLOCNO_COALESCE_DATA (a)->first = a;
4192 ALLOCNO_COALESCE_DATA (a)->next = a;
4194 coalesce_allocnos ();
4195 ira_free_bitmap (coloring_allocno_bitmap);
4196 regno_coalesced_allocno_cost
4197 = (int *) ira_allocate (max_regno * sizeof (int));
4198 regno_coalesced_allocno_num
4199 = (int *) ira_allocate (max_regno * sizeof (int));
4200 memset (regno_coalesced_allocno_num, 0, max_regno * sizeof (int));
4201 setup_coalesced_allocno_costs_and_nums (pseudo_regnos, n);
4202 /* Sort regnos according frequencies of the corresponding coalesced
4203 allocno sets. */
4204 qsort (pseudo_regnos, n, sizeof (int), coalesced_pseudo_reg_freq_compare);
4205 spilled_coalesced_allocnos
4206 = (ira_allocno_t *) ira_allocate (ira_allocnos_num
4207 * sizeof (ira_allocno_t));
4208 /* Collect allocnos representing the spilled coalesced allocno
4209 sets. */
4210 num = collect_spilled_coalesced_allocnos (pseudo_regnos, n,
4211 spilled_coalesced_allocnos);
4212 if (flag_ira_share_spill_slots
4213 && coalesce_spill_slots (spilled_coalesced_allocnos, num))
4215 setup_coalesced_allocno_costs_and_nums (pseudo_regnos, n);
4216 qsort (pseudo_regnos, n, sizeof (int),
4217 coalesced_pseudo_reg_freq_compare);
4218 num = collect_spilled_coalesced_allocnos (pseudo_regnos, n,
4219 spilled_coalesced_allocnos);
4221 ira_free_bitmap (processed_coalesced_allocno_bitmap);
4222 allocno_coalesced_p = false;
4223 /* Assign stack slot numbers to spilled allocno sets, use smaller
4224 numbers for most frequently used coalesced allocnos. -1 is
4225 reserved for dynamic search of stack slots for pseudos spilled by
4226 the reload. */
4227 slot_num = 1;
4228 for (i = 0; i < num; i++)
4230 allocno = spilled_coalesced_allocnos[i];
4231 if (ALLOCNO_COALESCE_DATA (allocno)->first != allocno
4232 || ALLOCNO_HARD_REGNO (allocno) >= 0
4233 || ira_equiv_no_lvalue_p (ALLOCNO_REGNO (allocno)))
4234 continue;
4235 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4236 fprintf (ira_dump_file, " Slot %d (freq,size):", slot_num);
4237 slot_num++;
4238 for (a = ALLOCNO_COALESCE_DATA (allocno)->next;;
4239 a = ALLOCNO_COALESCE_DATA (a)->next)
4241 ira_assert (ALLOCNO_HARD_REGNO (a) < 0);
4242 ALLOCNO_HARD_REGNO (a) = -slot_num;
4243 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4245 machine_mode mode = wider_subreg_mode
4246 (PSEUDO_REGNO_MODE (ALLOCNO_REGNO (a)),
4247 reg_max_ref_mode[ALLOCNO_REGNO (a)]);
4248 fprintf (ira_dump_file, " a%dr%d(%d,",
4249 ALLOCNO_NUM (a), ALLOCNO_REGNO (a), ALLOCNO_FREQ (a));
4250 print_dec (GET_MODE_SIZE (mode), ira_dump_file, SIGNED);
4251 fprintf (ira_dump_file, ")\n");
4254 if (a == allocno)
4255 break;
4257 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4258 fprintf (ira_dump_file, "\n");
4260 ira_spilled_reg_stack_slots_num = slot_num - 1;
4261 ira_free (spilled_coalesced_allocnos);
4262 /* Sort regnos according the slot numbers. */
4263 regno_max_ref_mode = reg_max_ref_mode;
4264 qsort (pseudo_regnos, n, sizeof (int), coalesced_pseudo_reg_slot_compare);
4265 FOR_EACH_ALLOCNO (a, ai)
4266 ALLOCNO_ADD_DATA (a) = NULL;
4267 ira_free (allocno_coalesce_data);
4268 ira_free (regno_coalesced_allocno_num);
4269 ira_free (regno_coalesced_allocno_cost);
4274 /* This page contains code used by the reload pass to improve the
4275 final code. */
4277 /* The function is called from reload to mark changes in the
4278 allocation of REGNO made by the reload. Remember that reg_renumber
4279 reflects the change result. */
4280 void
4281 ira_mark_allocation_change (int regno)
4283 ira_allocno_t a = ira_regno_allocno_map[regno];
4284 int old_hard_regno, hard_regno, cost;
4285 enum reg_class aclass = ALLOCNO_CLASS (a);
4287 ira_assert (a != NULL);
4288 hard_regno = reg_renumber[regno];
4289 if ((old_hard_regno = ALLOCNO_HARD_REGNO (a)) == hard_regno)
4290 return;
4291 if (old_hard_regno < 0)
4292 cost = -ALLOCNO_MEMORY_COST (a);
4293 else
4295 ira_assert (ira_class_hard_reg_index[aclass][old_hard_regno] >= 0);
4296 cost = -(ALLOCNO_HARD_REG_COSTS (a) == NULL
4297 ? ALLOCNO_CLASS_COST (a)
4298 : ALLOCNO_HARD_REG_COSTS (a)
4299 [ira_class_hard_reg_index[aclass][old_hard_regno]]);
4300 update_costs_from_copies (a, false, false);
4302 ira_overall_cost -= cost;
4303 ALLOCNO_HARD_REGNO (a) = hard_regno;
4304 if (hard_regno < 0)
4306 ALLOCNO_HARD_REGNO (a) = -1;
4307 cost += ALLOCNO_MEMORY_COST (a);
4309 else if (ira_class_hard_reg_index[aclass][hard_regno] >= 0)
4311 cost += (ALLOCNO_HARD_REG_COSTS (a) == NULL
4312 ? ALLOCNO_CLASS_COST (a)
4313 : ALLOCNO_HARD_REG_COSTS (a)
4314 [ira_class_hard_reg_index[aclass][hard_regno]]);
4315 update_costs_from_copies (a, true, false);
4317 else
4318 /* Reload changed class of the allocno. */
4319 cost = 0;
4320 ira_overall_cost += cost;
4323 /* This function is called when reload deletes memory-memory move. In
4324 this case we marks that the allocation of the corresponding
4325 allocnos should be not changed in future. Otherwise we risk to get
4326 a wrong code. */
4327 void
4328 ira_mark_memory_move_deletion (int dst_regno, int src_regno)
4330 ira_allocno_t dst = ira_regno_allocno_map[dst_regno];
4331 ira_allocno_t src = ira_regno_allocno_map[src_regno];
4333 ira_assert (dst != NULL && src != NULL
4334 && ALLOCNO_HARD_REGNO (dst) < 0
4335 && ALLOCNO_HARD_REGNO (src) < 0);
4336 ALLOCNO_DONT_REASSIGN_P (dst) = true;
4337 ALLOCNO_DONT_REASSIGN_P (src) = true;
4340 /* Try to assign a hard register (except for FORBIDDEN_REGS) to
4341 allocno A and return TRUE in the case of success. */
4342 static bool
4343 allocno_reload_assign (ira_allocno_t a, HARD_REG_SET forbidden_regs)
4345 int hard_regno;
4346 enum reg_class aclass;
4347 int regno = ALLOCNO_REGNO (a);
4348 HARD_REG_SET saved[2];
4349 int i, n;
4351 n = ALLOCNO_NUM_OBJECTS (a);
4352 for (i = 0; i < n; i++)
4354 ira_object_t obj = ALLOCNO_OBJECT (a, i);
4355 COPY_HARD_REG_SET (saved[i], OBJECT_TOTAL_CONFLICT_HARD_REGS (obj));
4356 IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), forbidden_regs);
4357 if (! flag_caller_saves && ALLOCNO_CALLS_CROSSED_NUM (a) != 0)
4358 IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
4359 call_used_reg_set);
4361 ALLOCNO_ASSIGNED_P (a) = false;
4362 aclass = ALLOCNO_CLASS (a);
4363 update_curr_costs (a);
4364 assign_hard_reg (a, true);
4365 hard_regno = ALLOCNO_HARD_REGNO (a);
4366 reg_renumber[regno] = hard_regno;
4367 if (hard_regno < 0)
4368 ALLOCNO_HARD_REGNO (a) = -1;
4369 else
4371 ira_assert (ira_class_hard_reg_index[aclass][hard_regno] >= 0);
4372 ira_overall_cost
4373 -= (ALLOCNO_MEMORY_COST (a)
4374 - (ALLOCNO_HARD_REG_COSTS (a) == NULL
4375 ? ALLOCNO_CLASS_COST (a)
4376 : ALLOCNO_HARD_REG_COSTS (a)[ira_class_hard_reg_index
4377 [aclass][hard_regno]]));
4378 if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0
4379 && ira_hard_reg_set_intersection_p (hard_regno, ALLOCNO_MODE (a),
4380 call_used_reg_set))
4382 ira_assert (flag_caller_saves);
4383 caller_save_needed = 1;
4387 /* If we found a hard register, modify the RTL for the pseudo
4388 register to show the hard register, and mark the pseudo register
4389 live. */
4390 if (reg_renumber[regno] >= 0)
4392 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4393 fprintf (ira_dump_file, ": reassign to %d\n", reg_renumber[regno]);
4394 SET_REGNO (regno_reg_rtx[regno], reg_renumber[regno]);
4395 mark_home_live (regno);
4397 else if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4398 fprintf (ira_dump_file, "\n");
4399 for (i = 0; i < n; i++)
4401 ira_object_t obj = ALLOCNO_OBJECT (a, i);
4402 COPY_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), saved[i]);
4404 return reg_renumber[regno] >= 0;
4407 /* Sort pseudos according their usage frequencies (putting most
4408 frequently ones first). */
4409 static int
4410 pseudo_reg_compare (const void *v1p, const void *v2p)
4412 int regno1 = *(const int *) v1p;
4413 int regno2 = *(const int *) v2p;
4414 int diff;
4416 if ((diff = REG_FREQ (regno2) - REG_FREQ (regno1)) != 0)
4417 return diff;
4418 return regno1 - regno2;
4421 /* Try to allocate hard registers to SPILLED_PSEUDO_REGS (there are
4422 NUM of them) or spilled pseudos conflicting with pseudos in
4423 SPILLED_PSEUDO_REGS. Return TRUE and update SPILLED, if the
4424 allocation has been changed. The function doesn't use
4425 BAD_SPILL_REGS and hard registers in PSEUDO_FORBIDDEN_REGS and
4426 PSEUDO_PREVIOUS_REGS for the corresponding pseudos. The function
4427 is called by the reload pass at the end of each reload
4428 iteration. */
4429 bool
4430 ira_reassign_pseudos (int *spilled_pseudo_regs, int num,
4431 HARD_REG_SET bad_spill_regs,
4432 HARD_REG_SET *pseudo_forbidden_regs,
4433 HARD_REG_SET *pseudo_previous_regs,
4434 bitmap spilled)
4436 int i, n, regno;
4437 bool changed_p;
4438 ira_allocno_t a;
4439 HARD_REG_SET forbidden_regs;
4440 bitmap temp = BITMAP_ALLOC (NULL);
4442 /* Add pseudos which conflict with pseudos already in
4443 SPILLED_PSEUDO_REGS to SPILLED_PSEUDO_REGS. This is preferable
4444 to allocating in two steps as some of the conflicts might have
4445 a higher priority than the pseudos passed in SPILLED_PSEUDO_REGS. */
4446 for (i = 0; i < num; i++)
4447 bitmap_set_bit (temp, spilled_pseudo_regs[i]);
4449 for (i = 0, n = num; i < n; i++)
4451 int nr, j;
4452 int regno = spilled_pseudo_regs[i];
4453 bitmap_set_bit (temp, regno);
4455 a = ira_regno_allocno_map[regno];
4456 nr = ALLOCNO_NUM_OBJECTS (a);
4457 for (j = 0; j < nr; j++)
4459 ira_object_t conflict_obj;
4460 ira_object_t obj = ALLOCNO_OBJECT (a, j);
4461 ira_object_conflict_iterator oci;
4463 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
4465 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
4466 if (ALLOCNO_HARD_REGNO (conflict_a) < 0
4467 && ! ALLOCNO_DONT_REASSIGN_P (conflict_a)
4468 && bitmap_set_bit (temp, ALLOCNO_REGNO (conflict_a)))
4470 spilled_pseudo_regs[num++] = ALLOCNO_REGNO (conflict_a);
4471 /* ?!? This seems wrong. */
4472 bitmap_set_bit (consideration_allocno_bitmap,
4473 ALLOCNO_NUM (conflict_a));
4479 if (num > 1)
4480 qsort (spilled_pseudo_regs, num, sizeof (int), pseudo_reg_compare);
4481 changed_p = false;
4482 /* Try to assign hard registers to pseudos from
4483 SPILLED_PSEUDO_REGS. */
4484 for (i = 0; i < num; i++)
4486 regno = spilled_pseudo_regs[i];
4487 COPY_HARD_REG_SET (forbidden_regs, bad_spill_regs);
4488 IOR_HARD_REG_SET (forbidden_regs, pseudo_forbidden_regs[regno]);
4489 IOR_HARD_REG_SET (forbidden_regs, pseudo_previous_regs[regno]);
4490 gcc_assert (reg_renumber[regno] < 0);
4491 a = ira_regno_allocno_map[regno];
4492 ira_mark_allocation_change (regno);
4493 ira_assert (reg_renumber[regno] < 0);
4494 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4495 fprintf (ira_dump_file,
4496 " Try Assign %d(a%d), cost=%d", regno, ALLOCNO_NUM (a),
4497 ALLOCNO_MEMORY_COST (a)
4498 - ALLOCNO_CLASS_COST (a));
4499 allocno_reload_assign (a, forbidden_regs);
4500 if (reg_renumber[regno] >= 0)
4502 CLEAR_REGNO_REG_SET (spilled, regno);
4503 changed_p = true;
4506 BITMAP_FREE (temp);
4507 return changed_p;
4510 /* The function is called by reload and returns already allocated
4511 stack slot (if any) for REGNO with given INHERENT_SIZE and
4512 TOTAL_SIZE. In the case of failure to find a slot which can be
4513 used for REGNO, the function returns NULL. */
4515 ira_reuse_stack_slot (int regno, poly_uint64 inherent_size,
4516 poly_uint64 total_size)
4518 unsigned int i;
4519 int slot_num, best_slot_num;
4520 int cost, best_cost;
4521 ira_copy_t cp, next_cp;
4522 ira_allocno_t another_allocno, allocno = ira_regno_allocno_map[regno];
4523 rtx x;
4524 bitmap_iterator bi;
4525 struct ira_spilled_reg_stack_slot *slot = NULL;
4527 ira_assert (! ira_use_lra_p);
4529 ira_assert (known_eq (inherent_size, PSEUDO_REGNO_BYTES (regno))
4530 && known_le (inherent_size, total_size)
4531 && ALLOCNO_HARD_REGNO (allocno) < 0);
4532 if (! flag_ira_share_spill_slots)
4533 return NULL_RTX;
4534 slot_num = -ALLOCNO_HARD_REGNO (allocno) - 2;
4535 if (slot_num != -1)
4537 slot = &ira_spilled_reg_stack_slots[slot_num];
4538 x = slot->mem;
4540 else
4542 best_cost = best_slot_num = -1;
4543 x = NULL_RTX;
4544 /* It means that the pseudo was spilled in the reload pass, try
4545 to reuse a slot. */
4546 for (slot_num = 0;
4547 slot_num < ira_spilled_reg_stack_slots_num;
4548 slot_num++)
4550 slot = &ira_spilled_reg_stack_slots[slot_num];
4551 if (slot->mem == NULL_RTX)
4552 continue;
4553 if (maybe_lt (slot->width, total_size)
4554 || maybe_lt (GET_MODE_SIZE (GET_MODE (slot->mem)), inherent_size))
4555 continue;
4557 EXECUTE_IF_SET_IN_BITMAP (&slot->spilled_regs,
4558 FIRST_PSEUDO_REGISTER, i, bi)
4560 another_allocno = ira_regno_allocno_map[i];
4561 if (allocnos_conflict_by_live_ranges_p (allocno,
4562 another_allocno))
4563 goto cont;
4565 for (cost = 0, cp = ALLOCNO_COPIES (allocno);
4566 cp != NULL;
4567 cp = next_cp)
4569 if (cp->first == allocno)
4571 next_cp = cp->next_first_allocno_copy;
4572 another_allocno = cp->second;
4574 else if (cp->second == allocno)
4576 next_cp = cp->next_second_allocno_copy;
4577 another_allocno = cp->first;
4579 else
4580 gcc_unreachable ();
4581 if (cp->insn == NULL_RTX)
4582 continue;
4583 if (bitmap_bit_p (&slot->spilled_regs,
4584 ALLOCNO_REGNO (another_allocno)))
4585 cost += cp->freq;
4587 if (cost > best_cost)
4589 best_cost = cost;
4590 best_slot_num = slot_num;
4592 cont:
4595 if (best_cost >= 0)
4597 slot_num = best_slot_num;
4598 slot = &ira_spilled_reg_stack_slots[slot_num];
4599 SET_REGNO_REG_SET (&slot->spilled_regs, regno);
4600 x = slot->mem;
4601 ALLOCNO_HARD_REGNO (allocno) = -slot_num - 2;
4604 if (x != NULL_RTX)
4606 ira_assert (known_ge (slot->width, total_size));
4607 #ifdef ENABLE_IRA_CHECKING
4608 EXECUTE_IF_SET_IN_BITMAP (&slot->spilled_regs,
4609 FIRST_PSEUDO_REGISTER, i, bi)
4611 ira_assert (! conflict_by_live_ranges_p (regno, i));
4613 #endif
4614 SET_REGNO_REG_SET (&slot->spilled_regs, regno);
4615 if (internal_flag_ira_verbose > 3 && ira_dump_file)
4617 fprintf (ira_dump_file, " Assigning %d(freq=%d) slot %d of",
4618 regno, REG_FREQ (regno), slot_num);
4619 EXECUTE_IF_SET_IN_BITMAP (&slot->spilled_regs,
4620 FIRST_PSEUDO_REGISTER, i, bi)
4622 if ((unsigned) regno != i)
4623 fprintf (ira_dump_file, " %d", i);
4625 fprintf (ira_dump_file, "\n");
4628 return x;
4631 /* This is called by reload every time a new stack slot X with
4632 TOTAL_SIZE was allocated for REGNO. We store this info for
4633 subsequent ira_reuse_stack_slot calls. */
4634 void
4635 ira_mark_new_stack_slot (rtx x, int regno, poly_uint64 total_size)
4637 struct ira_spilled_reg_stack_slot *slot;
4638 int slot_num;
4639 ira_allocno_t allocno;
4641 ira_assert (! ira_use_lra_p);
4643 ira_assert (known_le (PSEUDO_REGNO_BYTES (regno), total_size));
4644 allocno = ira_regno_allocno_map[regno];
4645 slot_num = -ALLOCNO_HARD_REGNO (allocno) - 2;
4646 if (slot_num == -1)
4648 slot_num = ira_spilled_reg_stack_slots_num++;
4649 ALLOCNO_HARD_REGNO (allocno) = -slot_num - 2;
4651 slot = &ira_spilled_reg_stack_slots[slot_num];
4652 INIT_REG_SET (&slot->spilled_regs);
4653 SET_REGNO_REG_SET (&slot->spilled_regs, regno);
4654 slot->mem = x;
4655 slot->width = total_size;
4656 if (internal_flag_ira_verbose > 3 && ira_dump_file)
4657 fprintf (ira_dump_file, " Assigning %d(freq=%d) a new slot %d\n",
4658 regno, REG_FREQ (regno), slot_num);
4662 /* Return spill cost for pseudo-registers whose numbers are in array
4663 REGNOS (with a negative number as an end marker) for reload with
4664 given IN and OUT for INSN. Return also number points (through
4665 EXCESS_PRESSURE_LIVE_LENGTH) where the pseudo-register lives and
4666 the register pressure is high, number of references of the
4667 pseudo-registers (through NREFS), number of callee-clobbered
4668 hard-registers occupied by the pseudo-registers (through
4669 CALL_USED_COUNT), and the first hard regno occupied by the
4670 pseudo-registers (through FIRST_HARD_REGNO). */
4671 static int
4672 calculate_spill_cost (int *regnos, rtx in, rtx out, rtx_insn *insn,
4673 int *excess_pressure_live_length,
4674 int *nrefs, int *call_used_count, int *first_hard_regno)
4676 int i, cost, regno, hard_regno, j, count, saved_cost, nregs;
4677 bool in_p, out_p;
4678 int length;
4679 ira_allocno_t a;
4681 *nrefs = 0;
4682 for (length = count = cost = i = 0;; i++)
4684 regno = regnos[i];
4685 if (regno < 0)
4686 break;
4687 *nrefs += REG_N_REFS (regno);
4688 hard_regno = reg_renumber[regno];
4689 ira_assert (hard_regno >= 0);
4690 a = ira_regno_allocno_map[regno];
4691 length += ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a) / ALLOCNO_NUM_OBJECTS (a);
4692 cost += ALLOCNO_MEMORY_COST (a) - ALLOCNO_CLASS_COST (a);
4693 nregs = hard_regno_nregs (hard_regno, ALLOCNO_MODE (a));
4694 for (j = 0; j < nregs; j++)
4695 if (! TEST_HARD_REG_BIT (call_used_reg_set, hard_regno + j))
4696 break;
4697 if (j == nregs)
4698 count++;
4699 in_p = in && REG_P (in) && (int) REGNO (in) == hard_regno;
4700 out_p = out && REG_P (out) && (int) REGNO (out) == hard_regno;
4701 if ((in_p || out_p)
4702 && find_regno_note (insn, REG_DEAD, hard_regno) != NULL_RTX)
4704 saved_cost = 0;
4705 if (in_p)
4706 saved_cost += ira_memory_move_cost
4707 [ALLOCNO_MODE (a)][ALLOCNO_CLASS (a)][1];
4708 if (out_p)
4709 saved_cost
4710 += ira_memory_move_cost
4711 [ALLOCNO_MODE (a)][ALLOCNO_CLASS (a)][0];
4712 cost -= REG_FREQ_FROM_BB (BLOCK_FOR_INSN (insn)) * saved_cost;
4715 *excess_pressure_live_length = length;
4716 *call_used_count = count;
4717 hard_regno = -1;
4718 if (regnos[0] >= 0)
4720 hard_regno = reg_renumber[regnos[0]];
4722 *first_hard_regno = hard_regno;
4723 return cost;
4726 /* Return TRUE if spilling pseudo-registers whose numbers are in array
4727 REGNOS is better than spilling pseudo-registers with numbers in
4728 OTHER_REGNOS for reload with given IN and OUT for INSN. The
4729 function used by the reload pass to make better register spilling
4730 decisions. */
4731 bool
4732 ira_better_spill_reload_regno_p (int *regnos, int *other_regnos,
4733 rtx in, rtx out, rtx_insn *insn)
4735 int cost, other_cost;
4736 int length, other_length;
4737 int nrefs, other_nrefs;
4738 int call_used_count, other_call_used_count;
4739 int hard_regno, other_hard_regno;
4741 cost = calculate_spill_cost (regnos, in, out, insn,
4742 &length, &nrefs, &call_used_count, &hard_regno);
4743 other_cost = calculate_spill_cost (other_regnos, in, out, insn,
4744 &other_length, &other_nrefs,
4745 &other_call_used_count,
4746 &other_hard_regno);
4747 if (nrefs == 0 && other_nrefs != 0)
4748 return true;
4749 if (nrefs != 0 && other_nrefs == 0)
4750 return false;
4751 if (cost != other_cost)
4752 return cost < other_cost;
4753 if (length != other_length)
4754 return length > other_length;
4755 #ifdef REG_ALLOC_ORDER
4756 if (hard_regno >= 0 && other_hard_regno >= 0)
4757 return (inv_reg_alloc_order[hard_regno]
4758 < inv_reg_alloc_order[other_hard_regno]);
4759 #else
4760 if (call_used_count != other_call_used_count)
4761 return call_used_count > other_call_used_count;
4762 #endif
4763 return false;
4768 /* Allocate and initialize data necessary for assign_hard_reg. */
4769 void
4770 ira_initiate_assign (void)
4772 sorted_allocnos
4773 = (ira_allocno_t *) ira_allocate (sizeof (ira_allocno_t)
4774 * ira_allocnos_num);
4775 consideration_allocno_bitmap = ira_allocate_bitmap ();
4776 initiate_cost_update ();
4777 allocno_priorities = (int *) ira_allocate (sizeof (int) * ira_allocnos_num);
4778 sorted_copies = (ira_copy_t *) ira_allocate (ira_copies_num
4779 * sizeof (ira_copy_t));
4782 /* Deallocate data used by assign_hard_reg. */
4783 void
4784 ira_finish_assign (void)
4786 ira_free (sorted_allocnos);
4787 ira_free_bitmap (consideration_allocno_bitmap);
4788 finish_cost_update ();
4789 ira_free (allocno_priorities);
4790 ira_free (sorted_copies);
4795 /* Entry function doing color-based register allocation. */
4796 static void
4797 color (void)
4799 allocno_stack_vec.create (ira_allocnos_num);
4800 memset (allocated_hardreg_p, 0, sizeof (allocated_hardreg_p));
4801 ira_initiate_assign ();
4802 do_coloring ();
4803 ira_finish_assign ();
4804 allocno_stack_vec.release ();
4805 move_spill_restore ();
4810 /* This page contains a simple register allocator without usage of
4811 allocno conflicts. This is used for fast allocation for -O0. */
4813 /* Do register allocation by not using allocno conflicts. It uses
4814 only allocno live ranges. The algorithm is close to Chow's
4815 priority coloring. */
4816 static void
4817 fast_allocation (void)
4819 int i, j, k, num, class_size, hard_regno;
4820 #ifdef STACK_REGS
4821 bool no_stack_reg_p;
4822 #endif
4823 enum reg_class aclass;
4824 machine_mode mode;
4825 ira_allocno_t a;
4826 ira_allocno_iterator ai;
4827 live_range_t r;
4828 HARD_REG_SET conflict_hard_regs, *used_hard_regs;
4830 sorted_allocnos = (ira_allocno_t *) ira_allocate (sizeof (ira_allocno_t)
4831 * ira_allocnos_num);
4832 num = 0;
4833 FOR_EACH_ALLOCNO (a, ai)
4834 sorted_allocnos[num++] = a;
4835 allocno_priorities = (int *) ira_allocate (sizeof (int) * ira_allocnos_num);
4836 setup_allocno_priorities (sorted_allocnos, num);
4837 used_hard_regs = (HARD_REG_SET *) ira_allocate (sizeof (HARD_REG_SET)
4838 * ira_max_point);
4839 for (i = 0; i < ira_max_point; i++)
4840 CLEAR_HARD_REG_SET (used_hard_regs[i]);
4841 qsort (sorted_allocnos, num, sizeof (ira_allocno_t),
4842 allocno_priority_compare_func);
4843 for (i = 0; i < num; i++)
4845 int nr, l;
4847 a = sorted_allocnos[i];
4848 nr = ALLOCNO_NUM_OBJECTS (a);
4849 CLEAR_HARD_REG_SET (conflict_hard_regs);
4850 for (l = 0; l < nr; l++)
4852 ira_object_t obj = ALLOCNO_OBJECT (a, l);
4853 IOR_HARD_REG_SET (conflict_hard_regs,
4854 OBJECT_CONFLICT_HARD_REGS (obj));
4855 for (r = OBJECT_LIVE_RANGES (obj); r != NULL; r = r->next)
4856 for (j = r->start; j <= r->finish; j++)
4857 IOR_HARD_REG_SET (conflict_hard_regs, used_hard_regs[j]);
4859 aclass = ALLOCNO_CLASS (a);
4860 ALLOCNO_ASSIGNED_P (a) = true;
4861 ALLOCNO_HARD_REGNO (a) = -1;
4862 if (hard_reg_set_subset_p (reg_class_contents[aclass],
4863 conflict_hard_regs))
4864 continue;
4865 mode = ALLOCNO_MODE (a);
4866 #ifdef STACK_REGS
4867 no_stack_reg_p = ALLOCNO_NO_STACK_REG_P (a);
4868 #endif
4869 class_size = ira_class_hard_regs_num[aclass];
4870 for (j = 0; j < class_size; j++)
4872 hard_regno = ira_class_hard_regs[aclass][j];
4873 #ifdef STACK_REGS
4874 if (no_stack_reg_p && FIRST_STACK_REG <= hard_regno
4875 && hard_regno <= LAST_STACK_REG)
4876 continue;
4877 #endif
4878 if (ira_hard_reg_set_intersection_p (hard_regno, mode, conflict_hard_regs)
4879 || (TEST_HARD_REG_BIT
4880 (ira_prohibited_class_mode_regs[aclass][mode], hard_regno)))
4881 continue;
4882 ALLOCNO_HARD_REGNO (a) = hard_regno;
4883 for (l = 0; l < nr; l++)
4885 ira_object_t obj = ALLOCNO_OBJECT (a, l);
4886 for (r = OBJECT_LIVE_RANGES (obj); r != NULL; r = r->next)
4887 for (k = r->start; k <= r->finish; k++)
4888 IOR_HARD_REG_SET (used_hard_regs[k],
4889 ira_reg_mode_hard_regset[hard_regno][mode]);
4891 break;
4894 ira_free (sorted_allocnos);
4895 ira_free (used_hard_regs);
4896 ira_free (allocno_priorities);
4897 if (internal_flag_ira_verbose > 1 && ira_dump_file != NULL)
4898 ira_print_disposition (ira_dump_file);
4903 /* Entry function doing coloring. */
4904 void
4905 ira_color (void)
4907 ira_allocno_t a;
4908 ira_allocno_iterator ai;
4910 /* Setup updated costs. */
4911 FOR_EACH_ALLOCNO (a, ai)
4913 ALLOCNO_UPDATED_MEMORY_COST (a) = ALLOCNO_MEMORY_COST (a);
4914 ALLOCNO_UPDATED_CLASS_COST (a) = ALLOCNO_CLASS_COST (a);
4916 if (ira_conflicts_p)
4917 color ();
4918 else
4919 fast_allocation ();