* lib/ubsan-dg.exp (check_effective_target_fsanitize_undefined):
[official-gcc.git] / gcc / ira-color.c
blob39387c84ed10ad90ccdc983a7d40d4ee378667b6
1 /* IRA allocation based on graph coloring.
2 Copyright (C) 2006-2014 Free Software Foundation, Inc.
3 Contributed by Vladimir Makarov <vmakarov@redhat.com>.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "rtl.h"
26 #include "tm_p.h"
27 #include "target.h"
28 #include "regs.h"
29 #include "flags.h"
30 #include "sbitmap.h"
31 #include "bitmap.h"
32 #include "hash-table.h"
33 #include "hard-reg-set.h"
34 #include "predict.h"
35 #include "vec.h"
36 #include "hashtab.h"
37 #include "hash-set.h"
38 #include "machmode.h"
39 #include "input.h"
40 #include "function.h"
41 #include "dominance.h"
42 #include "cfg.h"
43 #include "basic-block.h"
44 #include "expr.h"
45 #include "diagnostic-core.h"
46 #include "reload.h"
47 #include "params.h"
48 #include "df.h"
49 #include "ira-int.h"
51 typedef struct allocno_hard_regs *allocno_hard_regs_t;
53 /* The structure contains information about hard registers can be
54 assigned to allocnos. Usually it is allocno profitable hard
55 registers but in some cases this set can be a bit different. Major
56 reason of the difference is a requirement to use hard register sets
57 that form a tree or a forest (set of trees), i.e. hard register set
58 of a node should contain hard register sets of its subnodes. */
59 struct allocno_hard_regs
61 /* Hard registers can be assigned to an allocno. */
62 HARD_REG_SET set;
63 /* Overall (spilling) cost of all allocnos with given register
64 set. */
65 int64_t cost;
68 typedef struct allocno_hard_regs_node *allocno_hard_regs_node_t;
70 /* A node representing allocno hard registers. Such nodes form a
71 forest (set of trees). Each subnode of given node in the forest
72 refers for hard register set (usually allocno profitable hard
73 register set) which is a subset of one referred from given
74 node. */
75 struct allocno_hard_regs_node
77 /* Set up number of the node in preorder traversing of the forest. */
78 int preorder_num;
79 /* Used for different calculation like finding conflict size of an
80 allocno. */
81 int check;
82 /* Used for calculation of conflict size of an allocno. The
83 conflict size of the allocno is maximal number of given allocno
84 hard registers needed for allocation of the conflicting allocnos.
85 Given allocno is trivially colored if this number plus the number
86 of hard registers needed for given allocno is not greater than
87 the number of given allocno hard register set. */
88 int conflict_size;
89 /* The number of hard registers given by member hard_regs. */
90 int hard_regs_num;
91 /* The following member is used to form the final forest. */
92 bool used_p;
93 /* Pointer to the corresponding profitable hard registers. */
94 allocno_hard_regs_t hard_regs;
95 /* Parent, first subnode, previous and next node with the same
96 parent in the forest. */
97 allocno_hard_regs_node_t parent, first, prev, next;
100 /* Info about changing hard reg costs of an allocno. */
101 struct update_cost_record
103 /* Hard regno for which we changed the cost. */
104 int hard_regno;
105 /* Divisor used when we changed the cost of HARD_REGNO. */
106 int divisor;
107 /* Next record for given allocno. */
108 struct update_cost_record *next;
111 /* To decrease footprint of ira_allocno structure we store all data
112 needed only for coloring in the following structure. */
113 struct allocno_color_data
115 /* TRUE value means that the allocno was not removed yet from the
116 conflicting graph during coloring. */
117 unsigned int in_graph_p : 1;
118 /* TRUE if it is put on the stack to make other allocnos
119 colorable. */
120 unsigned int may_be_spilled_p : 1;
121 /* TRUE if the allocno is trivially colorable. */
122 unsigned int colorable_p : 1;
123 /* Number of hard registers of the allocno class really
124 available for the allocno allocation. It is number of the
125 profitable hard regs. */
126 int available_regs_num;
127 /* Allocnos in a bucket (used in coloring) chained by the following
128 two members. */
129 ira_allocno_t next_bucket_allocno;
130 ira_allocno_t prev_bucket_allocno;
131 /* Used for temporary purposes. */
132 int temp;
133 /* Used to exclude repeated processing. */
134 int last_process;
135 /* Profitable hard regs available for this pseudo allocation. It
136 means that the set excludes unavailable hard regs and hard regs
137 conflicting with given pseudo. They should be of the allocno
138 class. */
139 HARD_REG_SET profitable_hard_regs;
140 /* The allocno hard registers node. */
141 allocno_hard_regs_node_t hard_regs_node;
142 /* Array of structures allocno_hard_regs_subnode representing
143 given allocno hard registers node (the 1st element in the array)
144 and all its subnodes in the tree (forest) of allocno hard
145 register nodes (see comments above). */
146 int hard_regs_subnodes_start;
147 /* The length of the previous array. */
148 int hard_regs_subnodes_num;
149 /* Records about updating allocno hard reg costs from copies. If
150 the allocno did not get expected hard register, these records are
151 used to restore original hard reg costs of allocnos connected to
152 this allocno by copies. */
153 struct update_cost_record *update_cost_records;
154 /* Threads. We collect allocnos connected by copies into threads
155 and try to assign hard regs to allocnos by threads. */
156 /* Allocno representing all thread. */
157 ira_allocno_t first_thread_allocno;
158 /* Allocnos in thread forms a cycle list through the following
159 member. */
160 ira_allocno_t next_thread_allocno;
161 /* All thread frequency. Defined only for first thread allocno. */
162 int thread_freq;
165 /* See above. */
166 typedef struct allocno_color_data *allocno_color_data_t;
168 /* Container for storing allocno data concerning coloring. */
169 static allocno_color_data_t allocno_color_data;
171 /* Macro to access the data concerning coloring. */
172 #define ALLOCNO_COLOR_DATA(a) ((allocno_color_data_t) ALLOCNO_ADD_DATA (a))
174 /* Used for finding allocno colorability to exclude repeated allocno
175 processing and for updating preferencing to exclude repeated
176 allocno processing during assignment. */
177 static int curr_allocno_process;
179 /* This file contains code for regional graph coloring, spill/restore
180 code placement optimization, and code helping the reload pass to do
181 a better job. */
183 /* Bitmap of allocnos which should be colored. */
184 static bitmap coloring_allocno_bitmap;
186 /* Bitmap of allocnos which should be taken into account during
187 coloring. In general case it contains allocnos from
188 coloring_allocno_bitmap plus other already colored conflicting
189 allocnos. */
190 static bitmap consideration_allocno_bitmap;
192 /* All allocnos sorted according their priorities. */
193 static ira_allocno_t *sorted_allocnos;
195 /* Vec representing the stack of allocnos used during coloring. */
196 static vec<ira_allocno_t> allocno_stack_vec;
198 /* Helper for qsort comparison callbacks - return a positive integer if
199 X > Y, or a negative value otherwise. Use a conditional expression
200 instead of a difference computation to insulate from possible overflow
201 issues, e.g. X - Y < 0 for some X > 0 and Y < 0. */
202 #define SORTGT(x,y) (((x) > (y)) ? 1 : -1)
206 /* Definition of vector of allocno hard registers. */
208 /* Vector of unique allocno hard registers. */
209 static vec<allocno_hard_regs_t> allocno_hard_regs_vec;
211 struct allocno_hard_regs_hasher : typed_noop_remove <allocno_hard_regs>
213 typedef allocno_hard_regs value_type;
214 typedef allocno_hard_regs compare_type;
215 static inline hashval_t hash (const value_type *);
216 static inline bool equal (const value_type *, const compare_type *);
219 /* Returns hash value for allocno hard registers V. */
220 inline hashval_t
221 allocno_hard_regs_hasher::hash (const value_type *hv)
223 return iterative_hash (&hv->set, sizeof (HARD_REG_SET), 0);
226 /* Compares allocno hard registers V1 and V2. */
227 inline bool
228 allocno_hard_regs_hasher::equal (const value_type *hv1, const compare_type *hv2)
230 return hard_reg_set_equal_p (hv1->set, hv2->set);
233 /* Hash table of unique allocno hard registers. */
234 static hash_table<allocno_hard_regs_hasher> *allocno_hard_regs_htab;
236 /* Return allocno hard registers in the hash table equal to HV. */
237 static allocno_hard_regs_t
238 find_hard_regs (allocno_hard_regs_t hv)
240 return allocno_hard_regs_htab->find (hv);
243 /* Insert allocno hard registers HV in the hash table (if it is not
244 there yet) and return the value which in the table. */
245 static allocno_hard_regs_t
246 insert_hard_regs (allocno_hard_regs_t hv)
248 allocno_hard_regs **slot = allocno_hard_regs_htab->find_slot (hv, INSERT);
250 if (*slot == NULL)
251 *slot = hv;
252 return *slot;
255 /* Initialize data concerning allocno hard registers. */
256 static void
257 init_allocno_hard_regs (void)
259 allocno_hard_regs_vec.create (200);
260 allocno_hard_regs_htab
261 = new hash_table<allocno_hard_regs_hasher> (200);
264 /* Add (or update info about) allocno hard registers with SET and
265 COST. */
266 static allocno_hard_regs_t
267 add_allocno_hard_regs (HARD_REG_SET set, int64_t cost)
269 struct allocno_hard_regs temp;
270 allocno_hard_regs_t hv;
272 gcc_assert (! hard_reg_set_empty_p (set));
273 COPY_HARD_REG_SET (temp.set, set);
274 if ((hv = find_hard_regs (&temp)) != NULL)
275 hv->cost += cost;
276 else
278 hv = ((struct allocno_hard_regs *)
279 ira_allocate (sizeof (struct allocno_hard_regs)));
280 COPY_HARD_REG_SET (hv->set, set);
281 hv->cost = cost;
282 allocno_hard_regs_vec.safe_push (hv);
283 insert_hard_regs (hv);
285 return hv;
288 /* Finalize data concerning allocno hard registers. */
289 static void
290 finish_allocno_hard_regs (void)
292 int i;
293 allocno_hard_regs_t hv;
295 for (i = 0;
296 allocno_hard_regs_vec.iterate (i, &hv);
297 i++)
298 ira_free (hv);
299 delete allocno_hard_regs_htab;
300 allocno_hard_regs_htab = NULL;
301 allocno_hard_regs_vec.release ();
304 /* Sort hard regs according to their frequency of usage. */
305 static int
306 allocno_hard_regs_compare (const void *v1p, const void *v2p)
308 allocno_hard_regs_t hv1 = *(const allocno_hard_regs_t *) v1p;
309 allocno_hard_regs_t hv2 = *(const allocno_hard_regs_t *) v2p;
311 if (hv2->cost > hv1->cost)
312 return 1;
313 else if (hv2->cost < hv1->cost)
314 return -1;
315 else
316 return 0;
321 /* Used for finding a common ancestor of two allocno hard registers
322 nodes in the forest. We use the current value of
323 'node_check_tick' to mark all nodes from one node to the top and
324 then walking up from another node until we find a marked node.
326 It is also used to figure out allocno colorability as a mark that
327 we already reset value of member 'conflict_size' for the forest
328 node corresponding to the processed allocno. */
329 static int node_check_tick;
331 /* Roots of the forest containing hard register sets can be assigned
332 to allocnos. */
333 static allocno_hard_regs_node_t hard_regs_roots;
335 /* Definition of vector of allocno hard register nodes. */
337 /* Vector used to create the forest. */
338 static vec<allocno_hard_regs_node_t> hard_regs_node_vec;
340 /* Create and return allocno hard registers node containing allocno
341 hard registers HV. */
342 static allocno_hard_regs_node_t
343 create_new_allocno_hard_regs_node (allocno_hard_regs_t hv)
345 allocno_hard_regs_node_t new_node;
347 new_node = ((struct allocno_hard_regs_node *)
348 ira_allocate (sizeof (struct allocno_hard_regs_node)));
349 new_node->check = 0;
350 new_node->hard_regs = hv;
351 new_node->hard_regs_num = hard_reg_set_size (hv->set);
352 new_node->first = NULL;
353 new_node->used_p = false;
354 return new_node;
357 /* Add allocno hard registers node NEW_NODE to the forest on its level
358 given by ROOTS. */
359 static void
360 add_new_allocno_hard_regs_node_to_forest (allocno_hard_regs_node_t *roots,
361 allocno_hard_regs_node_t new_node)
363 new_node->next = *roots;
364 if (new_node->next != NULL)
365 new_node->next->prev = new_node;
366 new_node->prev = NULL;
367 *roots = new_node;
370 /* Add allocno hard registers HV (or its best approximation if it is
371 not possible) to the forest on its level given by ROOTS. */
372 static void
373 add_allocno_hard_regs_to_forest (allocno_hard_regs_node_t *roots,
374 allocno_hard_regs_t hv)
376 unsigned int i, start;
377 allocno_hard_regs_node_t node, prev, new_node;
378 HARD_REG_SET temp_set;
379 allocno_hard_regs_t hv2;
381 start = hard_regs_node_vec.length ();
382 for (node = *roots; node != NULL; node = node->next)
384 if (hard_reg_set_equal_p (hv->set, node->hard_regs->set))
385 return;
386 if (hard_reg_set_subset_p (hv->set, node->hard_regs->set))
388 add_allocno_hard_regs_to_forest (&node->first, hv);
389 return;
391 if (hard_reg_set_subset_p (node->hard_regs->set, hv->set))
392 hard_regs_node_vec.safe_push (node);
393 else if (hard_reg_set_intersect_p (hv->set, node->hard_regs->set))
395 COPY_HARD_REG_SET (temp_set, hv->set);
396 AND_HARD_REG_SET (temp_set, node->hard_regs->set);
397 hv2 = add_allocno_hard_regs (temp_set, hv->cost);
398 add_allocno_hard_regs_to_forest (&node->first, hv2);
401 if (hard_regs_node_vec.length ()
402 > start + 1)
404 /* Create a new node which contains nodes in hard_regs_node_vec. */
405 CLEAR_HARD_REG_SET (temp_set);
406 for (i = start;
407 i < hard_regs_node_vec.length ();
408 i++)
410 node = hard_regs_node_vec[i];
411 IOR_HARD_REG_SET (temp_set, node->hard_regs->set);
413 hv = add_allocno_hard_regs (temp_set, hv->cost);
414 new_node = create_new_allocno_hard_regs_node (hv);
415 prev = NULL;
416 for (i = start;
417 i < hard_regs_node_vec.length ();
418 i++)
420 node = hard_regs_node_vec[i];
421 if (node->prev == NULL)
422 *roots = node->next;
423 else
424 node->prev->next = node->next;
425 if (node->next != NULL)
426 node->next->prev = node->prev;
427 if (prev == NULL)
428 new_node->first = node;
429 else
430 prev->next = node;
431 node->prev = prev;
432 node->next = NULL;
433 prev = node;
435 add_new_allocno_hard_regs_node_to_forest (roots, new_node);
437 hard_regs_node_vec.truncate (start);
440 /* Add allocno hard registers nodes starting with the forest level
441 given by FIRST which contains biggest set inside SET. */
442 static void
443 collect_allocno_hard_regs_cover (allocno_hard_regs_node_t first,
444 HARD_REG_SET set)
446 allocno_hard_regs_node_t node;
448 ira_assert (first != NULL);
449 for (node = first; node != NULL; node = node->next)
450 if (hard_reg_set_subset_p (node->hard_regs->set, set))
451 hard_regs_node_vec.safe_push (node);
452 else if (hard_reg_set_intersect_p (set, node->hard_regs->set))
453 collect_allocno_hard_regs_cover (node->first, set);
456 /* Set up field parent as PARENT in all allocno hard registers nodes
457 in forest given by FIRST. */
458 static void
459 setup_allocno_hard_regs_nodes_parent (allocno_hard_regs_node_t first,
460 allocno_hard_regs_node_t parent)
462 allocno_hard_regs_node_t node;
464 for (node = first; node != NULL; node = node->next)
466 node->parent = parent;
467 setup_allocno_hard_regs_nodes_parent (node->first, node);
471 /* Return allocno hard registers node which is a first common ancestor
472 node of FIRST and SECOND in the forest. */
473 static allocno_hard_regs_node_t
474 first_common_ancestor_node (allocno_hard_regs_node_t first,
475 allocno_hard_regs_node_t second)
477 allocno_hard_regs_node_t node;
479 node_check_tick++;
480 for (node = first; node != NULL; node = node->parent)
481 node->check = node_check_tick;
482 for (node = second; node != NULL; node = node->parent)
483 if (node->check == node_check_tick)
484 return node;
485 return first_common_ancestor_node (second, first);
488 /* Print hard reg set SET to F. */
489 static void
490 print_hard_reg_set (FILE *f, HARD_REG_SET set, bool new_line_p)
492 int i, start;
494 for (start = -1, i = 0; i < FIRST_PSEUDO_REGISTER; i++)
496 if (TEST_HARD_REG_BIT (set, i))
498 if (i == 0 || ! TEST_HARD_REG_BIT (set, i - 1))
499 start = i;
501 if (start >= 0
502 && (i == FIRST_PSEUDO_REGISTER - 1 || ! TEST_HARD_REG_BIT (set, i)))
504 if (start == i - 1)
505 fprintf (f, " %d", start);
506 else if (start == i - 2)
507 fprintf (f, " %d %d", start, start + 1);
508 else
509 fprintf (f, " %d-%d", start, i - 1);
510 start = -1;
513 if (new_line_p)
514 fprintf (f, "\n");
517 /* Print allocno hard register subforest given by ROOTS and its LEVEL
518 to F. */
519 static void
520 print_hard_regs_subforest (FILE *f, allocno_hard_regs_node_t roots,
521 int level)
523 int i;
524 allocno_hard_regs_node_t node;
526 for (node = roots; node != NULL; node = node->next)
528 fprintf (f, " ");
529 for (i = 0; i < level * 2; i++)
530 fprintf (f, " ");
531 fprintf (f, "%d:(", node->preorder_num);
532 print_hard_reg_set (f, node->hard_regs->set, false);
533 fprintf (f, ")@%"PRId64"\n", node->hard_regs->cost);
534 print_hard_regs_subforest (f, node->first, level + 1);
538 /* Print the allocno hard register forest to F. */
539 static void
540 print_hard_regs_forest (FILE *f)
542 fprintf (f, " Hard reg set forest:\n");
543 print_hard_regs_subforest (f, hard_regs_roots, 1);
546 /* Print the allocno hard register forest to stderr. */
547 void
548 ira_debug_hard_regs_forest (void)
550 print_hard_regs_forest (stderr);
553 /* Remove unused allocno hard registers nodes from forest given by its
554 *ROOTS. */
555 static void
556 remove_unused_allocno_hard_regs_nodes (allocno_hard_regs_node_t *roots)
558 allocno_hard_regs_node_t node, prev, next, last;
560 for (prev = NULL, node = *roots; node != NULL; node = next)
562 next = node->next;
563 if (node->used_p)
565 remove_unused_allocno_hard_regs_nodes (&node->first);
566 prev = node;
568 else
570 for (last = node->first;
571 last != NULL && last->next != NULL;
572 last = last->next)
574 if (last != NULL)
576 if (prev == NULL)
577 *roots = node->first;
578 else
579 prev->next = node->first;
580 if (next != NULL)
581 next->prev = last;
582 last->next = next;
583 next = node->first;
585 else
587 if (prev == NULL)
588 *roots = next;
589 else
590 prev->next = next;
591 if (next != NULL)
592 next->prev = prev;
594 ira_free (node);
599 /* Set up fields preorder_num starting with START_NUM in all allocno
600 hard registers nodes in forest given by FIRST. Return biggest set
601 PREORDER_NUM increased by 1. */
602 static int
603 enumerate_allocno_hard_regs_nodes (allocno_hard_regs_node_t first,
604 allocno_hard_regs_node_t parent,
605 int start_num)
607 allocno_hard_regs_node_t node;
609 for (node = first; node != NULL; node = node->next)
611 node->preorder_num = start_num++;
612 node->parent = parent;
613 start_num = enumerate_allocno_hard_regs_nodes (node->first, node,
614 start_num);
616 return start_num;
619 /* Number of allocno hard registers nodes in the forest. */
620 static int allocno_hard_regs_nodes_num;
622 /* Table preorder number of allocno hard registers node in the forest
623 -> the allocno hard registers node. */
624 static allocno_hard_regs_node_t *allocno_hard_regs_nodes;
626 /* See below. */
627 typedef struct allocno_hard_regs_subnode *allocno_hard_regs_subnode_t;
629 /* The structure is used to describes all subnodes (not only immediate
630 ones) in the mentioned above tree for given allocno hard register
631 node. The usage of such data accelerates calculation of
632 colorability of given allocno. */
633 struct allocno_hard_regs_subnode
635 /* The conflict size of conflicting allocnos whose hard register
636 sets are equal sets (plus supersets if given node is given
637 allocno hard registers node) of one in the given node. */
638 int left_conflict_size;
639 /* The summary conflict size of conflicting allocnos whose hard
640 register sets are strict subsets of one in the given node.
641 Overall conflict size is
642 left_conflict_subnodes_size
643 + MIN (max_node_impact - left_conflict_subnodes_size,
644 left_conflict_size)
646 short left_conflict_subnodes_size;
647 short max_node_impact;
650 /* Container for hard regs subnodes of all allocnos. */
651 static allocno_hard_regs_subnode_t allocno_hard_regs_subnodes;
653 /* Table (preorder number of allocno hard registers node in the
654 forest, preorder number of allocno hard registers subnode) -> index
655 of the subnode relative to the node. -1 if it is not a
656 subnode. */
657 static int *allocno_hard_regs_subnode_index;
659 /* Setup arrays ALLOCNO_HARD_REGS_NODES and
660 ALLOCNO_HARD_REGS_SUBNODE_INDEX. */
661 static void
662 setup_allocno_hard_regs_subnode_index (allocno_hard_regs_node_t first)
664 allocno_hard_regs_node_t node, parent;
665 int index;
667 for (node = first; node != NULL; node = node->next)
669 allocno_hard_regs_nodes[node->preorder_num] = node;
670 for (parent = node; parent != NULL; parent = parent->parent)
672 index = parent->preorder_num * allocno_hard_regs_nodes_num;
673 allocno_hard_regs_subnode_index[index + node->preorder_num]
674 = node->preorder_num - parent->preorder_num;
676 setup_allocno_hard_regs_subnode_index (node->first);
680 /* Count all allocno hard registers nodes in tree ROOT. */
681 static int
682 get_allocno_hard_regs_subnodes_num (allocno_hard_regs_node_t root)
684 int len = 1;
686 for (root = root->first; root != NULL; root = root->next)
687 len += get_allocno_hard_regs_subnodes_num (root);
688 return len;
691 /* Build the forest of allocno hard registers nodes and assign each
692 allocno a node from the forest. */
693 static void
694 form_allocno_hard_regs_nodes_forest (void)
696 unsigned int i, j, size, len;
697 int start;
698 ira_allocno_t a;
699 allocno_hard_regs_t hv;
700 bitmap_iterator bi;
701 HARD_REG_SET temp;
702 allocno_hard_regs_node_t node, allocno_hard_regs_node;
703 allocno_color_data_t allocno_data;
705 node_check_tick = 0;
706 init_allocno_hard_regs ();
707 hard_regs_roots = NULL;
708 hard_regs_node_vec.create (100);
709 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
710 if (! TEST_HARD_REG_BIT (ira_no_alloc_regs, i))
712 CLEAR_HARD_REG_SET (temp);
713 SET_HARD_REG_BIT (temp, i);
714 hv = add_allocno_hard_regs (temp, 0);
715 node = create_new_allocno_hard_regs_node (hv);
716 add_new_allocno_hard_regs_node_to_forest (&hard_regs_roots, node);
718 start = allocno_hard_regs_vec.length ();
719 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
721 a = ira_allocnos[i];
722 allocno_data = ALLOCNO_COLOR_DATA (a);
724 if (hard_reg_set_empty_p (allocno_data->profitable_hard_regs))
725 continue;
726 hv = (add_allocno_hard_regs
727 (allocno_data->profitable_hard_regs,
728 ALLOCNO_MEMORY_COST (a) - ALLOCNO_CLASS_COST (a)));
730 SET_HARD_REG_SET (temp);
731 AND_COMPL_HARD_REG_SET (temp, ira_no_alloc_regs);
732 add_allocno_hard_regs (temp, 0);
733 qsort (allocno_hard_regs_vec.address () + start,
734 allocno_hard_regs_vec.length () - start,
735 sizeof (allocno_hard_regs_t), allocno_hard_regs_compare);
736 for (i = start;
737 allocno_hard_regs_vec.iterate (i, &hv);
738 i++)
740 add_allocno_hard_regs_to_forest (&hard_regs_roots, hv);
741 ira_assert (hard_regs_node_vec.length () == 0);
743 /* We need to set up parent fields for right work of
744 first_common_ancestor_node. */
745 setup_allocno_hard_regs_nodes_parent (hard_regs_roots, NULL);
746 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
748 a = ira_allocnos[i];
749 allocno_data = ALLOCNO_COLOR_DATA (a);
750 if (hard_reg_set_empty_p (allocno_data->profitable_hard_regs))
751 continue;
752 hard_regs_node_vec.truncate (0);
753 collect_allocno_hard_regs_cover (hard_regs_roots,
754 allocno_data->profitable_hard_regs);
755 allocno_hard_regs_node = NULL;
756 for (j = 0; hard_regs_node_vec.iterate (j, &node); j++)
757 allocno_hard_regs_node
758 = (j == 0
759 ? node
760 : first_common_ancestor_node (node, allocno_hard_regs_node));
761 /* That is a temporary storage. */
762 allocno_hard_regs_node->used_p = true;
763 allocno_data->hard_regs_node = allocno_hard_regs_node;
765 ira_assert (hard_regs_roots->next == NULL);
766 hard_regs_roots->used_p = true;
767 remove_unused_allocno_hard_regs_nodes (&hard_regs_roots);
768 allocno_hard_regs_nodes_num
769 = enumerate_allocno_hard_regs_nodes (hard_regs_roots, NULL, 0);
770 allocno_hard_regs_nodes
771 = ((allocno_hard_regs_node_t *)
772 ira_allocate (allocno_hard_regs_nodes_num
773 * sizeof (allocno_hard_regs_node_t)));
774 size = allocno_hard_regs_nodes_num * allocno_hard_regs_nodes_num;
775 allocno_hard_regs_subnode_index
776 = (int *) ira_allocate (size * sizeof (int));
777 for (i = 0; i < size; i++)
778 allocno_hard_regs_subnode_index[i] = -1;
779 setup_allocno_hard_regs_subnode_index (hard_regs_roots);
780 start = 0;
781 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
783 a = ira_allocnos[i];
784 allocno_data = ALLOCNO_COLOR_DATA (a);
785 if (hard_reg_set_empty_p (allocno_data->profitable_hard_regs))
786 continue;
787 len = get_allocno_hard_regs_subnodes_num (allocno_data->hard_regs_node);
788 allocno_data->hard_regs_subnodes_start = start;
789 allocno_data->hard_regs_subnodes_num = len;
790 start += len;
792 allocno_hard_regs_subnodes
793 = ((allocno_hard_regs_subnode_t)
794 ira_allocate (sizeof (struct allocno_hard_regs_subnode) * start));
795 hard_regs_node_vec.release ();
798 /* Free tree of allocno hard registers nodes given by its ROOT. */
799 static void
800 finish_allocno_hard_regs_nodes_tree (allocno_hard_regs_node_t root)
802 allocno_hard_regs_node_t child, next;
804 for (child = root->first; child != NULL; child = next)
806 next = child->next;
807 finish_allocno_hard_regs_nodes_tree (child);
809 ira_free (root);
812 /* Finish work with the forest of allocno hard registers nodes. */
813 static void
814 finish_allocno_hard_regs_nodes_forest (void)
816 allocno_hard_regs_node_t node, next;
818 ira_free (allocno_hard_regs_subnodes);
819 for (node = hard_regs_roots; node != NULL; node = next)
821 next = node->next;
822 finish_allocno_hard_regs_nodes_tree (node);
824 ira_free (allocno_hard_regs_nodes);
825 ira_free (allocno_hard_regs_subnode_index);
826 finish_allocno_hard_regs ();
829 /* Set up left conflict sizes and left conflict subnodes sizes of hard
830 registers subnodes of allocno A. Return TRUE if allocno A is
831 trivially colorable. */
832 static bool
833 setup_left_conflict_sizes_p (ira_allocno_t a)
835 int i, k, nobj, start;
836 int conflict_size, left_conflict_subnodes_size, node_preorder_num;
837 allocno_color_data_t data;
838 HARD_REG_SET profitable_hard_regs;
839 allocno_hard_regs_subnode_t subnodes;
840 allocno_hard_regs_node_t node;
841 HARD_REG_SET node_set;
843 nobj = ALLOCNO_NUM_OBJECTS (a);
844 conflict_size = 0;
845 data = ALLOCNO_COLOR_DATA (a);
846 subnodes = allocno_hard_regs_subnodes + data->hard_regs_subnodes_start;
847 COPY_HARD_REG_SET (profitable_hard_regs, data->profitable_hard_regs);
848 node = data->hard_regs_node;
849 node_preorder_num = node->preorder_num;
850 COPY_HARD_REG_SET (node_set, node->hard_regs->set);
851 node_check_tick++;
852 for (k = 0; k < nobj; k++)
854 ira_object_t obj = ALLOCNO_OBJECT (a, k);
855 ira_object_t conflict_obj;
856 ira_object_conflict_iterator oci;
858 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
860 int size;
861 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
862 allocno_hard_regs_node_t conflict_node, temp_node;
863 HARD_REG_SET conflict_node_set;
864 allocno_color_data_t conflict_data;
866 conflict_data = ALLOCNO_COLOR_DATA (conflict_a);
867 if (! ALLOCNO_COLOR_DATA (conflict_a)->in_graph_p
868 || ! hard_reg_set_intersect_p (profitable_hard_regs,
869 conflict_data
870 ->profitable_hard_regs))
871 continue;
872 conflict_node = conflict_data->hard_regs_node;
873 COPY_HARD_REG_SET (conflict_node_set, conflict_node->hard_regs->set);
874 if (hard_reg_set_subset_p (node_set, conflict_node_set))
875 temp_node = node;
876 else
878 ira_assert (hard_reg_set_subset_p (conflict_node_set, node_set));
879 temp_node = conflict_node;
881 if (temp_node->check != node_check_tick)
883 temp_node->check = node_check_tick;
884 temp_node->conflict_size = 0;
886 size = (ira_reg_class_max_nregs
887 [ALLOCNO_CLASS (conflict_a)][ALLOCNO_MODE (conflict_a)]);
888 if (ALLOCNO_NUM_OBJECTS (conflict_a) > 1)
889 /* We will deal with the subwords individually. */
890 size = 1;
891 temp_node->conflict_size += size;
894 for (i = 0; i < data->hard_regs_subnodes_num; i++)
896 allocno_hard_regs_node_t temp_node;
898 temp_node = allocno_hard_regs_nodes[i + node_preorder_num];
899 ira_assert (temp_node->preorder_num == i + node_preorder_num);
900 subnodes[i].left_conflict_size = (temp_node->check != node_check_tick
901 ? 0 : temp_node->conflict_size);
902 if (hard_reg_set_subset_p (temp_node->hard_regs->set,
903 profitable_hard_regs))
904 subnodes[i].max_node_impact = temp_node->hard_regs_num;
905 else
907 HARD_REG_SET temp_set;
908 int j, n, hard_regno;
909 enum reg_class aclass;
911 COPY_HARD_REG_SET (temp_set, temp_node->hard_regs->set);
912 AND_HARD_REG_SET (temp_set, profitable_hard_regs);
913 aclass = ALLOCNO_CLASS (a);
914 for (n = 0, j = ira_class_hard_regs_num[aclass] - 1; j >= 0; j--)
916 hard_regno = ira_class_hard_regs[aclass][j];
917 if (TEST_HARD_REG_BIT (temp_set, hard_regno))
918 n++;
920 subnodes[i].max_node_impact = n;
922 subnodes[i].left_conflict_subnodes_size = 0;
924 start = node_preorder_num * allocno_hard_regs_nodes_num;
925 for (i = data->hard_regs_subnodes_num - 1; i >= 0; i--)
927 int size, parent_i;
928 allocno_hard_regs_node_t parent;
930 size = (subnodes[i].left_conflict_subnodes_size
931 + MIN (subnodes[i].max_node_impact
932 - subnodes[i].left_conflict_subnodes_size,
933 subnodes[i].left_conflict_size));
934 parent = allocno_hard_regs_nodes[i + node_preorder_num]->parent;
935 if (parent == NULL)
936 continue;
937 parent_i
938 = allocno_hard_regs_subnode_index[start + parent->preorder_num];
939 if (parent_i < 0)
940 continue;
941 subnodes[parent_i].left_conflict_subnodes_size += size;
943 left_conflict_subnodes_size = subnodes[0].left_conflict_subnodes_size;
944 conflict_size
945 += (left_conflict_subnodes_size
946 + MIN (subnodes[0].max_node_impact - left_conflict_subnodes_size,
947 subnodes[0].left_conflict_size));
948 conflict_size += ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)];
949 data->colorable_p = conflict_size <= data->available_regs_num;
950 return data->colorable_p;
953 /* Update left conflict sizes of hard registers subnodes of allocno A
954 after removing allocno REMOVED_A with SIZE from the conflict graph.
955 Return TRUE if A is trivially colorable. */
956 static bool
957 update_left_conflict_sizes_p (ira_allocno_t a,
958 ira_allocno_t removed_a, int size)
960 int i, conflict_size, before_conflict_size, diff, start;
961 int node_preorder_num, parent_i;
962 allocno_hard_regs_node_t node, removed_node, parent;
963 allocno_hard_regs_subnode_t subnodes;
964 allocno_color_data_t data = ALLOCNO_COLOR_DATA (a);
966 ira_assert (! data->colorable_p);
967 node = data->hard_regs_node;
968 node_preorder_num = node->preorder_num;
969 removed_node = ALLOCNO_COLOR_DATA (removed_a)->hard_regs_node;
970 ira_assert (hard_reg_set_subset_p (removed_node->hard_regs->set,
971 node->hard_regs->set)
972 || hard_reg_set_subset_p (node->hard_regs->set,
973 removed_node->hard_regs->set));
974 start = node_preorder_num * allocno_hard_regs_nodes_num;
975 i = allocno_hard_regs_subnode_index[start + removed_node->preorder_num];
976 if (i < 0)
977 i = 0;
978 subnodes = allocno_hard_regs_subnodes + data->hard_regs_subnodes_start;
979 before_conflict_size
980 = (subnodes[i].left_conflict_subnodes_size
981 + MIN (subnodes[i].max_node_impact
982 - subnodes[i].left_conflict_subnodes_size,
983 subnodes[i].left_conflict_size));
984 subnodes[i].left_conflict_size -= size;
985 for (;;)
987 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 if ((diff = before_conflict_size - conflict_size) == 0)
993 break;
994 ira_assert (conflict_size < before_conflict_size);
995 parent = allocno_hard_regs_nodes[i + node_preorder_num]->parent;
996 if (parent == NULL)
997 break;
998 parent_i
999 = allocno_hard_regs_subnode_index[start + parent->preorder_num];
1000 if (parent_i < 0)
1001 break;
1002 i = parent_i;
1003 before_conflict_size
1004 = (subnodes[i].left_conflict_subnodes_size
1005 + MIN (subnodes[i].max_node_impact
1006 - subnodes[i].left_conflict_subnodes_size,
1007 subnodes[i].left_conflict_size));
1008 subnodes[i].left_conflict_subnodes_size -= diff;
1010 if (i != 0
1011 || (conflict_size
1012 + ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]
1013 > data->available_regs_num))
1014 return false;
1015 data->colorable_p = true;
1016 return true;
1019 /* Return true if allocno A has empty profitable hard regs. */
1020 static bool
1021 empty_profitable_hard_regs (ira_allocno_t a)
1023 allocno_color_data_t data = ALLOCNO_COLOR_DATA (a);
1025 return hard_reg_set_empty_p (data->profitable_hard_regs);
1028 /* Set up profitable hard registers for each allocno being
1029 colored. */
1030 static void
1031 setup_profitable_hard_regs (void)
1033 unsigned int i;
1034 int j, k, nobj, hard_regno, nregs, class_size;
1035 ira_allocno_t a;
1036 bitmap_iterator bi;
1037 enum reg_class aclass;
1038 machine_mode mode;
1039 allocno_color_data_t data;
1041 /* Initial set up from allocno classes and explicitly conflicting
1042 hard regs. */
1043 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
1045 a = ira_allocnos[i];
1046 if ((aclass = ALLOCNO_CLASS (a)) == NO_REGS)
1047 continue;
1048 data = ALLOCNO_COLOR_DATA (a);
1049 if (ALLOCNO_UPDATED_HARD_REG_COSTS (a) == NULL
1050 && ALLOCNO_CLASS_COST (a) > ALLOCNO_MEMORY_COST (a))
1051 CLEAR_HARD_REG_SET (data->profitable_hard_regs);
1052 else
1054 mode = ALLOCNO_MODE (a);
1055 COPY_HARD_REG_SET (data->profitable_hard_regs,
1056 ira_useful_class_mode_regs[aclass][mode]);
1057 nobj = ALLOCNO_NUM_OBJECTS (a);
1058 for (k = 0; k < nobj; k++)
1060 ira_object_t obj = ALLOCNO_OBJECT (a, k);
1062 AND_COMPL_HARD_REG_SET (data->profitable_hard_regs,
1063 OBJECT_TOTAL_CONFLICT_HARD_REGS (obj));
1067 /* Exclude hard regs already assigned for conflicting objects. */
1068 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, i, bi)
1070 a = ira_allocnos[i];
1071 if ((aclass = ALLOCNO_CLASS (a)) == NO_REGS
1072 || ! ALLOCNO_ASSIGNED_P (a)
1073 || (hard_regno = ALLOCNO_HARD_REGNO (a)) < 0)
1074 continue;
1075 mode = ALLOCNO_MODE (a);
1076 nregs = hard_regno_nregs[hard_regno][mode];
1077 nobj = ALLOCNO_NUM_OBJECTS (a);
1078 for (k = 0; k < nobj; k++)
1080 ira_object_t obj = ALLOCNO_OBJECT (a, k);
1081 ira_object_t conflict_obj;
1082 ira_object_conflict_iterator oci;
1084 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
1086 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
1088 /* We can process the conflict allocno repeatedly with
1089 the same result. */
1090 if (nregs == nobj && nregs > 1)
1092 int num = OBJECT_SUBWORD (conflict_obj);
1094 if (REG_WORDS_BIG_ENDIAN)
1095 CLEAR_HARD_REG_BIT
1096 (ALLOCNO_COLOR_DATA (conflict_a)->profitable_hard_regs,
1097 hard_regno + nobj - num - 1);
1098 else
1099 CLEAR_HARD_REG_BIT
1100 (ALLOCNO_COLOR_DATA (conflict_a)->profitable_hard_regs,
1101 hard_regno + num);
1103 else
1104 AND_COMPL_HARD_REG_SET
1105 (ALLOCNO_COLOR_DATA (conflict_a)->profitable_hard_regs,
1106 ira_reg_mode_hard_regset[hard_regno][mode]);
1110 /* Exclude too costly hard regs. */
1111 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
1113 int min_cost = INT_MAX;
1114 int *costs;
1116 a = ira_allocnos[i];
1117 if ((aclass = ALLOCNO_CLASS (a)) == NO_REGS
1118 || empty_profitable_hard_regs (a))
1119 continue;
1120 data = ALLOCNO_COLOR_DATA (a);
1121 mode = ALLOCNO_MODE (a);
1122 if ((costs = ALLOCNO_UPDATED_HARD_REG_COSTS (a)) != NULL
1123 || (costs = ALLOCNO_HARD_REG_COSTS (a)) != NULL)
1125 class_size = ira_class_hard_regs_num[aclass];
1126 for (j = 0; j < class_size; j++)
1128 hard_regno = ira_class_hard_regs[aclass][j];
1129 if (! TEST_HARD_REG_BIT (data->profitable_hard_regs,
1130 hard_regno))
1131 continue;
1132 if (ALLOCNO_UPDATED_MEMORY_COST (a) < costs[j])
1133 CLEAR_HARD_REG_BIT (data->profitable_hard_regs,
1134 hard_regno);
1135 else if (min_cost > costs[j])
1136 min_cost = costs[j];
1139 else if (ALLOCNO_UPDATED_MEMORY_COST (a)
1140 < ALLOCNO_UPDATED_CLASS_COST (a))
1141 CLEAR_HARD_REG_SET (data->profitable_hard_regs);
1142 if (ALLOCNO_UPDATED_CLASS_COST (a) > min_cost)
1143 ALLOCNO_UPDATED_CLASS_COST (a) = min_cost;
1149 /* This page contains functions used to choose hard registers for
1150 allocnos. */
1152 /* Pool for update cost records. */
1153 static alloc_pool update_cost_record_pool;
1155 /* Initiate update cost records. */
1156 static void
1157 init_update_cost_records (void)
1159 update_cost_record_pool
1160 = create_alloc_pool ("update cost records",
1161 sizeof (struct update_cost_record), 100);
1164 /* Return new update cost record with given params. */
1165 static struct update_cost_record *
1166 get_update_cost_record (int hard_regno, int divisor,
1167 struct update_cost_record *next)
1169 struct update_cost_record *record;
1171 record = (struct update_cost_record *) pool_alloc (update_cost_record_pool);
1172 record->hard_regno = hard_regno;
1173 record->divisor = divisor;
1174 record->next = next;
1175 return record;
1178 /* Free memory for all records in LIST. */
1179 static void
1180 free_update_cost_record_list (struct update_cost_record *list)
1182 struct update_cost_record *next;
1184 while (list != NULL)
1186 next = list->next;
1187 pool_free (update_cost_record_pool, list);
1188 list = next;
1192 /* Free memory allocated for all update cost records. */
1193 static void
1194 finish_update_cost_records (void)
1196 free_alloc_pool (update_cost_record_pool);
1199 /* Array whose element value is TRUE if the corresponding hard
1200 register was already allocated for an allocno. */
1201 static bool allocated_hardreg_p[FIRST_PSEUDO_REGISTER];
1203 /* Describes one element in a queue of allocnos whose costs need to be
1204 updated. Each allocno in the queue is known to have an allocno
1205 class. */
1206 struct update_cost_queue_elem
1208 /* This element is in the queue iff CHECK == update_cost_check. */
1209 int check;
1211 /* COST_HOP_DIVISOR**N, where N is the length of the shortest path
1212 connecting this allocno to the one being allocated. */
1213 int divisor;
1215 /* Allocno from which we are chaining costs of connected allocnos.
1216 It is used not go back in graph of allocnos connected by
1217 copies. */
1218 ira_allocno_t from;
1220 /* The next allocno in the queue, or null if this is the last element. */
1221 ira_allocno_t next;
1224 /* The first element in a queue of allocnos whose copy costs need to be
1225 updated. Null if the queue is empty. */
1226 static ira_allocno_t update_cost_queue;
1228 /* The last element in the queue described by update_cost_queue.
1229 Not valid if update_cost_queue is null. */
1230 static struct update_cost_queue_elem *update_cost_queue_tail;
1232 /* A pool of elements in the queue described by update_cost_queue.
1233 Elements are indexed by ALLOCNO_NUM. */
1234 static struct update_cost_queue_elem *update_cost_queue_elems;
1236 /* The current value of update_costs_from_copies call count. */
1237 static int update_cost_check;
1239 /* Allocate and initialize data necessary for function
1240 update_costs_from_copies. */
1241 static void
1242 initiate_cost_update (void)
1244 size_t size;
1246 size = ira_allocnos_num * sizeof (struct update_cost_queue_elem);
1247 update_cost_queue_elems
1248 = (struct update_cost_queue_elem *) ira_allocate (size);
1249 memset (update_cost_queue_elems, 0, size);
1250 update_cost_check = 0;
1251 init_update_cost_records ();
1254 /* Deallocate data used by function update_costs_from_copies. */
1255 static void
1256 finish_cost_update (void)
1258 ira_free (update_cost_queue_elems);
1259 finish_update_cost_records ();
1262 /* When we traverse allocnos to update hard register costs, the cost
1263 divisor will be multiplied by the following macro value for each
1264 hop from given allocno to directly connected allocnos. */
1265 #define COST_HOP_DIVISOR 4
1267 /* Start a new cost-updating pass. */
1268 static void
1269 start_update_cost (void)
1271 update_cost_check++;
1272 update_cost_queue = NULL;
1275 /* Add (ALLOCNO, FROM, DIVISOR) to the end of update_cost_queue, unless
1276 ALLOCNO is already in the queue, or has NO_REGS class. */
1277 static inline void
1278 queue_update_cost (ira_allocno_t allocno, ira_allocno_t from, int divisor)
1280 struct update_cost_queue_elem *elem;
1282 elem = &update_cost_queue_elems[ALLOCNO_NUM (allocno)];
1283 if (elem->check != update_cost_check
1284 && ALLOCNO_CLASS (allocno) != NO_REGS)
1286 elem->check = update_cost_check;
1287 elem->from = from;
1288 elem->divisor = divisor;
1289 elem->next = NULL;
1290 if (update_cost_queue == NULL)
1291 update_cost_queue = allocno;
1292 else
1293 update_cost_queue_tail->next = allocno;
1294 update_cost_queue_tail = elem;
1298 /* Try to remove the first element from update_cost_queue. Return
1299 false if the queue was empty, otherwise make (*ALLOCNO, *FROM,
1300 *DIVISOR) describe the removed element. */
1301 static inline bool
1302 get_next_update_cost (ira_allocno_t *allocno, ira_allocno_t *from, int *divisor)
1304 struct update_cost_queue_elem *elem;
1306 if (update_cost_queue == NULL)
1307 return false;
1309 *allocno = update_cost_queue;
1310 elem = &update_cost_queue_elems[ALLOCNO_NUM (*allocno)];
1311 *from = elem->from;
1312 *divisor = elem->divisor;
1313 update_cost_queue = elem->next;
1314 return true;
1317 /* Increase costs of HARD_REGNO by UPDATE_COST for ALLOCNO. Return
1318 true if we really modified the cost. */
1319 static bool
1320 update_allocno_cost (ira_allocno_t allocno, int hard_regno, int update_cost)
1322 int i;
1323 enum reg_class aclass = ALLOCNO_CLASS (allocno);
1325 i = ira_class_hard_reg_index[aclass][hard_regno];
1326 if (i < 0)
1327 return false;
1328 ira_allocate_and_set_or_copy_costs
1329 (&ALLOCNO_UPDATED_HARD_REG_COSTS (allocno), aclass,
1330 ALLOCNO_UPDATED_CLASS_COST (allocno),
1331 ALLOCNO_HARD_REG_COSTS (allocno));
1332 ira_allocate_and_set_or_copy_costs
1333 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (allocno),
1334 aclass, 0, ALLOCNO_CONFLICT_HARD_REG_COSTS (allocno));
1335 ALLOCNO_UPDATED_HARD_REG_COSTS (allocno)[i] += update_cost;
1336 ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (allocno)[i] += update_cost;
1337 return true;
1340 /* Update (decrease if DECR_P) HARD_REGNO cost of allocnos connected
1341 by copies to ALLOCNO to increase chances to remove some copies as
1342 the result of subsequent assignment. Record cost updates if
1343 RECORD_P is true. */
1344 static void
1345 update_costs_from_allocno (ira_allocno_t allocno, int hard_regno,
1346 int divisor, bool decr_p, bool record_p)
1348 int cost, update_cost;
1349 machine_mode mode;
1350 enum reg_class rclass, aclass;
1351 ira_allocno_t another_allocno, from = NULL;
1352 ira_copy_t cp, next_cp;
1354 rclass = REGNO_REG_CLASS (hard_regno);
1357 mode = ALLOCNO_MODE (allocno);
1358 ira_init_register_move_cost_if_necessary (mode);
1359 for (cp = ALLOCNO_COPIES (allocno); cp != NULL; cp = next_cp)
1361 if (cp->first == allocno)
1363 next_cp = cp->next_first_allocno_copy;
1364 another_allocno = cp->second;
1366 else if (cp->second == allocno)
1368 next_cp = cp->next_second_allocno_copy;
1369 another_allocno = cp->first;
1371 else
1372 gcc_unreachable ();
1374 if (another_allocno == from)
1375 continue;
1377 aclass = ALLOCNO_CLASS (another_allocno);
1378 if (! TEST_HARD_REG_BIT (reg_class_contents[aclass],
1379 hard_regno)
1380 || ALLOCNO_ASSIGNED_P (another_allocno))
1381 continue;
1383 cost = (cp->second == allocno
1384 ? ira_register_move_cost[mode][rclass][aclass]
1385 : ira_register_move_cost[mode][aclass][rclass]);
1386 if (decr_p)
1387 cost = -cost;
1389 update_cost = cp->freq * cost / divisor;
1390 if (update_cost == 0)
1391 continue;
1393 if (! update_allocno_cost (another_allocno, hard_regno, update_cost))
1394 continue;
1395 queue_update_cost (another_allocno, allocno, divisor * COST_HOP_DIVISOR);
1396 if (record_p && ALLOCNO_COLOR_DATA (another_allocno) != NULL)
1397 ALLOCNO_COLOR_DATA (another_allocno)->update_cost_records
1398 = get_update_cost_record (hard_regno, divisor,
1399 ALLOCNO_COLOR_DATA (another_allocno)
1400 ->update_cost_records);
1403 while (get_next_update_cost (&allocno, &from, &divisor));
1406 /* Decrease preferred ALLOCNO hard register costs and costs of
1407 allocnos connected to ALLOCNO through copy. */
1408 static void
1409 update_costs_from_prefs (ira_allocno_t allocno)
1411 ira_pref_t pref;
1413 start_update_cost ();
1414 for (pref = ALLOCNO_PREFS (allocno); pref != NULL; pref = pref->next_pref)
1415 update_costs_from_allocno (allocno, pref->hard_regno,
1416 COST_HOP_DIVISOR, true, true);
1419 /* Update (decrease if DECR_P) the cost of allocnos connected to
1420 ALLOCNO through copies to increase chances to remove some copies as
1421 the result of subsequent assignment. ALLOCNO was just assigned to
1422 a hard register. Record cost updates if RECORD_P is true. */
1423 static void
1424 update_costs_from_copies (ira_allocno_t allocno, bool decr_p, bool record_p)
1426 int hard_regno;
1428 hard_regno = ALLOCNO_HARD_REGNO (allocno);
1429 ira_assert (hard_regno >= 0 && ALLOCNO_CLASS (allocno) != NO_REGS);
1430 start_update_cost ();
1431 update_costs_from_allocno (allocno, hard_regno, 1, decr_p, record_p);
1434 /* Restore costs of allocnos connected to ALLOCNO by copies as it was
1435 before updating costs of these allocnos from given allocno. This
1436 is a wise thing to do as if given allocno did not get an expected
1437 hard reg, using smaller cost of the hard reg for allocnos connected
1438 by copies to given allocno becomes actually misleading. Free all
1439 update cost records for ALLOCNO as we don't need them anymore. */
1440 static void
1441 restore_costs_from_copies (ira_allocno_t allocno)
1443 struct update_cost_record *records, *curr;
1445 if (ALLOCNO_COLOR_DATA (allocno) == NULL)
1446 return;
1447 records = ALLOCNO_COLOR_DATA (allocno)->update_cost_records;
1448 start_update_cost ();
1449 for (curr = records; curr != NULL; curr = curr->next)
1450 update_costs_from_allocno (allocno, curr->hard_regno,
1451 curr->divisor, true, false);
1452 free_update_cost_record_list (records);
1453 ALLOCNO_COLOR_DATA (allocno)->update_cost_records = NULL;
1456 /* This function updates COSTS (decrease if DECR_P) for hard_registers
1457 of ACLASS by conflict costs of the unassigned allocnos
1458 connected by copies with allocnos in update_cost_queue. This
1459 update increases chances to remove some copies. */
1460 static void
1461 update_conflict_hard_regno_costs (int *costs, enum reg_class aclass,
1462 bool decr_p)
1464 int i, cost, class_size, freq, mult, div, divisor;
1465 int index, hard_regno;
1466 int *conflict_costs;
1467 bool cont_p;
1468 enum reg_class another_aclass;
1469 ira_allocno_t allocno, another_allocno, from;
1470 ira_copy_t cp, next_cp;
1472 while (get_next_update_cost (&allocno, &from, &divisor))
1473 for (cp = ALLOCNO_COPIES (allocno); cp != NULL; cp = next_cp)
1475 if (cp->first == allocno)
1477 next_cp = cp->next_first_allocno_copy;
1478 another_allocno = cp->second;
1480 else if (cp->second == allocno)
1482 next_cp = cp->next_second_allocno_copy;
1483 another_allocno = cp->first;
1485 else
1486 gcc_unreachable ();
1488 if (another_allocno == from)
1489 continue;
1491 another_aclass = ALLOCNO_CLASS (another_allocno);
1492 if (! ira_reg_classes_intersect_p[aclass][another_aclass]
1493 || ALLOCNO_ASSIGNED_P (another_allocno)
1494 || ALLOCNO_COLOR_DATA (another_allocno)->may_be_spilled_p)
1495 continue;
1496 class_size = ira_class_hard_regs_num[another_aclass];
1497 ira_allocate_and_copy_costs
1498 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (another_allocno),
1499 another_aclass, ALLOCNO_CONFLICT_HARD_REG_COSTS (another_allocno));
1500 conflict_costs
1501 = ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (another_allocno);
1502 if (conflict_costs == NULL)
1503 cont_p = true;
1504 else
1506 mult = cp->freq;
1507 freq = ALLOCNO_FREQ (another_allocno);
1508 if (freq == 0)
1509 freq = 1;
1510 div = freq * divisor;
1511 cont_p = false;
1512 for (i = class_size - 1; i >= 0; i--)
1514 hard_regno = ira_class_hard_regs[another_aclass][i];
1515 ira_assert (hard_regno >= 0);
1516 index = ira_class_hard_reg_index[aclass][hard_regno];
1517 if (index < 0)
1518 continue;
1519 cost = (int) ((unsigned) conflict_costs [i] * mult) / div;
1520 if (cost == 0)
1521 continue;
1522 cont_p = true;
1523 if (decr_p)
1524 cost = -cost;
1525 costs[index] += cost;
1528 /* Probably 5 hops will be enough. */
1529 if (cont_p
1530 && divisor <= (COST_HOP_DIVISOR
1531 * COST_HOP_DIVISOR
1532 * COST_HOP_DIVISOR
1533 * COST_HOP_DIVISOR))
1534 queue_update_cost (another_allocno, allocno, divisor * COST_HOP_DIVISOR);
1538 /* Set up conflicting (through CONFLICT_REGS) for each object of
1539 allocno A and the start allocno profitable regs (through
1540 START_PROFITABLE_REGS). Remember that the start profitable regs
1541 exclude hard regs which can not hold value of mode of allocno A.
1542 This covers mostly cases when multi-register value should be
1543 aligned. */
1544 static inline void
1545 get_conflict_and_start_profitable_regs (ira_allocno_t a, bool retry_p,
1546 HARD_REG_SET *conflict_regs,
1547 HARD_REG_SET *start_profitable_regs)
1549 int i, nwords;
1550 ira_object_t obj;
1552 nwords = ALLOCNO_NUM_OBJECTS (a);
1553 for (i = 0; i < nwords; i++)
1555 obj = ALLOCNO_OBJECT (a, i);
1556 COPY_HARD_REG_SET (conflict_regs[i],
1557 OBJECT_TOTAL_CONFLICT_HARD_REGS (obj));
1559 if (retry_p)
1561 COPY_HARD_REG_SET (*start_profitable_regs,
1562 reg_class_contents[ALLOCNO_CLASS (a)]);
1563 AND_COMPL_HARD_REG_SET (*start_profitable_regs,
1564 ira_prohibited_class_mode_regs
1565 [ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]);
1567 else
1568 COPY_HARD_REG_SET (*start_profitable_regs,
1569 ALLOCNO_COLOR_DATA (a)->profitable_hard_regs);
1572 /* Return true if HARD_REGNO is ok for assigning to allocno A with
1573 PROFITABLE_REGS and whose objects have CONFLICT_REGS. */
1574 static inline bool
1575 check_hard_reg_p (ira_allocno_t a, int hard_regno,
1576 HARD_REG_SET *conflict_regs, HARD_REG_SET profitable_regs)
1578 int j, nwords, nregs;
1579 enum reg_class aclass;
1580 machine_mode mode;
1582 aclass = ALLOCNO_CLASS (a);
1583 mode = ALLOCNO_MODE (a);
1584 if (TEST_HARD_REG_BIT (ira_prohibited_class_mode_regs[aclass][mode],
1585 hard_regno))
1586 return false;
1587 /* Checking only profitable hard regs. */
1588 if (! TEST_HARD_REG_BIT (profitable_regs, hard_regno))
1589 return false;
1590 nregs = hard_regno_nregs[hard_regno][mode];
1591 nwords = ALLOCNO_NUM_OBJECTS (a);
1592 for (j = 0; j < nregs; j++)
1594 int k;
1595 int set_to_test_start = 0, set_to_test_end = nwords;
1597 if (nregs == nwords)
1599 if (REG_WORDS_BIG_ENDIAN)
1600 set_to_test_start = nwords - j - 1;
1601 else
1602 set_to_test_start = j;
1603 set_to_test_end = set_to_test_start + 1;
1605 for (k = set_to_test_start; k < set_to_test_end; k++)
1606 if (TEST_HARD_REG_BIT (conflict_regs[k], hard_regno + j))
1607 break;
1608 if (k != set_to_test_end)
1609 break;
1611 return j == nregs;
1614 /* Return number of registers needed to be saved and restored at
1615 function prologue/epilogue if we allocate HARD_REGNO to hold value
1616 of MODE. */
1617 static int
1618 calculate_saved_nregs (int hard_regno, machine_mode mode)
1620 int i;
1621 int nregs = 0;
1623 ira_assert (hard_regno >= 0);
1624 for (i = hard_regno_nregs[hard_regno][mode] - 1; i >= 0; i--)
1625 if (!allocated_hardreg_p[hard_regno + i]
1626 && !TEST_HARD_REG_BIT (call_used_reg_set, hard_regno + i)
1627 && !LOCAL_REGNO (hard_regno + i))
1628 nregs++;
1629 return nregs;
1632 /* Choose a hard register for allocno A. If RETRY_P is TRUE, it means
1633 that the function called from function
1634 `ira_reassign_conflict_allocnos' and `allocno_reload_assign'. In
1635 this case some allocno data are not defined or updated and we
1636 should not touch these data. The function returns true if we
1637 managed to assign a hard register to the allocno.
1639 To assign a hard register, first of all we calculate all conflict
1640 hard registers which can come from conflicting allocnos with
1641 already assigned hard registers. After that we find first free
1642 hard register with the minimal cost. During hard register cost
1643 calculation we take conflict hard register costs into account to
1644 give a chance for conflicting allocnos to get a better hard
1645 register in the future.
1647 If the best hard register cost is bigger than cost of memory usage
1648 for the allocno, we don't assign a hard register to given allocno
1649 at all.
1651 If we assign a hard register to the allocno, we update costs of the
1652 hard register for allocnos connected by copies to improve a chance
1653 to coalesce insns represented by the copies when we assign hard
1654 registers to the allocnos connected by the copies. */
1655 static bool
1656 assign_hard_reg (ira_allocno_t a, bool retry_p)
1658 HARD_REG_SET conflicting_regs[2], profitable_hard_regs;
1659 int i, j, hard_regno, best_hard_regno, class_size;
1660 int cost, mem_cost, min_cost, full_cost, min_full_cost, nwords, word;
1661 int *a_costs;
1662 enum reg_class aclass;
1663 machine_mode mode;
1664 static int costs[FIRST_PSEUDO_REGISTER], full_costs[FIRST_PSEUDO_REGISTER];
1665 int saved_nregs;
1666 enum reg_class rclass;
1667 int add_cost;
1668 #ifdef STACK_REGS
1669 bool no_stack_reg_p;
1670 #endif
1672 ira_assert (! ALLOCNO_ASSIGNED_P (a));
1673 get_conflict_and_start_profitable_regs (a, retry_p,
1674 conflicting_regs,
1675 &profitable_hard_regs);
1676 aclass = ALLOCNO_CLASS (a);
1677 class_size = ira_class_hard_regs_num[aclass];
1678 best_hard_regno = -1;
1679 memset (full_costs, 0, sizeof (int) * class_size);
1680 mem_cost = 0;
1681 memset (costs, 0, sizeof (int) * class_size);
1682 memset (full_costs, 0, sizeof (int) * class_size);
1683 #ifdef STACK_REGS
1684 no_stack_reg_p = false;
1685 #endif
1686 if (! retry_p)
1687 start_update_cost ();
1688 mem_cost += ALLOCNO_UPDATED_MEMORY_COST (a);
1690 ira_allocate_and_copy_costs (&ALLOCNO_UPDATED_HARD_REG_COSTS (a),
1691 aclass, ALLOCNO_HARD_REG_COSTS (a));
1692 a_costs = ALLOCNO_UPDATED_HARD_REG_COSTS (a);
1693 #ifdef STACK_REGS
1694 no_stack_reg_p = no_stack_reg_p || ALLOCNO_TOTAL_NO_STACK_REG_P (a);
1695 #endif
1696 cost = ALLOCNO_UPDATED_CLASS_COST (a);
1697 for (i = 0; i < class_size; i++)
1698 if (a_costs != NULL)
1700 costs[i] += a_costs[i];
1701 full_costs[i] += a_costs[i];
1703 else
1705 costs[i] += cost;
1706 full_costs[i] += cost;
1708 nwords = ALLOCNO_NUM_OBJECTS (a);
1709 curr_allocno_process++;
1710 for (word = 0; word < nwords; word++)
1712 ira_object_t conflict_obj;
1713 ira_object_t obj = ALLOCNO_OBJECT (a, word);
1714 ira_object_conflict_iterator oci;
1716 /* Take preferences of conflicting allocnos into account. */
1717 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
1719 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
1720 enum reg_class conflict_aclass;
1721 allocno_color_data_t data = ALLOCNO_COLOR_DATA (conflict_a);
1723 /* Reload can give another class so we need to check all
1724 allocnos. */
1725 if (!retry_p
1726 && (!bitmap_bit_p (consideration_allocno_bitmap,
1727 ALLOCNO_NUM (conflict_a))
1728 || ((!ALLOCNO_ASSIGNED_P (conflict_a)
1729 || ALLOCNO_HARD_REGNO (conflict_a) < 0)
1730 && !(hard_reg_set_intersect_p
1731 (profitable_hard_regs,
1732 ALLOCNO_COLOR_DATA
1733 (conflict_a)->profitable_hard_regs)))))
1734 continue;
1735 conflict_aclass = ALLOCNO_CLASS (conflict_a);
1736 ira_assert (ira_reg_classes_intersect_p
1737 [aclass][conflict_aclass]);
1738 if (ALLOCNO_ASSIGNED_P (conflict_a))
1740 hard_regno = ALLOCNO_HARD_REGNO (conflict_a);
1741 if (hard_regno >= 0
1742 && (ira_hard_reg_set_intersection_p
1743 (hard_regno, ALLOCNO_MODE (conflict_a),
1744 reg_class_contents[aclass])))
1746 int n_objects = ALLOCNO_NUM_OBJECTS (conflict_a);
1747 int conflict_nregs;
1749 mode = ALLOCNO_MODE (conflict_a);
1750 conflict_nregs = hard_regno_nregs[hard_regno][mode];
1751 if (conflict_nregs == n_objects && conflict_nregs > 1)
1753 int num = OBJECT_SUBWORD (conflict_obj);
1755 if (REG_WORDS_BIG_ENDIAN)
1756 SET_HARD_REG_BIT (conflicting_regs[word],
1757 hard_regno + n_objects - num - 1);
1758 else
1759 SET_HARD_REG_BIT (conflicting_regs[word],
1760 hard_regno + num);
1762 else
1763 IOR_HARD_REG_SET
1764 (conflicting_regs[word],
1765 ira_reg_mode_hard_regset[hard_regno][mode]);
1766 if (hard_reg_set_subset_p (profitable_hard_regs,
1767 conflicting_regs[word]))
1768 goto fail;
1771 else if (! retry_p
1772 && ! ALLOCNO_COLOR_DATA (conflict_a)->may_be_spilled_p
1773 /* Don't process the conflict allocno twice. */
1774 && (ALLOCNO_COLOR_DATA (conflict_a)->last_process
1775 != curr_allocno_process))
1777 int k, *conflict_costs;
1779 ALLOCNO_COLOR_DATA (conflict_a)->last_process
1780 = curr_allocno_process;
1781 ira_allocate_and_copy_costs
1782 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (conflict_a),
1783 conflict_aclass,
1784 ALLOCNO_CONFLICT_HARD_REG_COSTS (conflict_a));
1785 conflict_costs
1786 = ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (conflict_a);
1787 if (conflict_costs != NULL)
1788 for (j = class_size - 1; j >= 0; j--)
1790 hard_regno = ira_class_hard_regs[aclass][j];
1791 ira_assert (hard_regno >= 0);
1792 k = ira_class_hard_reg_index[conflict_aclass][hard_regno];
1793 if (k < 0
1794 /* If HARD_REGNO is not available for CONFLICT_A,
1795 the conflict would be ignored, since HARD_REGNO
1796 will never be assigned to CONFLICT_A. */
1797 || !TEST_HARD_REG_BIT (data->profitable_hard_regs,
1798 hard_regno))
1799 continue;
1800 full_costs[j] -= conflict_costs[k];
1802 queue_update_cost (conflict_a, NULL, COST_HOP_DIVISOR);
1807 if (! retry_p)
1808 /* Take into account preferences of allocnos connected by copies to
1809 the conflict allocnos. */
1810 update_conflict_hard_regno_costs (full_costs, aclass, true);
1812 /* Take preferences of allocnos connected by copies into
1813 account. */
1814 if (! retry_p)
1816 start_update_cost ();
1817 queue_update_cost (a, NULL, COST_HOP_DIVISOR);
1818 update_conflict_hard_regno_costs (full_costs, aclass, false);
1820 min_cost = min_full_cost = INT_MAX;
1821 /* We don't care about giving callee saved registers to allocnos no
1822 living through calls because call clobbered registers are
1823 allocated first (it is usual practice to put them first in
1824 REG_ALLOC_ORDER). */
1825 mode = ALLOCNO_MODE (a);
1826 for (i = 0; i < class_size; i++)
1828 hard_regno = ira_class_hard_regs[aclass][i];
1829 #ifdef STACK_REGS
1830 if (no_stack_reg_p
1831 && FIRST_STACK_REG <= hard_regno && hard_regno <= LAST_STACK_REG)
1832 continue;
1833 #endif
1834 if (! check_hard_reg_p (a, hard_regno,
1835 conflicting_regs, profitable_hard_regs))
1836 continue;
1837 cost = costs[i];
1838 full_cost = full_costs[i];
1839 if (!HONOR_REG_ALLOC_ORDER)
1841 if ((saved_nregs = calculate_saved_nregs (hard_regno, mode)) != 0)
1842 /* We need to save/restore the hard register in
1843 epilogue/prologue. Therefore we increase the cost. */
1845 rclass = REGNO_REG_CLASS (hard_regno);
1846 add_cost = ((ira_memory_move_cost[mode][rclass][0]
1847 + ira_memory_move_cost[mode][rclass][1])
1848 * saved_nregs / hard_regno_nregs[hard_regno][mode] - 1);
1849 cost += add_cost;
1850 full_cost += add_cost;
1853 if (min_cost > cost)
1854 min_cost = cost;
1855 if (min_full_cost > full_cost)
1857 min_full_cost = full_cost;
1858 best_hard_regno = hard_regno;
1859 ira_assert (hard_regno >= 0);
1862 if (min_full_cost > mem_cost)
1864 if (! retry_p && internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
1865 fprintf (ira_dump_file, "(memory is more profitable %d vs %d) ",
1866 mem_cost, min_full_cost);
1867 best_hard_regno = -1;
1869 fail:
1870 if (best_hard_regno >= 0)
1872 for (i = hard_regno_nregs[best_hard_regno][mode] - 1; i >= 0; i--)
1873 allocated_hardreg_p[best_hard_regno + i] = true;
1875 if (! retry_p)
1876 restore_costs_from_copies (a);
1877 ALLOCNO_HARD_REGNO (a) = best_hard_regno;
1878 ALLOCNO_ASSIGNED_P (a) = true;
1879 if (best_hard_regno >= 0)
1880 update_costs_from_copies (a, true, ! retry_p);
1881 ira_assert (ALLOCNO_CLASS (a) == aclass);
1882 /* We don't need updated costs anymore. */
1883 ira_free_allocno_updated_costs (a);
1884 return best_hard_regno >= 0;
1889 /* An array used to sort copies. */
1890 static ira_copy_t *sorted_copies;
1892 /* Return TRUE if live ranges of allocnos A1 and A2 intersect. It is
1893 used to find a conflict for new allocnos or allocnos with the
1894 different allocno classes. */
1895 static bool
1896 allocnos_conflict_by_live_ranges_p (ira_allocno_t a1, ira_allocno_t a2)
1898 rtx reg1, reg2;
1899 int i, j;
1900 int n1 = ALLOCNO_NUM_OBJECTS (a1);
1901 int n2 = ALLOCNO_NUM_OBJECTS (a2);
1903 if (a1 == a2)
1904 return false;
1905 reg1 = regno_reg_rtx[ALLOCNO_REGNO (a1)];
1906 reg2 = regno_reg_rtx[ALLOCNO_REGNO (a2)];
1907 if (reg1 != NULL && reg2 != NULL
1908 && ORIGINAL_REGNO (reg1) == ORIGINAL_REGNO (reg2))
1909 return false;
1911 for (i = 0; i < n1; i++)
1913 ira_object_t c1 = ALLOCNO_OBJECT (a1, i);
1915 for (j = 0; j < n2; j++)
1917 ira_object_t c2 = ALLOCNO_OBJECT (a2, j);
1919 if (ira_live_ranges_intersect_p (OBJECT_LIVE_RANGES (c1),
1920 OBJECT_LIVE_RANGES (c2)))
1921 return true;
1924 return false;
1927 /* The function is used to sort copies according to their execution
1928 frequencies. */
1929 static int
1930 copy_freq_compare_func (const void *v1p, const void *v2p)
1932 ira_copy_t cp1 = *(const ira_copy_t *) v1p, cp2 = *(const ira_copy_t *) v2p;
1933 int pri1, pri2;
1935 pri1 = cp1->freq;
1936 pri2 = cp2->freq;
1937 if (pri2 - pri1)
1938 return pri2 - pri1;
1940 /* If frequencies are equal, sort by copies, so that the results of
1941 qsort leave nothing to chance. */
1942 return cp1->num - cp2->num;
1947 /* Return true if any allocno from thread of A1 conflicts with any
1948 allocno from thread A2. */
1949 static bool
1950 allocno_thread_conflict_p (ira_allocno_t a1, ira_allocno_t a2)
1952 ira_allocno_t a, conflict_a;
1954 for (a = ALLOCNO_COLOR_DATA (a2)->next_thread_allocno;;
1955 a = ALLOCNO_COLOR_DATA (a)->next_thread_allocno)
1957 for (conflict_a = ALLOCNO_COLOR_DATA (a1)->next_thread_allocno;;
1958 conflict_a = ALLOCNO_COLOR_DATA (conflict_a)->next_thread_allocno)
1960 if (allocnos_conflict_by_live_ranges_p (a, conflict_a))
1961 return true;
1962 if (conflict_a == a1)
1963 break;
1965 if (a == a2)
1966 break;
1968 return false;
1971 /* Merge two threads given correspondingly by their first allocnos T1
1972 and T2 (more accurately merging T2 into T1). */
1973 static void
1974 merge_threads (ira_allocno_t t1, ira_allocno_t t2)
1976 ira_allocno_t a, next, last;
1978 gcc_assert (t1 != t2
1979 && ALLOCNO_COLOR_DATA (t1)->first_thread_allocno == t1
1980 && ALLOCNO_COLOR_DATA (t2)->first_thread_allocno == t2);
1981 for (last = t2, a = ALLOCNO_COLOR_DATA (t2)->next_thread_allocno;;
1982 a = ALLOCNO_COLOR_DATA (a)->next_thread_allocno)
1984 ALLOCNO_COLOR_DATA (a)->first_thread_allocno = t1;
1985 if (a == t2)
1986 break;
1987 last = a;
1989 next = ALLOCNO_COLOR_DATA (t1)->next_thread_allocno;
1990 ALLOCNO_COLOR_DATA (t1)->next_thread_allocno = t2;
1991 ALLOCNO_COLOR_DATA (last)->next_thread_allocno = next;
1992 ALLOCNO_COLOR_DATA (t1)->thread_freq += ALLOCNO_COLOR_DATA (t2)->thread_freq;
1995 /* Create threads by processing CP_NUM copies from sorted copies. We
1996 process the most expensive copies first. */
1997 static void
1998 form_threads_from_copies (int cp_num)
2000 ira_allocno_t a, thread1, thread2;
2001 ira_copy_t cp;
2002 int i, n;
2004 qsort (sorted_copies, cp_num, sizeof (ira_copy_t), copy_freq_compare_func);
2005 /* Form threads processing copies, most frequently executed
2006 first. */
2007 for (; cp_num != 0;)
2009 for (i = 0; i < cp_num; i++)
2011 cp = sorted_copies[i];
2012 thread1 = ALLOCNO_COLOR_DATA (cp->first)->first_thread_allocno;
2013 thread2 = ALLOCNO_COLOR_DATA (cp->second)->first_thread_allocno;
2014 if (thread1 == thread2)
2015 continue;
2016 if (! allocno_thread_conflict_p (thread1, thread2))
2018 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2019 fprintf
2020 (ira_dump_file,
2021 " Forming thread by copy %d:a%dr%d-a%dr%d (freq=%d):\n",
2022 cp->num, ALLOCNO_NUM (cp->first), ALLOCNO_REGNO (cp->first),
2023 ALLOCNO_NUM (cp->second), ALLOCNO_REGNO (cp->second),
2024 cp->freq);
2025 merge_threads (thread1, thread2);
2026 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2028 thread1 = ALLOCNO_COLOR_DATA (thread1)->first_thread_allocno;
2029 fprintf (ira_dump_file, " Result (freq=%d): a%dr%d(%d)",
2030 ALLOCNO_COLOR_DATA (thread1)->thread_freq,
2031 ALLOCNO_NUM (thread1), ALLOCNO_REGNO (thread1),
2032 ALLOCNO_FREQ (thread1));
2033 for (a = ALLOCNO_COLOR_DATA (thread1)->next_thread_allocno;
2034 a != thread1;
2035 a = ALLOCNO_COLOR_DATA (a)->next_thread_allocno)
2036 fprintf (ira_dump_file, " a%dr%d(%d)",
2037 ALLOCNO_NUM (a), ALLOCNO_REGNO (a),
2038 ALLOCNO_FREQ (a));
2039 fprintf (ira_dump_file, "\n");
2041 i++;
2042 break;
2045 /* Collect the rest of copies. */
2046 for (n = 0; i < cp_num; i++)
2048 cp = sorted_copies[i];
2049 if (ALLOCNO_COLOR_DATA (cp->first)->first_thread_allocno
2050 != ALLOCNO_COLOR_DATA (cp->second)->first_thread_allocno)
2051 sorted_copies[n++] = cp;
2053 cp_num = n;
2057 /* Create threads by processing copies of all alocnos from BUCKET. We
2058 process the most expensive copies first. */
2059 static void
2060 form_threads_from_bucket (ira_allocno_t bucket)
2062 ira_allocno_t a;
2063 ira_copy_t cp, next_cp;
2064 int cp_num = 0;
2066 for (a = bucket; a != NULL; a = ALLOCNO_COLOR_DATA (a)->next_bucket_allocno)
2068 for (cp = ALLOCNO_COPIES (a); cp != NULL; cp = next_cp)
2070 if (cp->first == a)
2072 next_cp = cp->next_first_allocno_copy;
2073 sorted_copies[cp_num++] = cp;
2075 else if (cp->second == a)
2076 next_cp = cp->next_second_allocno_copy;
2077 else
2078 gcc_unreachable ();
2081 form_threads_from_copies (cp_num);
2084 /* Create threads by processing copies of colorable allocno A. We
2085 process most expensive copies first. */
2086 static void
2087 form_threads_from_colorable_allocno (ira_allocno_t a)
2089 ira_allocno_t another_a;
2090 ira_copy_t cp, next_cp;
2091 int cp_num = 0;
2093 for (cp = ALLOCNO_COPIES (a); cp != NULL; cp = next_cp)
2095 if (cp->first == a)
2097 next_cp = cp->next_first_allocno_copy;
2098 another_a = cp->second;
2100 else if (cp->second == a)
2102 next_cp = cp->next_second_allocno_copy;
2103 another_a = cp->first;
2105 else
2106 gcc_unreachable ();
2107 if ((! ALLOCNO_COLOR_DATA (another_a)->in_graph_p
2108 && !ALLOCNO_COLOR_DATA (another_a)->may_be_spilled_p)
2109 || ALLOCNO_COLOR_DATA (another_a)->colorable_p)
2110 sorted_copies[cp_num++] = cp;
2112 form_threads_from_copies (cp_num);
2115 /* Form initial threads which contain only one allocno. */
2116 static void
2117 init_allocno_threads (void)
2119 ira_allocno_t a;
2120 unsigned int j;
2121 bitmap_iterator bi;
2123 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
2125 a = ira_allocnos[j];
2126 /* Set up initial thread data: */
2127 ALLOCNO_COLOR_DATA (a)->first_thread_allocno
2128 = ALLOCNO_COLOR_DATA (a)->next_thread_allocno = a;
2129 ALLOCNO_COLOR_DATA (a)->thread_freq = ALLOCNO_FREQ (a);
2135 /* This page contains the allocator based on the Chaitin-Briggs algorithm. */
2137 /* Bucket of allocnos that can colored currently without spilling. */
2138 static ira_allocno_t colorable_allocno_bucket;
2140 /* Bucket of allocnos that might be not colored currently without
2141 spilling. */
2142 static ira_allocno_t uncolorable_allocno_bucket;
2144 /* The current number of allocnos in the uncolorable_bucket. */
2145 static int uncolorable_allocnos_num;
2147 /* Return the current spill priority of allocno A. The less the
2148 number, the more preferable the allocno for spilling. */
2149 static inline int
2150 allocno_spill_priority (ira_allocno_t a)
2152 allocno_color_data_t data = ALLOCNO_COLOR_DATA (a);
2154 return (data->temp
2155 / (ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a)
2156 * ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]
2157 + 1));
2160 /* Add allocno A to bucket *BUCKET_PTR. A should be not in a bucket
2161 before the call. */
2162 static void
2163 add_allocno_to_bucket (ira_allocno_t a, ira_allocno_t *bucket_ptr)
2165 ira_allocno_t first_a;
2166 allocno_color_data_t data;
2168 if (bucket_ptr == &uncolorable_allocno_bucket
2169 && ALLOCNO_CLASS (a) != NO_REGS)
2171 uncolorable_allocnos_num++;
2172 ira_assert (uncolorable_allocnos_num > 0);
2174 first_a = *bucket_ptr;
2175 data = ALLOCNO_COLOR_DATA (a);
2176 data->next_bucket_allocno = first_a;
2177 data->prev_bucket_allocno = NULL;
2178 if (first_a != NULL)
2179 ALLOCNO_COLOR_DATA (first_a)->prev_bucket_allocno = a;
2180 *bucket_ptr = a;
2183 /* Compare two allocnos to define which allocno should be pushed first
2184 into the coloring stack. If the return is a negative number, the
2185 allocno given by the first parameter will be pushed first. In this
2186 case such allocno has less priority than the second one and the
2187 hard register will be assigned to it after assignment to the second
2188 one. As the result of such assignment order, the second allocno
2189 has a better chance to get the best hard register. */
2190 static int
2191 bucket_allocno_compare_func (const void *v1p, const void *v2p)
2193 ira_allocno_t a1 = *(const ira_allocno_t *) v1p;
2194 ira_allocno_t a2 = *(const ira_allocno_t *) v2p;
2195 int diff, freq1, freq2, a1_num, a2_num;
2196 ira_allocno_t t1 = ALLOCNO_COLOR_DATA (a1)->first_thread_allocno;
2197 ira_allocno_t t2 = ALLOCNO_COLOR_DATA (a2)->first_thread_allocno;
2198 int cl1 = ALLOCNO_CLASS (a1), cl2 = ALLOCNO_CLASS (a2);
2200 freq1 = ALLOCNO_COLOR_DATA (t1)->thread_freq;
2201 freq2 = ALLOCNO_COLOR_DATA (t2)->thread_freq;
2202 if ((diff = freq1 - freq2) != 0)
2203 return diff;
2205 if ((diff = ALLOCNO_NUM (t2) - ALLOCNO_NUM (t1)) != 0)
2206 return diff;
2208 /* Push pseudos requiring less hard registers first. It means that
2209 we will assign pseudos requiring more hard registers first
2210 avoiding creation small holes in free hard register file into
2211 which the pseudos requiring more hard registers can not fit. */
2212 if ((diff = (ira_reg_class_max_nregs[cl1][ALLOCNO_MODE (a1)]
2213 - ira_reg_class_max_nregs[cl2][ALLOCNO_MODE (a2)])) != 0)
2214 return diff;
2216 freq1 = ALLOCNO_FREQ (a1);
2217 freq2 = ALLOCNO_FREQ (a2);
2218 if ((diff = freq1 - freq2) != 0)
2219 return diff;
2221 a1_num = ALLOCNO_COLOR_DATA (a1)->available_regs_num;
2222 a2_num = ALLOCNO_COLOR_DATA (a2)->available_regs_num;
2223 if ((diff = a2_num - a1_num) != 0)
2224 return diff;
2225 return ALLOCNO_NUM (a2) - ALLOCNO_NUM (a1);
2228 /* Sort bucket *BUCKET_PTR and return the result through
2229 BUCKET_PTR. */
2230 static void
2231 sort_bucket (ira_allocno_t *bucket_ptr,
2232 int (*compare_func) (const void *, const void *))
2234 ira_allocno_t a, head;
2235 int n;
2237 for (n = 0, a = *bucket_ptr;
2238 a != NULL;
2239 a = ALLOCNO_COLOR_DATA (a)->next_bucket_allocno)
2240 sorted_allocnos[n++] = a;
2241 if (n <= 1)
2242 return;
2243 qsort (sorted_allocnos, n, sizeof (ira_allocno_t), compare_func);
2244 head = NULL;
2245 for (n--; n >= 0; n--)
2247 a = sorted_allocnos[n];
2248 ALLOCNO_COLOR_DATA (a)->next_bucket_allocno = head;
2249 ALLOCNO_COLOR_DATA (a)->prev_bucket_allocno = NULL;
2250 if (head != NULL)
2251 ALLOCNO_COLOR_DATA (head)->prev_bucket_allocno = a;
2252 head = a;
2254 *bucket_ptr = head;
2257 /* Add ALLOCNO to colorable bucket maintaining the order according
2258 their priority. ALLOCNO should be not in a bucket before the
2259 call. */
2260 static void
2261 add_allocno_to_ordered_colorable_bucket (ira_allocno_t allocno)
2263 ira_allocno_t before, after;
2265 form_threads_from_colorable_allocno (allocno);
2266 for (before = colorable_allocno_bucket, after = NULL;
2267 before != NULL;
2268 after = before,
2269 before = ALLOCNO_COLOR_DATA (before)->next_bucket_allocno)
2270 if (bucket_allocno_compare_func (&allocno, &before) < 0)
2271 break;
2272 ALLOCNO_COLOR_DATA (allocno)->next_bucket_allocno = before;
2273 ALLOCNO_COLOR_DATA (allocno)->prev_bucket_allocno = after;
2274 if (after == NULL)
2275 colorable_allocno_bucket = allocno;
2276 else
2277 ALLOCNO_COLOR_DATA (after)->next_bucket_allocno = allocno;
2278 if (before != NULL)
2279 ALLOCNO_COLOR_DATA (before)->prev_bucket_allocno = allocno;
2282 /* Delete ALLOCNO from bucket *BUCKET_PTR. It should be there before
2283 the call. */
2284 static void
2285 delete_allocno_from_bucket (ira_allocno_t allocno, ira_allocno_t *bucket_ptr)
2287 ira_allocno_t prev_allocno, next_allocno;
2289 if (bucket_ptr == &uncolorable_allocno_bucket
2290 && ALLOCNO_CLASS (allocno) != NO_REGS)
2292 uncolorable_allocnos_num--;
2293 ira_assert (uncolorable_allocnos_num >= 0);
2295 prev_allocno = ALLOCNO_COLOR_DATA (allocno)->prev_bucket_allocno;
2296 next_allocno = ALLOCNO_COLOR_DATA (allocno)->next_bucket_allocno;
2297 if (prev_allocno != NULL)
2298 ALLOCNO_COLOR_DATA (prev_allocno)->next_bucket_allocno = next_allocno;
2299 else
2301 ira_assert (*bucket_ptr == allocno);
2302 *bucket_ptr = next_allocno;
2304 if (next_allocno != NULL)
2305 ALLOCNO_COLOR_DATA (next_allocno)->prev_bucket_allocno = prev_allocno;
2308 /* Put allocno A onto the coloring stack without removing it from its
2309 bucket. Pushing allocno to the coloring stack can result in moving
2310 conflicting allocnos from the uncolorable bucket to the colorable
2311 one. */
2312 static void
2313 push_allocno_to_stack (ira_allocno_t a)
2315 enum reg_class aclass;
2316 allocno_color_data_t data, conflict_data;
2317 int size, i, n = ALLOCNO_NUM_OBJECTS (a);
2319 data = ALLOCNO_COLOR_DATA (a);
2320 data->in_graph_p = false;
2321 allocno_stack_vec.safe_push (a);
2322 aclass = ALLOCNO_CLASS (a);
2323 if (aclass == NO_REGS)
2324 return;
2325 size = ira_reg_class_max_nregs[aclass][ALLOCNO_MODE (a)];
2326 if (n > 1)
2328 /* We will deal with the subwords individually. */
2329 gcc_assert (size == ALLOCNO_NUM_OBJECTS (a));
2330 size = 1;
2332 for (i = 0; i < n; i++)
2334 ira_object_t obj = ALLOCNO_OBJECT (a, i);
2335 ira_object_t conflict_obj;
2336 ira_object_conflict_iterator oci;
2338 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
2340 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
2342 conflict_data = ALLOCNO_COLOR_DATA (conflict_a);
2343 if (conflict_data->colorable_p
2344 || ! conflict_data->in_graph_p
2345 || ALLOCNO_ASSIGNED_P (conflict_a)
2346 || !(hard_reg_set_intersect_p
2347 (ALLOCNO_COLOR_DATA (a)->profitable_hard_regs,
2348 conflict_data->profitable_hard_regs)))
2349 continue;
2350 ira_assert (bitmap_bit_p (coloring_allocno_bitmap,
2351 ALLOCNO_NUM (conflict_a)));
2352 if (update_left_conflict_sizes_p (conflict_a, a, size))
2354 delete_allocno_from_bucket
2355 (conflict_a, &uncolorable_allocno_bucket);
2356 add_allocno_to_ordered_colorable_bucket (conflict_a);
2357 if (internal_flag_ira_verbose > 4 && ira_dump_file != NULL)
2359 fprintf (ira_dump_file, " Making");
2360 ira_print_expanded_allocno (conflict_a);
2361 fprintf (ira_dump_file, " colorable\n");
2369 /* Put ALLOCNO onto the coloring stack and remove it from its bucket.
2370 The allocno is in the colorable bucket if COLORABLE_P is TRUE. */
2371 static void
2372 remove_allocno_from_bucket_and_push (ira_allocno_t allocno, bool colorable_p)
2374 if (colorable_p)
2375 delete_allocno_from_bucket (allocno, &colorable_allocno_bucket);
2376 else
2377 delete_allocno_from_bucket (allocno, &uncolorable_allocno_bucket);
2378 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2380 fprintf (ira_dump_file, " Pushing");
2381 ira_print_expanded_allocno (allocno);
2382 if (colorable_p)
2383 fprintf (ira_dump_file, "(cost %d)\n",
2384 ALLOCNO_COLOR_DATA (allocno)->temp);
2385 else
2386 fprintf (ira_dump_file, "(potential spill: %spri=%d, cost=%d)\n",
2387 ALLOCNO_BAD_SPILL_P (allocno) ? "bad spill, " : "",
2388 allocno_spill_priority (allocno),
2389 ALLOCNO_COLOR_DATA (allocno)->temp);
2391 if (! colorable_p)
2392 ALLOCNO_COLOR_DATA (allocno)->may_be_spilled_p = true;
2393 push_allocno_to_stack (allocno);
2396 /* Put all allocnos from colorable bucket onto the coloring stack. */
2397 static void
2398 push_only_colorable (void)
2400 form_threads_from_bucket (colorable_allocno_bucket);
2401 sort_bucket (&colorable_allocno_bucket, bucket_allocno_compare_func);
2402 for (;colorable_allocno_bucket != NULL;)
2403 remove_allocno_from_bucket_and_push (colorable_allocno_bucket, true);
2406 /* Return the frequency of exit edges (if EXIT_P) or entry from/to the
2407 loop given by its LOOP_NODE. */
2409 ira_loop_edge_freq (ira_loop_tree_node_t loop_node, int regno, bool exit_p)
2411 int freq, i;
2412 edge_iterator ei;
2413 edge e;
2414 vec<edge> edges;
2416 ira_assert (current_loops != NULL && loop_node->loop != NULL
2417 && (regno < 0 || regno >= FIRST_PSEUDO_REGISTER));
2418 freq = 0;
2419 if (! exit_p)
2421 FOR_EACH_EDGE (e, ei, loop_node->loop->header->preds)
2422 if (e->src != loop_node->loop->latch
2423 && (regno < 0
2424 || (bitmap_bit_p (df_get_live_out (e->src), regno)
2425 && bitmap_bit_p (df_get_live_in (e->dest), regno))))
2426 freq += EDGE_FREQUENCY (e);
2428 else
2430 edges = get_loop_exit_edges (loop_node->loop);
2431 FOR_EACH_VEC_ELT (edges, i, e)
2432 if (regno < 0
2433 || (bitmap_bit_p (df_get_live_out (e->src), regno)
2434 && bitmap_bit_p (df_get_live_in (e->dest), regno)))
2435 freq += EDGE_FREQUENCY (e);
2436 edges.release ();
2439 return REG_FREQ_FROM_EDGE_FREQ (freq);
2442 /* Calculate and return the cost of putting allocno A into memory. */
2443 static int
2444 calculate_allocno_spill_cost (ira_allocno_t a)
2446 int regno, cost;
2447 machine_mode mode;
2448 enum reg_class rclass;
2449 ira_allocno_t parent_allocno;
2450 ira_loop_tree_node_t parent_node, loop_node;
2452 regno = ALLOCNO_REGNO (a);
2453 cost = ALLOCNO_UPDATED_MEMORY_COST (a) - ALLOCNO_UPDATED_CLASS_COST (a);
2454 if (ALLOCNO_CAP (a) != NULL)
2455 return cost;
2456 loop_node = ALLOCNO_LOOP_TREE_NODE (a);
2457 if ((parent_node = loop_node->parent) == NULL)
2458 return cost;
2459 if ((parent_allocno = parent_node->regno_allocno_map[regno]) == NULL)
2460 return cost;
2461 mode = ALLOCNO_MODE (a);
2462 rclass = ALLOCNO_CLASS (a);
2463 if (ALLOCNO_HARD_REGNO (parent_allocno) < 0)
2464 cost -= (ira_memory_move_cost[mode][rclass][0]
2465 * ira_loop_edge_freq (loop_node, regno, true)
2466 + ira_memory_move_cost[mode][rclass][1]
2467 * ira_loop_edge_freq (loop_node, regno, false));
2468 else
2470 ira_init_register_move_cost_if_necessary (mode);
2471 cost += ((ira_memory_move_cost[mode][rclass][1]
2472 * ira_loop_edge_freq (loop_node, regno, true)
2473 + ira_memory_move_cost[mode][rclass][0]
2474 * ira_loop_edge_freq (loop_node, regno, false))
2475 - (ira_register_move_cost[mode][rclass][rclass]
2476 * (ira_loop_edge_freq (loop_node, regno, false)
2477 + ira_loop_edge_freq (loop_node, regno, true))));
2479 return cost;
2482 /* Used for sorting allocnos for spilling. */
2483 static inline int
2484 allocno_spill_priority_compare (ira_allocno_t a1, ira_allocno_t a2)
2486 int pri1, pri2, diff;
2488 if (ALLOCNO_BAD_SPILL_P (a1) && ! ALLOCNO_BAD_SPILL_P (a2))
2489 return 1;
2490 if (ALLOCNO_BAD_SPILL_P (a2) && ! ALLOCNO_BAD_SPILL_P (a1))
2491 return -1;
2492 pri1 = allocno_spill_priority (a1);
2493 pri2 = allocno_spill_priority (a2);
2494 if ((diff = pri1 - pri2) != 0)
2495 return diff;
2496 if ((diff
2497 = ALLOCNO_COLOR_DATA (a1)->temp - ALLOCNO_COLOR_DATA (a2)->temp) != 0)
2498 return diff;
2499 return ALLOCNO_NUM (a1) - ALLOCNO_NUM (a2);
2502 /* Used for sorting allocnos for spilling. */
2503 static int
2504 allocno_spill_sort_compare (const void *v1p, const void *v2p)
2506 ira_allocno_t p1 = *(const ira_allocno_t *) v1p;
2507 ira_allocno_t p2 = *(const ira_allocno_t *) v2p;
2509 return allocno_spill_priority_compare (p1, p2);
2512 /* Push allocnos to the coloring stack. The order of allocnos in the
2513 stack defines the order for the subsequent coloring. */
2514 static void
2515 push_allocnos_to_stack (void)
2517 ira_allocno_t a;
2518 int cost;
2520 /* Calculate uncolorable allocno spill costs. */
2521 for (a = uncolorable_allocno_bucket;
2522 a != NULL;
2523 a = ALLOCNO_COLOR_DATA (a)->next_bucket_allocno)
2524 if (ALLOCNO_CLASS (a) != NO_REGS)
2526 cost = calculate_allocno_spill_cost (a);
2527 /* ??? Remove cost of copies between the coalesced
2528 allocnos. */
2529 ALLOCNO_COLOR_DATA (a)->temp = cost;
2531 sort_bucket (&uncolorable_allocno_bucket, allocno_spill_sort_compare);
2532 for (;;)
2534 push_only_colorable ();
2535 a = uncolorable_allocno_bucket;
2536 if (a == NULL)
2537 break;
2538 remove_allocno_from_bucket_and_push (a, false);
2540 ira_assert (colorable_allocno_bucket == NULL
2541 && uncolorable_allocno_bucket == NULL);
2542 ira_assert (uncolorable_allocnos_num == 0);
2545 /* Pop the coloring stack and assign hard registers to the popped
2546 allocnos. */
2547 static void
2548 pop_allocnos_from_stack (void)
2550 ira_allocno_t allocno;
2551 enum reg_class aclass;
2553 for (;allocno_stack_vec.length () != 0;)
2555 allocno = allocno_stack_vec.pop ();
2556 aclass = ALLOCNO_CLASS (allocno);
2557 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2559 fprintf (ira_dump_file, " Popping");
2560 ira_print_expanded_allocno (allocno);
2561 fprintf (ira_dump_file, " -- ");
2563 if (aclass == NO_REGS)
2565 ALLOCNO_HARD_REGNO (allocno) = -1;
2566 ALLOCNO_ASSIGNED_P (allocno) = true;
2567 ira_assert (ALLOCNO_UPDATED_HARD_REG_COSTS (allocno) == NULL);
2568 ira_assert
2569 (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (allocno) == NULL);
2570 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2571 fprintf (ira_dump_file, "assign memory\n");
2573 else if (assign_hard_reg (allocno, false))
2575 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2576 fprintf (ira_dump_file, "assign reg %d\n",
2577 ALLOCNO_HARD_REGNO (allocno));
2579 else if (ALLOCNO_ASSIGNED_P (allocno))
2581 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2582 fprintf (ira_dump_file, "spill%s\n",
2583 ALLOCNO_COLOR_DATA (allocno)->may_be_spilled_p
2584 ? "" : "!");
2586 ALLOCNO_COLOR_DATA (allocno)->in_graph_p = true;
2590 /* Set up number of available hard registers for allocno A. */
2591 static void
2592 setup_allocno_available_regs_num (ira_allocno_t a)
2594 int i, n, hard_regno, hard_regs_num, nwords;
2595 enum reg_class aclass;
2596 allocno_color_data_t data;
2598 aclass = ALLOCNO_CLASS (a);
2599 data = ALLOCNO_COLOR_DATA (a);
2600 data->available_regs_num = 0;
2601 if (aclass == NO_REGS)
2602 return;
2603 hard_regs_num = ira_class_hard_regs_num[aclass];
2604 nwords = ALLOCNO_NUM_OBJECTS (a);
2605 for (n = 0, i = hard_regs_num - 1; i >= 0; i--)
2607 hard_regno = ira_class_hard_regs[aclass][i];
2608 /* Checking only profitable hard regs. */
2609 if (TEST_HARD_REG_BIT (data->profitable_hard_regs, hard_regno))
2610 n++;
2612 data->available_regs_num = n;
2613 if (internal_flag_ira_verbose <= 2 || ira_dump_file == NULL)
2614 return;
2615 fprintf
2616 (ira_dump_file,
2617 " Allocno a%dr%d of %s(%d) has %d avail. regs ",
2618 ALLOCNO_NUM (a), ALLOCNO_REGNO (a),
2619 reg_class_names[aclass], ira_class_hard_regs_num[aclass], n);
2620 print_hard_reg_set (ira_dump_file, data->profitable_hard_regs, false);
2621 fprintf (ira_dump_file, ", %snode: ",
2622 hard_reg_set_equal_p (data->profitable_hard_regs,
2623 data->hard_regs_node->hard_regs->set)
2624 ? "" : "^");
2625 print_hard_reg_set (ira_dump_file,
2626 data->hard_regs_node->hard_regs->set, false);
2627 for (i = 0; i < nwords; i++)
2629 ira_object_t obj = ALLOCNO_OBJECT (a, i);
2631 if (nwords != 1)
2633 if (i != 0)
2634 fprintf (ira_dump_file, ", ");
2635 fprintf (ira_dump_file, " obj %d", i);
2637 fprintf (ira_dump_file, " (confl regs = ");
2638 print_hard_reg_set (ira_dump_file, OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
2639 false);
2640 fprintf (ira_dump_file, ")");
2642 fprintf (ira_dump_file, "\n");
2645 /* Put ALLOCNO in a bucket corresponding to its number and size of its
2646 conflicting allocnos and hard registers. */
2647 static void
2648 put_allocno_into_bucket (ira_allocno_t allocno)
2650 ALLOCNO_COLOR_DATA (allocno)->in_graph_p = true;
2651 setup_allocno_available_regs_num (allocno);
2652 if (setup_left_conflict_sizes_p (allocno))
2653 add_allocno_to_bucket (allocno, &colorable_allocno_bucket);
2654 else
2655 add_allocno_to_bucket (allocno, &uncolorable_allocno_bucket);
2658 /* Map: allocno number -> allocno priority. */
2659 static int *allocno_priorities;
2661 /* Set up priorities for N allocnos in array
2662 CONSIDERATION_ALLOCNOS. */
2663 static void
2664 setup_allocno_priorities (ira_allocno_t *consideration_allocnos, int n)
2666 int i, length, nrefs, priority, max_priority, mult;
2667 ira_allocno_t a;
2669 max_priority = 0;
2670 for (i = 0; i < n; i++)
2672 a = consideration_allocnos[i];
2673 nrefs = ALLOCNO_NREFS (a);
2674 ira_assert (nrefs >= 0);
2675 mult = floor_log2 (ALLOCNO_NREFS (a)) + 1;
2676 ira_assert (mult >= 0);
2677 allocno_priorities[ALLOCNO_NUM (a)]
2678 = priority
2679 = (mult
2680 * (ALLOCNO_MEMORY_COST (a) - ALLOCNO_CLASS_COST (a))
2681 * ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]);
2682 if (priority < 0)
2683 priority = -priority;
2684 if (max_priority < priority)
2685 max_priority = priority;
2687 mult = max_priority == 0 ? 1 : INT_MAX / max_priority;
2688 for (i = 0; i < n; i++)
2690 a = consideration_allocnos[i];
2691 length = ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a);
2692 if (ALLOCNO_NUM_OBJECTS (a) > 1)
2693 length /= ALLOCNO_NUM_OBJECTS (a);
2694 if (length <= 0)
2695 length = 1;
2696 allocno_priorities[ALLOCNO_NUM (a)]
2697 = allocno_priorities[ALLOCNO_NUM (a)] * mult / length;
2701 /* Sort allocnos according to the profit of usage of a hard register
2702 instead of memory for them. */
2703 static int
2704 allocno_cost_compare_func (const void *v1p, const void *v2p)
2706 ira_allocno_t p1 = *(const ira_allocno_t *) v1p;
2707 ira_allocno_t p2 = *(const ira_allocno_t *) v2p;
2708 int c1, c2;
2710 c1 = ALLOCNO_UPDATED_MEMORY_COST (p1) - ALLOCNO_UPDATED_CLASS_COST (p1);
2711 c2 = ALLOCNO_UPDATED_MEMORY_COST (p2) - ALLOCNO_UPDATED_CLASS_COST (p2);
2712 if (c1 - c2)
2713 return c1 - c2;
2715 /* If regs are equally good, sort by allocno numbers, so that the
2716 results of qsort leave nothing to chance. */
2717 return ALLOCNO_NUM (p1) - ALLOCNO_NUM (p2);
2720 /* We used Chaitin-Briggs coloring to assign as many pseudos as
2721 possible to hard registers. Let us try to improve allocation with
2722 cost point of view. This function improves the allocation by
2723 spilling some allocnos and assigning the freed hard registers to
2724 other allocnos if it decreases the overall allocation cost. */
2725 static void
2726 improve_allocation (void)
2728 unsigned int i;
2729 int j, k, n, hregno, conflict_hregno, base_cost, class_size, word, nwords;
2730 int check, spill_cost, min_cost, nregs, conflict_nregs, r, best;
2731 bool try_p;
2732 enum reg_class aclass;
2733 machine_mode mode;
2734 int *allocno_costs;
2735 int costs[FIRST_PSEUDO_REGISTER];
2736 HARD_REG_SET conflicting_regs[2], profitable_hard_regs;
2737 ira_allocno_t a;
2738 bitmap_iterator bi;
2740 /* Clear counts used to process conflicting allocnos only once for
2741 each allocno. */
2742 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
2743 ALLOCNO_COLOR_DATA (ira_allocnos[i])->temp = 0;
2744 check = n = 0;
2745 /* Process each allocno and try to assign a hard register to it by
2746 spilling some its conflicting allocnos. */
2747 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
2749 a = ira_allocnos[i];
2750 ALLOCNO_COLOR_DATA (a)->temp = 0;
2751 if (empty_profitable_hard_regs (a))
2752 continue;
2753 check++;
2754 aclass = ALLOCNO_CLASS (a);
2755 allocno_costs = ALLOCNO_UPDATED_HARD_REG_COSTS (a);
2756 if (allocno_costs == NULL)
2757 allocno_costs = ALLOCNO_HARD_REG_COSTS (a);
2758 if ((hregno = ALLOCNO_HARD_REGNO (a)) < 0)
2759 base_cost = ALLOCNO_UPDATED_MEMORY_COST (a);
2760 else if (allocno_costs == NULL)
2761 /* It means that assigning a hard register is not profitable
2762 (we don't waste memory for hard register costs in this
2763 case). */
2764 continue;
2765 else
2766 base_cost = allocno_costs[ira_class_hard_reg_index[aclass][hregno]];
2767 try_p = false;
2768 get_conflict_and_start_profitable_regs (a, false,
2769 conflicting_regs,
2770 &profitable_hard_regs);
2771 class_size = ira_class_hard_regs_num[aclass];
2772 /* Set up cost improvement for usage of each profitable hard
2773 register for allocno A. */
2774 for (j = 0; j < class_size; j++)
2776 hregno = ira_class_hard_regs[aclass][j];
2777 if (! check_hard_reg_p (a, hregno,
2778 conflicting_regs, profitable_hard_regs))
2779 continue;
2780 ira_assert (ira_class_hard_reg_index[aclass][hregno] == j);
2781 k = allocno_costs == NULL ? 0 : j;
2782 costs[hregno] = (allocno_costs == NULL
2783 ? ALLOCNO_UPDATED_CLASS_COST (a) : allocno_costs[k]);
2784 costs[hregno] -= base_cost;
2785 if (costs[hregno] < 0)
2786 try_p = true;
2788 if (! try_p)
2789 /* There is no chance to improve the allocation cost by
2790 assigning hard register to allocno A even without spilling
2791 conflicting allocnos. */
2792 continue;
2793 mode = ALLOCNO_MODE (a);
2794 nwords = ALLOCNO_NUM_OBJECTS (a);
2795 /* Process each allocno conflicting with A and update the cost
2796 improvement for profitable hard registers of A. To use a
2797 hard register for A we need to spill some conflicting
2798 allocnos and that creates penalty for the cost
2799 improvement. */
2800 for (word = 0; word < nwords; word++)
2802 ira_object_t conflict_obj;
2803 ira_object_t obj = ALLOCNO_OBJECT (a, word);
2804 ira_object_conflict_iterator oci;
2806 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
2808 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
2810 if (ALLOCNO_COLOR_DATA (conflict_a)->temp == check)
2811 /* We already processed this conflicting allocno
2812 because we processed earlier another object of the
2813 conflicting allocno. */
2814 continue;
2815 ALLOCNO_COLOR_DATA (conflict_a)->temp = check;
2816 if ((conflict_hregno = ALLOCNO_HARD_REGNO (conflict_a)) < 0)
2817 continue;
2818 spill_cost = ALLOCNO_UPDATED_MEMORY_COST (conflict_a);
2819 k = (ira_class_hard_reg_index
2820 [ALLOCNO_CLASS (conflict_a)][conflict_hregno]);
2821 ira_assert (k >= 0);
2822 if ((allocno_costs = ALLOCNO_UPDATED_HARD_REG_COSTS (conflict_a))
2823 != NULL)
2824 spill_cost -= allocno_costs[k];
2825 else if ((allocno_costs = ALLOCNO_HARD_REG_COSTS (conflict_a))
2826 != NULL)
2827 spill_cost -= allocno_costs[k];
2828 else
2829 spill_cost -= ALLOCNO_UPDATED_CLASS_COST (conflict_a);
2830 conflict_nregs
2831 = hard_regno_nregs[conflict_hregno][ALLOCNO_MODE (conflict_a)];
2832 for (r = conflict_hregno;
2833 r >= 0 && r + hard_regno_nregs[r][mode] > conflict_hregno;
2834 r--)
2835 if (check_hard_reg_p (a, r,
2836 conflicting_regs, profitable_hard_regs))
2837 costs[r] += spill_cost;
2838 for (r = conflict_hregno + 1;
2839 r < conflict_hregno + conflict_nregs;
2840 r++)
2841 if (check_hard_reg_p (a, r,
2842 conflicting_regs, profitable_hard_regs))
2843 costs[r] += spill_cost;
2846 min_cost = INT_MAX;
2847 best = -1;
2848 /* Now we choose hard register for A which results in highest
2849 allocation cost improvement. */
2850 for (j = 0; j < class_size; j++)
2852 hregno = ira_class_hard_regs[aclass][j];
2853 if (check_hard_reg_p (a, hregno,
2854 conflicting_regs, profitable_hard_regs)
2855 && min_cost > costs[hregno])
2857 best = hregno;
2858 min_cost = costs[hregno];
2861 if (min_cost >= 0)
2862 /* We are in a situation when assigning any hard register to A
2863 by spilling some conflicting allocnos does not improve the
2864 allocation cost. */
2865 continue;
2866 nregs = hard_regno_nregs[best][mode];
2867 /* Now spill conflicting allocnos which contain a hard register
2868 of A when we assign the best chosen hard register to it. */
2869 for (word = 0; word < nwords; word++)
2871 ira_object_t conflict_obj;
2872 ira_object_t obj = ALLOCNO_OBJECT (a, word);
2873 ira_object_conflict_iterator oci;
2875 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
2877 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
2879 if ((conflict_hregno = ALLOCNO_HARD_REGNO (conflict_a)) < 0)
2880 continue;
2881 conflict_nregs
2882 = hard_regno_nregs[conflict_hregno][ALLOCNO_MODE (conflict_a)];
2883 if (best + nregs <= conflict_hregno
2884 || conflict_hregno + conflict_nregs <= best)
2885 /* No intersection. */
2886 continue;
2887 ALLOCNO_HARD_REGNO (conflict_a) = -1;
2888 sorted_allocnos[n++] = conflict_a;
2889 if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
2890 fprintf (ira_dump_file, "Spilling a%dr%d for a%dr%d\n",
2891 ALLOCNO_NUM (conflict_a), ALLOCNO_REGNO (conflict_a),
2892 ALLOCNO_NUM (a), ALLOCNO_REGNO (a));
2895 /* Assign the best chosen hard register to A. */
2896 ALLOCNO_HARD_REGNO (a) = best;
2897 if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
2898 fprintf (ira_dump_file, "Assigning %d to a%dr%d\n",
2899 best, ALLOCNO_NUM (a), ALLOCNO_REGNO (a));
2901 if (n == 0)
2902 return;
2903 /* We spilled some allocnos to assign their hard registers to other
2904 allocnos. The spilled allocnos are now in array
2905 'sorted_allocnos'. There is still a possibility that some of the
2906 spilled allocnos can get hard registers. So let us try assign
2907 them hard registers again (just a reminder -- function
2908 'assign_hard_reg' assigns hard registers only if it is possible
2909 and profitable). We process the spilled allocnos with biggest
2910 benefit to get hard register first -- see function
2911 'allocno_cost_compare_func'. */
2912 qsort (sorted_allocnos, n, sizeof (ira_allocno_t),
2913 allocno_cost_compare_func);
2914 for (j = 0; j < n; j++)
2916 a = sorted_allocnos[j];
2917 ALLOCNO_ASSIGNED_P (a) = false;
2918 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2920 fprintf (ira_dump_file, " ");
2921 ira_print_expanded_allocno (a);
2922 fprintf (ira_dump_file, " -- ");
2924 if (assign_hard_reg (a, false))
2926 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2927 fprintf (ira_dump_file, "assign hard reg %d\n",
2928 ALLOCNO_HARD_REGNO (a));
2930 else
2932 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2933 fprintf (ira_dump_file, "assign memory\n");
2938 /* Sort allocnos according to their priorities. */
2939 static int
2940 allocno_priority_compare_func (const void *v1p, const void *v2p)
2942 ira_allocno_t a1 = *(const ira_allocno_t *) v1p;
2943 ira_allocno_t a2 = *(const ira_allocno_t *) v2p;
2944 int pri1, pri2;
2946 pri1 = allocno_priorities[ALLOCNO_NUM (a1)];
2947 pri2 = allocno_priorities[ALLOCNO_NUM (a2)];
2948 if (pri2 != pri1)
2949 return SORTGT (pri2, pri1);
2951 /* If regs are equally good, sort by allocnos, so that the results of
2952 qsort leave nothing to chance. */
2953 return ALLOCNO_NUM (a1) - ALLOCNO_NUM (a2);
2956 /* Chaitin-Briggs coloring for allocnos in COLORING_ALLOCNO_BITMAP
2957 taking into account allocnos in CONSIDERATION_ALLOCNO_BITMAP. */
2958 static void
2959 color_allocnos (void)
2961 unsigned int i, n;
2962 bitmap_iterator bi;
2963 ira_allocno_t a;
2965 setup_profitable_hard_regs ();
2966 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
2968 int l, nr;
2969 HARD_REG_SET conflict_hard_regs;
2970 allocno_color_data_t data;
2971 ira_pref_t pref, next_pref;
2973 a = ira_allocnos[i];
2974 nr = ALLOCNO_NUM_OBJECTS (a);
2975 CLEAR_HARD_REG_SET (conflict_hard_regs);
2976 for (l = 0; l < nr; l++)
2978 ira_object_t obj = ALLOCNO_OBJECT (a, l);
2979 IOR_HARD_REG_SET (conflict_hard_regs,
2980 OBJECT_CONFLICT_HARD_REGS (obj));
2982 data = ALLOCNO_COLOR_DATA (a);
2983 for (pref = ALLOCNO_PREFS (a); pref != NULL; pref = next_pref)
2985 next_pref = pref->next_pref;
2986 if (! ira_hard_reg_in_set_p (pref->hard_regno,
2987 ALLOCNO_MODE (a),
2988 data->profitable_hard_regs))
2989 ira_remove_pref (pref);
2992 if (flag_ira_algorithm == IRA_ALGORITHM_PRIORITY)
2994 n = 0;
2995 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
2997 a = ira_allocnos[i];
2998 if (ALLOCNO_CLASS (a) == NO_REGS)
3000 ALLOCNO_HARD_REGNO (a) = -1;
3001 ALLOCNO_ASSIGNED_P (a) = true;
3002 ira_assert (ALLOCNO_UPDATED_HARD_REG_COSTS (a) == NULL);
3003 ira_assert (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a) == NULL);
3004 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3006 fprintf (ira_dump_file, " Spill");
3007 ira_print_expanded_allocno (a);
3008 fprintf (ira_dump_file, "\n");
3010 continue;
3012 sorted_allocnos[n++] = a;
3014 if (n != 0)
3016 setup_allocno_priorities (sorted_allocnos, n);
3017 qsort (sorted_allocnos, n, sizeof (ira_allocno_t),
3018 allocno_priority_compare_func);
3019 for (i = 0; i < n; i++)
3021 a = sorted_allocnos[i];
3022 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3024 fprintf (ira_dump_file, " ");
3025 ira_print_expanded_allocno (a);
3026 fprintf (ira_dump_file, " -- ");
3028 if (assign_hard_reg (a, false))
3030 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3031 fprintf (ira_dump_file, "assign hard reg %d\n",
3032 ALLOCNO_HARD_REGNO (a));
3034 else
3036 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3037 fprintf (ira_dump_file, "assign memory\n");
3042 else
3044 form_allocno_hard_regs_nodes_forest ();
3045 if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
3046 print_hard_regs_forest (ira_dump_file);
3047 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
3049 a = ira_allocnos[i];
3050 if (ALLOCNO_CLASS (a) != NO_REGS && ! empty_profitable_hard_regs (a))
3052 ALLOCNO_COLOR_DATA (a)->in_graph_p = true;
3053 update_costs_from_prefs (a);
3055 else
3057 ALLOCNO_HARD_REGNO (a) = -1;
3058 ALLOCNO_ASSIGNED_P (a) = true;
3059 /* We don't need updated costs anymore. */
3060 ira_free_allocno_updated_costs (a);
3061 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3063 fprintf (ira_dump_file, " Spill");
3064 ira_print_expanded_allocno (a);
3065 fprintf (ira_dump_file, "\n");
3069 /* Put the allocnos into the corresponding buckets. */
3070 colorable_allocno_bucket = NULL;
3071 uncolorable_allocno_bucket = NULL;
3072 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
3074 a = ira_allocnos[i];
3075 if (ALLOCNO_COLOR_DATA (a)->in_graph_p)
3076 put_allocno_into_bucket (a);
3078 push_allocnos_to_stack ();
3079 pop_allocnos_from_stack ();
3080 finish_allocno_hard_regs_nodes_forest ();
3082 improve_allocation ();
3087 /* Output information about the loop given by its LOOP_TREE_NODE. */
3088 static void
3089 print_loop_title (ira_loop_tree_node_t loop_tree_node)
3091 unsigned int j;
3092 bitmap_iterator bi;
3093 ira_loop_tree_node_t subloop_node, dest_loop_node;
3094 edge e;
3095 edge_iterator ei;
3097 if (loop_tree_node->parent == NULL)
3098 fprintf (ira_dump_file,
3099 "\n Loop 0 (parent -1, header bb%d, depth 0)\n bbs:",
3100 NUM_FIXED_BLOCKS);
3101 else
3103 ira_assert (current_loops != NULL && loop_tree_node->loop != NULL);
3104 fprintf (ira_dump_file,
3105 "\n Loop %d (parent %d, header bb%d, depth %d)\n bbs:",
3106 loop_tree_node->loop_num, loop_tree_node->parent->loop_num,
3107 loop_tree_node->loop->header->index,
3108 loop_depth (loop_tree_node->loop));
3110 for (subloop_node = loop_tree_node->children;
3111 subloop_node != NULL;
3112 subloop_node = subloop_node->next)
3113 if (subloop_node->bb != NULL)
3115 fprintf (ira_dump_file, " %d", subloop_node->bb->index);
3116 FOR_EACH_EDGE (e, ei, subloop_node->bb->succs)
3117 if (e->dest != EXIT_BLOCK_PTR_FOR_FN (cfun)
3118 && ((dest_loop_node = IRA_BB_NODE (e->dest)->parent)
3119 != loop_tree_node))
3120 fprintf (ira_dump_file, "(->%d:l%d)",
3121 e->dest->index, dest_loop_node->loop_num);
3123 fprintf (ira_dump_file, "\n all:");
3124 EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->all_allocnos, 0, j, bi)
3125 fprintf (ira_dump_file, " %dr%d", j, ALLOCNO_REGNO (ira_allocnos[j]));
3126 fprintf (ira_dump_file, "\n modified regnos:");
3127 EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->modified_regnos, 0, j, bi)
3128 fprintf (ira_dump_file, " %d", j);
3129 fprintf (ira_dump_file, "\n border:");
3130 EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->border_allocnos, 0, j, bi)
3131 fprintf (ira_dump_file, " %dr%d", j, ALLOCNO_REGNO (ira_allocnos[j]));
3132 fprintf (ira_dump_file, "\n Pressure:");
3133 for (j = 0; (int) j < ira_pressure_classes_num; j++)
3135 enum reg_class pclass;
3137 pclass = ira_pressure_classes[j];
3138 if (loop_tree_node->reg_pressure[pclass] == 0)
3139 continue;
3140 fprintf (ira_dump_file, " %s=%d", reg_class_names[pclass],
3141 loop_tree_node->reg_pressure[pclass]);
3143 fprintf (ira_dump_file, "\n");
3146 /* Color the allocnos inside loop (in the extreme case it can be all
3147 of the function) given the corresponding LOOP_TREE_NODE. The
3148 function is called for each loop during top-down traverse of the
3149 loop tree. */
3150 static void
3151 color_pass (ira_loop_tree_node_t loop_tree_node)
3153 int regno, hard_regno, index = -1, n;
3154 int cost, exit_freq, enter_freq;
3155 unsigned int j;
3156 bitmap_iterator bi;
3157 machine_mode mode;
3158 enum reg_class rclass, aclass, pclass;
3159 ira_allocno_t a, subloop_allocno;
3160 ira_loop_tree_node_t subloop_node;
3162 ira_assert (loop_tree_node->bb == NULL);
3163 if (internal_flag_ira_verbose > 1 && ira_dump_file != NULL)
3164 print_loop_title (loop_tree_node);
3166 bitmap_copy (coloring_allocno_bitmap, loop_tree_node->all_allocnos);
3167 bitmap_copy (consideration_allocno_bitmap, coloring_allocno_bitmap);
3168 n = 0;
3169 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
3171 a = ira_allocnos[j];
3172 n++;
3173 if (! ALLOCNO_ASSIGNED_P (a))
3174 continue;
3175 bitmap_clear_bit (coloring_allocno_bitmap, ALLOCNO_NUM (a));
3177 allocno_color_data
3178 = (allocno_color_data_t) ira_allocate (sizeof (struct allocno_color_data)
3179 * n);
3180 memset (allocno_color_data, 0, sizeof (struct allocno_color_data) * n);
3181 curr_allocno_process = 0;
3182 n = 0;
3183 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
3185 a = ira_allocnos[j];
3186 ALLOCNO_ADD_DATA (a) = allocno_color_data + n;
3187 n++;
3189 init_allocno_threads ();
3190 /* Color all mentioned allocnos including transparent ones. */
3191 color_allocnos ();
3192 /* Process caps. They are processed just once. */
3193 if (flag_ira_region == IRA_REGION_MIXED
3194 || flag_ira_region == IRA_REGION_ALL)
3195 EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->all_allocnos, 0, j, bi)
3197 a = ira_allocnos[j];
3198 if (ALLOCNO_CAP_MEMBER (a) == NULL)
3199 continue;
3200 /* Remove from processing in the next loop. */
3201 bitmap_clear_bit (consideration_allocno_bitmap, j);
3202 rclass = ALLOCNO_CLASS (a);
3203 pclass = ira_pressure_class_translate[rclass];
3204 if (flag_ira_region == IRA_REGION_MIXED
3205 && (loop_tree_node->reg_pressure[pclass]
3206 <= ira_class_hard_regs_num[pclass]))
3208 mode = ALLOCNO_MODE (a);
3209 hard_regno = ALLOCNO_HARD_REGNO (a);
3210 if (hard_regno >= 0)
3212 index = ira_class_hard_reg_index[rclass][hard_regno];
3213 ira_assert (index >= 0);
3215 regno = ALLOCNO_REGNO (a);
3216 subloop_allocno = ALLOCNO_CAP_MEMBER (a);
3217 subloop_node = ALLOCNO_LOOP_TREE_NODE (subloop_allocno);
3218 ira_assert (!ALLOCNO_ASSIGNED_P (subloop_allocno));
3219 ALLOCNO_HARD_REGNO (subloop_allocno) = hard_regno;
3220 ALLOCNO_ASSIGNED_P (subloop_allocno) = true;
3221 if (hard_regno >= 0)
3222 update_costs_from_copies (subloop_allocno, true, true);
3223 /* We don't need updated costs anymore. */
3224 ira_free_allocno_updated_costs (subloop_allocno);
3227 /* Update costs of the corresponding allocnos (not caps) in the
3228 subloops. */
3229 for (subloop_node = loop_tree_node->subloops;
3230 subloop_node != NULL;
3231 subloop_node = subloop_node->subloop_next)
3233 ira_assert (subloop_node->bb == NULL);
3234 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
3236 a = ira_allocnos[j];
3237 ira_assert (ALLOCNO_CAP_MEMBER (a) == NULL);
3238 mode = ALLOCNO_MODE (a);
3239 rclass = ALLOCNO_CLASS (a);
3240 pclass = ira_pressure_class_translate[rclass];
3241 hard_regno = ALLOCNO_HARD_REGNO (a);
3242 /* Use hard register class here. ??? */
3243 if (hard_regno >= 0)
3245 index = ira_class_hard_reg_index[rclass][hard_regno];
3246 ira_assert (index >= 0);
3248 regno = ALLOCNO_REGNO (a);
3249 /* ??? conflict costs */
3250 subloop_allocno = subloop_node->regno_allocno_map[regno];
3251 if (subloop_allocno == NULL
3252 || ALLOCNO_CAP (subloop_allocno) != NULL)
3253 continue;
3254 ira_assert (ALLOCNO_CLASS (subloop_allocno) == rclass);
3255 ira_assert (bitmap_bit_p (subloop_node->all_allocnos,
3256 ALLOCNO_NUM (subloop_allocno)));
3257 if ((flag_ira_region == IRA_REGION_MIXED
3258 && (loop_tree_node->reg_pressure[pclass]
3259 <= ira_class_hard_regs_num[pclass]))
3260 || (pic_offset_table_rtx != NULL
3261 && regno == (int) REGNO (pic_offset_table_rtx)))
3263 if (! ALLOCNO_ASSIGNED_P (subloop_allocno))
3265 ALLOCNO_HARD_REGNO (subloop_allocno) = hard_regno;
3266 ALLOCNO_ASSIGNED_P (subloop_allocno) = true;
3267 if (hard_regno >= 0)
3268 update_costs_from_copies (subloop_allocno, true, true);
3269 /* We don't need updated costs anymore. */
3270 ira_free_allocno_updated_costs (subloop_allocno);
3272 continue;
3274 exit_freq = ira_loop_edge_freq (subloop_node, regno, true);
3275 enter_freq = ira_loop_edge_freq (subloop_node, regno, false);
3276 ira_assert (regno < ira_reg_equiv_len);
3277 if (ira_equiv_no_lvalue_p (regno))
3279 if (! ALLOCNO_ASSIGNED_P (subloop_allocno))
3281 ALLOCNO_HARD_REGNO (subloop_allocno) = hard_regno;
3282 ALLOCNO_ASSIGNED_P (subloop_allocno) = true;
3283 if (hard_regno >= 0)
3284 update_costs_from_copies (subloop_allocno, true, true);
3285 /* We don't need updated costs anymore. */
3286 ira_free_allocno_updated_costs (subloop_allocno);
3289 else if (hard_regno < 0)
3291 ALLOCNO_UPDATED_MEMORY_COST (subloop_allocno)
3292 -= ((ira_memory_move_cost[mode][rclass][1] * enter_freq)
3293 + (ira_memory_move_cost[mode][rclass][0] * exit_freq));
3295 else
3297 aclass = ALLOCNO_CLASS (subloop_allocno);
3298 ira_init_register_move_cost_if_necessary (mode);
3299 cost = (ira_register_move_cost[mode][rclass][rclass]
3300 * (exit_freq + enter_freq));
3301 ira_allocate_and_set_or_copy_costs
3302 (&ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno), aclass,
3303 ALLOCNO_UPDATED_CLASS_COST (subloop_allocno),
3304 ALLOCNO_HARD_REG_COSTS (subloop_allocno));
3305 ira_allocate_and_set_or_copy_costs
3306 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (subloop_allocno),
3307 aclass, 0, ALLOCNO_CONFLICT_HARD_REG_COSTS (subloop_allocno));
3308 ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno)[index] -= cost;
3309 ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (subloop_allocno)[index]
3310 -= cost;
3311 if (ALLOCNO_UPDATED_CLASS_COST (subloop_allocno)
3312 > ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno)[index])
3313 ALLOCNO_UPDATED_CLASS_COST (subloop_allocno)
3314 = ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno)[index];
3315 ALLOCNO_UPDATED_MEMORY_COST (subloop_allocno)
3316 += (ira_memory_move_cost[mode][rclass][0] * enter_freq
3317 + ira_memory_move_cost[mode][rclass][1] * exit_freq);
3321 ira_free (allocno_color_data);
3322 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
3324 a = ira_allocnos[j];
3325 ALLOCNO_ADD_DATA (a) = NULL;
3329 /* Initialize the common data for coloring and calls functions to do
3330 Chaitin-Briggs and regional coloring. */
3331 static void
3332 do_coloring (void)
3334 coloring_allocno_bitmap = ira_allocate_bitmap ();
3335 if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
3336 fprintf (ira_dump_file, "\n**** Allocnos coloring:\n\n");
3338 ira_traverse_loop_tree (false, ira_loop_tree_root, color_pass, NULL);
3340 if (internal_flag_ira_verbose > 1 && ira_dump_file != NULL)
3341 ira_print_disposition (ira_dump_file);
3343 ira_free_bitmap (coloring_allocno_bitmap);
3348 /* Move spill/restore code, which are to be generated in ira-emit.c,
3349 to less frequent points (if it is profitable) by reassigning some
3350 allocnos (in loop with subloops containing in another loop) to
3351 memory which results in longer live-range where the corresponding
3352 pseudo-registers will be in memory. */
3353 static void
3354 move_spill_restore (void)
3356 int cost, regno, hard_regno, hard_regno2, index;
3357 bool changed_p;
3358 int enter_freq, exit_freq;
3359 machine_mode mode;
3360 enum reg_class rclass;
3361 ira_allocno_t a, parent_allocno, subloop_allocno;
3362 ira_loop_tree_node_t parent, loop_node, subloop_node;
3363 ira_allocno_iterator ai;
3365 for (;;)
3367 changed_p = false;
3368 if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
3369 fprintf (ira_dump_file, "New iteration of spill/restore move\n");
3370 FOR_EACH_ALLOCNO (a, ai)
3372 regno = ALLOCNO_REGNO (a);
3373 loop_node = ALLOCNO_LOOP_TREE_NODE (a);
3374 if (ALLOCNO_CAP_MEMBER (a) != NULL
3375 || ALLOCNO_CAP (a) != NULL
3376 || (hard_regno = ALLOCNO_HARD_REGNO (a)) < 0
3377 || loop_node->children == NULL
3378 /* don't do the optimization because it can create
3379 copies and the reload pass can spill the allocno set
3380 by copy although the allocno will not get memory
3381 slot. */
3382 || ira_equiv_no_lvalue_p (regno)
3383 || !bitmap_bit_p (loop_node->border_allocnos, ALLOCNO_NUM (a)))
3384 continue;
3385 mode = ALLOCNO_MODE (a);
3386 rclass = ALLOCNO_CLASS (a);
3387 index = ira_class_hard_reg_index[rclass][hard_regno];
3388 ira_assert (index >= 0);
3389 cost = (ALLOCNO_MEMORY_COST (a)
3390 - (ALLOCNO_HARD_REG_COSTS (a) == NULL
3391 ? ALLOCNO_CLASS_COST (a)
3392 : ALLOCNO_HARD_REG_COSTS (a)[index]));
3393 ira_init_register_move_cost_if_necessary (mode);
3394 for (subloop_node = loop_node->subloops;
3395 subloop_node != NULL;
3396 subloop_node = subloop_node->subloop_next)
3398 ira_assert (subloop_node->bb == NULL);
3399 subloop_allocno = subloop_node->regno_allocno_map[regno];
3400 if (subloop_allocno == NULL)
3401 continue;
3402 ira_assert (rclass == ALLOCNO_CLASS (subloop_allocno));
3403 /* We have accumulated cost. To get the real cost of
3404 allocno usage in the loop we should subtract costs of
3405 the subloop allocnos. */
3406 cost -= (ALLOCNO_MEMORY_COST (subloop_allocno)
3407 - (ALLOCNO_HARD_REG_COSTS (subloop_allocno) == NULL
3408 ? ALLOCNO_CLASS_COST (subloop_allocno)
3409 : ALLOCNO_HARD_REG_COSTS (subloop_allocno)[index]));
3410 exit_freq = ira_loop_edge_freq (subloop_node, regno, true);
3411 enter_freq = ira_loop_edge_freq (subloop_node, regno, false);
3412 if ((hard_regno2 = ALLOCNO_HARD_REGNO (subloop_allocno)) < 0)
3413 cost -= (ira_memory_move_cost[mode][rclass][0] * exit_freq
3414 + ira_memory_move_cost[mode][rclass][1] * enter_freq);
3415 else
3417 cost
3418 += (ira_memory_move_cost[mode][rclass][0] * exit_freq
3419 + ira_memory_move_cost[mode][rclass][1] * enter_freq);
3420 if (hard_regno2 != hard_regno)
3421 cost -= (ira_register_move_cost[mode][rclass][rclass]
3422 * (exit_freq + enter_freq));
3425 if ((parent = loop_node->parent) != NULL
3426 && (parent_allocno = parent->regno_allocno_map[regno]) != NULL)
3428 ira_assert (rclass == ALLOCNO_CLASS (parent_allocno));
3429 exit_freq = ira_loop_edge_freq (loop_node, regno, true);
3430 enter_freq = ira_loop_edge_freq (loop_node, regno, false);
3431 if ((hard_regno2 = ALLOCNO_HARD_REGNO (parent_allocno)) < 0)
3432 cost -= (ira_memory_move_cost[mode][rclass][0] * exit_freq
3433 + ira_memory_move_cost[mode][rclass][1] * enter_freq);
3434 else
3436 cost
3437 += (ira_memory_move_cost[mode][rclass][1] * exit_freq
3438 + ira_memory_move_cost[mode][rclass][0] * enter_freq);
3439 if (hard_regno2 != hard_regno)
3440 cost -= (ira_register_move_cost[mode][rclass][rclass]
3441 * (exit_freq + enter_freq));
3444 if (cost < 0)
3446 ALLOCNO_HARD_REGNO (a) = -1;
3447 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3449 fprintf
3450 (ira_dump_file,
3451 " Moving spill/restore for a%dr%d up from loop %d",
3452 ALLOCNO_NUM (a), regno, loop_node->loop_num);
3453 fprintf (ira_dump_file, " - profit %d\n", -cost);
3455 changed_p = true;
3458 if (! changed_p)
3459 break;
3465 /* Update current hard reg costs and current conflict hard reg costs
3466 for allocno A. It is done by processing its copies containing
3467 other allocnos already assigned. */
3468 static void
3469 update_curr_costs (ira_allocno_t a)
3471 int i, hard_regno, cost;
3472 machine_mode mode;
3473 enum reg_class aclass, rclass;
3474 ira_allocno_t another_a;
3475 ira_copy_t cp, next_cp;
3477 ira_free_allocno_updated_costs (a);
3478 ira_assert (! ALLOCNO_ASSIGNED_P (a));
3479 aclass = ALLOCNO_CLASS (a);
3480 if (aclass == NO_REGS)
3481 return;
3482 mode = ALLOCNO_MODE (a);
3483 ira_init_register_move_cost_if_necessary (mode);
3484 for (cp = ALLOCNO_COPIES (a); cp != NULL; cp = next_cp)
3486 if (cp->first == a)
3488 next_cp = cp->next_first_allocno_copy;
3489 another_a = cp->second;
3491 else if (cp->second == a)
3493 next_cp = cp->next_second_allocno_copy;
3494 another_a = cp->first;
3496 else
3497 gcc_unreachable ();
3498 if (! ira_reg_classes_intersect_p[aclass][ALLOCNO_CLASS (another_a)]
3499 || ! ALLOCNO_ASSIGNED_P (another_a)
3500 || (hard_regno = ALLOCNO_HARD_REGNO (another_a)) < 0)
3501 continue;
3502 rclass = REGNO_REG_CLASS (hard_regno);
3503 i = ira_class_hard_reg_index[aclass][hard_regno];
3504 if (i < 0)
3505 continue;
3506 cost = (cp->first == a
3507 ? ira_register_move_cost[mode][rclass][aclass]
3508 : ira_register_move_cost[mode][aclass][rclass]);
3509 ira_allocate_and_set_or_copy_costs
3510 (&ALLOCNO_UPDATED_HARD_REG_COSTS (a), aclass, ALLOCNO_CLASS_COST (a),
3511 ALLOCNO_HARD_REG_COSTS (a));
3512 ira_allocate_and_set_or_copy_costs
3513 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a),
3514 aclass, 0, ALLOCNO_CONFLICT_HARD_REG_COSTS (a));
3515 ALLOCNO_UPDATED_HARD_REG_COSTS (a)[i] -= cp->freq * cost;
3516 ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a)[i] -= cp->freq * cost;
3520 /* Try to assign hard registers to the unassigned allocnos and
3521 allocnos conflicting with them or conflicting with allocnos whose
3522 regno >= START_REGNO. The function is called after ira_flattening,
3523 so more allocnos (including ones created in ira-emit.c) will have a
3524 chance to get a hard register. We use simple assignment algorithm
3525 based on priorities. */
3526 void
3527 ira_reassign_conflict_allocnos (int start_regno)
3529 int i, allocnos_to_color_num;
3530 ira_allocno_t a;
3531 enum reg_class aclass;
3532 bitmap allocnos_to_color;
3533 ira_allocno_iterator ai;
3535 allocnos_to_color = ira_allocate_bitmap ();
3536 allocnos_to_color_num = 0;
3537 FOR_EACH_ALLOCNO (a, ai)
3539 int n = ALLOCNO_NUM_OBJECTS (a);
3541 if (! ALLOCNO_ASSIGNED_P (a)
3542 && ! bitmap_bit_p (allocnos_to_color, ALLOCNO_NUM (a)))
3544 if (ALLOCNO_CLASS (a) != NO_REGS)
3545 sorted_allocnos[allocnos_to_color_num++] = a;
3546 else
3548 ALLOCNO_ASSIGNED_P (a) = true;
3549 ALLOCNO_HARD_REGNO (a) = -1;
3550 ira_assert (ALLOCNO_UPDATED_HARD_REG_COSTS (a) == NULL);
3551 ira_assert (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a) == NULL);
3553 bitmap_set_bit (allocnos_to_color, ALLOCNO_NUM (a));
3555 if (ALLOCNO_REGNO (a) < start_regno
3556 || (aclass = ALLOCNO_CLASS (a)) == NO_REGS)
3557 continue;
3558 for (i = 0; i < n; i++)
3560 ira_object_t obj = ALLOCNO_OBJECT (a, i);
3561 ira_object_t conflict_obj;
3562 ira_object_conflict_iterator oci;
3564 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
3566 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
3568 ira_assert (ira_reg_classes_intersect_p
3569 [aclass][ALLOCNO_CLASS (conflict_a)]);
3570 if (!bitmap_set_bit (allocnos_to_color, ALLOCNO_NUM (conflict_a)))
3571 continue;
3572 sorted_allocnos[allocnos_to_color_num++] = conflict_a;
3576 ira_free_bitmap (allocnos_to_color);
3577 if (allocnos_to_color_num > 1)
3579 setup_allocno_priorities (sorted_allocnos, allocnos_to_color_num);
3580 qsort (sorted_allocnos, allocnos_to_color_num, sizeof (ira_allocno_t),
3581 allocno_priority_compare_func);
3583 for (i = 0; i < allocnos_to_color_num; i++)
3585 a = sorted_allocnos[i];
3586 ALLOCNO_ASSIGNED_P (a) = false;
3587 update_curr_costs (a);
3589 for (i = 0; i < allocnos_to_color_num; i++)
3591 a = sorted_allocnos[i];
3592 if (assign_hard_reg (a, true))
3594 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3595 fprintf
3596 (ira_dump_file,
3597 " Secondary allocation: assign hard reg %d to reg %d\n",
3598 ALLOCNO_HARD_REGNO (a), ALLOCNO_REGNO (a));
3605 /* This page contains functions used to find conflicts using allocno
3606 live ranges. */
3608 #ifdef ENABLE_IRA_CHECKING
3610 /* Return TRUE if live ranges of pseudo-registers REGNO1 and REGNO2
3611 intersect. This should be used when there is only one region.
3612 Currently this is used during reload. */
3613 static bool
3614 conflict_by_live_ranges_p (int regno1, int regno2)
3616 ira_allocno_t a1, a2;
3618 ira_assert (regno1 >= FIRST_PSEUDO_REGISTER
3619 && regno2 >= FIRST_PSEUDO_REGISTER);
3620 /* Reg info calculated by dataflow infrastructure can be different
3621 from one calculated by regclass. */
3622 if ((a1 = ira_loop_tree_root->regno_allocno_map[regno1]) == NULL
3623 || (a2 = ira_loop_tree_root->regno_allocno_map[regno2]) == NULL)
3624 return false;
3625 return allocnos_conflict_by_live_ranges_p (a1, a2);
3628 #endif
3632 /* This page contains code to coalesce memory stack slots used by
3633 spilled allocnos. This results in smaller stack frame, better data
3634 locality, and in smaller code for some architectures like
3635 x86/x86_64 where insn size depends on address displacement value.
3636 On the other hand, it can worsen insn scheduling after the RA but
3637 in practice it is less important than smaller stack frames. */
3639 /* TRUE if we coalesced some allocnos. In other words, if we got
3640 loops formed by members first_coalesced_allocno and
3641 next_coalesced_allocno containing more one allocno. */
3642 static bool allocno_coalesced_p;
3644 /* Bitmap used to prevent a repeated allocno processing because of
3645 coalescing. */
3646 static bitmap processed_coalesced_allocno_bitmap;
3648 /* See below. */
3649 typedef struct coalesce_data *coalesce_data_t;
3651 /* To decrease footprint of ira_allocno structure we store all data
3652 needed only for coalescing in the following structure. */
3653 struct coalesce_data
3655 /* Coalesced allocnos form a cyclic list. One allocno given by
3656 FIRST represents all coalesced allocnos. The
3657 list is chained by NEXT. */
3658 ira_allocno_t first;
3659 ira_allocno_t next;
3660 int temp;
3663 /* Container for storing allocno data concerning coalescing. */
3664 static coalesce_data_t allocno_coalesce_data;
3666 /* Macro to access the data concerning coalescing. */
3667 #define ALLOCNO_COALESCE_DATA(a) ((coalesce_data_t) ALLOCNO_ADD_DATA (a))
3669 /* Merge two sets of coalesced allocnos given correspondingly by
3670 allocnos A1 and A2 (more accurately merging A2 set into A1
3671 set). */
3672 static void
3673 merge_allocnos (ira_allocno_t a1, ira_allocno_t a2)
3675 ira_allocno_t a, first, last, next;
3677 first = ALLOCNO_COALESCE_DATA (a1)->first;
3678 a = ALLOCNO_COALESCE_DATA (a2)->first;
3679 if (first == a)
3680 return;
3681 for (last = a2, a = ALLOCNO_COALESCE_DATA (a2)->next;;
3682 a = ALLOCNO_COALESCE_DATA (a)->next)
3684 ALLOCNO_COALESCE_DATA (a)->first = first;
3685 if (a == a2)
3686 break;
3687 last = a;
3689 next = allocno_coalesce_data[ALLOCNO_NUM (first)].next;
3690 allocno_coalesce_data[ALLOCNO_NUM (first)].next = a2;
3691 allocno_coalesce_data[ALLOCNO_NUM (last)].next = next;
3694 /* Return TRUE if there are conflicting allocnos from two sets of
3695 coalesced allocnos given correspondingly by allocnos A1 and A2. We
3696 use live ranges to find conflicts because conflicts are represented
3697 only for allocnos of the same allocno class and during the reload
3698 pass we coalesce allocnos for sharing stack memory slots. */
3699 static bool
3700 coalesced_allocno_conflict_p (ira_allocno_t a1, ira_allocno_t a2)
3702 ira_allocno_t a, conflict_a;
3704 if (allocno_coalesced_p)
3706 bitmap_clear (processed_coalesced_allocno_bitmap);
3707 for (a = ALLOCNO_COALESCE_DATA (a1)->next;;
3708 a = ALLOCNO_COALESCE_DATA (a)->next)
3710 bitmap_set_bit (processed_coalesced_allocno_bitmap, ALLOCNO_NUM (a));
3711 if (a == a1)
3712 break;
3715 for (a = ALLOCNO_COALESCE_DATA (a2)->next;;
3716 a = ALLOCNO_COALESCE_DATA (a)->next)
3718 for (conflict_a = ALLOCNO_COALESCE_DATA (a1)->next;;
3719 conflict_a = ALLOCNO_COALESCE_DATA (conflict_a)->next)
3721 if (allocnos_conflict_by_live_ranges_p (a, conflict_a))
3722 return true;
3723 if (conflict_a == a1)
3724 break;
3726 if (a == a2)
3727 break;
3729 return false;
3732 /* The major function for aggressive allocno coalescing. We coalesce
3733 only spilled allocnos. If some allocnos have been coalesced, we
3734 set up flag allocno_coalesced_p. */
3735 static void
3736 coalesce_allocnos (void)
3738 ira_allocno_t a;
3739 ira_copy_t cp, next_cp;
3740 unsigned int j;
3741 int i, n, cp_num, regno;
3742 bitmap_iterator bi;
3744 cp_num = 0;
3745 /* Collect copies. */
3746 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, j, bi)
3748 a = ira_allocnos[j];
3749 regno = ALLOCNO_REGNO (a);
3750 if (! ALLOCNO_ASSIGNED_P (a) || ALLOCNO_HARD_REGNO (a) >= 0
3751 || ira_equiv_no_lvalue_p (regno))
3752 continue;
3753 for (cp = ALLOCNO_COPIES (a); cp != NULL; cp = next_cp)
3755 if (cp->first == a)
3757 next_cp = cp->next_first_allocno_copy;
3758 regno = ALLOCNO_REGNO (cp->second);
3759 /* For priority coloring we coalesce allocnos only with
3760 the same allocno class not with intersected allocno
3761 classes as it were possible. It is done for
3762 simplicity. */
3763 if ((cp->insn != NULL || cp->constraint_p)
3764 && ALLOCNO_ASSIGNED_P (cp->second)
3765 && ALLOCNO_HARD_REGNO (cp->second) < 0
3766 && ! ira_equiv_no_lvalue_p (regno))
3767 sorted_copies[cp_num++] = cp;
3769 else if (cp->second == a)
3770 next_cp = cp->next_second_allocno_copy;
3771 else
3772 gcc_unreachable ();
3775 qsort (sorted_copies, cp_num, sizeof (ira_copy_t), copy_freq_compare_func);
3776 /* Coalesced copies, most frequently executed first. */
3777 for (; cp_num != 0;)
3779 for (i = 0; i < cp_num; i++)
3781 cp = sorted_copies[i];
3782 if (! coalesced_allocno_conflict_p (cp->first, cp->second))
3784 allocno_coalesced_p = true;
3785 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3786 fprintf
3787 (ira_dump_file,
3788 " Coalescing copy %d:a%dr%d-a%dr%d (freq=%d)\n",
3789 cp->num, ALLOCNO_NUM (cp->first), ALLOCNO_REGNO (cp->first),
3790 ALLOCNO_NUM (cp->second), ALLOCNO_REGNO (cp->second),
3791 cp->freq);
3792 merge_allocnos (cp->first, cp->second);
3793 i++;
3794 break;
3797 /* Collect the rest of copies. */
3798 for (n = 0; i < cp_num; i++)
3800 cp = sorted_copies[i];
3801 if (allocno_coalesce_data[ALLOCNO_NUM (cp->first)].first
3802 != allocno_coalesce_data[ALLOCNO_NUM (cp->second)].first)
3803 sorted_copies[n++] = cp;
3805 cp_num = n;
3809 /* Usage cost and order number of coalesced allocno set to which
3810 given pseudo register belongs to. */
3811 static int *regno_coalesced_allocno_cost;
3812 static int *regno_coalesced_allocno_num;
3814 /* Sort pseudos according frequencies of coalesced allocno sets they
3815 belong to (putting most frequently ones first), and according to
3816 coalesced allocno set order numbers. */
3817 static int
3818 coalesced_pseudo_reg_freq_compare (const void *v1p, const void *v2p)
3820 const int regno1 = *(const int *) v1p;
3821 const int regno2 = *(const int *) v2p;
3822 int diff;
3824 if ((diff = (regno_coalesced_allocno_cost[regno2]
3825 - regno_coalesced_allocno_cost[regno1])) != 0)
3826 return diff;
3827 if ((diff = (regno_coalesced_allocno_num[regno1]
3828 - regno_coalesced_allocno_num[regno2])) != 0)
3829 return diff;
3830 return regno1 - regno2;
3833 /* Widest width in which each pseudo reg is referred to (via subreg).
3834 It is used for sorting pseudo registers. */
3835 static unsigned int *regno_max_ref_width;
3837 /* Redefine STACK_GROWS_DOWNWARD in terms of 0 or 1. */
3838 #ifdef STACK_GROWS_DOWNWARD
3839 # undef STACK_GROWS_DOWNWARD
3840 # define STACK_GROWS_DOWNWARD 1
3841 #else
3842 # define STACK_GROWS_DOWNWARD 0
3843 #endif
3845 /* Sort pseudos according their slot numbers (putting ones with
3846 smaller numbers first, or last when the frame pointer is not
3847 needed). */
3848 static int
3849 coalesced_pseudo_reg_slot_compare (const void *v1p, const void *v2p)
3851 const int regno1 = *(const int *) v1p;
3852 const int regno2 = *(const int *) v2p;
3853 ira_allocno_t a1 = ira_regno_allocno_map[regno1];
3854 ira_allocno_t a2 = ira_regno_allocno_map[regno2];
3855 int diff, slot_num1, slot_num2;
3856 int total_size1, total_size2;
3858 if (a1 == NULL || ALLOCNO_HARD_REGNO (a1) >= 0)
3860 if (a2 == NULL || ALLOCNO_HARD_REGNO (a2) >= 0)
3861 return regno1 - regno2;
3862 return 1;
3864 else if (a2 == NULL || ALLOCNO_HARD_REGNO (a2) >= 0)
3865 return -1;
3866 slot_num1 = -ALLOCNO_HARD_REGNO (a1);
3867 slot_num2 = -ALLOCNO_HARD_REGNO (a2);
3868 if ((diff = slot_num1 - slot_num2) != 0)
3869 return (frame_pointer_needed
3870 || (!FRAME_GROWS_DOWNWARD) == STACK_GROWS_DOWNWARD ? diff : -diff);
3871 total_size1 = MAX (PSEUDO_REGNO_BYTES (regno1),
3872 regno_max_ref_width[regno1]);
3873 total_size2 = MAX (PSEUDO_REGNO_BYTES (regno2),
3874 regno_max_ref_width[regno2]);
3875 if ((diff = total_size2 - total_size1) != 0)
3876 return diff;
3877 return regno1 - regno2;
3880 /* Setup REGNO_COALESCED_ALLOCNO_COST and REGNO_COALESCED_ALLOCNO_NUM
3881 for coalesced allocno sets containing allocnos with their regnos
3882 given in array PSEUDO_REGNOS of length N. */
3883 static void
3884 setup_coalesced_allocno_costs_and_nums (int *pseudo_regnos, int n)
3886 int i, num, regno, cost;
3887 ira_allocno_t allocno, a;
3889 for (num = i = 0; i < n; i++)
3891 regno = pseudo_regnos[i];
3892 allocno = ira_regno_allocno_map[regno];
3893 if (allocno == NULL)
3895 regno_coalesced_allocno_cost[regno] = 0;
3896 regno_coalesced_allocno_num[regno] = ++num;
3897 continue;
3899 if (ALLOCNO_COALESCE_DATA (allocno)->first != allocno)
3900 continue;
3901 num++;
3902 for (cost = 0, a = ALLOCNO_COALESCE_DATA (allocno)->next;;
3903 a = ALLOCNO_COALESCE_DATA (a)->next)
3905 cost += ALLOCNO_FREQ (a);
3906 if (a == allocno)
3907 break;
3909 for (a = ALLOCNO_COALESCE_DATA (allocno)->next;;
3910 a = ALLOCNO_COALESCE_DATA (a)->next)
3912 regno_coalesced_allocno_num[ALLOCNO_REGNO (a)] = num;
3913 regno_coalesced_allocno_cost[ALLOCNO_REGNO (a)] = cost;
3914 if (a == allocno)
3915 break;
3920 /* Collect spilled allocnos representing coalesced allocno sets (the
3921 first coalesced allocno). The collected allocnos are returned
3922 through array SPILLED_COALESCED_ALLOCNOS. The function returns the
3923 number of the collected allocnos. The allocnos are given by their
3924 regnos in array PSEUDO_REGNOS of length N. */
3925 static int
3926 collect_spilled_coalesced_allocnos (int *pseudo_regnos, int n,
3927 ira_allocno_t *spilled_coalesced_allocnos)
3929 int i, num, regno;
3930 ira_allocno_t allocno;
3932 for (num = i = 0; i < n; i++)
3934 regno = pseudo_regnos[i];
3935 allocno = ira_regno_allocno_map[regno];
3936 if (allocno == NULL || ALLOCNO_HARD_REGNO (allocno) >= 0
3937 || ALLOCNO_COALESCE_DATA (allocno)->first != allocno)
3938 continue;
3939 spilled_coalesced_allocnos[num++] = allocno;
3941 return num;
3944 /* Array of live ranges of size IRA_ALLOCNOS_NUM. Live range for
3945 given slot contains live ranges of coalesced allocnos assigned to
3946 given slot. */
3947 static live_range_t *slot_coalesced_allocnos_live_ranges;
3949 /* Return TRUE if coalesced allocnos represented by ALLOCNO has live
3950 ranges intersected with live ranges of coalesced allocnos assigned
3951 to slot with number N. */
3952 static bool
3953 slot_coalesced_allocno_live_ranges_intersect_p (ira_allocno_t allocno, int n)
3955 ira_allocno_t a;
3957 for (a = ALLOCNO_COALESCE_DATA (allocno)->next;;
3958 a = ALLOCNO_COALESCE_DATA (a)->next)
3960 int i;
3961 int nr = ALLOCNO_NUM_OBJECTS (a);
3963 for (i = 0; i < nr; i++)
3965 ira_object_t obj = ALLOCNO_OBJECT (a, i);
3967 if (ira_live_ranges_intersect_p
3968 (slot_coalesced_allocnos_live_ranges[n],
3969 OBJECT_LIVE_RANGES (obj)))
3970 return true;
3972 if (a == allocno)
3973 break;
3975 return false;
3978 /* Update live ranges of slot to which coalesced allocnos represented
3979 by ALLOCNO were assigned. */
3980 static void
3981 setup_slot_coalesced_allocno_live_ranges (ira_allocno_t allocno)
3983 int i, n;
3984 ira_allocno_t a;
3985 live_range_t r;
3987 n = ALLOCNO_COALESCE_DATA (allocno)->temp;
3988 for (a = ALLOCNO_COALESCE_DATA (allocno)->next;;
3989 a = ALLOCNO_COALESCE_DATA (a)->next)
3991 int nr = ALLOCNO_NUM_OBJECTS (a);
3992 for (i = 0; i < nr; i++)
3994 ira_object_t obj = ALLOCNO_OBJECT (a, i);
3996 r = ira_copy_live_range_list (OBJECT_LIVE_RANGES (obj));
3997 slot_coalesced_allocnos_live_ranges[n]
3998 = ira_merge_live_ranges
3999 (slot_coalesced_allocnos_live_ranges[n], r);
4001 if (a == allocno)
4002 break;
4006 /* We have coalesced allocnos involving in copies. Coalesce allocnos
4007 further in order to share the same memory stack slot. Allocnos
4008 representing sets of allocnos coalesced before the call are given
4009 in array SPILLED_COALESCED_ALLOCNOS of length NUM. Return TRUE if
4010 some allocnos were coalesced in the function. */
4011 static bool
4012 coalesce_spill_slots (ira_allocno_t *spilled_coalesced_allocnos, int num)
4014 int i, j, n, last_coalesced_allocno_num;
4015 ira_allocno_t allocno, a;
4016 bool merged_p = false;
4017 bitmap set_jump_crosses = regstat_get_setjmp_crosses ();
4019 slot_coalesced_allocnos_live_ranges
4020 = (live_range_t *) ira_allocate (sizeof (live_range_t) * ira_allocnos_num);
4021 memset (slot_coalesced_allocnos_live_ranges, 0,
4022 sizeof (live_range_t) * ira_allocnos_num);
4023 last_coalesced_allocno_num = 0;
4024 /* Coalesce non-conflicting spilled allocnos preferring most
4025 frequently used. */
4026 for (i = 0; i < num; i++)
4028 allocno = spilled_coalesced_allocnos[i];
4029 if (ALLOCNO_COALESCE_DATA (allocno)->first != allocno
4030 || bitmap_bit_p (set_jump_crosses, ALLOCNO_REGNO (allocno))
4031 || ira_equiv_no_lvalue_p (ALLOCNO_REGNO (allocno)))
4032 continue;
4033 for (j = 0; j < i; j++)
4035 a = spilled_coalesced_allocnos[j];
4036 n = ALLOCNO_COALESCE_DATA (a)->temp;
4037 if (ALLOCNO_COALESCE_DATA (a)->first == a
4038 && ! bitmap_bit_p (set_jump_crosses, ALLOCNO_REGNO (a))
4039 && ! ira_equiv_no_lvalue_p (ALLOCNO_REGNO (a))
4040 && ! slot_coalesced_allocno_live_ranges_intersect_p (allocno, n))
4041 break;
4043 if (j >= i)
4045 /* No coalescing: set up number for coalesced allocnos
4046 represented by ALLOCNO. */
4047 ALLOCNO_COALESCE_DATA (allocno)->temp = last_coalesced_allocno_num++;
4048 setup_slot_coalesced_allocno_live_ranges (allocno);
4050 else
4052 allocno_coalesced_p = true;
4053 merged_p = true;
4054 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4055 fprintf (ira_dump_file,
4056 " Coalescing spilled allocnos a%dr%d->a%dr%d\n",
4057 ALLOCNO_NUM (allocno), ALLOCNO_REGNO (allocno),
4058 ALLOCNO_NUM (a), ALLOCNO_REGNO (a));
4059 ALLOCNO_COALESCE_DATA (allocno)->temp
4060 = ALLOCNO_COALESCE_DATA (a)->temp;
4061 setup_slot_coalesced_allocno_live_ranges (allocno);
4062 merge_allocnos (a, allocno);
4063 ira_assert (ALLOCNO_COALESCE_DATA (a)->first == a);
4066 for (i = 0; i < ira_allocnos_num; i++)
4067 ira_finish_live_range_list (slot_coalesced_allocnos_live_ranges[i]);
4068 ira_free (slot_coalesced_allocnos_live_ranges);
4069 return merged_p;
4072 /* Sort pseudo-register numbers in array PSEUDO_REGNOS of length N for
4073 subsequent assigning stack slots to them in the reload pass. To do
4074 this we coalesce spilled allocnos first to decrease the number of
4075 memory-memory move insns. This function is called by the
4076 reload. */
4077 void
4078 ira_sort_regnos_for_alter_reg (int *pseudo_regnos, int n,
4079 unsigned int *reg_max_ref_width)
4081 int max_regno = max_reg_num ();
4082 int i, regno, num, slot_num;
4083 ira_allocno_t allocno, a;
4084 ira_allocno_iterator ai;
4085 ira_allocno_t *spilled_coalesced_allocnos;
4087 ira_assert (! ira_use_lra_p);
4089 /* Set up allocnos can be coalesced. */
4090 coloring_allocno_bitmap = ira_allocate_bitmap ();
4091 for (i = 0; i < n; i++)
4093 regno = pseudo_regnos[i];
4094 allocno = ira_regno_allocno_map[regno];
4095 if (allocno != NULL)
4096 bitmap_set_bit (coloring_allocno_bitmap, ALLOCNO_NUM (allocno));
4098 allocno_coalesced_p = false;
4099 processed_coalesced_allocno_bitmap = ira_allocate_bitmap ();
4100 allocno_coalesce_data
4101 = (coalesce_data_t) ira_allocate (sizeof (struct coalesce_data)
4102 * ira_allocnos_num);
4103 /* Initialize coalesce data for allocnos. */
4104 FOR_EACH_ALLOCNO (a, ai)
4106 ALLOCNO_ADD_DATA (a) = allocno_coalesce_data + ALLOCNO_NUM (a);
4107 ALLOCNO_COALESCE_DATA (a)->first = a;
4108 ALLOCNO_COALESCE_DATA (a)->next = a;
4110 coalesce_allocnos ();
4111 ira_free_bitmap (coloring_allocno_bitmap);
4112 regno_coalesced_allocno_cost
4113 = (int *) ira_allocate (max_regno * sizeof (int));
4114 regno_coalesced_allocno_num
4115 = (int *) ira_allocate (max_regno * sizeof (int));
4116 memset (regno_coalesced_allocno_num, 0, max_regno * sizeof (int));
4117 setup_coalesced_allocno_costs_and_nums (pseudo_regnos, n);
4118 /* Sort regnos according frequencies of the corresponding coalesced
4119 allocno sets. */
4120 qsort (pseudo_regnos, n, sizeof (int), coalesced_pseudo_reg_freq_compare);
4121 spilled_coalesced_allocnos
4122 = (ira_allocno_t *) ira_allocate (ira_allocnos_num
4123 * sizeof (ira_allocno_t));
4124 /* Collect allocnos representing the spilled coalesced allocno
4125 sets. */
4126 num = collect_spilled_coalesced_allocnos (pseudo_regnos, n,
4127 spilled_coalesced_allocnos);
4128 if (flag_ira_share_spill_slots
4129 && coalesce_spill_slots (spilled_coalesced_allocnos, num))
4131 setup_coalesced_allocno_costs_and_nums (pseudo_regnos, n);
4132 qsort (pseudo_regnos, n, sizeof (int),
4133 coalesced_pseudo_reg_freq_compare);
4134 num = collect_spilled_coalesced_allocnos (pseudo_regnos, n,
4135 spilled_coalesced_allocnos);
4137 ira_free_bitmap (processed_coalesced_allocno_bitmap);
4138 allocno_coalesced_p = false;
4139 /* Assign stack slot numbers to spilled allocno sets, use smaller
4140 numbers for most frequently used coalesced allocnos. -1 is
4141 reserved for dynamic search of stack slots for pseudos spilled by
4142 the reload. */
4143 slot_num = 1;
4144 for (i = 0; i < num; i++)
4146 allocno = spilled_coalesced_allocnos[i];
4147 if (ALLOCNO_COALESCE_DATA (allocno)->first != allocno
4148 || ALLOCNO_HARD_REGNO (allocno) >= 0
4149 || ira_equiv_no_lvalue_p (ALLOCNO_REGNO (allocno)))
4150 continue;
4151 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4152 fprintf (ira_dump_file, " Slot %d (freq,size):", slot_num);
4153 slot_num++;
4154 for (a = ALLOCNO_COALESCE_DATA (allocno)->next;;
4155 a = ALLOCNO_COALESCE_DATA (a)->next)
4157 ira_assert (ALLOCNO_HARD_REGNO (a) < 0);
4158 ALLOCNO_HARD_REGNO (a) = -slot_num;
4159 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4160 fprintf (ira_dump_file, " a%dr%d(%d,%d)",
4161 ALLOCNO_NUM (a), ALLOCNO_REGNO (a), ALLOCNO_FREQ (a),
4162 MAX (PSEUDO_REGNO_BYTES (ALLOCNO_REGNO (a)),
4163 reg_max_ref_width[ALLOCNO_REGNO (a)]));
4165 if (a == allocno)
4166 break;
4168 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4169 fprintf (ira_dump_file, "\n");
4171 ira_spilled_reg_stack_slots_num = slot_num - 1;
4172 ira_free (spilled_coalesced_allocnos);
4173 /* Sort regnos according the slot numbers. */
4174 regno_max_ref_width = reg_max_ref_width;
4175 qsort (pseudo_regnos, n, sizeof (int), coalesced_pseudo_reg_slot_compare);
4176 FOR_EACH_ALLOCNO (a, ai)
4177 ALLOCNO_ADD_DATA (a) = NULL;
4178 ira_free (allocno_coalesce_data);
4179 ira_free (regno_coalesced_allocno_num);
4180 ira_free (regno_coalesced_allocno_cost);
4185 /* This page contains code used by the reload pass to improve the
4186 final code. */
4188 /* The function is called from reload to mark changes in the
4189 allocation of REGNO made by the reload. Remember that reg_renumber
4190 reflects the change result. */
4191 void
4192 ira_mark_allocation_change (int regno)
4194 ira_allocno_t a = ira_regno_allocno_map[regno];
4195 int old_hard_regno, hard_regno, cost;
4196 enum reg_class aclass = ALLOCNO_CLASS (a);
4198 ira_assert (a != NULL);
4199 hard_regno = reg_renumber[regno];
4200 if ((old_hard_regno = ALLOCNO_HARD_REGNO (a)) == hard_regno)
4201 return;
4202 if (old_hard_regno < 0)
4203 cost = -ALLOCNO_MEMORY_COST (a);
4204 else
4206 ira_assert (ira_class_hard_reg_index[aclass][old_hard_regno] >= 0);
4207 cost = -(ALLOCNO_HARD_REG_COSTS (a) == NULL
4208 ? ALLOCNO_CLASS_COST (a)
4209 : ALLOCNO_HARD_REG_COSTS (a)
4210 [ira_class_hard_reg_index[aclass][old_hard_regno]]);
4211 update_costs_from_copies (a, false, false);
4213 ira_overall_cost -= cost;
4214 ALLOCNO_HARD_REGNO (a) = hard_regno;
4215 if (hard_regno < 0)
4217 ALLOCNO_HARD_REGNO (a) = -1;
4218 cost += ALLOCNO_MEMORY_COST (a);
4220 else if (ira_class_hard_reg_index[aclass][hard_regno] >= 0)
4222 cost += (ALLOCNO_HARD_REG_COSTS (a) == NULL
4223 ? ALLOCNO_CLASS_COST (a)
4224 : ALLOCNO_HARD_REG_COSTS (a)
4225 [ira_class_hard_reg_index[aclass][hard_regno]]);
4226 update_costs_from_copies (a, true, false);
4228 else
4229 /* Reload changed class of the allocno. */
4230 cost = 0;
4231 ira_overall_cost += cost;
4234 /* This function is called when reload deletes memory-memory move. In
4235 this case we marks that the allocation of the corresponding
4236 allocnos should be not changed in future. Otherwise we risk to get
4237 a wrong code. */
4238 void
4239 ira_mark_memory_move_deletion (int dst_regno, int src_regno)
4241 ira_allocno_t dst = ira_regno_allocno_map[dst_regno];
4242 ira_allocno_t src = ira_regno_allocno_map[src_regno];
4244 ira_assert (dst != NULL && src != NULL
4245 && ALLOCNO_HARD_REGNO (dst) < 0
4246 && ALLOCNO_HARD_REGNO (src) < 0);
4247 ALLOCNO_DONT_REASSIGN_P (dst) = true;
4248 ALLOCNO_DONT_REASSIGN_P (src) = true;
4251 /* Try to assign a hard register (except for FORBIDDEN_REGS) to
4252 allocno A and return TRUE in the case of success. */
4253 static bool
4254 allocno_reload_assign (ira_allocno_t a, HARD_REG_SET forbidden_regs)
4256 int hard_regno;
4257 enum reg_class aclass;
4258 int regno = ALLOCNO_REGNO (a);
4259 HARD_REG_SET saved[2];
4260 int i, n;
4262 n = ALLOCNO_NUM_OBJECTS (a);
4263 for (i = 0; i < n; i++)
4265 ira_object_t obj = ALLOCNO_OBJECT (a, i);
4266 COPY_HARD_REG_SET (saved[i], OBJECT_TOTAL_CONFLICT_HARD_REGS (obj));
4267 IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), forbidden_regs);
4268 if (! flag_caller_saves && ALLOCNO_CALLS_CROSSED_NUM (a) != 0)
4269 IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
4270 call_used_reg_set);
4272 ALLOCNO_ASSIGNED_P (a) = false;
4273 aclass = ALLOCNO_CLASS (a);
4274 update_curr_costs (a);
4275 assign_hard_reg (a, true);
4276 hard_regno = ALLOCNO_HARD_REGNO (a);
4277 reg_renumber[regno] = hard_regno;
4278 if (hard_regno < 0)
4279 ALLOCNO_HARD_REGNO (a) = -1;
4280 else
4282 ira_assert (ira_class_hard_reg_index[aclass][hard_regno] >= 0);
4283 ira_overall_cost
4284 -= (ALLOCNO_MEMORY_COST (a)
4285 - (ALLOCNO_HARD_REG_COSTS (a) == NULL
4286 ? ALLOCNO_CLASS_COST (a)
4287 : ALLOCNO_HARD_REG_COSTS (a)[ira_class_hard_reg_index
4288 [aclass][hard_regno]]));
4289 if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0
4290 && ira_hard_reg_set_intersection_p (hard_regno, ALLOCNO_MODE (a),
4291 call_used_reg_set))
4293 ira_assert (flag_caller_saves);
4294 caller_save_needed = 1;
4298 /* If we found a hard register, modify the RTL for the pseudo
4299 register to show the hard register, and mark the pseudo register
4300 live. */
4301 if (reg_renumber[regno] >= 0)
4303 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4304 fprintf (ira_dump_file, ": reassign to %d\n", reg_renumber[regno]);
4305 SET_REGNO (regno_reg_rtx[regno], reg_renumber[regno]);
4306 mark_home_live (regno);
4308 else if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4309 fprintf (ira_dump_file, "\n");
4310 for (i = 0; i < n; i++)
4312 ira_object_t obj = ALLOCNO_OBJECT (a, i);
4313 COPY_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), saved[i]);
4315 return reg_renumber[regno] >= 0;
4318 /* Sort pseudos according their usage frequencies (putting most
4319 frequently ones first). */
4320 static int
4321 pseudo_reg_compare (const void *v1p, const void *v2p)
4323 int regno1 = *(const int *) v1p;
4324 int regno2 = *(const int *) v2p;
4325 int diff;
4327 if ((diff = REG_FREQ (regno2) - REG_FREQ (regno1)) != 0)
4328 return diff;
4329 return regno1 - regno2;
4332 /* Try to allocate hard registers to SPILLED_PSEUDO_REGS (there are
4333 NUM of them) or spilled pseudos conflicting with pseudos in
4334 SPILLED_PSEUDO_REGS. Return TRUE and update SPILLED, if the
4335 allocation has been changed. The function doesn't use
4336 BAD_SPILL_REGS and hard registers in PSEUDO_FORBIDDEN_REGS and
4337 PSEUDO_PREVIOUS_REGS for the corresponding pseudos. The function
4338 is called by the reload pass at the end of each reload
4339 iteration. */
4340 bool
4341 ira_reassign_pseudos (int *spilled_pseudo_regs, int num,
4342 HARD_REG_SET bad_spill_regs,
4343 HARD_REG_SET *pseudo_forbidden_regs,
4344 HARD_REG_SET *pseudo_previous_regs,
4345 bitmap spilled)
4347 int i, n, regno;
4348 bool changed_p;
4349 ira_allocno_t a;
4350 HARD_REG_SET forbidden_regs;
4351 bitmap temp = BITMAP_ALLOC (NULL);
4353 /* Add pseudos which conflict with pseudos already in
4354 SPILLED_PSEUDO_REGS to SPILLED_PSEUDO_REGS. This is preferable
4355 to allocating in two steps as some of the conflicts might have
4356 a higher priority than the pseudos passed in SPILLED_PSEUDO_REGS. */
4357 for (i = 0; i < num; i++)
4358 bitmap_set_bit (temp, spilled_pseudo_regs[i]);
4360 for (i = 0, n = num; i < n; i++)
4362 int nr, j;
4363 int regno = spilled_pseudo_regs[i];
4364 bitmap_set_bit (temp, regno);
4366 a = ira_regno_allocno_map[regno];
4367 nr = ALLOCNO_NUM_OBJECTS (a);
4368 for (j = 0; j < nr; j++)
4370 ira_object_t conflict_obj;
4371 ira_object_t obj = ALLOCNO_OBJECT (a, j);
4372 ira_object_conflict_iterator oci;
4374 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
4376 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
4377 if (ALLOCNO_HARD_REGNO (conflict_a) < 0
4378 && ! ALLOCNO_DONT_REASSIGN_P (conflict_a)
4379 && bitmap_set_bit (temp, ALLOCNO_REGNO (conflict_a)))
4381 spilled_pseudo_regs[num++] = ALLOCNO_REGNO (conflict_a);
4382 /* ?!? This seems wrong. */
4383 bitmap_set_bit (consideration_allocno_bitmap,
4384 ALLOCNO_NUM (conflict_a));
4390 if (num > 1)
4391 qsort (spilled_pseudo_regs, num, sizeof (int), pseudo_reg_compare);
4392 changed_p = false;
4393 /* Try to assign hard registers to pseudos from
4394 SPILLED_PSEUDO_REGS. */
4395 for (i = 0; i < num; i++)
4397 regno = spilled_pseudo_regs[i];
4398 COPY_HARD_REG_SET (forbidden_regs, bad_spill_regs);
4399 IOR_HARD_REG_SET (forbidden_regs, pseudo_forbidden_regs[regno]);
4400 IOR_HARD_REG_SET (forbidden_regs, pseudo_previous_regs[regno]);
4401 gcc_assert (reg_renumber[regno] < 0);
4402 a = ira_regno_allocno_map[regno];
4403 ira_mark_allocation_change (regno);
4404 ira_assert (reg_renumber[regno] < 0);
4405 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4406 fprintf (ira_dump_file,
4407 " Try Assign %d(a%d), cost=%d", regno, ALLOCNO_NUM (a),
4408 ALLOCNO_MEMORY_COST (a)
4409 - ALLOCNO_CLASS_COST (a));
4410 allocno_reload_assign (a, forbidden_regs);
4411 if (reg_renumber[regno] >= 0)
4413 CLEAR_REGNO_REG_SET (spilled, regno);
4414 changed_p = true;
4417 BITMAP_FREE (temp);
4418 return changed_p;
4421 /* The function is called by reload and returns already allocated
4422 stack slot (if any) for REGNO with given INHERENT_SIZE and
4423 TOTAL_SIZE. In the case of failure to find a slot which can be
4424 used for REGNO, the function returns NULL. */
4426 ira_reuse_stack_slot (int regno, unsigned int inherent_size,
4427 unsigned int total_size)
4429 unsigned int i;
4430 int slot_num, best_slot_num;
4431 int cost, best_cost;
4432 ira_copy_t cp, next_cp;
4433 ira_allocno_t another_allocno, allocno = ira_regno_allocno_map[regno];
4434 rtx x;
4435 bitmap_iterator bi;
4436 struct ira_spilled_reg_stack_slot *slot = NULL;
4438 ira_assert (! ira_use_lra_p);
4440 ira_assert (inherent_size == PSEUDO_REGNO_BYTES (regno)
4441 && inherent_size <= total_size
4442 && ALLOCNO_HARD_REGNO (allocno) < 0);
4443 if (! flag_ira_share_spill_slots)
4444 return NULL_RTX;
4445 slot_num = -ALLOCNO_HARD_REGNO (allocno) - 2;
4446 if (slot_num != -1)
4448 slot = &ira_spilled_reg_stack_slots[slot_num];
4449 x = slot->mem;
4451 else
4453 best_cost = best_slot_num = -1;
4454 x = NULL_RTX;
4455 /* It means that the pseudo was spilled in the reload pass, try
4456 to reuse a slot. */
4457 for (slot_num = 0;
4458 slot_num < ira_spilled_reg_stack_slots_num;
4459 slot_num++)
4461 slot = &ira_spilled_reg_stack_slots[slot_num];
4462 if (slot->mem == NULL_RTX)
4463 continue;
4464 if (slot->width < total_size
4465 || GET_MODE_SIZE (GET_MODE (slot->mem)) < inherent_size)
4466 continue;
4468 EXECUTE_IF_SET_IN_BITMAP (&slot->spilled_regs,
4469 FIRST_PSEUDO_REGISTER, i, bi)
4471 another_allocno = ira_regno_allocno_map[i];
4472 if (allocnos_conflict_by_live_ranges_p (allocno,
4473 another_allocno))
4474 goto cont;
4476 for (cost = 0, cp = ALLOCNO_COPIES (allocno);
4477 cp != NULL;
4478 cp = next_cp)
4480 if (cp->first == allocno)
4482 next_cp = cp->next_first_allocno_copy;
4483 another_allocno = cp->second;
4485 else if (cp->second == allocno)
4487 next_cp = cp->next_second_allocno_copy;
4488 another_allocno = cp->first;
4490 else
4491 gcc_unreachable ();
4492 if (cp->insn == NULL_RTX)
4493 continue;
4494 if (bitmap_bit_p (&slot->spilled_regs,
4495 ALLOCNO_REGNO (another_allocno)))
4496 cost += cp->freq;
4498 if (cost > best_cost)
4500 best_cost = cost;
4501 best_slot_num = slot_num;
4503 cont:
4506 if (best_cost >= 0)
4508 slot_num = best_slot_num;
4509 slot = &ira_spilled_reg_stack_slots[slot_num];
4510 SET_REGNO_REG_SET (&slot->spilled_regs, regno);
4511 x = slot->mem;
4512 ALLOCNO_HARD_REGNO (allocno) = -slot_num - 2;
4515 if (x != NULL_RTX)
4517 ira_assert (slot->width >= total_size);
4518 #ifdef ENABLE_IRA_CHECKING
4519 EXECUTE_IF_SET_IN_BITMAP (&slot->spilled_regs,
4520 FIRST_PSEUDO_REGISTER, i, bi)
4522 ira_assert (! conflict_by_live_ranges_p (regno, i));
4524 #endif
4525 SET_REGNO_REG_SET (&slot->spilled_regs, regno);
4526 if (internal_flag_ira_verbose > 3 && ira_dump_file)
4528 fprintf (ira_dump_file, " Assigning %d(freq=%d) slot %d of",
4529 regno, REG_FREQ (regno), slot_num);
4530 EXECUTE_IF_SET_IN_BITMAP (&slot->spilled_regs,
4531 FIRST_PSEUDO_REGISTER, i, bi)
4533 if ((unsigned) regno != i)
4534 fprintf (ira_dump_file, " %d", i);
4536 fprintf (ira_dump_file, "\n");
4539 return x;
4542 /* This is called by reload every time a new stack slot X with
4543 TOTAL_SIZE was allocated for REGNO. We store this info for
4544 subsequent ira_reuse_stack_slot calls. */
4545 void
4546 ira_mark_new_stack_slot (rtx x, int regno, unsigned int total_size)
4548 struct ira_spilled_reg_stack_slot *slot;
4549 int slot_num;
4550 ira_allocno_t allocno;
4552 ira_assert (! ira_use_lra_p);
4554 ira_assert (PSEUDO_REGNO_BYTES (regno) <= total_size);
4555 allocno = ira_regno_allocno_map[regno];
4556 slot_num = -ALLOCNO_HARD_REGNO (allocno) - 2;
4557 if (slot_num == -1)
4559 slot_num = ira_spilled_reg_stack_slots_num++;
4560 ALLOCNO_HARD_REGNO (allocno) = -slot_num - 2;
4562 slot = &ira_spilled_reg_stack_slots[slot_num];
4563 INIT_REG_SET (&slot->spilled_regs);
4564 SET_REGNO_REG_SET (&slot->spilled_regs, regno);
4565 slot->mem = x;
4566 slot->width = total_size;
4567 if (internal_flag_ira_verbose > 3 && ira_dump_file)
4568 fprintf (ira_dump_file, " Assigning %d(freq=%d) a new slot %d\n",
4569 regno, REG_FREQ (regno), slot_num);
4573 /* Return spill cost for pseudo-registers whose numbers are in array
4574 REGNOS (with a negative number as an end marker) for reload with
4575 given IN and OUT for INSN. Return also number points (through
4576 EXCESS_PRESSURE_LIVE_LENGTH) where the pseudo-register lives and
4577 the register pressure is high, number of references of the
4578 pseudo-registers (through NREFS), number of callee-clobbered
4579 hard-registers occupied by the pseudo-registers (through
4580 CALL_USED_COUNT), and the first hard regno occupied by the
4581 pseudo-registers (through FIRST_HARD_REGNO). */
4582 static int
4583 calculate_spill_cost (int *regnos, rtx in, rtx out, rtx insn,
4584 int *excess_pressure_live_length,
4585 int *nrefs, int *call_used_count, int *first_hard_regno)
4587 int i, cost, regno, hard_regno, j, count, saved_cost, nregs;
4588 bool in_p, out_p;
4589 int length;
4590 ira_allocno_t a;
4592 *nrefs = 0;
4593 for (length = count = cost = i = 0;; i++)
4595 regno = regnos[i];
4596 if (regno < 0)
4597 break;
4598 *nrefs += REG_N_REFS (regno);
4599 hard_regno = reg_renumber[regno];
4600 ira_assert (hard_regno >= 0);
4601 a = ira_regno_allocno_map[regno];
4602 length += ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a) / ALLOCNO_NUM_OBJECTS (a);
4603 cost += ALLOCNO_MEMORY_COST (a) - ALLOCNO_CLASS_COST (a);
4604 nregs = hard_regno_nregs[hard_regno][ALLOCNO_MODE (a)];
4605 for (j = 0; j < nregs; j++)
4606 if (! TEST_HARD_REG_BIT (call_used_reg_set, hard_regno + j))
4607 break;
4608 if (j == nregs)
4609 count++;
4610 in_p = in && REG_P (in) && (int) REGNO (in) == hard_regno;
4611 out_p = out && REG_P (out) && (int) REGNO (out) == hard_regno;
4612 if ((in_p || out_p)
4613 && find_regno_note (insn, REG_DEAD, hard_regno) != NULL_RTX)
4615 saved_cost = 0;
4616 if (in_p)
4617 saved_cost += ira_memory_move_cost
4618 [ALLOCNO_MODE (a)][ALLOCNO_CLASS (a)][1];
4619 if (out_p)
4620 saved_cost
4621 += ira_memory_move_cost
4622 [ALLOCNO_MODE (a)][ALLOCNO_CLASS (a)][0];
4623 cost -= REG_FREQ_FROM_BB (BLOCK_FOR_INSN (insn)) * saved_cost;
4626 *excess_pressure_live_length = length;
4627 *call_used_count = count;
4628 hard_regno = -1;
4629 if (regnos[0] >= 0)
4631 hard_regno = reg_renumber[regnos[0]];
4633 *first_hard_regno = hard_regno;
4634 return cost;
4637 /* Return TRUE if spilling pseudo-registers whose numbers are in array
4638 REGNOS is better than spilling pseudo-registers with numbers in
4639 OTHER_REGNOS for reload with given IN and OUT for INSN. The
4640 function used by the reload pass to make better register spilling
4641 decisions. */
4642 bool
4643 ira_better_spill_reload_regno_p (int *regnos, int *other_regnos,
4644 rtx in, rtx out, rtx insn)
4646 int cost, other_cost;
4647 int length, other_length;
4648 int nrefs, other_nrefs;
4649 int call_used_count, other_call_used_count;
4650 int hard_regno, other_hard_regno;
4652 cost = calculate_spill_cost (regnos, in, out, insn,
4653 &length, &nrefs, &call_used_count, &hard_regno);
4654 other_cost = calculate_spill_cost (other_regnos, in, out, insn,
4655 &other_length, &other_nrefs,
4656 &other_call_used_count,
4657 &other_hard_regno);
4658 if (nrefs == 0 && other_nrefs != 0)
4659 return true;
4660 if (nrefs != 0 && other_nrefs == 0)
4661 return false;
4662 if (cost != other_cost)
4663 return cost < other_cost;
4664 if (length != other_length)
4665 return length > other_length;
4666 #ifdef REG_ALLOC_ORDER
4667 if (hard_regno >= 0 && other_hard_regno >= 0)
4668 return (inv_reg_alloc_order[hard_regno]
4669 < inv_reg_alloc_order[other_hard_regno]);
4670 #else
4671 if (call_used_count != other_call_used_count)
4672 return call_used_count > other_call_used_count;
4673 #endif
4674 return false;
4679 /* Allocate and initialize data necessary for assign_hard_reg. */
4680 void
4681 ira_initiate_assign (void)
4683 sorted_allocnos
4684 = (ira_allocno_t *) ira_allocate (sizeof (ira_allocno_t)
4685 * ira_allocnos_num);
4686 consideration_allocno_bitmap = ira_allocate_bitmap ();
4687 initiate_cost_update ();
4688 allocno_priorities = (int *) ira_allocate (sizeof (int) * ira_allocnos_num);
4689 sorted_copies = (ira_copy_t *) ira_allocate (ira_copies_num
4690 * sizeof (ira_copy_t));
4693 /* Deallocate data used by assign_hard_reg. */
4694 void
4695 ira_finish_assign (void)
4697 ira_free (sorted_allocnos);
4698 ira_free_bitmap (consideration_allocno_bitmap);
4699 finish_cost_update ();
4700 ira_free (allocno_priorities);
4701 ira_free (sorted_copies);
4706 /* Entry function doing color-based register allocation. */
4707 static void
4708 color (void)
4710 allocno_stack_vec.create (ira_allocnos_num);
4711 memset (allocated_hardreg_p, 0, sizeof (allocated_hardreg_p));
4712 ira_initiate_assign ();
4713 do_coloring ();
4714 ira_finish_assign ();
4715 allocno_stack_vec.release ();
4716 move_spill_restore ();
4721 /* This page contains a simple register allocator without usage of
4722 allocno conflicts. This is used for fast allocation for -O0. */
4724 /* Do register allocation by not using allocno conflicts. It uses
4725 only allocno live ranges. The algorithm is close to Chow's
4726 priority coloring. */
4727 static void
4728 fast_allocation (void)
4730 int i, j, k, num, class_size, hard_regno;
4731 #ifdef STACK_REGS
4732 bool no_stack_reg_p;
4733 #endif
4734 enum reg_class aclass;
4735 machine_mode mode;
4736 ira_allocno_t a;
4737 ira_allocno_iterator ai;
4738 live_range_t r;
4739 HARD_REG_SET conflict_hard_regs, *used_hard_regs;
4741 sorted_allocnos = (ira_allocno_t *) ira_allocate (sizeof (ira_allocno_t)
4742 * ira_allocnos_num);
4743 num = 0;
4744 FOR_EACH_ALLOCNO (a, ai)
4745 sorted_allocnos[num++] = a;
4746 allocno_priorities = (int *) ira_allocate (sizeof (int) * ira_allocnos_num);
4747 setup_allocno_priorities (sorted_allocnos, num);
4748 used_hard_regs = (HARD_REG_SET *) ira_allocate (sizeof (HARD_REG_SET)
4749 * ira_max_point);
4750 for (i = 0; i < ira_max_point; i++)
4751 CLEAR_HARD_REG_SET (used_hard_regs[i]);
4752 qsort (sorted_allocnos, num, sizeof (ira_allocno_t),
4753 allocno_priority_compare_func);
4754 for (i = 0; i < num; i++)
4756 int nr, l;
4758 a = sorted_allocnos[i];
4759 nr = ALLOCNO_NUM_OBJECTS (a);
4760 CLEAR_HARD_REG_SET (conflict_hard_regs);
4761 for (l = 0; l < nr; l++)
4763 ira_object_t obj = ALLOCNO_OBJECT (a, l);
4764 IOR_HARD_REG_SET (conflict_hard_regs,
4765 OBJECT_CONFLICT_HARD_REGS (obj));
4766 for (r = OBJECT_LIVE_RANGES (obj); r != NULL; r = r->next)
4767 for (j = r->start; j <= r->finish; j++)
4768 IOR_HARD_REG_SET (conflict_hard_regs, used_hard_regs[j]);
4770 aclass = ALLOCNO_CLASS (a);
4771 ALLOCNO_ASSIGNED_P (a) = true;
4772 ALLOCNO_HARD_REGNO (a) = -1;
4773 if (hard_reg_set_subset_p (reg_class_contents[aclass],
4774 conflict_hard_regs))
4775 continue;
4776 mode = ALLOCNO_MODE (a);
4777 #ifdef STACK_REGS
4778 no_stack_reg_p = ALLOCNO_NO_STACK_REG_P (a);
4779 #endif
4780 class_size = ira_class_hard_regs_num[aclass];
4781 for (j = 0; j < class_size; j++)
4783 hard_regno = ira_class_hard_regs[aclass][j];
4784 #ifdef STACK_REGS
4785 if (no_stack_reg_p && FIRST_STACK_REG <= hard_regno
4786 && hard_regno <= LAST_STACK_REG)
4787 continue;
4788 #endif
4789 if (ira_hard_reg_set_intersection_p (hard_regno, mode, conflict_hard_regs)
4790 || (TEST_HARD_REG_BIT
4791 (ira_prohibited_class_mode_regs[aclass][mode], hard_regno)))
4792 continue;
4793 ALLOCNO_HARD_REGNO (a) = hard_regno;
4794 for (l = 0; l < nr; l++)
4796 ira_object_t obj = ALLOCNO_OBJECT (a, l);
4797 for (r = OBJECT_LIVE_RANGES (obj); r != NULL; r = r->next)
4798 for (k = r->start; k <= r->finish; k++)
4799 IOR_HARD_REG_SET (used_hard_regs[k],
4800 ira_reg_mode_hard_regset[hard_regno][mode]);
4802 break;
4805 ira_free (sorted_allocnos);
4806 ira_free (used_hard_regs);
4807 ira_free (allocno_priorities);
4808 if (internal_flag_ira_verbose > 1 && ira_dump_file != NULL)
4809 ira_print_disposition (ira_dump_file);
4814 /* Entry function doing coloring. */
4815 void
4816 ira_color (void)
4818 ira_allocno_t a;
4819 ira_allocno_iterator ai;
4821 /* Setup updated costs. */
4822 FOR_EACH_ALLOCNO (a, ai)
4824 ALLOCNO_UPDATED_MEMORY_COST (a) = ALLOCNO_MEMORY_COST (a);
4825 ALLOCNO_UPDATED_CLASS_COST (a) = ALLOCNO_CLASS_COST (a);
4827 if (ira_conflicts_p)
4828 color ();
4829 else
4830 fast_allocation ();