Support slim switch for cfg graph dump
[official-gcc.git] / gcc / ira-color.c
blobdea47fef2d7b961bc64d5db38053cac1c3473fda
1 /* IRA allocation based on graph coloring.
2 Copyright (C) 2006-2013 Free Software Foundation, Inc.
3 Contributed by Vladimir Makarov <vmakarov@redhat.com>.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "rtl.h"
26 #include "tm_p.h"
27 #include "target.h"
28 #include "regs.h"
29 #include "flags.h"
30 #include "sbitmap.h"
31 #include "bitmap.h"
32 #include "hard-reg-set.h"
33 #include "basic-block.h"
34 #include "expr.h"
35 #include "diagnostic-core.h"
36 #include "reload.h"
37 #include "params.h"
38 #include "df.h"
39 #include "ira-int.h"
41 typedef struct allocno_hard_regs *allocno_hard_regs_t;
43 /* The structure contains information about hard registers can be
44 assigned to allocnos. Usually it is allocno profitable hard
45 registers but in some cases this set can be a bit different. Major
46 reason of the difference is a requirement to use hard register sets
47 that form a tree or a forest (set of trees), i.e. hard register set
48 of a node should contain hard register sets of its subnodes. */
49 struct allocno_hard_regs
51 /* Hard registers can be assigned to an allocno. */
52 HARD_REG_SET set;
53 /* Overall (spilling) cost of all allocnos with given register
54 set. */
55 HOST_WIDEST_INT cost;
58 typedef struct allocno_hard_regs_node *allocno_hard_regs_node_t;
60 /* A node representing allocno hard registers. Such nodes form a
61 forest (set of trees). Each subnode of given node in the forest
62 refers for hard register set (usually allocno profitable hard
63 register set) which is a subset of one referred from given
64 node. */
65 struct allocno_hard_regs_node
67 /* Set up number of the node in preorder traversing of the forest. */
68 int preorder_num;
69 /* Used for different calculation like finding conflict size of an
70 allocno. */
71 int check;
72 /* Used for calculation of conflict size of an allocno. The
73 conflict size of the allocno is maximal number of given allocno
74 hard registers needed for allocation of the conflicting allocnos.
75 Given allocno is trivially colored if this number plus the number
76 of hard registers needed for given allocno is not greater than
77 the number of given allocno hard register set. */
78 int conflict_size;
79 /* The number of hard registers given by member hard_regs. */
80 int hard_regs_num;
81 /* The following member is used to form the final forest. */
82 bool used_p;
83 /* Pointer to the corresponding profitable hard registers. */
84 allocno_hard_regs_t hard_regs;
85 /* Parent, first subnode, previous and next node with the same
86 parent in the forest. */
87 allocno_hard_regs_node_t parent, first, prev, next;
90 /* To decrease footprint of ira_allocno structure we store all data
91 needed only for coloring in the following structure. */
92 struct allocno_color_data
94 /* TRUE value means that the allocno was not removed yet from the
95 conflicting graph during colouring. */
96 unsigned int in_graph_p : 1;
97 /* TRUE if it is put on the stack to make other allocnos
98 colorable. */
99 unsigned int may_be_spilled_p : 1;
100 /* TRUE if the allocno is trivially colorable. */
101 unsigned int colorable_p : 1;
102 /* Number of hard registers of the allocno class really
103 available for the allocno allocation. It is number of the
104 profitable hard regs. */
105 int available_regs_num;
106 /* Allocnos in a bucket (used in coloring) chained by the following
107 two members. */
108 ira_allocno_t next_bucket_allocno;
109 ira_allocno_t prev_bucket_allocno;
110 /* Used for temporary purposes. */
111 int temp;
112 /* Used to exclude repeated processing. */
113 int last_process;
114 /* Profitable hard regs available for this pseudo allocation. It
115 means that the set excludes unavailable hard regs and hard regs
116 conflicting with given pseudo. They should be of the allocno
117 class. */
118 HARD_REG_SET profitable_hard_regs;
119 /* The allocno hard registers node. */
120 allocno_hard_regs_node_t hard_regs_node;
121 /* Array of structures allocno_hard_regs_subnode representing
122 given allocno hard registers node (the 1st element in the array)
123 and all its subnodes in the tree (forest) of allocno hard
124 register nodes (see comments above). */
125 int hard_regs_subnodes_start;
126 /* The length of the previous array. */
127 int hard_regs_subnodes_num;
130 /* See above. */
131 typedef struct allocno_color_data *allocno_color_data_t;
133 /* Container for storing allocno data concerning coloring. */
134 static allocno_color_data_t allocno_color_data;
136 /* Macro to access the data concerning coloring. */
137 #define ALLOCNO_COLOR_DATA(a) ((allocno_color_data_t) ALLOCNO_ADD_DATA (a))
139 /* Used for finding allocno colorability to exclude repeated allocno
140 processing and for updating preferencing to exclude repeated
141 allocno processing during assignment. */
142 static int curr_allocno_process;
144 /* This file contains code for regional graph coloring, spill/restore
145 code placement optimization, and code helping the reload pass to do
146 a better job. */
148 /* Bitmap of allocnos which should be colored. */
149 static bitmap coloring_allocno_bitmap;
151 /* Bitmap of allocnos which should be taken into account during
152 coloring. In general case it contains allocnos from
153 coloring_allocno_bitmap plus other already colored conflicting
154 allocnos. */
155 static bitmap consideration_allocno_bitmap;
157 /* All allocnos sorted according their priorities. */
158 static ira_allocno_t *sorted_allocnos;
160 /* Vec representing the stack of allocnos used during coloring. */
161 static vec<ira_allocno_t> allocno_stack_vec;
163 /* Helper for qsort comparison callbacks - return a positive integer if
164 X > Y, or a negative value otherwise. Use a conditional expression
165 instead of a difference computation to insulate from possible overflow
166 issues, e.g. X - Y < 0 for some X > 0 and Y < 0. */
167 #define SORTGT(x,y) (((x) > (y)) ? 1 : -1)
171 /* Definition of vector of allocno hard registers. */
173 /* Vector of unique allocno hard registers. */
174 static vec<allocno_hard_regs_t> allocno_hard_regs_vec;
176 /* Returns hash value for allocno hard registers V. */
177 static hashval_t
178 allocno_hard_regs_hash (const void *v)
180 const struct allocno_hard_regs *hv = (const struct allocno_hard_regs *) v;
182 return iterative_hash (&hv->set, sizeof (HARD_REG_SET), 0);
185 /* Compares allocno hard registers V1 and V2. */
186 static int
187 allocno_hard_regs_eq (const void *v1, const void *v2)
189 const struct allocno_hard_regs *hv1 = (const struct allocno_hard_regs *) v1;
190 const struct allocno_hard_regs *hv2 = (const struct allocno_hard_regs *) v2;
192 return hard_reg_set_equal_p (hv1->set, hv2->set);
195 /* Hash table of unique allocno hard registers. */
196 static htab_t allocno_hard_regs_htab;
198 /* Return allocno hard registers in the hash table equal to HV. */
199 static allocno_hard_regs_t
200 find_hard_regs (allocno_hard_regs_t hv)
202 return (allocno_hard_regs_t) htab_find (allocno_hard_regs_htab, hv);
205 /* Insert allocno hard registers HV in the hash table (if it is not
206 there yet) and return the value which in the table. */
207 static allocno_hard_regs_t
208 insert_hard_regs (allocno_hard_regs_t hv)
210 PTR *slot = htab_find_slot (allocno_hard_regs_htab, hv, INSERT);
212 if (*slot == NULL)
213 *slot = hv;
214 return (allocno_hard_regs_t) *slot;
217 /* Initialize data concerning allocno hard registers. */
218 static void
219 init_allocno_hard_regs (void)
221 allocno_hard_regs_vec.create (200);
222 allocno_hard_regs_htab
223 = htab_create (200, allocno_hard_regs_hash, allocno_hard_regs_eq, NULL);
226 /* Add (or update info about) allocno hard registers with SET and
227 COST. */
228 static allocno_hard_regs_t
229 add_allocno_hard_regs (HARD_REG_SET set, HOST_WIDEST_INT cost)
231 struct allocno_hard_regs temp;
232 allocno_hard_regs_t hv;
234 gcc_assert (! hard_reg_set_empty_p (set));
235 COPY_HARD_REG_SET (temp.set, set);
236 if ((hv = find_hard_regs (&temp)) != NULL)
237 hv->cost += cost;
238 else
240 hv = ((struct allocno_hard_regs *)
241 ira_allocate (sizeof (struct allocno_hard_regs)));
242 COPY_HARD_REG_SET (hv->set, set);
243 hv->cost = cost;
244 allocno_hard_regs_vec.safe_push (hv);
245 insert_hard_regs (hv);
247 return hv;
250 /* Finalize data concerning allocno hard registers. */
251 static void
252 finish_allocno_hard_regs (void)
254 int i;
255 allocno_hard_regs_t hv;
257 for (i = 0;
258 allocno_hard_regs_vec.iterate (i, &hv);
259 i++)
260 ira_free (hv);
261 htab_delete (allocno_hard_regs_htab);
262 allocno_hard_regs_vec.release ();
265 /* Sort hard regs according to their frequency of usage. */
266 static int
267 allocno_hard_regs_compare (const void *v1p, const void *v2p)
269 allocno_hard_regs_t hv1 = *(const allocno_hard_regs_t *) v1p;
270 allocno_hard_regs_t hv2 = *(const allocno_hard_regs_t *) v2p;
272 if (hv2->cost > hv1->cost)
273 return 1;
274 else if (hv2->cost < hv1->cost)
275 return -1;
276 else
277 return 0;
282 /* Used for finding a common ancestor of two allocno hard registers
283 nodes in the forest. We use the current value of
284 'node_check_tick' to mark all nodes from one node to the top and
285 then walking up from another node until we find a marked node.
287 It is also used to figure out allocno colorability as a mark that
288 we already reset value of member 'conflict_size' for the forest
289 node corresponding to the processed allocno. */
290 static int node_check_tick;
292 /* Roots of the forest containing hard register sets can be assigned
293 to allocnos. */
294 static allocno_hard_regs_node_t hard_regs_roots;
296 /* Definition of vector of allocno hard register nodes. */
298 /* Vector used to create the forest. */
299 static vec<allocno_hard_regs_node_t> hard_regs_node_vec;
301 /* Create and return allocno hard registers node containing allocno
302 hard registers HV. */
303 static allocno_hard_regs_node_t
304 create_new_allocno_hard_regs_node (allocno_hard_regs_t hv)
306 allocno_hard_regs_node_t new_node;
308 new_node = ((struct allocno_hard_regs_node *)
309 ira_allocate (sizeof (struct allocno_hard_regs_node)));
310 new_node->check = 0;
311 new_node->hard_regs = hv;
312 new_node->hard_regs_num = hard_reg_set_size (hv->set);
313 new_node->first = NULL;
314 new_node->used_p = false;
315 return new_node;
318 /* Add allocno hard registers node NEW_NODE to the forest on its level
319 given by ROOTS. */
320 static void
321 add_new_allocno_hard_regs_node_to_forest (allocno_hard_regs_node_t *roots,
322 allocno_hard_regs_node_t new_node)
324 new_node->next = *roots;
325 if (new_node->next != NULL)
326 new_node->next->prev = new_node;
327 new_node->prev = NULL;
328 *roots = new_node;
331 /* Add allocno hard registers HV (or its best approximation if it is
332 not possible) to the forest on its level given by ROOTS. */
333 static void
334 add_allocno_hard_regs_to_forest (allocno_hard_regs_node_t *roots,
335 allocno_hard_regs_t hv)
337 unsigned int i, start;
338 allocno_hard_regs_node_t node, prev, new_node;
339 HARD_REG_SET temp_set;
340 allocno_hard_regs_t hv2;
342 start = hard_regs_node_vec.length ();
343 for (node = *roots; node != NULL; node = node->next)
345 if (hard_reg_set_equal_p (hv->set, node->hard_regs->set))
346 return;
347 if (hard_reg_set_subset_p (hv->set, node->hard_regs->set))
349 add_allocno_hard_regs_to_forest (&node->first, hv);
350 return;
352 if (hard_reg_set_subset_p (node->hard_regs->set, hv->set))
353 hard_regs_node_vec.safe_push (node);
354 else if (hard_reg_set_intersect_p (hv->set, node->hard_regs->set))
356 COPY_HARD_REG_SET (temp_set, hv->set);
357 AND_HARD_REG_SET (temp_set, node->hard_regs->set);
358 hv2 = add_allocno_hard_regs (temp_set, hv->cost);
359 add_allocno_hard_regs_to_forest (&node->first, hv2);
362 if (hard_regs_node_vec.length ()
363 > start + 1)
365 /* Create a new node which contains nodes in hard_regs_node_vec. */
366 CLEAR_HARD_REG_SET (temp_set);
367 for (i = start;
368 i < hard_regs_node_vec.length ();
369 i++)
371 node = hard_regs_node_vec[i];
372 IOR_HARD_REG_SET (temp_set, node->hard_regs->set);
374 hv = add_allocno_hard_regs (temp_set, hv->cost);
375 new_node = create_new_allocno_hard_regs_node (hv);
376 prev = NULL;
377 for (i = start;
378 i < hard_regs_node_vec.length ();
379 i++)
381 node = hard_regs_node_vec[i];
382 if (node->prev == NULL)
383 *roots = node->next;
384 else
385 node->prev->next = node->next;
386 if (node->next != NULL)
387 node->next->prev = node->prev;
388 if (prev == NULL)
389 new_node->first = node;
390 else
391 prev->next = node;
392 node->prev = prev;
393 node->next = NULL;
394 prev = node;
396 add_new_allocno_hard_regs_node_to_forest (roots, new_node);
398 hard_regs_node_vec.truncate (start);
401 /* Add allocno hard registers nodes starting with the forest level
402 given by FIRST which contains biggest set inside SET. */
403 static void
404 collect_allocno_hard_regs_cover (allocno_hard_regs_node_t first,
405 HARD_REG_SET set)
407 allocno_hard_regs_node_t node;
409 ira_assert (first != NULL);
410 for (node = first; node != NULL; node = node->next)
411 if (hard_reg_set_subset_p (node->hard_regs->set, set))
412 hard_regs_node_vec.safe_push (node);
413 else if (hard_reg_set_intersect_p (set, node->hard_regs->set))
414 collect_allocno_hard_regs_cover (node->first, set);
417 /* Set up field parent as PARENT in all allocno hard registers nodes
418 in forest given by FIRST. */
419 static void
420 setup_allocno_hard_regs_nodes_parent (allocno_hard_regs_node_t first,
421 allocno_hard_regs_node_t parent)
423 allocno_hard_regs_node_t node;
425 for (node = first; node != NULL; node = node->next)
427 node->parent = parent;
428 setup_allocno_hard_regs_nodes_parent (node->first, node);
432 /* Return allocno hard registers node which is a first common ancestor
433 node of FIRST and SECOND in the forest. */
434 static allocno_hard_regs_node_t
435 first_common_ancestor_node (allocno_hard_regs_node_t first,
436 allocno_hard_regs_node_t second)
438 allocno_hard_regs_node_t node;
440 node_check_tick++;
441 for (node = first; node != NULL; node = node->parent)
442 node->check = node_check_tick;
443 for (node = second; node != NULL; node = node->parent)
444 if (node->check == node_check_tick)
445 return node;
446 return first_common_ancestor_node (second, first);
449 /* Print hard reg set SET to F. */
450 static void
451 print_hard_reg_set (FILE *f, HARD_REG_SET set, bool new_line_p)
453 int i, start;
455 for (start = -1, i = 0; i < FIRST_PSEUDO_REGISTER; i++)
457 if (TEST_HARD_REG_BIT (set, i))
459 if (i == 0 || ! TEST_HARD_REG_BIT (set, i - 1))
460 start = i;
462 if (start >= 0
463 && (i == FIRST_PSEUDO_REGISTER - 1 || ! TEST_HARD_REG_BIT (set, i)))
465 if (start == i - 1)
466 fprintf (f, " %d", start);
467 else if (start == i - 2)
468 fprintf (f, " %d %d", start, start + 1);
469 else
470 fprintf (f, " %d-%d", start, i - 1);
471 start = -1;
474 if (new_line_p)
475 fprintf (f, "\n");
478 /* Print allocno hard register subforest given by ROOTS and its LEVEL
479 to F. */
480 static void
481 print_hard_regs_subforest (FILE *f, allocno_hard_regs_node_t roots,
482 int level)
484 int i;
485 allocno_hard_regs_node_t node;
487 for (node = roots; node != NULL; node = node->next)
489 fprintf (f, " ");
490 for (i = 0; i < level * 2; i++)
491 fprintf (f, " ");
492 fprintf (f, "%d:(", node->preorder_num);
493 print_hard_reg_set (f, node->hard_regs->set, false);
494 fprintf (f, ")@" HOST_WIDEST_INT_PRINT_DEC "\n", node->hard_regs->cost);
495 print_hard_regs_subforest (f, node->first, level + 1);
499 /* Print the allocno hard register forest to F. */
500 static void
501 print_hard_regs_forest (FILE *f)
503 fprintf (f, " Hard reg set forest:\n");
504 print_hard_regs_subforest (f, hard_regs_roots, 1);
507 /* Print the allocno hard register forest to stderr. */
508 void
509 ira_debug_hard_regs_forest (void)
511 print_hard_regs_forest (stderr);
514 /* Remove unused allocno hard registers nodes from forest given by its
515 *ROOTS. */
516 static void
517 remove_unused_allocno_hard_regs_nodes (allocno_hard_regs_node_t *roots)
519 allocno_hard_regs_node_t node, prev, next, last;
521 for (prev = NULL, node = *roots; node != NULL; node = next)
523 next = node->next;
524 if (node->used_p)
526 remove_unused_allocno_hard_regs_nodes (&node->first);
527 prev = node;
529 else
531 for (last = node->first;
532 last != NULL && last->next != NULL;
533 last = last->next)
535 if (last != NULL)
537 if (prev == NULL)
538 *roots = node->first;
539 else
540 prev->next = node->first;
541 if (next != NULL)
542 next->prev = last;
543 last->next = next;
544 next = node->first;
546 else
548 if (prev == NULL)
549 *roots = next;
550 else
551 prev->next = next;
552 if (next != NULL)
553 next->prev = prev;
555 ira_free (node);
560 /* Set up fields preorder_num starting with START_NUM in all allocno
561 hard registers nodes in forest given by FIRST. Return biggest set
562 PREORDER_NUM increased by 1. */
563 static int
564 enumerate_allocno_hard_regs_nodes (allocno_hard_regs_node_t first,
565 allocno_hard_regs_node_t parent,
566 int start_num)
568 allocno_hard_regs_node_t node;
570 for (node = first; node != NULL; node = node->next)
572 node->preorder_num = start_num++;
573 node->parent = parent;
574 start_num = enumerate_allocno_hard_regs_nodes (node->first, node,
575 start_num);
577 return start_num;
580 /* Number of allocno hard registers nodes in the forest. */
581 static int allocno_hard_regs_nodes_num;
583 /* Table preorder number of allocno hard registers node in the forest
584 -> the allocno hard registers node. */
585 static allocno_hard_regs_node_t *allocno_hard_regs_nodes;
587 /* See below. */
588 typedef struct allocno_hard_regs_subnode *allocno_hard_regs_subnode_t;
590 /* The structure is used to describes all subnodes (not only immediate
591 ones) in the mentioned above tree for given allocno hard register
592 node. The usage of such data accelerates calculation of
593 colorability of given allocno. */
594 struct allocno_hard_regs_subnode
596 /* The conflict size of conflicting allocnos whose hard register
597 sets are equal sets (plus supersets if given node is given
598 allocno hard registers node) of one in the given node. */
599 int left_conflict_size;
600 /* The summary conflict size of conflicting allocnos whose hard
601 register sets are strict subsets of one in the given node.
602 Overall conflict size is
603 left_conflict_subnodes_size
604 + MIN (max_node_impact - left_conflict_subnodes_size,
605 left_conflict_size)
607 short left_conflict_subnodes_size;
608 short max_node_impact;
611 /* Container for hard regs subnodes of all allocnos. */
612 static allocno_hard_regs_subnode_t allocno_hard_regs_subnodes;
614 /* Table (preorder number of allocno hard registers node in the
615 forest, preorder number of allocno hard registers subnode) -> index
616 of the subnode relative to the node. -1 if it is not a
617 subnode. */
618 static int *allocno_hard_regs_subnode_index;
620 /* Setup arrays ALLOCNO_HARD_REGS_NODES and
621 ALLOCNO_HARD_REGS_SUBNODE_INDEX. */
622 static void
623 setup_allocno_hard_regs_subnode_index (allocno_hard_regs_node_t first)
625 allocno_hard_regs_node_t node, parent;
626 int index;
628 for (node = first; node != NULL; node = node->next)
630 allocno_hard_regs_nodes[node->preorder_num] = node;
631 for (parent = node; parent != NULL; parent = parent->parent)
633 index = parent->preorder_num * allocno_hard_regs_nodes_num;
634 allocno_hard_regs_subnode_index[index + node->preorder_num]
635 = node->preorder_num - parent->preorder_num;
637 setup_allocno_hard_regs_subnode_index (node->first);
641 /* Count all allocno hard registers nodes in tree ROOT. */
642 static int
643 get_allocno_hard_regs_subnodes_num (allocno_hard_regs_node_t root)
645 int len = 1;
647 for (root = root->first; root != NULL; root = root->next)
648 len += get_allocno_hard_regs_subnodes_num (root);
649 return len;
652 /* Build the forest of allocno hard registers nodes and assign each
653 allocno a node from the forest. */
654 static void
655 form_allocno_hard_regs_nodes_forest (void)
657 unsigned int i, j, size, len;
658 int start;
659 ira_allocno_t a;
660 allocno_hard_regs_t hv;
661 bitmap_iterator bi;
662 HARD_REG_SET temp;
663 allocno_hard_regs_node_t node, allocno_hard_regs_node;
664 allocno_color_data_t allocno_data;
666 node_check_tick = 0;
667 init_allocno_hard_regs ();
668 hard_regs_roots = NULL;
669 hard_regs_node_vec.create (100);
670 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
671 if (! TEST_HARD_REG_BIT (ira_no_alloc_regs, i))
673 CLEAR_HARD_REG_SET (temp);
674 SET_HARD_REG_BIT (temp, i);
675 hv = add_allocno_hard_regs (temp, 0);
676 node = create_new_allocno_hard_regs_node (hv);
677 add_new_allocno_hard_regs_node_to_forest (&hard_regs_roots, node);
679 start = allocno_hard_regs_vec.length ();
680 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
682 a = ira_allocnos[i];
683 allocno_data = ALLOCNO_COLOR_DATA (a);
685 if (hard_reg_set_empty_p (allocno_data->profitable_hard_regs))
686 continue;
687 hv = (add_allocno_hard_regs
688 (allocno_data->profitable_hard_regs,
689 ALLOCNO_MEMORY_COST (a) - ALLOCNO_CLASS_COST (a)));
691 SET_HARD_REG_SET (temp);
692 AND_COMPL_HARD_REG_SET (temp, ira_no_alloc_regs);
693 add_allocno_hard_regs (temp, 0);
694 qsort (allocno_hard_regs_vec.address () + start,
695 allocno_hard_regs_vec.length () - start,
696 sizeof (allocno_hard_regs_t), allocno_hard_regs_compare);
697 for (i = start;
698 allocno_hard_regs_vec.iterate (i, &hv);
699 i++)
701 add_allocno_hard_regs_to_forest (&hard_regs_roots, hv);
702 ira_assert (hard_regs_node_vec.length () == 0);
704 /* We need to set up parent fields for right work of
705 first_common_ancestor_node. */
706 setup_allocno_hard_regs_nodes_parent (hard_regs_roots, NULL);
707 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
709 a = ira_allocnos[i];
710 allocno_data = ALLOCNO_COLOR_DATA (a);
711 if (hard_reg_set_empty_p (allocno_data->profitable_hard_regs))
712 continue;
713 hard_regs_node_vec.truncate (0);
714 collect_allocno_hard_regs_cover (hard_regs_roots,
715 allocno_data->profitable_hard_regs);
716 allocno_hard_regs_node = NULL;
717 for (j = 0; hard_regs_node_vec.iterate (j, &node); j++)
718 allocno_hard_regs_node
719 = (j == 0
720 ? node
721 : first_common_ancestor_node (node, allocno_hard_regs_node));
722 /* That is a temporary storage. */
723 allocno_hard_regs_node->used_p = true;
724 allocno_data->hard_regs_node = allocno_hard_regs_node;
726 ira_assert (hard_regs_roots->next == NULL);
727 hard_regs_roots->used_p = true;
728 remove_unused_allocno_hard_regs_nodes (&hard_regs_roots);
729 allocno_hard_regs_nodes_num
730 = enumerate_allocno_hard_regs_nodes (hard_regs_roots, NULL, 0);
731 allocno_hard_regs_nodes
732 = ((allocno_hard_regs_node_t *)
733 ira_allocate (allocno_hard_regs_nodes_num
734 * sizeof (allocno_hard_regs_node_t)));
735 size = allocno_hard_regs_nodes_num * allocno_hard_regs_nodes_num;
736 allocno_hard_regs_subnode_index
737 = (int *) ira_allocate (size * sizeof (int));
738 for (i = 0; i < size; i++)
739 allocno_hard_regs_subnode_index[i] = -1;
740 setup_allocno_hard_regs_subnode_index (hard_regs_roots);
741 start = 0;
742 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
744 a = ira_allocnos[i];
745 allocno_data = ALLOCNO_COLOR_DATA (a);
746 if (hard_reg_set_empty_p (allocno_data->profitable_hard_regs))
747 continue;
748 len = get_allocno_hard_regs_subnodes_num (allocno_data->hard_regs_node);
749 allocno_data->hard_regs_subnodes_start = start;
750 allocno_data->hard_regs_subnodes_num = len;
751 start += len;
753 allocno_hard_regs_subnodes
754 = ((allocno_hard_regs_subnode_t)
755 ira_allocate (sizeof (struct allocno_hard_regs_subnode) * start));
756 hard_regs_node_vec.release ();
759 /* Free tree of allocno hard registers nodes given by its ROOT. */
760 static void
761 finish_allocno_hard_regs_nodes_tree (allocno_hard_regs_node_t root)
763 allocno_hard_regs_node_t child, next;
765 for (child = root->first; child != NULL; child = next)
767 next = child->next;
768 finish_allocno_hard_regs_nodes_tree (child);
770 ira_free (root);
773 /* Finish work with the forest of allocno hard registers nodes. */
774 static void
775 finish_allocno_hard_regs_nodes_forest (void)
777 allocno_hard_regs_node_t node, next;
779 ira_free (allocno_hard_regs_subnodes);
780 for (node = hard_regs_roots; node != NULL; node = next)
782 next = node->next;
783 finish_allocno_hard_regs_nodes_tree (node);
785 ira_free (allocno_hard_regs_nodes);
786 ira_free (allocno_hard_regs_subnode_index);
787 finish_allocno_hard_regs ();
790 /* Set up left conflict sizes and left conflict subnodes sizes of hard
791 registers subnodes of allocno A. Return TRUE if allocno A is
792 trivially colorable. */
793 static bool
794 setup_left_conflict_sizes_p (ira_allocno_t a)
796 int i, k, nobj, start;
797 int conflict_size, left_conflict_subnodes_size, node_preorder_num;
798 allocno_color_data_t data;
799 HARD_REG_SET profitable_hard_regs;
800 allocno_hard_regs_subnode_t subnodes;
801 allocno_hard_regs_node_t node;
802 HARD_REG_SET node_set;
804 nobj = ALLOCNO_NUM_OBJECTS (a);
805 conflict_size = 0;
806 data = ALLOCNO_COLOR_DATA (a);
807 subnodes = allocno_hard_regs_subnodes + data->hard_regs_subnodes_start;
808 COPY_HARD_REG_SET (profitable_hard_regs, data->profitable_hard_regs);
809 node = data->hard_regs_node;
810 node_preorder_num = node->preorder_num;
811 COPY_HARD_REG_SET (node_set, node->hard_regs->set);
812 node_check_tick++;
813 for (k = 0; k < nobj; k++)
815 ira_object_t obj = ALLOCNO_OBJECT (a, k);
816 ira_object_t conflict_obj;
817 ira_object_conflict_iterator oci;
819 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
821 int size;
822 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
823 allocno_hard_regs_node_t conflict_node, temp_node;
824 HARD_REG_SET conflict_node_set;
825 allocno_color_data_t conflict_data;
827 conflict_data = ALLOCNO_COLOR_DATA (conflict_a);
828 if (! ALLOCNO_COLOR_DATA (conflict_a)->in_graph_p
829 || ! hard_reg_set_intersect_p (profitable_hard_regs,
830 conflict_data
831 ->profitable_hard_regs))
832 continue;
833 conflict_node = conflict_data->hard_regs_node;
834 COPY_HARD_REG_SET (conflict_node_set, conflict_node->hard_regs->set);
835 if (hard_reg_set_subset_p (node_set, conflict_node_set))
836 temp_node = node;
837 else
839 ira_assert (hard_reg_set_subset_p (conflict_node_set, node_set));
840 temp_node = conflict_node;
842 if (temp_node->check != node_check_tick)
844 temp_node->check = node_check_tick;
845 temp_node->conflict_size = 0;
847 size = (ira_reg_class_max_nregs
848 [ALLOCNO_CLASS (conflict_a)][ALLOCNO_MODE (conflict_a)]);
849 if (ALLOCNO_NUM_OBJECTS (conflict_a) > 1)
850 /* We will deal with the subwords individually. */
851 size = 1;
852 temp_node->conflict_size += size;
855 for (i = 0; i < data->hard_regs_subnodes_num; i++)
857 allocno_hard_regs_node_t temp_node;
859 temp_node = allocno_hard_regs_nodes[i + node_preorder_num];
860 ira_assert (temp_node->preorder_num == i + node_preorder_num);
861 subnodes[i].left_conflict_size = (temp_node->check != node_check_tick
862 ? 0 : temp_node->conflict_size);
863 if (hard_reg_set_subset_p (temp_node->hard_regs->set,
864 profitable_hard_regs))
865 subnodes[i].max_node_impact = temp_node->hard_regs_num;
866 else
868 HARD_REG_SET temp_set;
869 int j, n, hard_regno;
870 enum reg_class aclass;
872 COPY_HARD_REG_SET (temp_set, temp_node->hard_regs->set);
873 AND_HARD_REG_SET (temp_set, profitable_hard_regs);
874 aclass = ALLOCNO_CLASS (a);
875 for (n = 0, j = ira_class_hard_regs_num[aclass] - 1; j >= 0; j--)
877 hard_regno = ira_class_hard_regs[aclass][j];
878 if (TEST_HARD_REG_BIT (temp_set, hard_regno))
879 n++;
881 subnodes[i].max_node_impact = n;
883 subnodes[i].left_conflict_subnodes_size = 0;
885 start = node_preorder_num * allocno_hard_regs_nodes_num;
886 for (i = data->hard_regs_subnodes_num - 1; i >= 0; i--)
888 int size, parent_i;
889 allocno_hard_regs_node_t parent;
891 size = (subnodes[i].left_conflict_subnodes_size
892 + MIN (subnodes[i].max_node_impact
893 - subnodes[i].left_conflict_subnodes_size,
894 subnodes[i].left_conflict_size));
895 parent = allocno_hard_regs_nodes[i + node_preorder_num]->parent;
896 if (parent == NULL)
897 continue;
898 parent_i
899 = allocno_hard_regs_subnode_index[start + parent->preorder_num];
900 if (parent_i < 0)
901 continue;
902 subnodes[parent_i].left_conflict_subnodes_size += size;
904 left_conflict_subnodes_size = subnodes[0].left_conflict_subnodes_size;
905 conflict_size
906 += (left_conflict_subnodes_size
907 + MIN (subnodes[0].max_node_impact - left_conflict_subnodes_size,
908 subnodes[0].left_conflict_size));
909 conflict_size += ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)];
910 data->colorable_p = conflict_size <= data->available_regs_num;
911 return data->colorable_p;
914 /* Update left conflict sizes of hard registers subnodes of allocno A
915 after removing allocno REMOVED_A with SIZE from the conflict graph.
916 Return TRUE if A is trivially colorable. */
917 static bool
918 update_left_conflict_sizes_p (ira_allocno_t a,
919 ira_allocno_t removed_a, int size)
921 int i, conflict_size, before_conflict_size, diff, start;
922 int node_preorder_num, parent_i;
923 allocno_hard_regs_node_t node, removed_node, parent;
924 allocno_hard_regs_subnode_t subnodes;
925 allocno_color_data_t data = ALLOCNO_COLOR_DATA (a);
927 ira_assert (! data->colorable_p);
928 node = data->hard_regs_node;
929 node_preorder_num = node->preorder_num;
930 removed_node = ALLOCNO_COLOR_DATA (removed_a)->hard_regs_node;
931 ira_assert (hard_reg_set_subset_p (removed_node->hard_regs->set,
932 node->hard_regs->set)
933 || hard_reg_set_subset_p (node->hard_regs->set,
934 removed_node->hard_regs->set));
935 start = node_preorder_num * allocno_hard_regs_nodes_num;
936 i = allocno_hard_regs_subnode_index[start + removed_node->preorder_num];
937 if (i < 0)
938 i = 0;
939 subnodes = allocno_hard_regs_subnodes + data->hard_regs_subnodes_start;
940 before_conflict_size
941 = (subnodes[i].left_conflict_subnodes_size
942 + MIN (subnodes[i].max_node_impact
943 - subnodes[i].left_conflict_subnodes_size,
944 subnodes[i].left_conflict_size));
945 subnodes[i].left_conflict_size -= size;
946 for (;;)
948 conflict_size
949 = (subnodes[i].left_conflict_subnodes_size
950 + MIN (subnodes[i].max_node_impact
951 - subnodes[i].left_conflict_subnodes_size,
952 subnodes[i].left_conflict_size));
953 if ((diff = before_conflict_size - conflict_size) == 0)
954 break;
955 ira_assert (conflict_size < before_conflict_size);
956 parent = allocno_hard_regs_nodes[i + node_preorder_num]->parent;
957 if (parent == NULL)
958 break;
959 parent_i
960 = allocno_hard_regs_subnode_index[start + parent->preorder_num];
961 if (parent_i < 0)
962 break;
963 i = parent_i;
964 before_conflict_size
965 = (subnodes[i].left_conflict_subnodes_size
966 + MIN (subnodes[i].max_node_impact
967 - subnodes[i].left_conflict_subnodes_size,
968 subnodes[i].left_conflict_size));
969 subnodes[i].left_conflict_subnodes_size -= diff;
971 if (i != 0
972 || (conflict_size
973 + ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]
974 > data->available_regs_num))
975 return false;
976 data->colorable_p = true;
977 return true;
980 /* Return true if allocno A has empty profitable hard regs. */
981 static bool
982 empty_profitable_hard_regs (ira_allocno_t a)
984 allocno_color_data_t data = ALLOCNO_COLOR_DATA (a);
986 return hard_reg_set_empty_p (data->profitable_hard_regs);
989 /* Set up profitable hard registers for each allocno being
990 colored. */
991 static void
992 setup_profitable_hard_regs (void)
994 unsigned int i;
995 int j, k, nobj, hard_regno, nregs, class_size;
996 ira_allocno_t a;
997 bitmap_iterator bi;
998 enum reg_class aclass;
999 enum machine_mode mode;
1000 allocno_color_data_t data;
1002 /* Initial set up from allocno classes and explicitly conflicting
1003 hard regs. */
1004 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
1006 a = ira_allocnos[i];
1007 if ((aclass = ALLOCNO_CLASS (a)) == NO_REGS)
1008 continue;
1009 data = ALLOCNO_COLOR_DATA (a);
1010 if (ALLOCNO_UPDATED_HARD_REG_COSTS (a) == NULL
1011 && ALLOCNO_CLASS_COST (a) > ALLOCNO_MEMORY_COST (a))
1012 CLEAR_HARD_REG_SET (data->profitable_hard_regs);
1013 else
1015 mode = ALLOCNO_MODE (a);
1016 COPY_HARD_REG_SET (data->profitable_hard_regs,
1017 ira_useful_class_mode_regs[aclass][mode]);
1018 nobj = ALLOCNO_NUM_OBJECTS (a);
1019 for (k = 0; k < nobj; k++)
1021 ira_object_t obj = ALLOCNO_OBJECT (a, k);
1023 AND_COMPL_HARD_REG_SET (data->profitable_hard_regs,
1024 OBJECT_TOTAL_CONFLICT_HARD_REGS (obj));
1028 /* Exclude hard regs already assigned for conflicting objects. */
1029 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, i, bi)
1031 a = ira_allocnos[i];
1032 if ((aclass = ALLOCNO_CLASS (a)) == NO_REGS
1033 || ! ALLOCNO_ASSIGNED_P (a)
1034 || (hard_regno = ALLOCNO_HARD_REGNO (a)) < 0)
1035 continue;
1036 mode = ALLOCNO_MODE (a);
1037 nregs = hard_regno_nregs[hard_regno][mode];
1038 nobj = ALLOCNO_NUM_OBJECTS (a);
1039 for (k = 0; k < nobj; k++)
1041 ira_object_t obj = ALLOCNO_OBJECT (a, k);
1042 ira_object_t conflict_obj;
1043 ira_object_conflict_iterator oci;
1045 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
1047 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
1049 /* We can process the conflict allocno repeatedly with
1050 the same result. */
1051 if (nregs == nobj && nregs > 1)
1053 int num = OBJECT_SUBWORD (conflict_obj);
1055 if (REG_WORDS_BIG_ENDIAN)
1056 CLEAR_HARD_REG_BIT
1057 (ALLOCNO_COLOR_DATA (conflict_a)->profitable_hard_regs,
1058 hard_regno + nobj - num - 1);
1059 else
1060 CLEAR_HARD_REG_BIT
1061 (ALLOCNO_COLOR_DATA (conflict_a)->profitable_hard_regs,
1062 hard_regno + num);
1064 else
1065 AND_COMPL_HARD_REG_SET
1066 (ALLOCNO_COLOR_DATA (conflict_a)->profitable_hard_regs,
1067 ira_reg_mode_hard_regset[hard_regno][mode]);
1071 /* Exclude too costly hard regs. */
1072 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
1074 int min_cost = INT_MAX;
1075 int *costs;
1077 a = ira_allocnos[i];
1078 if ((aclass = ALLOCNO_CLASS (a)) == NO_REGS
1079 || empty_profitable_hard_regs (a))
1080 continue;
1081 data = ALLOCNO_COLOR_DATA (a);
1082 mode = ALLOCNO_MODE (a);
1083 if ((costs = ALLOCNO_UPDATED_HARD_REG_COSTS (a)) != NULL
1084 || (costs = ALLOCNO_HARD_REG_COSTS (a)) != NULL)
1086 class_size = ira_class_hard_regs_num[aclass];
1087 for (j = 0; j < class_size; j++)
1089 hard_regno = ira_class_hard_regs[aclass][j];
1090 if (! TEST_HARD_REG_BIT (data->profitable_hard_regs,
1091 hard_regno))
1092 continue;
1093 if (ALLOCNO_UPDATED_MEMORY_COST (a) < costs[j])
1094 CLEAR_HARD_REG_BIT (data->profitable_hard_regs,
1095 hard_regno);
1096 else if (min_cost > costs[j])
1097 min_cost = costs[j];
1100 else if (ALLOCNO_UPDATED_MEMORY_COST (a)
1101 < ALLOCNO_UPDATED_CLASS_COST (a))
1102 CLEAR_HARD_REG_SET (data->profitable_hard_regs);
1103 if (ALLOCNO_UPDATED_CLASS_COST (a) > min_cost)
1104 ALLOCNO_UPDATED_CLASS_COST (a) = min_cost;
1110 /* This page contains functions used to choose hard registers for
1111 allocnos. */
1113 /* Array whose element value is TRUE if the corresponding hard
1114 register was already allocated for an allocno. */
1115 static bool allocated_hardreg_p[FIRST_PSEUDO_REGISTER];
1117 /* Describes one element in a queue of allocnos whose costs need to be
1118 updated. Each allocno in the queue is known to have an allocno
1119 class. */
1120 struct update_cost_queue_elem
1122 /* This element is in the queue iff CHECK == update_cost_check. */
1123 int check;
1125 /* COST_HOP_DIVISOR**N, where N is the length of the shortest path
1126 connecting this allocno to the one being allocated. */
1127 int divisor;
1129 /* The next allocno in the queue, or null if this is the last element. */
1130 ira_allocno_t next;
1133 /* The first element in a queue of allocnos whose copy costs need to be
1134 updated. Null if the queue is empty. */
1135 static ira_allocno_t update_cost_queue;
1137 /* The last element in the queue described by update_cost_queue.
1138 Not valid if update_cost_queue is null. */
1139 static struct update_cost_queue_elem *update_cost_queue_tail;
1141 /* A pool of elements in the queue described by update_cost_queue.
1142 Elements are indexed by ALLOCNO_NUM. */
1143 static struct update_cost_queue_elem *update_cost_queue_elems;
1145 /* The current value of update_copy_cost call count. */
1146 static int update_cost_check;
1148 /* Allocate and initialize data necessary for function
1149 update_copy_costs. */
1150 static void
1151 initiate_cost_update (void)
1153 size_t size;
1155 size = ira_allocnos_num * sizeof (struct update_cost_queue_elem);
1156 update_cost_queue_elems
1157 = (struct update_cost_queue_elem *) ira_allocate (size);
1158 memset (update_cost_queue_elems, 0, size);
1159 update_cost_check = 0;
1162 /* Deallocate data used by function update_copy_costs. */
1163 static void
1164 finish_cost_update (void)
1166 ira_free (update_cost_queue_elems);
1169 /* When we traverse allocnos to update hard register costs, the cost
1170 divisor will be multiplied by the following macro value for each
1171 hop from given allocno to directly connected allocnos. */
1172 #define COST_HOP_DIVISOR 4
1174 /* Start a new cost-updating pass. */
1175 static void
1176 start_update_cost (void)
1178 update_cost_check++;
1179 update_cost_queue = NULL;
1182 /* Add (ALLOCNO, DIVISOR) to the end of update_cost_queue, unless
1183 ALLOCNO is already in the queue, or has NO_REGS class. */
1184 static inline void
1185 queue_update_cost (ira_allocno_t allocno, int divisor)
1187 struct update_cost_queue_elem *elem;
1189 elem = &update_cost_queue_elems[ALLOCNO_NUM (allocno)];
1190 if (elem->check != update_cost_check
1191 && ALLOCNO_CLASS (allocno) != NO_REGS)
1193 elem->check = update_cost_check;
1194 elem->divisor = divisor;
1195 elem->next = NULL;
1196 if (update_cost_queue == NULL)
1197 update_cost_queue = allocno;
1198 else
1199 update_cost_queue_tail->next = allocno;
1200 update_cost_queue_tail = elem;
1204 /* Try to remove the first element from update_cost_queue. Return false
1205 if the queue was empty, otherwise make (*ALLOCNO, *DIVISOR) describe
1206 the removed element. */
1207 static inline bool
1208 get_next_update_cost (ira_allocno_t *allocno, int *divisor)
1210 struct update_cost_queue_elem *elem;
1212 if (update_cost_queue == NULL)
1213 return false;
1215 *allocno = update_cost_queue;
1216 elem = &update_cost_queue_elems[ALLOCNO_NUM (*allocno)];
1217 *divisor = elem->divisor;
1218 update_cost_queue = elem->next;
1219 return true;
1222 /* Update the cost of allocnos to increase chances to remove some
1223 copies as the result of subsequent assignment. */
1224 static void
1225 update_copy_costs (ira_allocno_t allocno, bool decr_p)
1227 int i, cost, update_cost, hard_regno, divisor;
1228 enum machine_mode mode;
1229 enum reg_class rclass, aclass;
1230 ira_allocno_t another_allocno;
1231 ira_copy_t cp, next_cp;
1233 hard_regno = ALLOCNO_HARD_REGNO (allocno);
1234 ira_assert (hard_regno >= 0);
1236 aclass = ALLOCNO_CLASS (allocno);
1237 if (aclass == NO_REGS)
1238 return;
1239 i = ira_class_hard_reg_index[aclass][hard_regno];
1240 ira_assert (i >= 0);
1241 rclass = REGNO_REG_CLASS (hard_regno);
1243 start_update_cost ();
1244 divisor = 1;
1247 mode = ALLOCNO_MODE (allocno);
1248 ira_init_register_move_cost_if_necessary (mode);
1249 for (cp = ALLOCNO_COPIES (allocno); cp != NULL; cp = next_cp)
1251 if (cp->first == allocno)
1253 next_cp = cp->next_first_allocno_copy;
1254 another_allocno = cp->second;
1256 else if (cp->second == allocno)
1258 next_cp = cp->next_second_allocno_copy;
1259 another_allocno = cp->first;
1261 else
1262 gcc_unreachable ();
1264 aclass = ALLOCNO_CLASS (another_allocno);
1265 if (! TEST_HARD_REG_BIT (reg_class_contents[aclass],
1266 hard_regno)
1267 || ALLOCNO_ASSIGNED_P (another_allocno))
1268 continue;
1270 cost = (cp->second == allocno
1271 ? ira_register_move_cost[mode][rclass][aclass]
1272 : ira_register_move_cost[mode][aclass][rclass]);
1273 if (decr_p)
1274 cost = -cost;
1276 update_cost = cp->freq * cost / divisor;
1277 if (update_cost == 0)
1278 continue;
1280 ira_allocate_and_set_or_copy_costs
1281 (&ALLOCNO_UPDATED_HARD_REG_COSTS (another_allocno), aclass,
1282 ALLOCNO_UPDATED_CLASS_COST (another_allocno),
1283 ALLOCNO_HARD_REG_COSTS (another_allocno));
1284 ira_allocate_and_set_or_copy_costs
1285 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (another_allocno),
1286 aclass, 0, ALLOCNO_CONFLICT_HARD_REG_COSTS (another_allocno));
1287 i = ira_class_hard_reg_index[aclass][hard_regno];
1288 if (i < 0)
1289 continue;
1290 ALLOCNO_UPDATED_HARD_REG_COSTS (another_allocno)[i] += update_cost;
1291 ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (another_allocno)[i]
1292 += update_cost;
1294 queue_update_cost (another_allocno, divisor * COST_HOP_DIVISOR);
1297 while (get_next_update_cost (&allocno, &divisor));
1300 /* This function updates COSTS (decrease if DECR_P) for hard_registers
1301 of ACLASS by conflict costs of the unassigned allocnos
1302 connected by copies with allocnos in update_cost_queue. This
1303 update increases chances to remove some copies. */
1304 static void
1305 update_conflict_hard_regno_costs (int *costs, enum reg_class aclass,
1306 bool decr_p)
1308 int i, cost, class_size, freq, mult, div, divisor;
1309 int index, hard_regno;
1310 int *conflict_costs;
1311 bool cont_p;
1312 enum reg_class another_aclass;
1313 ira_allocno_t allocno, another_allocno;
1314 ira_copy_t cp, next_cp;
1316 while (get_next_update_cost (&allocno, &divisor))
1317 for (cp = ALLOCNO_COPIES (allocno); cp != NULL; cp = next_cp)
1319 if (cp->first == allocno)
1321 next_cp = cp->next_first_allocno_copy;
1322 another_allocno = cp->second;
1324 else if (cp->second == allocno)
1326 next_cp = cp->next_second_allocno_copy;
1327 another_allocno = cp->first;
1329 else
1330 gcc_unreachable ();
1331 another_aclass = ALLOCNO_CLASS (another_allocno);
1332 if (! ira_reg_classes_intersect_p[aclass][another_aclass]
1333 || ALLOCNO_ASSIGNED_P (another_allocno)
1334 || ALLOCNO_COLOR_DATA (another_allocno)->may_be_spilled_p)
1335 continue;
1336 class_size = ira_class_hard_regs_num[another_aclass];
1337 ira_allocate_and_copy_costs
1338 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (another_allocno),
1339 another_aclass, ALLOCNO_CONFLICT_HARD_REG_COSTS (another_allocno));
1340 conflict_costs
1341 = ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (another_allocno);
1342 if (conflict_costs == NULL)
1343 cont_p = true;
1344 else
1346 mult = cp->freq;
1347 freq = ALLOCNO_FREQ (another_allocno);
1348 if (freq == 0)
1349 freq = 1;
1350 div = freq * divisor;
1351 cont_p = false;
1352 for (i = class_size - 1; i >= 0; i--)
1354 hard_regno = ira_class_hard_regs[another_aclass][i];
1355 ira_assert (hard_regno >= 0);
1356 index = ira_class_hard_reg_index[aclass][hard_regno];
1357 if (index < 0)
1358 continue;
1359 cost = conflict_costs [i] * mult / div;
1360 if (cost == 0)
1361 continue;
1362 cont_p = true;
1363 if (decr_p)
1364 cost = -cost;
1365 costs[index] += cost;
1368 /* Probably 5 hops will be enough. */
1369 if (cont_p
1370 && divisor <= (COST_HOP_DIVISOR
1371 * COST_HOP_DIVISOR
1372 * COST_HOP_DIVISOR
1373 * COST_HOP_DIVISOR))
1374 queue_update_cost (another_allocno, divisor * COST_HOP_DIVISOR);
1378 /* Set up conflicting (through CONFLICT_REGS) for each object of
1379 allocno A and the start allocno profitable regs (through
1380 START_PROFITABLE_REGS). Remember that the start profitable regs
1381 exclude hard regs which can not hold value of mode of allocno A.
1382 This covers mostly cases when multi-register value should be
1383 aligned. */
1384 static inline void
1385 get_conflict_and_start_profitable_regs (ira_allocno_t a, bool retry_p,
1386 HARD_REG_SET *conflict_regs,
1387 HARD_REG_SET *start_profitable_regs)
1389 int i, nwords;
1390 ira_object_t obj;
1392 nwords = ALLOCNO_NUM_OBJECTS (a);
1393 for (i = 0; i < nwords; i++)
1395 obj = ALLOCNO_OBJECT (a, i);
1396 COPY_HARD_REG_SET (conflict_regs[i],
1397 OBJECT_TOTAL_CONFLICT_HARD_REGS (obj));
1399 if (retry_p)
1401 COPY_HARD_REG_SET (*start_profitable_regs,
1402 reg_class_contents[ALLOCNO_CLASS (a)]);
1403 AND_COMPL_HARD_REG_SET (*start_profitable_regs,
1404 ira_prohibited_class_mode_regs
1405 [ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]);
1407 else
1408 COPY_HARD_REG_SET (*start_profitable_regs,
1409 ALLOCNO_COLOR_DATA (a)->profitable_hard_regs);
1412 /* Return true if HARD_REGNO is ok for assigning to allocno A with
1413 PROFITABLE_REGS and whose objects have CONFLICT_REGS. */
1414 static inline bool
1415 check_hard_reg_p (ira_allocno_t a, int hard_regno,
1416 HARD_REG_SET *conflict_regs, HARD_REG_SET profitable_regs)
1418 int j, nwords, nregs;
1419 enum reg_class aclass;
1420 enum machine_mode mode;
1422 aclass = ALLOCNO_CLASS (a);
1423 mode = ALLOCNO_MODE (a);
1424 if (TEST_HARD_REG_BIT (ira_prohibited_class_mode_regs[aclass][mode],
1425 hard_regno))
1426 return false;
1427 /* Checking only profitable hard regs. */
1428 if (! TEST_HARD_REG_BIT (profitable_regs, hard_regno))
1429 return false;
1430 nregs = hard_regno_nregs[hard_regno][mode];
1431 nwords = ALLOCNO_NUM_OBJECTS (a);
1432 for (j = 0; j < nregs; j++)
1434 int k;
1435 int set_to_test_start = 0, set_to_test_end = nwords;
1437 if (nregs == nwords)
1439 if (REG_WORDS_BIG_ENDIAN)
1440 set_to_test_start = nwords - j - 1;
1441 else
1442 set_to_test_start = j;
1443 set_to_test_end = set_to_test_start + 1;
1445 for (k = set_to_test_start; k < set_to_test_end; k++)
1446 if (TEST_HARD_REG_BIT (conflict_regs[k], hard_regno + j))
1447 break;
1448 if (k != set_to_test_end)
1449 break;
1451 return j == nregs;
1453 #ifndef HONOR_REG_ALLOC_ORDER
1455 /* Return number of registers needed to be saved and restored at
1456 function prologue/epilogue if we allocate HARD_REGNO to hold value
1457 of MODE. */
1458 static int
1459 calculate_saved_nregs (int hard_regno, enum machine_mode mode)
1461 int i;
1462 int nregs = 0;
1464 ira_assert (hard_regno >= 0);
1465 for (i = hard_regno_nregs[hard_regno][mode] - 1; i >= 0; i--)
1466 if (!allocated_hardreg_p[hard_regno + i]
1467 && !TEST_HARD_REG_BIT (call_used_reg_set, hard_regno + i)
1468 && !LOCAL_REGNO (hard_regno + i))
1469 nregs++;
1470 return nregs;
1472 #endif
1474 /* Choose a hard register for allocno A. If RETRY_P is TRUE, it means
1475 that the function called from function
1476 `ira_reassign_conflict_allocnos' and `allocno_reload_assign'. In
1477 this case some allocno data are not defined or updated and we
1478 should not touch these data. The function returns true if we
1479 managed to assign a hard register to the allocno.
1481 To assign a hard register, first of all we calculate all conflict
1482 hard registers which can come from conflicting allocnos with
1483 already assigned hard registers. After that we find first free
1484 hard register with the minimal cost. During hard register cost
1485 calculation we take conflict hard register costs into account to
1486 give a chance for conflicting allocnos to get a better hard
1487 register in the future.
1489 If the best hard register cost is bigger than cost of memory usage
1490 for the allocno, we don't assign a hard register to given allocno
1491 at all.
1493 If we assign a hard register to the allocno, we update costs of the
1494 hard register for allocnos connected by copies to improve a chance
1495 to coalesce insns represented by the copies when we assign hard
1496 registers to the allocnos connected by the copies. */
1497 static bool
1498 assign_hard_reg (ira_allocno_t a, bool retry_p)
1500 HARD_REG_SET conflicting_regs[2], profitable_hard_regs;
1501 int i, j, hard_regno, best_hard_regno, class_size;
1502 int cost, mem_cost, min_cost, full_cost, min_full_cost, nwords, word;
1503 int *a_costs;
1504 enum reg_class aclass;
1505 enum machine_mode mode;
1506 static int costs[FIRST_PSEUDO_REGISTER], full_costs[FIRST_PSEUDO_REGISTER];
1507 #ifndef HONOR_REG_ALLOC_ORDER
1508 int saved_nregs;
1509 enum reg_class rclass;
1510 int add_cost;
1511 #endif
1512 #ifdef STACK_REGS
1513 bool no_stack_reg_p;
1514 #endif
1516 ira_assert (! ALLOCNO_ASSIGNED_P (a));
1517 get_conflict_and_start_profitable_regs (a, retry_p,
1518 conflicting_regs,
1519 &profitable_hard_regs);
1520 aclass = ALLOCNO_CLASS (a);
1521 class_size = ira_class_hard_regs_num[aclass];
1522 best_hard_regno = -1;
1523 memset (full_costs, 0, sizeof (int) * class_size);
1524 mem_cost = 0;
1525 memset (costs, 0, sizeof (int) * class_size);
1526 memset (full_costs, 0, sizeof (int) * class_size);
1527 #ifdef STACK_REGS
1528 no_stack_reg_p = false;
1529 #endif
1530 if (! retry_p)
1531 start_update_cost ();
1532 mem_cost += ALLOCNO_UPDATED_MEMORY_COST (a);
1534 ira_allocate_and_copy_costs (&ALLOCNO_UPDATED_HARD_REG_COSTS (a),
1535 aclass, ALLOCNO_HARD_REG_COSTS (a));
1536 a_costs = ALLOCNO_UPDATED_HARD_REG_COSTS (a);
1537 #ifdef STACK_REGS
1538 no_stack_reg_p = no_stack_reg_p || ALLOCNO_TOTAL_NO_STACK_REG_P (a);
1539 #endif
1540 cost = ALLOCNO_UPDATED_CLASS_COST (a);
1541 for (i = 0; i < class_size; i++)
1542 if (a_costs != NULL)
1544 costs[i] += a_costs[i];
1545 full_costs[i] += a_costs[i];
1547 else
1549 costs[i] += cost;
1550 full_costs[i] += cost;
1552 nwords = ALLOCNO_NUM_OBJECTS (a);
1553 curr_allocno_process++;
1554 for (word = 0; word < nwords; word++)
1556 ira_object_t conflict_obj;
1557 ira_object_t obj = ALLOCNO_OBJECT (a, word);
1558 ira_object_conflict_iterator oci;
1560 /* Take preferences of conflicting allocnos into account. */
1561 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
1563 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
1564 enum reg_class conflict_aclass;
1566 /* Reload can give another class so we need to check all
1567 allocnos. */
1568 if (!retry_p
1569 && (!bitmap_bit_p (consideration_allocno_bitmap,
1570 ALLOCNO_NUM (conflict_a))
1571 || ((!ALLOCNO_ASSIGNED_P (conflict_a)
1572 || ALLOCNO_HARD_REGNO (conflict_a) < 0)
1573 && !(hard_reg_set_intersect_p
1574 (profitable_hard_regs,
1575 ALLOCNO_COLOR_DATA
1576 (conflict_a)->profitable_hard_regs)))))
1577 continue;
1578 conflict_aclass = ALLOCNO_CLASS (conflict_a);
1579 ira_assert (ira_reg_classes_intersect_p
1580 [aclass][conflict_aclass]);
1581 if (ALLOCNO_ASSIGNED_P (conflict_a))
1583 hard_regno = ALLOCNO_HARD_REGNO (conflict_a);
1584 if (hard_regno >= 0
1585 && (ira_hard_reg_set_intersection_p
1586 (hard_regno, ALLOCNO_MODE (conflict_a),
1587 reg_class_contents[aclass])))
1589 int n_objects = ALLOCNO_NUM_OBJECTS (conflict_a);
1590 int conflict_nregs;
1592 mode = ALLOCNO_MODE (conflict_a);
1593 conflict_nregs = hard_regno_nregs[hard_regno][mode];
1594 if (conflict_nregs == n_objects && conflict_nregs > 1)
1596 int num = OBJECT_SUBWORD (conflict_obj);
1598 if (REG_WORDS_BIG_ENDIAN)
1599 SET_HARD_REG_BIT (conflicting_regs[word],
1600 hard_regno + n_objects - num - 1);
1601 else
1602 SET_HARD_REG_BIT (conflicting_regs[word],
1603 hard_regno + num);
1605 else
1606 IOR_HARD_REG_SET
1607 (conflicting_regs[word],
1608 ira_reg_mode_hard_regset[hard_regno][mode]);
1609 if (hard_reg_set_subset_p (profitable_hard_regs,
1610 conflicting_regs[word]))
1611 goto fail;
1614 else if (! retry_p
1615 && ! ALLOCNO_COLOR_DATA (conflict_a)->may_be_spilled_p
1616 /* Don't process the conflict allocno twice. */
1617 && (ALLOCNO_COLOR_DATA (conflict_a)->last_process
1618 != curr_allocno_process))
1620 int k, *conflict_costs;
1622 ALLOCNO_COLOR_DATA (conflict_a)->last_process
1623 = curr_allocno_process;
1624 ira_allocate_and_copy_costs
1625 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (conflict_a),
1626 conflict_aclass,
1627 ALLOCNO_CONFLICT_HARD_REG_COSTS (conflict_a));
1628 conflict_costs
1629 = ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (conflict_a);
1630 if (conflict_costs != NULL)
1631 for (j = class_size - 1; j >= 0; j--)
1633 hard_regno = ira_class_hard_regs[aclass][j];
1634 ira_assert (hard_regno >= 0);
1635 k = ira_class_hard_reg_index[conflict_aclass][hard_regno];
1636 if (k < 0)
1637 continue;
1638 full_costs[j] -= conflict_costs[k];
1640 queue_update_cost (conflict_a, COST_HOP_DIVISOR);
1644 if (! retry_p)
1645 /* Take into account preferences of allocnos connected by copies to
1646 the conflict allocnos. */
1647 update_conflict_hard_regno_costs (full_costs, aclass, true);
1649 /* Take preferences of allocnos connected by copies into
1650 account. */
1651 if (! retry_p)
1653 start_update_cost ();
1654 queue_update_cost (a, COST_HOP_DIVISOR);
1655 update_conflict_hard_regno_costs (full_costs, aclass, false);
1657 min_cost = min_full_cost = INT_MAX;
1658 /* We don't care about giving callee saved registers to allocnos no
1659 living through calls because call clobbered registers are
1660 allocated first (it is usual practice to put them first in
1661 REG_ALLOC_ORDER). */
1662 mode = ALLOCNO_MODE (a);
1663 for (i = 0; i < class_size; i++)
1665 hard_regno = ira_class_hard_regs[aclass][i];
1666 #ifdef STACK_REGS
1667 if (no_stack_reg_p
1668 && FIRST_STACK_REG <= hard_regno && hard_regno <= LAST_STACK_REG)
1669 continue;
1670 #endif
1671 if (! check_hard_reg_p (a, hard_regno,
1672 conflicting_regs, profitable_hard_regs))
1673 continue;
1674 cost = costs[i];
1675 full_cost = full_costs[i];
1676 #ifndef HONOR_REG_ALLOC_ORDER
1677 if ((saved_nregs = calculate_saved_nregs (hard_regno, mode)) != 0)
1678 /* We need to save/restore the hard register in
1679 epilogue/prologue. Therefore we increase the cost. */
1681 rclass = REGNO_REG_CLASS (hard_regno);
1682 add_cost = ((ira_memory_move_cost[mode][rclass][0]
1683 + ira_memory_move_cost[mode][rclass][1])
1684 * saved_nregs / hard_regno_nregs[hard_regno][mode] - 1);
1685 cost += add_cost;
1686 full_cost += add_cost;
1688 #endif
1689 if (min_cost > cost)
1690 min_cost = cost;
1691 if (min_full_cost > full_cost)
1693 min_full_cost = full_cost;
1694 best_hard_regno = hard_regno;
1695 ira_assert (hard_regno >= 0);
1698 if (min_full_cost > mem_cost)
1700 if (! retry_p && internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
1701 fprintf (ira_dump_file, "(memory is more profitable %d vs %d) ",
1702 mem_cost, min_full_cost);
1703 best_hard_regno = -1;
1705 fail:
1706 if (best_hard_regno >= 0)
1708 for (i = hard_regno_nregs[best_hard_regno][mode] - 1; i >= 0; i--)
1709 allocated_hardreg_p[best_hard_regno + i] = true;
1711 ALLOCNO_HARD_REGNO (a) = best_hard_regno;
1712 ALLOCNO_ASSIGNED_P (a) = true;
1713 if (best_hard_regno >= 0)
1714 update_copy_costs (a, true);
1715 ira_assert (ALLOCNO_CLASS (a) == aclass);
1716 /* We don't need updated costs anymore: */
1717 ira_free_allocno_updated_costs (a);
1718 return best_hard_regno >= 0;
1723 /* This page contains the allocator based on the Chaitin-Briggs algorithm. */
1725 /* Bucket of allocnos that can colored currently without spilling. */
1726 static ira_allocno_t colorable_allocno_bucket;
1728 /* Bucket of allocnos that might be not colored currently without
1729 spilling. */
1730 static ira_allocno_t uncolorable_allocno_bucket;
1732 /* The current number of allocnos in the uncolorable_bucket. */
1733 static int uncolorable_allocnos_num;
1735 /* Return the current spill priority of allocno A. The less the
1736 number, the more preferable the allocno for spilling. */
1737 static inline int
1738 allocno_spill_priority (ira_allocno_t a)
1740 allocno_color_data_t data = ALLOCNO_COLOR_DATA (a);
1742 return (data->temp
1743 / (ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a)
1744 * ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]
1745 + 1));
1748 /* Add allocno A to bucket *BUCKET_PTR. A should be not in a bucket
1749 before the call. */
1750 static void
1751 add_allocno_to_bucket (ira_allocno_t a, ira_allocno_t *bucket_ptr)
1753 ira_allocno_t first_a;
1754 allocno_color_data_t data;
1756 if (bucket_ptr == &uncolorable_allocno_bucket
1757 && ALLOCNO_CLASS (a) != NO_REGS)
1759 uncolorable_allocnos_num++;
1760 ira_assert (uncolorable_allocnos_num > 0);
1762 first_a = *bucket_ptr;
1763 data = ALLOCNO_COLOR_DATA (a);
1764 data->next_bucket_allocno = first_a;
1765 data->prev_bucket_allocno = NULL;
1766 if (first_a != NULL)
1767 ALLOCNO_COLOR_DATA (first_a)->prev_bucket_allocno = a;
1768 *bucket_ptr = a;
1771 /* Compare two allocnos to define which allocno should be pushed first
1772 into the coloring stack. If the return is a negative number, the
1773 allocno given by the first parameter will be pushed first. In this
1774 case such allocno has less priority than the second one and the
1775 hard register will be assigned to it after assignment to the second
1776 one. As the result of such assignment order, the second allocno
1777 has a better chance to get the best hard register. */
1778 static int
1779 bucket_allocno_compare_func (const void *v1p, const void *v2p)
1781 ira_allocno_t a1 = *(const ira_allocno_t *) v1p;
1782 ira_allocno_t a2 = *(const ira_allocno_t *) v2p;
1783 int diff, a1_freq, a2_freq, a1_num, a2_num;
1784 int cl1 = ALLOCNO_CLASS (a1), cl2 = ALLOCNO_CLASS (a2);
1786 /* Push pseudos requiring less hard registers first. It means that
1787 we will assign pseudos requiring more hard registers first
1788 avoiding creation small holes in free hard register file into
1789 which the pseudos requiring more hard registers can not fit. */
1790 if ((diff = (ira_reg_class_max_nregs[cl1][ALLOCNO_MODE (a1)]
1791 - ira_reg_class_max_nregs[cl2][ALLOCNO_MODE (a2)])) != 0)
1792 return diff;
1793 a1_freq = ALLOCNO_FREQ (a1);
1794 a2_freq = ALLOCNO_FREQ (a2);
1795 if ((diff = a1_freq - a2_freq) != 0)
1796 return diff;
1797 a1_num = ALLOCNO_COLOR_DATA (a1)->available_regs_num;
1798 a2_num = ALLOCNO_COLOR_DATA (a2)->available_regs_num;
1799 if ((diff = a2_num - a1_num) != 0)
1800 return diff;
1801 return ALLOCNO_NUM (a2) - ALLOCNO_NUM (a1);
1804 /* Sort bucket *BUCKET_PTR and return the result through
1805 BUCKET_PTR. */
1806 static void
1807 sort_bucket (ira_allocno_t *bucket_ptr,
1808 int (*compare_func) (const void *, const void *))
1810 ira_allocno_t a, head;
1811 int n;
1813 for (n = 0, a = *bucket_ptr;
1814 a != NULL;
1815 a = ALLOCNO_COLOR_DATA (a)->next_bucket_allocno)
1816 sorted_allocnos[n++] = a;
1817 if (n <= 1)
1818 return;
1819 qsort (sorted_allocnos, n, sizeof (ira_allocno_t), compare_func);
1820 head = NULL;
1821 for (n--; n >= 0; n--)
1823 a = sorted_allocnos[n];
1824 ALLOCNO_COLOR_DATA (a)->next_bucket_allocno = head;
1825 ALLOCNO_COLOR_DATA (a)->prev_bucket_allocno = NULL;
1826 if (head != NULL)
1827 ALLOCNO_COLOR_DATA (head)->prev_bucket_allocno = a;
1828 head = a;
1830 *bucket_ptr = head;
1833 /* Add ALLOCNO to bucket *BUCKET_PTR maintaining the order according
1834 their priority. ALLOCNO should be not in a bucket before the
1835 call. */
1836 static void
1837 add_allocno_to_ordered_bucket (ira_allocno_t allocno,
1838 ira_allocno_t *bucket_ptr)
1840 ira_allocno_t before, after;
1842 if (bucket_ptr == &uncolorable_allocno_bucket
1843 && ALLOCNO_CLASS (allocno) != NO_REGS)
1845 uncolorable_allocnos_num++;
1846 ira_assert (uncolorable_allocnos_num > 0);
1848 for (before = *bucket_ptr, after = NULL;
1849 before != NULL;
1850 after = before,
1851 before = ALLOCNO_COLOR_DATA (before)->next_bucket_allocno)
1852 if (bucket_allocno_compare_func (&allocno, &before) < 0)
1853 break;
1854 ALLOCNO_COLOR_DATA (allocno)->next_bucket_allocno = before;
1855 ALLOCNO_COLOR_DATA (allocno)->prev_bucket_allocno = after;
1856 if (after == NULL)
1857 *bucket_ptr = allocno;
1858 else
1859 ALLOCNO_COLOR_DATA (after)->next_bucket_allocno = allocno;
1860 if (before != NULL)
1861 ALLOCNO_COLOR_DATA (before)->prev_bucket_allocno = allocno;
1864 /* Delete ALLOCNO from bucket *BUCKET_PTR. It should be there before
1865 the call. */
1866 static void
1867 delete_allocno_from_bucket (ira_allocno_t allocno, ira_allocno_t *bucket_ptr)
1869 ira_allocno_t prev_allocno, next_allocno;
1871 if (bucket_ptr == &uncolorable_allocno_bucket
1872 && ALLOCNO_CLASS (allocno) != NO_REGS)
1874 uncolorable_allocnos_num--;
1875 ira_assert (uncolorable_allocnos_num >= 0);
1877 prev_allocno = ALLOCNO_COLOR_DATA (allocno)->prev_bucket_allocno;
1878 next_allocno = ALLOCNO_COLOR_DATA (allocno)->next_bucket_allocno;
1879 if (prev_allocno != NULL)
1880 ALLOCNO_COLOR_DATA (prev_allocno)->next_bucket_allocno = next_allocno;
1881 else
1883 ira_assert (*bucket_ptr == allocno);
1884 *bucket_ptr = next_allocno;
1886 if (next_allocno != NULL)
1887 ALLOCNO_COLOR_DATA (next_allocno)->prev_bucket_allocno = prev_allocno;
1890 /* Put allocno A onto the coloring stack without removing it from its
1891 bucket. Pushing allocno to the coloring stack can result in moving
1892 conflicting allocnos from the uncolorable bucket to the colorable
1893 one. */
1894 static void
1895 push_allocno_to_stack (ira_allocno_t a)
1897 enum reg_class aclass;
1898 allocno_color_data_t data, conflict_data;
1899 int size, i, n = ALLOCNO_NUM_OBJECTS (a);
1901 data = ALLOCNO_COLOR_DATA (a);
1902 data->in_graph_p = false;
1903 allocno_stack_vec.safe_push (a);
1904 aclass = ALLOCNO_CLASS (a);
1905 if (aclass == NO_REGS)
1906 return;
1907 size = ira_reg_class_max_nregs[aclass][ALLOCNO_MODE (a)];
1908 if (n > 1)
1910 /* We will deal with the subwords individually. */
1911 gcc_assert (size == ALLOCNO_NUM_OBJECTS (a));
1912 size = 1;
1914 for (i = 0; i < n; i++)
1916 ira_object_t obj = ALLOCNO_OBJECT (a, i);
1917 ira_object_t conflict_obj;
1918 ira_object_conflict_iterator oci;
1920 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
1922 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
1924 conflict_data = ALLOCNO_COLOR_DATA (conflict_a);
1925 if (conflict_data->colorable_p
1926 || ! conflict_data->in_graph_p
1927 || ALLOCNO_ASSIGNED_P (conflict_a)
1928 || !(hard_reg_set_intersect_p
1929 (ALLOCNO_COLOR_DATA (a)->profitable_hard_regs,
1930 conflict_data->profitable_hard_regs)))
1931 continue;
1932 ira_assert (bitmap_bit_p (coloring_allocno_bitmap,
1933 ALLOCNO_NUM (conflict_a)));
1934 if (update_left_conflict_sizes_p (conflict_a, a, size))
1936 delete_allocno_from_bucket
1937 (conflict_a, &uncolorable_allocno_bucket);
1938 add_allocno_to_ordered_bucket
1939 (conflict_a, &colorable_allocno_bucket);
1940 if (internal_flag_ira_verbose > 4 && ira_dump_file != NULL)
1942 fprintf (ira_dump_file, " Making");
1943 ira_print_expanded_allocno (conflict_a);
1944 fprintf (ira_dump_file, " colorable\n");
1952 /* Put ALLOCNO onto the coloring stack and remove it from its bucket.
1953 The allocno is in the colorable bucket if COLORABLE_P is TRUE. */
1954 static void
1955 remove_allocno_from_bucket_and_push (ira_allocno_t allocno, bool colorable_p)
1957 if (colorable_p)
1958 delete_allocno_from_bucket (allocno, &colorable_allocno_bucket);
1959 else
1960 delete_allocno_from_bucket (allocno, &uncolorable_allocno_bucket);
1961 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
1963 fprintf (ira_dump_file, " Pushing");
1964 ira_print_expanded_allocno (allocno);
1965 if (colorable_p)
1966 fprintf (ira_dump_file, "(cost %d)\n",
1967 ALLOCNO_COLOR_DATA (allocno)->temp);
1968 else
1969 fprintf (ira_dump_file, "(potential spill: %spri=%d, cost=%d)\n",
1970 ALLOCNO_BAD_SPILL_P (allocno) ? "bad spill, " : "",
1971 allocno_spill_priority (allocno),
1972 ALLOCNO_COLOR_DATA (allocno)->temp);
1974 if (! colorable_p)
1975 ALLOCNO_COLOR_DATA (allocno)->may_be_spilled_p = true;
1976 push_allocno_to_stack (allocno);
1979 /* Put all allocnos from colorable bucket onto the coloring stack. */
1980 static void
1981 push_only_colorable (void)
1983 sort_bucket (&colorable_allocno_bucket, bucket_allocno_compare_func);
1984 for (;colorable_allocno_bucket != NULL;)
1985 remove_allocno_from_bucket_and_push (colorable_allocno_bucket, true);
1988 /* Return the frequency of exit edges (if EXIT_P) or entry from/to the
1989 loop given by its LOOP_NODE. */
1991 ira_loop_edge_freq (ira_loop_tree_node_t loop_node, int regno, bool exit_p)
1993 int freq, i;
1994 edge_iterator ei;
1995 edge e;
1996 vec<edge> edges;
1998 ira_assert (current_loops != NULL && loop_node->loop != NULL
1999 && (regno < 0 || regno >= FIRST_PSEUDO_REGISTER));
2000 freq = 0;
2001 if (! exit_p)
2003 FOR_EACH_EDGE (e, ei, loop_node->loop->header->preds)
2004 if (e->src != loop_node->loop->latch
2005 && (regno < 0
2006 || (bitmap_bit_p (df_get_live_out (e->src), regno)
2007 && bitmap_bit_p (df_get_live_in (e->dest), regno))))
2008 freq += EDGE_FREQUENCY (e);
2010 else
2012 edges = get_loop_exit_edges (loop_node->loop);
2013 FOR_EACH_VEC_ELT (edges, i, e)
2014 if (regno < 0
2015 || (bitmap_bit_p (df_get_live_out (e->src), regno)
2016 && bitmap_bit_p (df_get_live_in (e->dest), regno)))
2017 freq += EDGE_FREQUENCY (e);
2018 edges.release ();
2021 return REG_FREQ_FROM_EDGE_FREQ (freq);
2024 /* Calculate and return the cost of putting allocno A into memory. */
2025 static int
2026 calculate_allocno_spill_cost (ira_allocno_t a)
2028 int regno, cost;
2029 enum machine_mode mode;
2030 enum reg_class rclass;
2031 ira_allocno_t parent_allocno;
2032 ira_loop_tree_node_t parent_node, loop_node;
2034 regno = ALLOCNO_REGNO (a);
2035 cost = ALLOCNO_UPDATED_MEMORY_COST (a) - ALLOCNO_UPDATED_CLASS_COST (a);
2036 if (ALLOCNO_CAP (a) != NULL)
2037 return cost;
2038 loop_node = ALLOCNO_LOOP_TREE_NODE (a);
2039 if ((parent_node = loop_node->parent) == NULL)
2040 return cost;
2041 if ((parent_allocno = parent_node->regno_allocno_map[regno]) == NULL)
2042 return cost;
2043 mode = ALLOCNO_MODE (a);
2044 rclass = ALLOCNO_CLASS (a);
2045 if (ALLOCNO_HARD_REGNO (parent_allocno) < 0)
2046 cost -= (ira_memory_move_cost[mode][rclass][0]
2047 * ira_loop_edge_freq (loop_node, regno, true)
2048 + ira_memory_move_cost[mode][rclass][1]
2049 * ira_loop_edge_freq (loop_node, regno, false));
2050 else
2052 ira_init_register_move_cost_if_necessary (mode);
2053 cost += ((ira_memory_move_cost[mode][rclass][1]
2054 * ira_loop_edge_freq (loop_node, regno, true)
2055 + ira_memory_move_cost[mode][rclass][0]
2056 * ira_loop_edge_freq (loop_node, regno, false))
2057 - (ira_register_move_cost[mode][rclass][rclass]
2058 * (ira_loop_edge_freq (loop_node, regno, false)
2059 + ira_loop_edge_freq (loop_node, regno, true))));
2061 return cost;
2064 /* Used for sorting allocnos for spilling. */
2065 static inline int
2066 allocno_spill_priority_compare (ira_allocno_t a1, ira_allocno_t a2)
2068 int pri1, pri2, diff;
2070 if (ALLOCNO_BAD_SPILL_P (a1) && ! ALLOCNO_BAD_SPILL_P (a2))
2071 return 1;
2072 if (ALLOCNO_BAD_SPILL_P (a2) && ! ALLOCNO_BAD_SPILL_P (a1))
2073 return -1;
2074 pri1 = allocno_spill_priority (a1);
2075 pri2 = allocno_spill_priority (a2);
2076 if ((diff = pri1 - pri2) != 0)
2077 return diff;
2078 if ((diff
2079 = ALLOCNO_COLOR_DATA (a1)->temp - ALLOCNO_COLOR_DATA (a2)->temp) != 0)
2080 return diff;
2081 return ALLOCNO_NUM (a1) - ALLOCNO_NUM (a2);
2084 /* Used for sorting allocnos for spilling. */
2085 static int
2086 allocno_spill_sort_compare (const void *v1p, const void *v2p)
2088 ira_allocno_t p1 = *(const ira_allocno_t *) v1p;
2089 ira_allocno_t p2 = *(const ira_allocno_t *) v2p;
2091 return allocno_spill_priority_compare (p1, p2);
2094 /* Push allocnos to the coloring stack. The order of allocnos in the
2095 stack defines the order for the subsequent coloring. */
2096 static void
2097 push_allocnos_to_stack (void)
2099 ira_allocno_t a;
2100 int cost;
2102 /* Calculate uncolorable allocno spill costs. */
2103 for (a = uncolorable_allocno_bucket;
2104 a != NULL;
2105 a = ALLOCNO_COLOR_DATA (a)->next_bucket_allocno)
2106 if (ALLOCNO_CLASS (a) != NO_REGS)
2108 cost = calculate_allocno_spill_cost (a);
2109 /* ??? Remove cost of copies between the coalesced
2110 allocnos. */
2111 ALLOCNO_COLOR_DATA (a)->temp = cost;
2113 sort_bucket (&uncolorable_allocno_bucket, allocno_spill_sort_compare);
2114 for (;;)
2116 push_only_colorable ();
2117 a = uncolorable_allocno_bucket;
2118 if (a == NULL)
2119 break;
2120 remove_allocno_from_bucket_and_push (a, false);
2122 ira_assert (colorable_allocno_bucket == NULL
2123 && uncolorable_allocno_bucket == NULL);
2124 ira_assert (uncolorable_allocnos_num == 0);
2127 /* Pop the coloring stack and assign hard registers to the popped
2128 allocnos. */
2129 static void
2130 pop_allocnos_from_stack (void)
2132 ira_allocno_t allocno;
2133 enum reg_class aclass;
2135 for (;allocno_stack_vec.length () != 0;)
2137 allocno = allocno_stack_vec.pop ();
2138 aclass = ALLOCNO_CLASS (allocno);
2139 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2141 fprintf (ira_dump_file, " Popping");
2142 ira_print_expanded_allocno (allocno);
2143 fprintf (ira_dump_file, " -- ");
2145 if (aclass == NO_REGS)
2147 ALLOCNO_HARD_REGNO (allocno) = -1;
2148 ALLOCNO_ASSIGNED_P (allocno) = true;
2149 ira_assert (ALLOCNO_UPDATED_HARD_REG_COSTS (allocno) == NULL);
2150 ira_assert
2151 (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (allocno) == NULL);
2152 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2153 fprintf (ira_dump_file, "assign memory\n");
2155 else if (assign_hard_reg (allocno, false))
2157 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2158 fprintf (ira_dump_file, "assign reg %d\n",
2159 ALLOCNO_HARD_REGNO (allocno));
2161 else if (ALLOCNO_ASSIGNED_P (allocno))
2163 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2164 fprintf (ira_dump_file, "spill\n");
2166 ALLOCNO_COLOR_DATA (allocno)->in_graph_p = true;
2170 /* Set up number of available hard registers for allocno A. */
2171 static void
2172 setup_allocno_available_regs_num (ira_allocno_t a)
2174 int i, n, hard_regno, hard_regs_num, nwords;
2175 enum reg_class aclass;
2176 allocno_color_data_t data;
2178 aclass = ALLOCNO_CLASS (a);
2179 data = ALLOCNO_COLOR_DATA (a);
2180 data->available_regs_num = 0;
2181 if (aclass == NO_REGS)
2182 return;
2183 hard_regs_num = ira_class_hard_regs_num[aclass];
2184 nwords = ALLOCNO_NUM_OBJECTS (a);
2185 for (n = 0, i = hard_regs_num - 1; i >= 0; i--)
2187 hard_regno = ira_class_hard_regs[aclass][i];
2188 /* Checking only profitable hard regs. */
2189 if (TEST_HARD_REG_BIT (data->profitable_hard_regs, hard_regno))
2190 n++;
2192 data->available_regs_num = n;
2193 if (internal_flag_ira_verbose <= 2 || ira_dump_file == NULL)
2194 return;
2195 fprintf
2196 (ira_dump_file,
2197 " Allocno a%dr%d of %s(%d) has %d avail. regs ",
2198 ALLOCNO_NUM (a), ALLOCNO_REGNO (a),
2199 reg_class_names[aclass], ira_class_hard_regs_num[aclass], n);
2200 print_hard_reg_set (ira_dump_file, data->profitable_hard_regs, false);
2201 fprintf (ira_dump_file, ", %snode: ",
2202 hard_reg_set_equal_p (data->profitable_hard_regs,
2203 data->hard_regs_node->hard_regs->set)
2204 ? "" : "^");
2205 print_hard_reg_set (ira_dump_file,
2206 data->hard_regs_node->hard_regs->set, false);
2207 for (i = 0; i < nwords; i++)
2209 ira_object_t obj = ALLOCNO_OBJECT (a, i);
2211 if (nwords != 1)
2213 if (i != 0)
2214 fprintf (ira_dump_file, ", ");
2215 fprintf (ira_dump_file, " obj %d", i);
2217 fprintf (ira_dump_file, " (confl regs = ");
2218 print_hard_reg_set (ira_dump_file, OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
2219 false);
2220 fprintf (ira_dump_file, ")");
2222 fprintf (ira_dump_file, "\n");
2225 /* Put ALLOCNO in a bucket corresponding to its number and size of its
2226 conflicting allocnos and hard registers. */
2227 static void
2228 put_allocno_into_bucket (ira_allocno_t allocno)
2230 ALLOCNO_COLOR_DATA (allocno)->in_graph_p = true;
2231 setup_allocno_available_regs_num (allocno);
2232 if (setup_left_conflict_sizes_p (allocno))
2233 add_allocno_to_bucket (allocno, &colorable_allocno_bucket);
2234 else
2235 add_allocno_to_bucket (allocno, &uncolorable_allocno_bucket);
2238 /* Map: allocno number -> allocno priority. */
2239 static int *allocno_priorities;
2241 /* Set up priorities for N allocnos in array
2242 CONSIDERATION_ALLOCNOS. */
2243 static void
2244 setup_allocno_priorities (ira_allocno_t *consideration_allocnos, int n)
2246 int i, length, nrefs, priority, max_priority, mult;
2247 ira_allocno_t a;
2249 max_priority = 0;
2250 for (i = 0; i < n; i++)
2252 a = consideration_allocnos[i];
2253 nrefs = ALLOCNO_NREFS (a);
2254 ira_assert (nrefs >= 0);
2255 mult = floor_log2 (ALLOCNO_NREFS (a)) + 1;
2256 ira_assert (mult >= 0);
2257 allocno_priorities[ALLOCNO_NUM (a)]
2258 = priority
2259 = (mult
2260 * (ALLOCNO_MEMORY_COST (a) - ALLOCNO_CLASS_COST (a))
2261 * ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]);
2262 if (priority < 0)
2263 priority = -priority;
2264 if (max_priority < priority)
2265 max_priority = priority;
2267 mult = max_priority == 0 ? 1 : INT_MAX / max_priority;
2268 for (i = 0; i < n; i++)
2270 a = consideration_allocnos[i];
2271 length = ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a);
2272 if (ALLOCNO_NUM_OBJECTS (a) > 1)
2273 length /= ALLOCNO_NUM_OBJECTS (a);
2274 if (length <= 0)
2275 length = 1;
2276 allocno_priorities[ALLOCNO_NUM (a)]
2277 = allocno_priorities[ALLOCNO_NUM (a)] * mult / length;
2281 /* Sort allocnos according to the profit of usage of a hard register
2282 instead of memory for them. */
2283 static int
2284 allocno_cost_compare_func (const void *v1p, const void *v2p)
2286 ira_allocno_t p1 = *(const ira_allocno_t *) v1p;
2287 ira_allocno_t p2 = *(const ira_allocno_t *) v2p;
2288 int c1, c2;
2290 c1 = ALLOCNO_UPDATED_MEMORY_COST (p1) - ALLOCNO_UPDATED_CLASS_COST (p1);
2291 c2 = ALLOCNO_UPDATED_MEMORY_COST (p2) - ALLOCNO_UPDATED_CLASS_COST (p2);
2292 if (c1 - c2)
2293 return c1 - c2;
2295 /* If regs are equally good, sort by allocno numbers, so that the
2296 results of qsort leave nothing to chance. */
2297 return ALLOCNO_NUM (p1) - ALLOCNO_NUM (p2);
2300 /* We used Chaitin-Briggs coloring to assign as many pseudos as
2301 possible to hard registers. Let us try to improve allocation with
2302 cost point of view. This function improves the allocation by
2303 spilling some allocnos and assigning the freed hard registers to
2304 other allocnos if it decreases the overall allocation cost. */
2305 static void
2306 improve_allocation (void)
2308 unsigned int i;
2309 int j, k, n, hregno, conflict_hregno, base_cost, class_size, word, nwords;
2310 int check, spill_cost, min_cost, nregs, conflict_nregs, r, best;
2311 bool try_p;
2312 enum reg_class aclass;
2313 enum machine_mode mode;
2314 int *allocno_costs;
2315 int costs[FIRST_PSEUDO_REGISTER];
2316 HARD_REG_SET conflicting_regs[2], profitable_hard_regs;
2317 ira_allocno_t a;
2318 bitmap_iterator bi;
2320 /* Clear counts used to process conflicting allocnos only once for
2321 each allocno. */
2322 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
2323 ALLOCNO_COLOR_DATA (ira_allocnos[i])->temp = 0;
2324 check = n = 0;
2325 /* Process each allocno and try to assign a hard register to it by
2326 spilling some its conflicting allocnos. */
2327 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
2329 a = ira_allocnos[i];
2330 ALLOCNO_COLOR_DATA (a)->temp = 0;
2331 if (empty_profitable_hard_regs (a))
2332 continue;
2333 check++;
2334 aclass = ALLOCNO_CLASS (a);
2335 allocno_costs = ALLOCNO_UPDATED_HARD_REG_COSTS (a);
2336 if (allocno_costs == NULL)
2337 allocno_costs = ALLOCNO_HARD_REG_COSTS (a);
2338 if ((hregno = ALLOCNO_HARD_REGNO (a)) < 0)
2339 base_cost = ALLOCNO_UPDATED_MEMORY_COST (a);
2340 else if (allocno_costs == NULL)
2341 /* It means that assigning a hard register is not profitable
2342 (we don't waste memory for hard register costs in this
2343 case). */
2344 continue;
2345 else
2346 base_cost = allocno_costs[ira_class_hard_reg_index[aclass][hregno]];
2347 try_p = false;
2348 get_conflict_and_start_profitable_regs (a, false,
2349 conflicting_regs,
2350 &profitable_hard_regs);
2351 class_size = ira_class_hard_regs_num[aclass];
2352 /* Set up cost improvement for usage of each profitable hard
2353 register for allocno A. */
2354 for (j = 0; j < class_size; j++)
2356 hregno = ira_class_hard_regs[aclass][j];
2357 if (! check_hard_reg_p (a, hregno,
2358 conflicting_regs, profitable_hard_regs))
2359 continue;
2360 ira_assert (ira_class_hard_reg_index[aclass][hregno] == j);
2361 k = allocno_costs == NULL ? 0 : j;
2362 costs[hregno] = (allocno_costs == NULL
2363 ? ALLOCNO_UPDATED_CLASS_COST (a) : allocno_costs[k]);
2364 costs[hregno] -= base_cost;
2365 if (costs[hregno] < 0)
2366 try_p = true;
2368 if (! try_p)
2369 /* There is no chance to improve the allocation cost by
2370 assigning hard register to allocno A even without spilling
2371 conflicting allocnos. */
2372 continue;
2373 mode = ALLOCNO_MODE (a);
2374 nwords = ALLOCNO_NUM_OBJECTS (a);
2375 /* Process each allocno conflicting with A and update the cost
2376 improvement for profitable hard registers of A. To use a
2377 hard register for A we need to spill some conflicting
2378 allocnos and that creates penalty for the cost
2379 improvement. */
2380 for (word = 0; word < nwords; word++)
2382 ira_object_t conflict_obj;
2383 ira_object_t obj = ALLOCNO_OBJECT (a, word);
2384 ira_object_conflict_iterator oci;
2386 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
2388 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
2390 if (ALLOCNO_COLOR_DATA (conflict_a)->temp == check)
2391 /* We already processed this conflicting allocno
2392 because we processed earlier another object of the
2393 conflicting allocno. */
2394 continue;
2395 ALLOCNO_COLOR_DATA (conflict_a)->temp = check;
2396 if ((conflict_hregno = ALLOCNO_HARD_REGNO (conflict_a)) < 0)
2397 continue;
2398 spill_cost = ALLOCNO_UPDATED_MEMORY_COST (conflict_a);
2399 k = (ira_class_hard_reg_index
2400 [ALLOCNO_CLASS (conflict_a)][conflict_hregno]);
2401 ira_assert (k >= 0);
2402 if ((allocno_costs = ALLOCNO_UPDATED_HARD_REG_COSTS (conflict_a))
2403 != NULL)
2404 spill_cost -= allocno_costs[k];
2405 else if ((allocno_costs = ALLOCNO_HARD_REG_COSTS (conflict_a))
2406 != NULL)
2407 spill_cost -= allocno_costs[k];
2408 else
2409 spill_cost -= ALLOCNO_UPDATED_CLASS_COST (conflict_a);
2410 conflict_nregs
2411 = hard_regno_nregs[conflict_hregno][ALLOCNO_MODE (conflict_a)];
2412 for (r = conflict_hregno;
2413 r >= 0 && r + hard_regno_nregs[r][mode] > conflict_hregno;
2414 r--)
2415 if (check_hard_reg_p (a, r,
2416 conflicting_regs, profitable_hard_regs))
2417 costs[r] += spill_cost;
2418 for (r = conflict_hregno + 1;
2419 r < conflict_hregno + conflict_nregs;
2420 r++)
2421 if (check_hard_reg_p (a, r,
2422 conflicting_regs, profitable_hard_regs))
2423 costs[r] += spill_cost;
2426 min_cost = INT_MAX;
2427 best = -1;
2428 /* Now we choose hard register for A which results in highest
2429 allocation cost improvement. */
2430 for (j = 0; j < class_size; j++)
2432 hregno = ira_class_hard_regs[aclass][j];
2433 if (check_hard_reg_p (a, hregno,
2434 conflicting_regs, profitable_hard_regs)
2435 && min_cost > costs[hregno])
2437 best = hregno;
2438 min_cost = costs[hregno];
2441 if (min_cost >= 0)
2442 /* We are in a situation when assigning any hard register to A
2443 by spilling some conflicting allocnos does not improve the
2444 allocation cost. */
2445 continue;
2446 nregs = hard_regno_nregs[best][mode];
2447 /* Now spill conflicting allocnos which contain a hard register
2448 of A when we assign the best chosen hard register to it. */
2449 for (word = 0; word < nwords; word++)
2451 ira_object_t conflict_obj;
2452 ira_object_t obj = ALLOCNO_OBJECT (a, word);
2453 ira_object_conflict_iterator oci;
2455 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
2457 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
2459 if ((conflict_hregno = ALLOCNO_HARD_REGNO (conflict_a)) < 0)
2460 continue;
2461 conflict_nregs
2462 = hard_regno_nregs[conflict_hregno][ALLOCNO_MODE (conflict_a)];
2463 if (best + nregs <= conflict_hregno
2464 || conflict_hregno + conflict_nregs <= best)
2465 /* No intersection. */
2466 continue;
2467 ALLOCNO_HARD_REGNO (conflict_a) = -1;
2468 sorted_allocnos[n++] = conflict_a;
2469 if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
2470 fprintf (ira_dump_file, "Spilling a%dr%d for a%dr%d\n",
2471 ALLOCNO_NUM (conflict_a), ALLOCNO_REGNO (conflict_a),
2472 ALLOCNO_NUM (a), ALLOCNO_REGNO (a));
2475 /* Assign the best chosen hard register to A. */
2476 ALLOCNO_HARD_REGNO (a) = best;
2477 if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
2478 fprintf (ira_dump_file, "Assigning %d to a%dr%d\n",
2479 best, ALLOCNO_NUM (a), ALLOCNO_REGNO (a));
2481 if (n == 0)
2482 return;
2483 /* We spilled some allocnos to assign their hard registers to other
2484 allocnos. The spilled allocnos are now in array
2485 'sorted_allocnos'. There is still a possibility that some of the
2486 spilled allocnos can get hard registers. So let us try assign
2487 them hard registers again (just a reminder -- function
2488 'assign_hard_reg' assigns hard registers only if it is possible
2489 and profitable). We process the spilled allocnos with biggest
2490 benefit to get hard register first -- see function
2491 'allocno_cost_compare_func'. */
2492 qsort (sorted_allocnos, n, sizeof (ira_allocno_t),
2493 allocno_cost_compare_func);
2494 for (j = 0; j < n; j++)
2496 a = sorted_allocnos[j];
2497 ALLOCNO_ASSIGNED_P (a) = false;
2498 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2500 fprintf (ira_dump_file, " ");
2501 ira_print_expanded_allocno (a);
2502 fprintf (ira_dump_file, " -- ");
2504 if (assign_hard_reg (a, false))
2506 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2507 fprintf (ira_dump_file, "assign hard reg %d\n",
2508 ALLOCNO_HARD_REGNO (a));
2510 else
2512 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2513 fprintf (ira_dump_file, "assign memory\n");
2518 /* Sort allocnos according to their priorities. */
2519 static int
2520 allocno_priority_compare_func (const void *v1p, const void *v2p)
2522 ira_allocno_t a1 = *(const ira_allocno_t *) v1p;
2523 ira_allocno_t a2 = *(const ira_allocno_t *) v2p;
2524 int pri1, pri2;
2526 pri1 = allocno_priorities[ALLOCNO_NUM (a1)];
2527 pri2 = allocno_priorities[ALLOCNO_NUM (a2)];
2528 if (pri2 != pri1)
2529 return SORTGT (pri2, pri1);
2531 /* If regs are equally good, sort by allocnos, so that the results of
2532 qsort leave nothing to chance. */
2533 return ALLOCNO_NUM (a1) - ALLOCNO_NUM (a2);
2536 /* Chaitin-Briggs coloring for allocnos in COLORING_ALLOCNO_BITMAP
2537 taking into account allocnos in CONSIDERATION_ALLOCNO_BITMAP. */
2538 static void
2539 color_allocnos (void)
2541 unsigned int i, n;
2542 bitmap_iterator bi;
2543 ira_allocno_t a;
2545 setup_profitable_hard_regs ();
2546 if (flag_ira_algorithm == IRA_ALGORITHM_PRIORITY)
2548 n = 0;
2549 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
2551 a = ira_allocnos[i];
2552 if (ALLOCNO_CLASS (a) == NO_REGS)
2554 ALLOCNO_HARD_REGNO (a) = -1;
2555 ALLOCNO_ASSIGNED_P (a) = true;
2556 ira_assert (ALLOCNO_UPDATED_HARD_REG_COSTS (a) == NULL);
2557 ira_assert (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a) == NULL);
2558 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2560 fprintf (ira_dump_file, " Spill");
2561 ira_print_expanded_allocno (a);
2562 fprintf (ira_dump_file, "\n");
2564 continue;
2566 sorted_allocnos[n++] = a;
2568 if (n != 0)
2570 setup_allocno_priorities (sorted_allocnos, n);
2571 qsort (sorted_allocnos, n, sizeof (ira_allocno_t),
2572 allocno_priority_compare_func);
2573 for (i = 0; i < n; i++)
2575 a = sorted_allocnos[i];
2576 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2578 fprintf (ira_dump_file, " ");
2579 ira_print_expanded_allocno (a);
2580 fprintf (ira_dump_file, " -- ");
2582 if (assign_hard_reg (a, false))
2584 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2585 fprintf (ira_dump_file, "assign hard reg %d\n",
2586 ALLOCNO_HARD_REGNO (a));
2588 else
2590 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2591 fprintf (ira_dump_file, "assign memory\n");
2596 else
2598 form_allocno_hard_regs_nodes_forest ();
2599 if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
2600 print_hard_regs_forest (ira_dump_file);
2601 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
2603 a = ira_allocnos[i];
2604 if (ALLOCNO_CLASS (a) != NO_REGS && ! empty_profitable_hard_regs (a))
2605 ALLOCNO_COLOR_DATA (a)->in_graph_p = true;
2606 else
2608 ALLOCNO_HARD_REGNO (a) = -1;
2609 ALLOCNO_ASSIGNED_P (a) = true;
2610 /* We don't need updated costs anymore. */
2611 ira_free_allocno_updated_costs (a);
2612 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2614 fprintf (ira_dump_file, " Spill");
2615 ira_print_expanded_allocno (a);
2616 fprintf (ira_dump_file, "\n");
2620 /* Put the allocnos into the corresponding buckets. */
2621 colorable_allocno_bucket = NULL;
2622 uncolorable_allocno_bucket = NULL;
2623 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
2625 a = ira_allocnos[i];
2626 if (ALLOCNO_COLOR_DATA (a)->in_graph_p)
2627 put_allocno_into_bucket (a);
2629 push_allocnos_to_stack ();
2630 pop_allocnos_from_stack ();
2631 finish_allocno_hard_regs_nodes_forest ();
2633 improve_allocation ();
2638 /* Output information about the loop given by its LOOP_TREE_NODE. */
2639 static void
2640 print_loop_title (ira_loop_tree_node_t loop_tree_node)
2642 unsigned int j;
2643 bitmap_iterator bi;
2644 ira_loop_tree_node_t subloop_node, dest_loop_node;
2645 edge e;
2646 edge_iterator ei;
2648 if (loop_tree_node->parent == NULL)
2649 fprintf (ira_dump_file,
2650 "\n Loop 0 (parent -1, header bb%d, depth 0)\n bbs:",
2651 NUM_FIXED_BLOCKS);
2652 else
2654 ira_assert (current_loops != NULL && loop_tree_node->loop != NULL);
2655 fprintf (ira_dump_file,
2656 "\n Loop %d (parent %d, header bb%d, depth %d)\n bbs:",
2657 loop_tree_node->loop_num, loop_tree_node->parent->loop_num,
2658 loop_tree_node->loop->header->index,
2659 loop_depth (loop_tree_node->loop));
2661 for (subloop_node = loop_tree_node->children;
2662 subloop_node != NULL;
2663 subloop_node = subloop_node->next)
2664 if (subloop_node->bb != NULL)
2666 fprintf (ira_dump_file, " %d", subloop_node->bb->index);
2667 FOR_EACH_EDGE (e, ei, subloop_node->bb->succs)
2668 if (e->dest != EXIT_BLOCK_PTR
2669 && ((dest_loop_node = IRA_BB_NODE (e->dest)->parent)
2670 != loop_tree_node))
2671 fprintf (ira_dump_file, "(->%d:l%d)",
2672 e->dest->index, dest_loop_node->loop_num);
2674 fprintf (ira_dump_file, "\n all:");
2675 EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->all_allocnos, 0, j, bi)
2676 fprintf (ira_dump_file, " %dr%d", j, ALLOCNO_REGNO (ira_allocnos[j]));
2677 fprintf (ira_dump_file, "\n modified regnos:");
2678 EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->modified_regnos, 0, j, bi)
2679 fprintf (ira_dump_file, " %d", j);
2680 fprintf (ira_dump_file, "\n border:");
2681 EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->border_allocnos, 0, j, bi)
2682 fprintf (ira_dump_file, " %dr%d", j, ALLOCNO_REGNO (ira_allocnos[j]));
2683 fprintf (ira_dump_file, "\n Pressure:");
2684 for (j = 0; (int) j < ira_pressure_classes_num; j++)
2686 enum reg_class pclass;
2688 pclass = ira_pressure_classes[j];
2689 if (loop_tree_node->reg_pressure[pclass] == 0)
2690 continue;
2691 fprintf (ira_dump_file, " %s=%d", reg_class_names[pclass],
2692 loop_tree_node->reg_pressure[pclass]);
2694 fprintf (ira_dump_file, "\n");
2697 /* Color the allocnos inside loop (in the extreme case it can be all
2698 of the function) given the corresponding LOOP_TREE_NODE. The
2699 function is called for each loop during top-down traverse of the
2700 loop tree. */
2701 static void
2702 color_pass (ira_loop_tree_node_t loop_tree_node)
2704 int regno, hard_regno, index = -1, n;
2705 int cost, exit_freq, enter_freq;
2706 unsigned int j;
2707 bitmap_iterator bi;
2708 enum machine_mode mode;
2709 enum reg_class rclass, aclass, pclass;
2710 ira_allocno_t a, subloop_allocno;
2711 ira_loop_tree_node_t subloop_node;
2713 ira_assert (loop_tree_node->bb == NULL);
2714 if (internal_flag_ira_verbose > 1 && ira_dump_file != NULL)
2715 print_loop_title (loop_tree_node);
2717 bitmap_copy (coloring_allocno_bitmap, loop_tree_node->all_allocnos);
2718 bitmap_copy (consideration_allocno_bitmap, coloring_allocno_bitmap);
2719 n = 0;
2720 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
2722 a = ira_allocnos[j];
2723 n++;
2724 if (! ALLOCNO_ASSIGNED_P (a))
2725 continue;
2726 bitmap_clear_bit (coloring_allocno_bitmap, ALLOCNO_NUM (a));
2728 allocno_color_data
2729 = (allocno_color_data_t) ira_allocate (sizeof (struct allocno_color_data)
2730 * n);
2731 memset (allocno_color_data, 0, sizeof (struct allocno_color_data) * n);
2732 curr_allocno_process = 0;
2733 n = 0;
2734 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
2736 a = ira_allocnos[j];
2737 ALLOCNO_ADD_DATA (a) = allocno_color_data + n;
2738 n++;
2740 /* Color all mentioned allocnos including transparent ones. */
2741 color_allocnos ();
2742 /* Process caps. They are processed just once. */
2743 if (flag_ira_region == IRA_REGION_MIXED
2744 || flag_ira_region == IRA_REGION_ALL)
2745 EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->all_allocnos, 0, j, bi)
2747 a = ira_allocnos[j];
2748 if (ALLOCNO_CAP_MEMBER (a) == NULL)
2749 continue;
2750 /* Remove from processing in the next loop. */
2751 bitmap_clear_bit (consideration_allocno_bitmap, j);
2752 rclass = ALLOCNO_CLASS (a);
2753 pclass = ira_pressure_class_translate[rclass];
2754 if (flag_ira_region == IRA_REGION_MIXED
2755 && (loop_tree_node->reg_pressure[pclass]
2756 <= ira_class_hard_regs_num[pclass]))
2758 mode = ALLOCNO_MODE (a);
2759 hard_regno = ALLOCNO_HARD_REGNO (a);
2760 if (hard_regno >= 0)
2762 index = ira_class_hard_reg_index[rclass][hard_regno];
2763 ira_assert (index >= 0);
2765 regno = ALLOCNO_REGNO (a);
2766 subloop_allocno = ALLOCNO_CAP_MEMBER (a);
2767 subloop_node = ALLOCNO_LOOP_TREE_NODE (subloop_allocno);
2768 ira_assert (!ALLOCNO_ASSIGNED_P (subloop_allocno));
2769 ALLOCNO_HARD_REGNO (subloop_allocno) = hard_regno;
2770 ALLOCNO_ASSIGNED_P (subloop_allocno) = true;
2771 if (hard_regno >= 0)
2772 update_copy_costs (subloop_allocno, true);
2773 /* We don't need updated costs anymore: */
2774 ira_free_allocno_updated_costs (subloop_allocno);
2777 /* Update costs of the corresponding allocnos (not caps) in the
2778 subloops. */
2779 for (subloop_node = loop_tree_node->subloops;
2780 subloop_node != NULL;
2781 subloop_node = subloop_node->subloop_next)
2783 ira_assert (subloop_node->bb == NULL);
2784 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
2786 a = ira_allocnos[j];
2787 ira_assert (ALLOCNO_CAP_MEMBER (a) == NULL);
2788 mode = ALLOCNO_MODE (a);
2789 rclass = ALLOCNO_CLASS (a);
2790 pclass = ira_pressure_class_translate[rclass];
2791 hard_regno = ALLOCNO_HARD_REGNO (a);
2792 /* Use hard register class here. ??? */
2793 if (hard_regno >= 0)
2795 index = ira_class_hard_reg_index[rclass][hard_regno];
2796 ira_assert (index >= 0);
2798 regno = ALLOCNO_REGNO (a);
2799 /* ??? conflict costs */
2800 subloop_allocno = subloop_node->regno_allocno_map[regno];
2801 if (subloop_allocno == NULL
2802 || ALLOCNO_CAP (subloop_allocno) != NULL)
2803 continue;
2804 ira_assert (ALLOCNO_CLASS (subloop_allocno) == rclass);
2805 ira_assert (bitmap_bit_p (subloop_node->all_allocnos,
2806 ALLOCNO_NUM (subloop_allocno)));
2807 if ((flag_ira_region == IRA_REGION_MIXED)
2808 && (loop_tree_node->reg_pressure[pclass]
2809 <= ira_class_hard_regs_num[pclass]))
2811 if (! ALLOCNO_ASSIGNED_P (subloop_allocno))
2813 ALLOCNO_HARD_REGNO (subloop_allocno) = hard_regno;
2814 ALLOCNO_ASSIGNED_P (subloop_allocno) = true;
2815 if (hard_regno >= 0)
2816 update_copy_costs (subloop_allocno, true);
2817 /* We don't need updated costs anymore: */
2818 ira_free_allocno_updated_costs (subloop_allocno);
2820 continue;
2822 exit_freq = ira_loop_edge_freq (subloop_node, regno, true);
2823 enter_freq = ira_loop_edge_freq (subloop_node, regno, false);
2824 ira_assert (regno < ira_reg_equiv_len);
2825 if (ira_equiv_no_lvalue_p (regno))
2827 if (! ALLOCNO_ASSIGNED_P (subloop_allocno))
2829 ALLOCNO_HARD_REGNO (subloop_allocno) = hard_regno;
2830 ALLOCNO_ASSIGNED_P (subloop_allocno) = true;
2831 if (hard_regno >= 0)
2832 update_copy_costs (subloop_allocno, true);
2833 /* We don't need updated costs anymore: */
2834 ira_free_allocno_updated_costs (subloop_allocno);
2837 else if (hard_regno < 0)
2839 ALLOCNO_UPDATED_MEMORY_COST (subloop_allocno)
2840 -= ((ira_memory_move_cost[mode][rclass][1] * enter_freq)
2841 + (ira_memory_move_cost[mode][rclass][0] * exit_freq));
2843 else
2845 aclass = ALLOCNO_CLASS (subloop_allocno);
2846 ira_init_register_move_cost_if_necessary (mode);
2847 cost = (ira_register_move_cost[mode][rclass][rclass]
2848 * (exit_freq + enter_freq));
2849 ira_allocate_and_set_or_copy_costs
2850 (&ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno), aclass,
2851 ALLOCNO_UPDATED_CLASS_COST (subloop_allocno),
2852 ALLOCNO_HARD_REG_COSTS (subloop_allocno));
2853 ira_allocate_and_set_or_copy_costs
2854 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (subloop_allocno),
2855 aclass, 0, ALLOCNO_CONFLICT_HARD_REG_COSTS (subloop_allocno));
2856 ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno)[index] -= cost;
2857 ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (subloop_allocno)[index]
2858 -= cost;
2859 if (ALLOCNO_UPDATED_CLASS_COST (subloop_allocno)
2860 > ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno)[index])
2861 ALLOCNO_UPDATED_CLASS_COST (subloop_allocno)
2862 = ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno)[index];
2863 ALLOCNO_UPDATED_MEMORY_COST (subloop_allocno)
2864 += (ira_memory_move_cost[mode][rclass][0] * enter_freq
2865 + ira_memory_move_cost[mode][rclass][1] * exit_freq);
2869 ira_free (allocno_color_data);
2870 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, j, bi)
2872 a = ira_allocnos[j];
2873 ALLOCNO_ADD_DATA (a) = NULL;
2877 /* Initialize the common data for coloring and calls functions to do
2878 Chaitin-Briggs and regional coloring. */
2879 static void
2880 do_coloring (void)
2882 coloring_allocno_bitmap = ira_allocate_bitmap ();
2883 if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
2884 fprintf (ira_dump_file, "\n**** Allocnos coloring:\n\n");
2886 ira_traverse_loop_tree (false, ira_loop_tree_root, color_pass, NULL);
2888 if (internal_flag_ira_verbose > 1 && ira_dump_file != NULL)
2889 ira_print_disposition (ira_dump_file);
2891 ira_free_bitmap (coloring_allocno_bitmap);
2896 /* Move spill/restore code, which are to be generated in ira-emit.c,
2897 to less frequent points (if it is profitable) by reassigning some
2898 allocnos (in loop with subloops containing in another loop) to
2899 memory which results in longer live-range where the corresponding
2900 pseudo-registers will be in memory. */
2901 static void
2902 move_spill_restore (void)
2904 int cost, regno, hard_regno, hard_regno2, index;
2905 bool changed_p;
2906 int enter_freq, exit_freq;
2907 enum machine_mode mode;
2908 enum reg_class rclass;
2909 ira_allocno_t a, parent_allocno, subloop_allocno;
2910 ira_loop_tree_node_t parent, loop_node, subloop_node;
2911 ira_allocno_iterator ai;
2913 for (;;)
2915 changed_p = false;
2916 if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
2917 fprintf (ira_dump_file, "New iteration of spill/restore move\n");
2918 FOR_EACH_ALLOCNO (a, ai)
2920 regno = ALLOCNO_REGNO (a);
2921 loop_node = ALLOCNO_LOOP_TREE_NODE (a);
2922 if (ALLOCNO_CAP_MEMBER (a) != NULL
2923 || ALLOCNO_CAP (a) != NULL
2924 || (hard_regno = ALLOCNO_HARD_REGNO (a)) < 0
2925 || loop_node->children == NULL
2926 /* don't do the optimization because it can create
2927 copies and the reload pass can spill the allocno set
2928 by copy although the allocno will not get memory
2929 slot. */
2930 || ira_equiv_no_lvalue_p (regno)
2931 || !bitmap_bit_p (loop_node->border_allocnos, ALLOCNO_NUM (a)))
2932 continue;
2933 mode = ALLOCNO_MODE (a);
2934 rclass = ALLOCNO_CLASS (a);
2935 index = ira_class_hard_reg_index[rclass][hard_regno];
2936 ira_assert (index >= 0);
2937 cost = (ALLOCNO_MEMORY_COST (a)
2938 - (ALLOCNO_HARD_REG_COSTS (a) == NULL
2939 ? ALLOCNO_CLASS_COST (a)
2940 : ALLOCNO_HARD_REG_COSTS (a)[index]));
2941 ira_init_register_move_cost_if_necessary (mode);
2942 for (subloop_node = loop_node->subloops;
2943 subloop_node != NULL;
2944 subloop_node = subloop_node->subloop_next)
2946 ira_assert (subloop_node->bb == NULL);
2947 subloop_allocno = subloop_node->regno_allocno_map[regno];
2948 if (subloop_allocno == NULL)
2949 continue;
2950 ira_assert (rclass == ALLOCNO_CLASS (subloop_allocno));
2951 /* We have accumulated cost. To get the real cost of
2952 allocno usage in the loop we should subtract costs of
2953 the subloop allocnos. */
2954 cost -= (ALLOCNO_MEMORY_COST (subloop_allocno)
2955 - (ALLOCNO_HARD_REG_COSTS (subloop_allocno) == NULL
2956 ? ALLOCNO_CLASS_COST (subloop_allocno)
2957 : ALLOCNO_HARD_REG_COSTS (subloop_allocno)[index]));
2958 exit_freq = ira_loop_edge_freq (subloop_node, regno, true);
2959 enter_freq = ira_loop_edge_freq (subloop_node, regno, false);
2960 if ((hard_regno2 = ALLOCNO_HARD_REGNO (subloop_allocno)) < 0)
2961 cost -= (ira_memory_move_cost[mode][rclass][0] * exit_freq
2962 + ira_memory_move_cost[mode][rclass][1] * enter_freq);
2963 else
2965 cost
2966 += (ira_memory_move_cost[mode][rclass][0] * exit_freq
2967 + ira_memory_move_cost[mode][rclass][1] * enter_freq);
2968 if (hard_regno2 != hard_regno)
2969 cost -= (ira_register_move_cost[mode][rclass][rclass]
2970 * (exit_freq + enter_freq));
2973 if ((parent = loop_node->parent) != NULL
2974 && (parent_allocno = parent->regno_allocno_map[regno]) != NULL)
2976 ira_assert (rclass == ALLOCNO_CLASS (parent_allocno));
2977 exit_freq = ira_loop_edge_freq (loop_node, regno, true);
2978 enter_freq = ira_loop_edge_freq (loop_node, regno, false);
2979 if ((hard_regno2 = ALLOCNO_HARD_REGNO (parent_allocno)) < 0)
2980 cost -= (ira_memory_move_cost[mode][rclass][0] * exit_freq
2981 + ira_memory_move_cost[mode][rclass][1] * enter_freq);
2982 else
2984 cost
2985 += (ira_memory_move_cost[mode][rclass][1] * exit_freq
2986 + ira_memory_move_cost[mode][rclass][0] * enter_freq);
2987 if (hard_regno2 != hard_regno)
2988 cost -= (ira_register_move_cost[mode][rclass][rclass]
2989 * (exit_freq + enter_freq));
2992 if (cost < 0)
2994 ALLOCNO_HARD_REGNO (a) = -1;
2995 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2997 fprintf
2998 (ira_dump_file,
2999 " Moving spill/restore for a%dr%d up from loop %d",
3000 ALLOCNO_NUM (a), regno, loop_node->loop_num);
3001 fprintf (ira_dump_file, " - profit %d\n", -cost);
3003 changed_p = true;
3006 if (! changed_p)
3007 break;
3013 /* Update current hard reg costs and current conflict hard reg costs
3014 for allocno A. It is done by processing its copies containing
3015 other allocnos already assigned. */
3016 static void
3017 update_curr_costs (ira_allocno_t a)
3019 int i, hard_regno, cost;
3020 enum machine_mode mode;
3021 enum reg_class aclass, rclass;
3022 ira_allocno_t another_a;
3023 ira_copy_t cp, next_cp;
3025 ira_free_allocno_updated_costs (a);
3026 ira_assert (! ALLOCNO_ASSIGNED_P (a));
3027 aclass = ALLOCNO_CLASS (a);
3028 if (aclass == NO_REGS)
3029 return;
3030 mode = ALLOCNO_MODE (a);
3031 ira_init_register_move_cost_if_necessary (mode);
3032 for (cp = ALLOCNO_COPIES (a); cp != NULL; cp = next_cp)
3034 if (cp->first == a)
3036 next_cp = cp->next_first_allocno_copy;
3037 another_a = cp->second;
3039 else if (cp->second == a)
3041 next_cp = cp->next_second_allocno_copy;
3042 another_a = cp->first;
3044 else
3045 gcc_unreachable ();
3046 if (! ira_reg_classes_intersect_p[aclass][ALLOCNO_CLASS (another_a)]
3047 || ! ALLOCNO_ASSIGNED_P (another_a)
3048 || (hard_regno = ALLOCNO_HARD_REGNO (another_a)) < 0)
3049 continue;
3050 rclass = REGNO_REG_CLASS (hard_regno);
3051 i = ira_class_hard_reg_index[aclass][hard_regno];
3052 if (i < 0)
3053 continue;
3054 cost = (cp->first == a
3055 ? ira_register_move_cost[mode][rclass][aclass]
3056 : ira_register_move_cost[mode][aclass][rclass]);
3057 ira_allocate_and_set_or_copy_costs
3058 (&ALLOCNO_UPDATED_HARD_REG_COSTS (a), aclass, ALLOCNO_CLASS_COST (a),
3059 ALLOCNO_HARD_REG_COSTS (a));
3060 ira_allocate_and_set_or_copy_costs
3061 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a),
3062 aclass, 0, ALLOCNO_CONFLICT_HARD_REG_COSTS (a));
3063 ALLOCNO_UPDATED_HARD_REG_COSTS (a)[i] -= cp->freq * cost;
3064 ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a)[i] -= cp->freq * cost;
3068 /* Try to assign hard registers to the unassigned allocnos and
3069 allocnos conflicting with them or conflicting with allocnos whose
3070 regno >= START_REGNO. The function is called after ira_flattening,
3071 so more allocnos (including ones created in ira-emit.c) will have a
3072 chance to get a hard register. We use simple assignment algorithm
3073 based on priorities. */
3074 void
3075 ira_reassign_conflict_allocnos (int start_regno)
3077 int i, allocnos_to_color_num;
3078 ira_allocno_t a;
3079 enum reg_class aclass;
3080 bitmap allocnos_to_color;
3081 ira_allocno_iterator ai;
3083 allocnos_to_color = ira_allocate_bitmap ();
3084 allocnos_to_color_num = 0;
3085 FOR_EACH_ALLOCNO (a, ai)
3087 int n = ALLOCNO_NUM_OBJECTS (a);
3089 if (! ALLOCNO_ASSIGNED_P (a)
3090 && ! bitmap_bit_p (allocnos_to_color, ALLOCNO_NUM (a)))
3092 if (ALLOCNO_CLASS (a) != NO_REGS)
3093 sorted_allocnos[allocnos_to_color_num++] = a;
3094 else
3096 ALLOCNO_ASSIGNED_P (a) = true;
3097 ALLOCNO_HARD_REGNO (a) = -1;
3098 ira_assert (ALLOCNO_UPDATED_HARD_REG_COSTS (a) == NULL);
3099 ira_assert (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a) == NULL);
3101 bitmap_set_bit (allocnos_to_color, ALLOCNO_NUM (a));
3103 if (ALLOCNO_REGNO (a) < start_regno
3104 || (aclass = ALLOCNO_CLASS (a)) == NO_REGS)
3105 continue;
3106 for (i = 0; i < n; i++)
3108 ira_object_t obj = ALLOCNO_OBJECT (a, i);
3109 ira_object_t conflict_obj;
3110 ira_object_conflict_iterator oci;
3112 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
3114 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
3116 ira_assert (ira_reg_classes_intersect_p
3117 [aclass][ALLOCNO_CLASS (conflict_a)]);
3118 if (!bitmap_set_bit (allocnos_to_color, ALLOCNO_NUM (conflict_a)))
3119 continue;
3120 sorted_allocnos[allocnos_to_color_num++] = conflict_a;
3124 ira_free_bitmap (allocnos_to_color);
3125 if (allocnos_to_color_num > 1)
3127 setup_allocno_priorities (sorted_allocnos, allocnos_to_color_num);
3128 qsort (sorted_allocnos, allocnos_to_color_num, sizeof (ira_allocno_t),
3129 allocno_priority_compare_func);
3131 for (i = 0; i < allocnos_to_color_num; i++)
3133 a = sorted_allocnos[i];
3134 ALLOCNO_ASSIGNED_P (a) = false;
3135 update_curr_costs (a);
3137 for (i = 0; i < allocnos_to_color_num; i++)
3139 a = sorted_allocnos[i];
3140 if (assign_hard_reg (a, true))
3142 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3143 fprintf
3144 (ira_dump_file,
3145 " Secondary allocation: assign hard reg %d to reg %d\n",
3146 ALLOCNO_HARD_REGNO (a), ALLOCNO_REGNO (a));
3153 /* This page contains functions used to find conflicts using allocno
3154 live ranges. */
3156 /* Return TRUE if live ranges of allocnos A1 and A2 intersect. It is
3157 used to find a conflict for new allocnos or allocnos with the
3158 different allocno classes. */
3159 static bool
3160 allocnos_conflict_by_live_ranges_p (ira_allocno_t a1, ira_allocno_t a2)
3162 rtx reg1, reg2;
3163 int i, j;
3164 int n1 = ALLOCNO_NUM_OBJECTS (a1);
3165 int n2 = ALLOCNO_NUM_OBJECTS (a2);
3167 if (a1 == a2)
3168 return false;
3169 reg1 = regno_reg_rtx[ALLOCNO_REGNO (a1)];
3170 reg2 = regno_reg_rtx[ALLOCNO_REGNO (a2)];
3171 if (reg1 != NULL && reg2 != NULL
3172 && ORIGINAL_REGNO (reg1) == ORIGINAL_REGNO (reg2))
3173 return false;
3175 for (i = 0; i < n1; i++)
3177 ira_object_t c1 = ALLOCNO_OBJECT (a1, i);
3179 for (j = 0; j < n2; j++)
3181 ira_object_t c2 = ALLOCNO_OBJECT (a2, j);
3183 if (ira_live_ranges_intersect_p (OBJECT_LIVE_RANGES (c1),
3184 OBJECT_LIVE_RANGES (c2)))
3185 return true;
3188 return false;
3191 #ifdef ENABLE_IRA_CHECKING
3193 /* Return TRUE if live ranges of pseudo-registers REGNO1 and REGNO2
3194 intersect. This should be used when there is only one region.
3195 Currently this is used during reload. */
3196 static bool
3197 conflict_by_live_ranges_p (int regno1, int regno2)
3199 ira_allocno_t a1, a2;
3201 ira_assert (regno1 >= FIRST_PSEUDO_REGISTER
3202 && regno2 >= FIRST_PSEUDO_REGISTER);
3203 /* Reg info caclulated by dataflow infrastructure can be different
3204 from one calculated by regclass. */
3205 if ((a1 = ira_loop_tree_root->regno_allocno_map[regno1]) == NULL
3206 || (a2 = ira_loop_tree_root->regno_allocno_map[regno2]) == NULL)
3207 return false;
3208 return allocnos_conflict_by_live_ranges_p (a1, a2);
3211 #endif
3215 /* This page contains code to coalesce memory stack slots used by
3216 spilled allocnos. This results in smaller stack frame, better data
3217 locality, and in smaller code for some architectures like
3218 x86/x86_64 where insn size depends on address displacement value.
3219 On the other hand, it can worsen insn scheduling after the RA but
3220 in practice it is less important than smaller stack frames. */
3222 /* TRUE if we coalesced some allocnos. In other words, if we got
3223 loops formed by members first_coalesced_allocno and
3224 next_coalesced_allocno containing more one allocno. */
3225 static bool allocno_coalesced_p;
3227 /* Bitmap used to prevent a repeated allocno processing because of
3228 coalescing. */
3229 static bitmap processed_coalesced_allocno_bitmap;
3231 /* See below. */
3232 typedef struct coalesce_data *coalesce_data_t;
3234 /* To decrease footprint of ira_allocno structure we store all data
3235 needed only for coalescing in the following structure. */
3236 struct coalesce_data
3238 /* Coalesced allocnos form a cyclic list. One allocno given by
3239 FIRST represents all coalesced allocnos. The
3240 list is chained by NEXT. */
3241 ira_allocno_t first;
3242 ira_allocno_t next;
3243 int temp;
3246 /* Container for storing allocno data concerning coalescing. */
3247 static coalesce_data_t allocno_coalesce_data;
3249 /* Macro to access the data concerning coalescing. */
3250 #define ALLOCNO_COALESCE_DATA(a) ((coalesce_data_t) ALLOCNO_ADD_DATA (a))
3252 /* The function is used to sort allocnos according to their execution
3253 frequencies. */
3254 static int
3255 copy_freq_compare_func (const void *v1p, const void *v2p)
3257 ira_copy_t cp1 = *(const ira_copy_t *) v1p, cp2 = *(const ira_copy_t *) v2p;
3258 int pri1, pri2;
3260 pri1 = cp1->freq;
3261 pri2 = cp2->freq;
3262 if (pri2 - pri1)
3263 return pri2 - pri1;
3265 /* If freqencies are equal, sort by copies, so that the results of
3266 qsort leave nothing to chance. */
3267 return cp1->num - cp2->num;
3270 /* Merge two sets of coalesced allocnos given correspondingly by
3271 allocnos A1 and A2 (more accurately merging A2 set into A1
3272 set). */
3273 static void
3274 merge_allocnos (ira_allocno_t a1, ira_allocno_t a2)
3276 ira_allocno_t a, first, last, next;
3278 first = ALLOCNO_COALESCE_DATA (a1)->first;
3279 a = ALLOCNO_COALESCE_DATA (a2)->first;
3280 if (first == a)
3281 return;
3282 for (last = a2, a = ALLOCNO_COALESCE_DATA (a2)->next;;
3283 a = ALLOCNO_COALESCE_DATA (a)->next)
3285 ALLOCNO_COALESCE_DATA (a)->first = first;
3286 if (a == a2)
3287 break;
3288 last = a;
3290 next = allocno_coalesce_data[ALLOCNO_NUM (first)].next;
3291 allocno_coalesce_data[ALLOCNO_NUM (first)].next = a2;
3292 allocno_coalesce_data[ALLOCNO_NUM (last)].next = next;
3295 /* Return TRUE if there are conflicting allocnos from two sets of
3296 coalesced allocnos given correspondingly by allocnos A1 and A2. We
3297 use live ranges to find conflicts because conflicts are represented
3298 only for allocnos of the same allocno class and during the reload
3299 pass we coalesce allocnos for sharing stack memory slots. */
3300 static bool
3301 coalesced_allocno_conflict_p (ira_allocno_t a1, ira_allocno_t a2)
3303 ira_allocno_t a, conflict_a;
3305 if (allocno_coalesced_p)
3307 bitmap_clear (processed_coalesced_allocno_bitmap);
3308 for (a = ALLOCNO_COALESCE_DATA (a1)->next;;
3309 a = ALLOCNO_COALESCE_DATA (a)->next)
3311 bitmap_set_bit (processed_coalesced_allocno_bitmap, ALLOCNO_NUM (a));
3312 if (a == a1)
3313 break;
3316 for (a = ALLOCNO_COALESCE_DATA (a2)->next;;
3317 a = ALLOCNO_COALESCE_DATA (a)->next)
3319 for (conflict_a = ALLOCNO_COALESCE_DATA (a1)->next;;
3320 conflict_a = ALLOCNO_COALESCE_DATA (conflict_a)->next)
3322 if (allocnos_conflict_by_live_ranges_p (a, conflict_a))
3323 return true;
3324 if (conflict_a == a1)
3325 break;
3327 if (a == a2)
3328 break;
3330 return false;
3333 /* The major function for aggressive allocno coalescing. We coalesce
3334 only spilled allocnos. If some allocnos have been coalesced, we
3335 set up flag allocno_coalesced_p. */
3336 static void
3337 coalesce_allocnos (void)
3339 ira_allocno_t a;
3340 ira_copy_t cp, next_cp, *sorted_copies;
3341 unsigned int j;
3342 int i, n, cp_num, regno;
3343 bitmap_iterator bi;
3345 sorted_copies = (ira_copy_t *) ira_allocate (ira_copies_num
3346 * sizeof (ira_copy_t));
3347 cp_num = 0;
3348 /* Collect copies. */
3349 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, j, bi)
3351 a = ira_allocnos[j];
3352 regno = ALLOCNO_REGNO (a);
3353 if (! ALLOCNO_ASSIGNED_P (a) || ALLOCNO_HARD_REGNO (a) >= 0
3354 || ira_equiv_no_lvalue_p (regno))
3355 continue;
3356 for (cp = ALLOCNO_COPIES (a); cp != NULL; cp = next_cp)
3358 if (cp->first == a)
3360 next_cp = cp->next_first_allocno_copy;
3361 regno = ALLOCNO_REGNO (cp->second);
3362 /* For priority coloring we coalesce allocnos only with
3363 the same allocno class not with intersected allocno
3364 classes as it were possible. It is done for
3365 simplicity. */
3366 if ((cp->insn != NULL || cp->constraint_p)
3367 && ALLOCNO_ASSIGNED_P (cp->second)
3368 && ALLOCNO_HARD_REGNO (cp->second) < 0
3369 && ! ira_equiv_no_lvalue_p (regno))
3370 sorted_copies[cp_num++] = cp;
3372 else if (cp->second == a)
3373 next_cp = cp->next_second_allocno_copy;
3374 else
3375 gcc_unreachable ();
3378 qsort (sorted_copies, cp_num, sizeof (ira_copy_t), copy_freq_compare_func);
3379 /* Coalesced copies, most frequently executed first. */
3380 for (; cp_num != 0;)
3382 for (i = 0; i < cp_num; i++)
3384 cp = sorted_copies[i];
3385 if (! coalesced_allocno_conflict_p (cp->first, cp->second))
3387 allocno_coalesced_p = true;
3388 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3389 fprintf
3390 (ira_dump_file,
3391 " Coalescing copy %d:a%dr%d-a%dr%d (freq=%d)\n",
3392 cp->num, ALLOCNO_NUM (cp->first), ALLOCNO_REGNO (cp->first),
3393 ALLOCNO_NUM (cp->second), ALLOCNO_REGNO (cp->second),
3394 cp->freq);
3395 merge_allocnos (cp->first, cp->second);
3396 i++;
3397 break;
3400 /* Collect the rest of copies. */
3401 for (n = 0; i < cp_num; i++)
3403 cp = sorted_copies[i];
3404 if (allocno_coalesce_data[ALLOCNO_NUM (cp->first)].first
3405 != allocno_coalesce_data[ALLOCNO_NUM (cp->second)].first)
3406 sorted_copies[n++] = cp;
3408 cp_num = n;
3410 ira_free (sorted_copies);
3413 /* Usage cost and order number of coalesced allocno set to which
3414 given pseudo register belongs to. */
3415 static int *regno_coalesced_allocno_cost;
3416 static int *regno_coalesced_allocno_num;
3418 /* Sort pseudos according frequencies of coalesced allocno sets they
3419 belong to (putting most frequently ones first), and according to
3420 coalesced allocno set order numbers. */
3421 static int
3422 coalesced_pseudo_reg_freq_compare (const void *v1p, const void *v2p)
3424 const int regno1 = *(const int *) v1p;
3425 const int regno2 = *(const int *) v2p;
3426 int diff;
3428 if ((diff = (regno_coalesced_allocno_cost[regno2]
3429 - regno_coalesced_allocno_cost[regno1])) != 0)
3430 return diff;
3431 if ((diff = (regno_coalesced_allocno_num[regno1]
3432 - regno_coalesced_allocno_num[regno2])) != 0)
3433 return diff;
3434 return regno1 - regno2;
3437 /* Widest width in which each pseudo reg is referred to (via subreg).
3438 It is used for sorting pseudo registers. */
3439 static unsigned int *regno_max_ref_width;
3441 /* Redefine STACK_GROWS_DOWNWARD in terms of 0 or 1. */
3442 #ifdef STACK_GROWS_DOWNWARD
3443 # undef STACK_GROWS_DOWNWARD
3444 # define STACK_GROWS_DOWNWARD 1
3445 #else
3446 # define STACK_GROWS_DOWNWARD 0
3447 #endif
3449 /* Sort pseudos according their slot numbers (putting ones with
3450 smaller numbers first, or last when the frame pointer is not
3451 needed). */
3452 static int
3453 coalesced_pseudo_reg_slot_compare (const void *v1p, const void *v2p)
3455 const int regno1 = *(const int *) v1p;
3456 const int regno2 = *(const int *) v2p;
3457 ira_allocno_t a1 = ira_regno_allocno_map[regno1];
3458 ira_allocno_t a2 = ira_regno_allocno_map[regno2];
3459 int diff, slot_num1, slot_num2;
3460 int total_size1, total_size2;
3462 if (a1 == NULL || ALLOCNO_HARD_REGNO (a1) >= 0)
3464 if (a2 == NULL || ALLOCNO_HARD_REGNO (a2) >= 0)
3465 return regno1 - regno2;
3466 return 1;
3468 else if (a2 == NULL || ALLOCNO_HARD_REGNO (a2) >= 0)
3469 return -1;
3470 slot_num1 = -ALLOCNO_HARD_REGNO (a1);
3471 slot_num2 = -ALLOCNO_HARD_REGNO (a2);
3472 if ((diff = slot_num1 - slot_num2) != 0)
3473 return (frame_pointer_needed
3474 || !FRAME_GROWS_DOWNWARD == STACK_GROWS_DOWNWARD ? diff : -diff);
3475 total_size1 = MAX (PSEUDO_REGNO_BYTES (regno1),
3476 regno_max_ref_width[regno1]);
3477 total_size2 = MAX (PSEUDO_REGNO_BYTES (regno2),
3478 regno_max_ref_width[regno2]);
3479 if ((diff = total_size2 - total_size1) != 0)
3480 return diff;
3481 return regno1 - regno2;
3484 /* Setup REGNO_COALESCED_ALLOCNO_COST and REGNO_COALESCED_ALLOCNO_NUM
3485 for coalesced allocno sets containing allocnos with their regnos
3486 given in array PSEUDO_REGNOS of length N. */
3487 static void
3488 setup_coalesced_allocno_costs_and_nums (int *pseudo_regnos, int n)
3490 int i, num, regno, cost;
3491 ira_allocno_t allocno, a;
3493 for (num = i = 0; i < n; i++)
3495 regno = pseudo_regnos[i];
3496 allocno = ira_regno_allocno_map[regno];
3497 if (allocno == NULL)
3499 regno_coalesced_allocno_cost[regno] = 0;
3500 regno_coalesced_allocno_num[regno] = ++num;
3501 continue;
3503 if (ALLOCNO_COALESCE_DATA (allocno)->first != allocno)
3504 continue;
3505 num++;
3506 for (cost = 0, a = ALLOCNO_COALESCE_DATA (allocno)->next;;
3507 a = ALLOCNO_COALESCE_DATA (a)->next)
3509 cost += ALLOCNO_FREQ (a);
3510 if (a == allocno)
3511 break;
3513 for (a = ALLOCNO_COALESCE_DATA (allocno)->next;;
3514 a = ALLOCNO_COALESCE_DATA (a)->next)
3516 regno_coalesced_allocno_num[ALLOCNO_REGNO (a)] = num;
3517 regno_coalesced_allocno_cost[ALLOCNO_REGNO (a)] = cost;
3518 if (a == allocno)
3519 break;
3524 /* Collect spilled allocnos representing coalesced allocno sets (the
3525 first coalesced allocno). The collected allocnos are returned
3526 through array SPILLED_COALESCED_ALLOCNOS. The function returns the
3527 number of the collected allocnos. The allocnos are given by their
3528 regnos in array PSEUDO_REGNOS of length N. */
3529 static int
3530 collect_spilled_coalesced_allocnos (int *pseudo_regnos, int n,
3531 ira_allocno_t *spilled_coalesced_allocnos)
3533 int i, num, regno;
3534 ira_allocno_t allocno;
3536 for (num = i = 0; i < n; i++)
3538 regno = pseudo_regnos[i];
3539 allocno = ira_regno_allocno_map[regno];
3540 if (allocno == NULL || ALLOCNO_HARD_REGNO (allocno) >= 0
3541 || ALLOCNO_COALESCE_DATA (allocno)->first != allocno)
3542 continue;
3543 spilled_coalesced_allocnos[num++] = allocno;
3545 return num;
3548 /* Array of live ranges of size IRA_ALLOCNOS_NUM. Live range for
3549 given slot contains live ranges of coalesced allocnos assigned to
3550 given slot. */
3551 static live_range_t *slot_coalesced_allocnos_live_ranges;
3553 /* Return TRUE if coalesced allocnos represented by ALLOCNO has live
3554 ranges intersected with live ranges of coalesced allocnos assigned
3555 to slot with number N. */
3556 static bool
3557 slot_coalesced_allocno_live_ranges_intersect_p (ira_allocno_t allocno, int n)
3559 ira_allocno_t a;
3561 for (a = ALLOCNO_COALESCE_DATA (allocno)->next;;
3562 a = ALLOCNO_COALESCE_DATA (a)->next)
3564 int i;
3565 int nr = ALLOCNO_NUM_OBJECTS (a);
3567 for (i = 0; i < nr; i++)
3569 ira_object_t obj = ALLOCNO_OBJECT (a, i);
3571 if (ira_live_ranges_intersect_p
3572 (slot_coalesced_allocnos_live_ranges[n],
3573 OBJECT_LIVE_RANGES (obj)))
3574 return true;
3576 if (a == allocno)
3577 break;
3579 return false;
3582 /* Update live ranges of slot to which coalesced allocnos represented
3583 by ALLOCNO were assigned. */
3584 static void
3585 setup_slot_coalesced_allocno_live_ranges (ira_allocno_t allocno)
3587 int i, n;
3588 ira_allocno_t a;
3589 live_range_t r;
3591 n = ALLOCNO_COALESCE_DATA (allocno)->temp;
3592 for (a = ALLOCNO_COALESCE_DATA (allocno)->next;;
3593 a = ALLOCNO_COALESCE_DATA (a)->next)
3595 int nr = ALLOCNO_NUM_OBJECTS (a);
3596 for (i = 0; i < nr; i++)
3598 ira_object_t obj = ALLOCNO_OBJECT (a, i);
3600 r = ira_copy_live_range_list (OBJECT_LIVE_RANGES (obj));
3601 slot_coalesced_allocnos_live_ranges[n]
3602 = ira_merge_live_ranges
3603 (slot_coalesced_allocnos_live_ranges[n], r);
3605 if (a == allocno)
3606 break;
3610 /* We have coalesced allocnos involving in copies. Coalesce allocnos
3611 further in order to share the same memory stack slot. Allocnos
3612 representing sets of allocnos coalesced before the call are given
3613 in array SPILLED_COALESCED_ALLOCNOS of length NUM. Return TRUE if
3614 some allocnos were coalesced in the function. */
3615 static bool
3616 coalesce_spill_slots (ira_allocno_t *spilled_coalesced_allocnos, int num)
3618 int i, j, n, last_coalesced_allocno_num;
3619 ira_allocno_t allocno, a;
3620 bool merged_p = false;
3621 bitmap set_jump_crosses = regstat_get_setjmp_crosses ();
3623 slot_coalesced_allocnos_live_ranges
3624 = (live_range_t *) ira_allocate (sizeof (live_range_t) * ira_allocnos_num);
3625 memset (slot_coalesced_allocnos_live_ranges, 0,
3626 sizeof (live_range_t) * ira_allocnos_num);
3627 last_coalesced_allocno_num = 0;
3628 /* Coalesce non-conflicting spilled allocnos preferring most
3629 frequently used. */
3630 for (i = 0; i < num; i++)
3632 allocno = spilled_coalesced_allocnos[i];
3633 if (ALLOCNO_COALESCE_DATA (allocno)->first != allocno
3634 || bitmap_bit_p (set_jump_crosses, ALLOCNO_REGNO (allocno))
3635 || ira_equiv_no_lvalue_p (ALLOCNO_REGNO (allocno)))
3636 continue;
3637 for (j = 0; j < i; j++)
3639 a = spilled_coalesced_allocnos[j];
3640 n = ALLOCNO_COALESCE_DATA (a)->temp;
3641 if (ALLOCNO_COALESCE_DATA (a)->first == a
3642 && ! bitmap_bit_p (set_jump_crosses, ALLOCNO_REGNO (a))
3643 && ! ira_equiv_no_lvalue_p (ALLOCNO_REGNO (a))
3644 && ! slot_coalesced_allocno_live_ranges_intersect_p (allocno, n))
3645 break;
3647 if (j >= i)
3649 /* No coalescing: set up number for coalesced allocnos
3650 represented by ALLOCNO. */
3651 ALLOCNO_COALESCE_DATA (allocno)->temp = last_coalesced_allocno_num++;
3652 setup_slot_coalesced_allocno_live_ranges (allocno);
3654 else
3656 allocno_coalesced_p = true;
3657 merged_p = true;
3658 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3659 fprintf (ira_dump_file,
3660 " Coalescing spilled allocnos a%dr%d->a%dr%d\n",
3661 ALLOCNO_NUM (allocno), ALLOCNO_REGNO (allocno),
3662 ALLOCNO_NUM (a), ALLOCNO_REGNO (a));
3663 ALLOCNO_COALESCE_DATA (allocno)->temp
3664 = ALLOCNO_COALESCE_DATA (a)->temp;
3665 setup_slot_coalesced_allocno_live_ranges (allocno);
3666 merge_allocnos (a, allocno);
3667 ira_assert (ALLOCNO_COALESCE_DATA (a)->first == a);
3670 for (i = 0; i < ira_allocnos_num; i++)
3671 ira_finish_live_range_list (slot_coalesced_allocnos_live_ranges[i]);
3672 ira_free (slot_coalesced_allocnos_live_ranges);
3673 return merged_p;
3676 /* Sort pseudo-register numbers in array PSEUDO_REGNOS of length N for
3677 subsequent assigning stack slots to them in the reload pass. To do
3678 this we coalesce spilled allocnos first to decrease the number of
3679 memory-memory move insns. This function is called by the
3680 reload. */
3681 void
3682 ira_sort_regnos_for_alter_reg (int *pseudo_regnos, int n,
3683 unsigned int *reg_max_ref_width)
3685 int max_regno = max_reg_num ();
3686 int i, regno, num, slot_num;
3687 ira_allocno_t allocno, a;
3688 ira_allocno_iterator ai;
3689 ira_allocno_t *spilled_coalesced_allocnos;
3691 /* Set up allocnos can be coalesced. */
3692 coloring_allocno_bitmap = ira_allocate_bitmap ();
3693 for (i = 0; i < n; i++)
3695 regno = pseudo_regnos[i];
3696 allocno = ira_regno_allocno_map[regno];
3697 if (allocno != NULL)
3698 bitmap_set_bit (coloring_allocno_bitmap, ALLOCNO_NUM (allocno));
3700 allocno_coalesced_p = false;
3701 processed_coalesced_allocno_bitmap = ira_allocate_bitmap ();
3702 allocno_coalesce_data
3703 = (coalesce_data_t) ira_allocate (sizeof (struct coalesce_data)
3704 * ira_allocnos_num);
3705 /* Initialize coalesce data for allocnos. */
3706 FOR_EACH_ALLOCNO (a, ai)
3708 ALLOCNO_ADD_DATA (a) = allocno_coalesce_data + ALLOCNO_NUM (a);
3709 ALLOCNO_COALESCE_DATA (a)->first = a;
3710 ALLOCNO_COALESCE_DATA (a)->next = a;
3712 coalesce_allocnos ();
3713 ira_free_bitmap (coloring_allocno_bitmap);
3714 regno_coalesced_allocno_cost
3715 = (int *) ira_allocate (max_regno * sizeof (int));
3716 regno_coalesced_allocno_num
3717 = (int *) ira_allocate (max_regno * sizeof (int));
3718 memset (regno_coalesced_allocno_num, 0, max_regno * sizeof (int));
3719 setup_coalesced_allocno_costs_and_nums (pseudo_regnos, n);
3720 /* Sort regnos according frequencies of the corresponding coalesced
3721 allocno sets. */
3722 qsort (pseudo_regnos, n, sizeof (int), coalesced_pseudo_reg_freq_compare);
3723 spilled_coalesced_allocnos
3724 = (ira_allocno_t *) ira_allocate (ira_allocnos_num
3725 * sizeof (ira_allocno_t));
3726 /* Collect allocnos representing the spilled coalesced allocno
3727 sets. */
3728 num = collect_spilled_coalesced_allocnos (pseudo_regnos, n,
3729 spilled_coalesced_allocnos);
3730 if (flag_ira_share_spill_slots
3731 && coalesce_spill_slots (spilled_coalesced_allocnos, num))
3733 setup_coalesced_allocno_costs_and_nums (pseudo_regnos, n);
3734 qsort (pseudo_regnos, n, sizeof (int),
3735 coalesced_pseudo_reg_freq_compare);
3736 num = collect_spilled_coalesced_allocnos (pseudo_regnos, n,
3737 spilled_coalesced_allocnos);
3739 ira_free_bitmap (processed_coalesced_allocno_bitmap);
3740 allocno_coalesced_p = false;
3741 /* Assign stack slot numbers to spilled allocno sets, use smaller
3742 numbers for most frequently used coalesced allocnos. -1 is
3743 reserved for dynamic search of stack slots for pseudos spilled by
3744 the reload. */
3745 slot_num = 1;
3746 for (i = 0; i < num; i++)
3748 allocno = spilled_coalesced_allocnos[i];
3749 if (ALLOCNO_COALESCE_DATA (allocno)->first != allocno
3750 || ALLOCNO_HARD_REGNO (allocno) >= 0
3751 || ira_equiv_no_lvalue_p (ALLOCNO_REGNO (allocno)))
3752 continue;
3753 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3754 fprintf (ira_dump_file, " Slot %d (freq,size):", slot_num);
3755 slot_num++;
3756 for (a = ALLOCNO_COALESCE_DATA (allocno)->next;;
3757 a = ALLOCNO_COALESCE_DATA (a)->next)
3759 ira_assert (ALLOCNO_HARD_REGNO (a) < 0);
3760 ALLOCNO_HARD_REGNO (a) = -slot_num;
3761 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3762 fprintf (ira_dump_file, " a%dr%d(%d,%d)",
3763 ALLOCNO_NUM (a), ALLOCNO_REGNO (a), ALLOCNO_FREQ (a),
3764 MAX (PSEUDO_REGNO_BYTES (ALLOCNO_REGNO (a)),
3765 reg_max_ref_width[ALLOCNO_REGNO (a)]));
3767 if (a == allocno)
3768 break;
3770 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3771 fprintf (ira_dump_file, "\n");
3773 ira_spilled_reg_stack_slots_num = slot_num - 1;
3774 ira_free (spilled_coalesced_allocnos);
3775 /* Sort regnos according the slot numbers. */
3776 regno_max_ref_width = reg_max_ref_width;
3777 qsort (pseudo_regnos, n, sizeof (int), coalesced_pseudo_reg_slot_compare);
3778 FOR_EACH_ALLOCNO (a, ai)
3779 ALLOCNO_ADD_DATA (a) = NULL;
3780 ira_free (allocno_coalesce_data);
3781 ira_free (regno_coalesced_allocno_num);
3782 ira_free (regno_coalesced_allocno_cost);
3787 /* This page contains code used by the reload pass to improve the
3788 final code. */
3790 /* The function is called from reload to mark changes in the
3791 allocation of REGNO made by the reload. Remember that reg_renumber
3792 reflects the change result. */
3793 void
3794 ira_mark_allocation_change (int regno)
3796 ira_allocno_t a = ira_regno_allocno_map[regno];
3797 int old_hard_regno, hard_regno, cost;
3798 enum reg_class aclass = ALLOCNO_CLASS (a);
3800 ira_assert (a != NULL);
3801 hard_regno = reg_renumber[regno];
3802 if ((old_hard_regno = ALLOCNO_HARD_REGNO (a)) == hard_regno)
3803 return;
3804 if (old_hard_regno < 0)
3805 cost = -ALLOCNO_MEMORY_COST (a);
3806 else
3808 ira_assert (ira_class_hard_reg_index[aclass][old_hard_regno] >= 0);
3809 cost = -(ALLOCNO_HARD_REG_COSTS (a) == NULL
3810 ? ALLOCNO_CLASS_COST (a)
3811 : ALLOCNO_HARD_REG_COSTS (a)
3812 [ira_class_hard_reg_index[aclass][old_hard_regno]]);
3813 update_copy_costs (a, false);
3815 ira_overall_cost -= cost;
3816 ALLOCNO_HARD_REGNO (a) = hard_regno;
3817 if (hard_regno < 0)
3819 ALLOCNO_HARD_REGNO (a) = -1;
3820 cost += ALLOCNO_MEMORY_COST (a);
3822 else if (ira_class_hard_reg_index[aclass][hard_regno] >= 0)
3824 cost += (ALLOCNO_HARD_REG_COSTS (a) == NULL
3825 ? ALLOCNO_CLASS_COST (a)
3826 : ALLOCNO_HARD_REG_COSTS (a)
3827 [ira_class_hard_reg_index[aclass][hard_regno]]);
3828 update_copy_costs (a, true);
3830 else
3831 /* Reload changed class of the allocno. */
3832 cost = 0;
3833 ira_overall_cost += cost;
3836 /* This function is called when reload deletes memory-memory move. In
3837 this case we marks that the allocation of the corresponding
3838 allocnos should be not changed in future. Otherwise we risk to get
3839 a wrong code. */
3840 void
3841 ira_mark_memory_move_deletion (int dst_regno, int src_regno)
3843 ira_allocno_t dst = ira_regno_allocno_map[dst_regno];
3844 ira_allocno_t src = ira_regno_allocno_map[src_regno];
3846 ira_assert (dst != NULL && src != NULL
3847 && ALLOCNO_HARD_REGNO (dst) < 0
3848 && ALLOCNO_HARD_REGNO (src) < 0);
3849 ALLOCNO_DONT_REASSIGN_P (dst) = true;
3850 ALLOCNO_DONT_REASSIGN_P (src) = true;
3853 /* Try to assign a hard register (except for FORBIDDEN_REGS) to
3854 allocno A and return TRUE in the case of success. */
3855 static bool
3856 allocno_reload_assign (ira_allocno_t a, HARD_REG_SET forbidden_regs)
3858 int hard_regno;
3859 enum reg_class aclass;
3860 int regno = ALLOCNO_REGNO (a);
3861 HARD_REG_SET saved[2];
3862 int i, n;
3864 n = ALLOCNO_NUM_OBJECTS (a);
3865 for (i = 0; i < n; i++)
3867 ira_object_t obj = ALLOCNO_OBJECT (a, i);
3868 COPY_HARD_REG_SET (saved[i], OBJECT_TOTAL_CONFLICT_HARD_REGS (obj));
3869 IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), forbidden_regs);
3870 if (! flag_caller_saves && ALLOCNO_CALLS_CROSSED_NUM (a) != 0)
3871 IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
3872 call_used_reg_set);
3874 ALLOCNO_ASSIGNED_P (a) = false;
3875 aclass = ALLOCNO_CLASS (a);
3876 update_curr_costs (a);
3877 assign_hard_reg (a, true);
3878 hard_regno = ALLOCNO_HARD_REGNO (a);
3879 reg_renumber[regno] = hard_regno;
3880 if (hard_regno < 0)
3881 ALLOCNO_HARD_REGNO (a) = -1;
3882 else
3884 ira_assert (ira_class_hard_reg_index[aclass][hard_regno] >= 0);
3885 ira_overall_cost
3886 -= (ALLOCNO_MEMORY_COST (a)
3887 - (ALLOCNO_HARD_REG_COSTS (a) == NULL
3888 ? ALLOCNO_CLASS_COST (a)
3889 : ALLOCNO_HARD_REG_COSTS (a)[ira_class_hard_reg_index
3890 [aclass][hard_regno]]));
3891 if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0
3892 && ira_hard_reg_set_intersection_p (hard_regno, ALLOCNO_MODE (a),
3893 call_used_reg_set))
3895 ira_assert (flag_caller_saves);
3896 caller_save_needed = 1;
3900 /* If we found a hard register, modify the RTL for the pseudo
3901 register to show the hard register, and mark the pseudo register
3902 live. */
3903 if (reg_renumber[regno] >= 0)
3905 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3906 fprintf (ira_dump_file, ": reassign to %d\n", reg_renumber[regno]);
3907 SET_REGNO (regno_reg_rtx[regno], reg_renumber[regno]);
3908 mark_home_live (regno);
3910 else if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3911 fprintf (ira_dump_file, "\n");
3912 for (i = 0; i < n; i++)
3914 ira_object_t obj = ALLOCNO_OBJECT (a, i);
3915 COPY_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), saved[i]);
3917 return reg_renumber[regno] >= 0;
3920 /* Sort pseudos according their usage frequencies (putting most
3921 frequently ones first). */
3922 static int
3923 pseudo_reg_compare (const void *v1p, const void *v2p)
3925 int regno1 = *(const int *) v1p;
3926 int regno2 = *(const int *) v2p;
3927 int diff;
3929 if ((diff = REG_FREQ (regno2) - REG_FREQ (regno1)) != 0)
3930 return diff;
3931 return regno1 - regno2;
3934 /* Try to allocate hard registers to SPILLED_PSEUDO_REGS (there are
3935 NUM of them) or spilled pseudos conflicting with pseudos in
3936 SPILLED_PSEUDO_REGS. Return TRUE and update SPILLED, if the
3937 allocation has been changed. The function doesn't use
3938 BAD_SPILL_REGS and hard registers in PSEUDO_FORBIDDEN_REGS and
3939 PSEUDO_PREVIOUS_REGS for the corresponding pseudos. The function
3940 is called by the reload pass at the end of each reload
3941 iteration. */
3942 bool
3943 ira_reassign_pseudos (int *spilled_pseudo_regs, int num,
3944 HARD_REG_SET bad_spill_regs,
3945 HARD_REG_SET *pseudo_forbidden_regs,
3946 HARD_REG_SET *pseudo_previous_regs,
3947 bitmap spilled)
3949 int i, n, regno;
3950 bool changed_p;
3951 ira_allocno_t a;
3952 HARD_REG_SET forbidden_regs;
3953 bitmap temp = BITMAP_ALLOC (NULL);
3955 /* Add pseudos which conflict with pseudos already in
3956 SPILLED_PSEUDO_REGS to SPILLED_PSEUDO_REGS. This is preferable
3957 to allocating in two steps as some of the conflicts might have
3958 a higher priority than the pseudos passed in SPILLED_PSEUDO_REGS. */
3959 for (i = 0; i < num; i++)
3960 bitmap_set_bit (temp, spilled_pseudo_regs[i]);
3962 for (i = 0, n = num; i < n; i++)
3964 int nr, j;
3965 int regno = spilled_pseudo_regs[i];
3966 bitmap_set_bit (temp, regno);
3968 a = ira_regno_allocno_map[regno];
3969 nr = ALLOCNO_NUM_OBJECTS (a);
3970 for (j = 0; j < nr; j++)
3972 ira_object_t conflict_obj;
3973 ira_object_t obj = ALLOCNO_OBJECT (a, j);
3974 ira_object_conflict_iterator oci;
3976 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
3978 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
3979 if (ALLOCNO_HARD_REGNO (conflict_a) < 0
3980 && ! ALLOCNO_DONT_REASSIGN_P (conflict_a)
3981 && bitmap_set_bit (temp, ALLOCNO_REGNO (conflict_a)))
3983 spilled_pseudo_regs[num++] = ALLOCNO_REGNO (conflict_a);
3984 /* ?!? This seems wrong. */
3985 bitmap_set_bit (consideration_allocno_bitmap,
3986 ALLOCNO_NUM (conflict_a));
3992 if (num > 1)
3993 qsort (spilled_pseudo_regs, num, sizeof (int), pseudo_reg_compare);
3994 changed_p = false;
3995 /* Try to assign hard registers to pseudos from
3996 SPILLED_PSEUDO_REGS. */
3997 for (i = 0; i < num; i++)
3999 regno = spilled_pseudo_regs[i];
4000 COPY_HARD_REG_SET (forbidden_regs, bad_spill_regs);
4001 IOR_HARD_REG_SET (forbidden_regs, pseudo_forbidden_regs[regno]);
4002 IOR_HARD_REG_SET (forbidden_regs, pseudo_previous_regs[regno]);
4003 gcc_assert (reg_renumber[regno] < 0);
4004 a = ira_regno_allocno_map[regno];
4005 ira_mark_allocation_change (regno);
4006 ira_assert (reg_renumber[regno] < 0);
4007 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4008 fprintf (ira_dump_file,
4009 " Try Assign %d(a%d), cost=%d", regno, ALLOCNO_NUM (a),
4010 ALLOCNO_MEMORY_COST (a)
4011 - ALLOCNO_CLASS_COST (a));
4012 allocno_reload_assign (a, forbidden_regs);
4013 if (reg_renumber[regno] >= 0)
4015 CLEAR_REGNO_REG_SET (spilled, regno);
4016 changed_p = true;
4019 BITMAP_FREE (temp);
4020 return changed_p;
4023 /* The function is called by reload and returns already allocated
4024 stack slot (if any) for REGNO with given INHERENT_SIZE and
4025 TOTAL_SIZE. In the case of failure to find a slot which can be
4026 used for REGNO, the function returns NULL. */
4028 ira_reuse_stack_slot (int regno, unsigned int inherent_size,
4029 unsigned int total_size)
4031 unsigned int i;
4032 int slot_num, best_slot_num;
4033 int cost, best_cost;
4034 ira_copy_t cp, next_cp;
4035 ira_allocno_t another_allocno, allocno = ira_regno_allocno_map[regno];
4036 rtx x;
4037 bitmap_iterator bi;
4038 struct ira_spilled_reg_stack_slot *slot = NULL;
4040 ira_assert (inherent_size == PSEUDO_REGNO_BYTES (regno)
4041 && inherent_size <= total_size
4042 && ALLOCNO_HARD_REGNO (allocno) < 0);
4043 if (! flag_ira_share_spill_slots)
4044 return NULL_RTX;
4045 slot_num = -ALLOCNO_HARD_REGNO (allocno) - 2;
4046 if (slot_num != -1)
4048 slot = &ira_spilled_reg_stack_slots[slot_num];
4049 x = slot->mem;
4051 else
4053 best_cost = best_slot_num = -1;
4054 x = NULL_RTX;
4055 /* It means that the pseudo was spilled in the reload pass, try
4056 to reuse a slot. */
4057 for (slot_num = 0;
4058 slot_num < ira_spilled_reg_stack_slots_num;
4059 slot_num++)
4061 slot = &ira_spilled_reg_stack_slots[slot_num];
4062 if (slot->mem == NULL_RTX)
4063 continue;
4064 if (slot->width < total_size
4065 || GET_MODE_SIZE (GET_MODE (slot->mem)) < inherent_size)
4066 continue;
4068 EXECUTE_IF_SET_IN_BITMAP (&slot->spilled_regs,
4069 FIRST_PSEUDO_REGISTER, i, bi)
4071 another_allocno = ira_regno_allocno_map[i];
4072 if (allocnos_conflict_by_live_ranges_p (allocno,
4073 another_allocno))
4074 goto cont;
4076 for (cost = 0, cp = ALLOCNO_COPIES (allocno);
4077 cp != NULL;
4078 cp = next_cp)
4080 if (cp->first == allocno)
4082 next_cp = cp->next_first_allocno_copy;
4083 another_allocno = cp->second;
4085 else if (cp->second == allocno)
4087 next_cp = cp->next_second_allocno_copy;
4088 another_allocno = cp->first;
4090 else
4091 gcc_unreachable ();
4092 if (cp->insn == NULL_RTX)
4093 continue;
4094 if (bitmap_bit_p (&slot->spilled_regs,
4095 ALLOCNO_REGNO (another_allocno)))
4096 cost += cp->freq;
4098 if (cost > best_cost)
4100 best_cost = cost;
4101 best_slot_num = slot_num;
4103 cont:
4106 if (best_cost >= 0)
4108 slot_num = best_slot_num;
4109 slot = &ira_spilled_reg_stack_slots[slot_num];
4110 SET_REGNO_REG_SET (&slot->spilled_regs, regno);
4111 x = slot->mem;
4112 ALLOCNO_HARD_REGNO (allocno) = -slot_num - 2;
4115 if (x != NULL_RTX)
4117 ira_assert (slot->width >= total_size);
4118 #ifdef ENABLE_IRA_CHECKING
4119 EXECUTE_IF_SET_IN_BITMAP (&slot->spilled_regs,
4120 FIRST_PSEUDO_REGISTER, i, bi)
4122 ira_assert (! conflict_by_live_ranges_p (regno, i));
4124 #endif
4125 SET_REGNO_REG_SET (&slot->spilled_regs, regno);
4126 if (internal_flag_ira_verbose > 3 && ira_dump_file)
4128 fprintf (ira_dump_file, " Assigning %d(freq=%d) slot %d of",
4129 regno, REG_FREQ (regno), slot_num);
4130 EXECUTE_IF_SET_IN_BITMAP (&slot->spilled_regs,
4131 FIRST_PSEUDO_REGISTER, i, bi)
4133 if ((unsigned) regno != i)
4134 fprintf (ira_dump_file, " %d", i);
4136 fprintf (ira_dump_file, "\n");
4139 return x;
4142 /* This is called by reload every time a new stack slot X with
4143 TOTAL_SIZE was allocated for REGNO. We store this info for
4144 subsequent ira_reuse_stack_slot calls. */
4145 void
4146 ira_mark_new_stack_slot (rtx x, int regno, unsigned int total_size)
4148 struct ira_spilled_reg_stack_slot *slot;
4149 int slot_num;
4150 ira_allocno_t allocno;
4152 ira_assert (PSEUDO_REGNO_BYTES (regno) <= total_size);
4153 allocno = ira_regno_allocno_map[regno];
4154 slot_num = -ALLOCNO_HARD_REGNO (allocno) - 2;
4155 if (slot_num == -1)
4157 slot_num = ira_spilled_reg_stack_slots_num++;
4158 ALLOCNO_HARD_REGNO (allocno) = -slot_num - 2;
4160 slot = &ira_spilled_reg_stack_slots[slot_num];
4161 INIT_REG_SET (&slot->spilled_regs);
4162 SET_REGNO_REG_SET (&slot->spilled_regs, regno);
4163 slot->mem = x;
4164 slot->width = total_size;
4165 if (internal_flag_ira_verbose > 3 && ira_dump_file)
4166 fprintf (ira_dump_file, " Assigning %d(freq=%d) a new slot %d\n",
4167 regno, REG_FREQ (regno), slot_num);
4171 /* Return spill cost for pseudo-registers whose numbers are in array
4172 REGNOS (with a negative number as an end marker) for reload with
4173 given IN and OUT for INSN. Return also number points (through
4174 EXCESS_PRESSURE_LIVE_LENGTH) where the pseudo-register lives and
4175 the register pressure is high, number of references of the
4176 pseudo-registers (through NREFS), number of callee-clobbered
4177 hard-registers occupied by the pseudo-registers (through
4178 CALL_USED_COUNT), and the first hard regno occupied by the
4179 pseudo-registers (through FIRST_HARD_REGNO). */
4180 static int
4181 calculate_spill_cost (int *regnos, rtx in, rtx out, rtx insn,
4182 int *excess_pressure_live_length,
4183 int *nrefs, int *call_used_count, int *first_hard_regno)
4185 int i, cost, regno, hard_regno, j, count, saved_cost, nregs;
4186 bool in_p, out_p;
4187 int length;
4188 ira_allocno_t a;
4190 *nrefs = 0;
4191 for (length = count = cost = i = 0;; i++)
4193 regno = regnos[i];
4194 if (regno < 0)
4195 break;
4196 *nrefs += REG_N_REFS (regno);
4197 hard_regno = reg_renumber[regno];
4198 ira_assert (hard_regno >= 0);
4199 a = ira_regno_allocno_map[regno];
4200 length += ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a) / ALLOCNO_NUM_OBJECTS (a);
4201 cost += ALLOCNO_MEMORY_COST (a) - ALLOCNO_CLASS_COST (a);
4202 nregs = hard_regno_nregs[hard_regno][ALLOCNO_MODE (a)];
4203 for (j = 0; j < nregs; j++)
4204 if (! TEST_HARD_REG_BIT (call_used_reg_set, hard_regno + j))
4205 break;
4206 if (j == nregs)
4207 count++;
4208 in_p = in && REG_P (in) && (int) REGNO (in) == hard_regno;
4209 out_p = out && REG_P (out) && (int) REGNO (out) == hard_regno;
4210 if ((in_p || out_p)
4211 && find_regno_note (insn, REG_DEAD, hard_regno) != NULL_RTX)
4213 saved_cost = 0;
4214 if (in_p)
4215 saved_cost += ira_memory_move_cost
4216 [ALLOCNO_MODE (a)][ALLOCNO_CLASS (a)][1];
4217 if (out_p)
4218 saved_cost
4219 += ira_memory_move_cost
4220 [ALLOCNO_MODE (a)][ALLOCNO_CLASS (a)][0];
4221 cost -= REG_FREQ_FROM_BB (BLOCK_FOR_INSN (insn)) * saved_cost;
4224 *excess_pressure_live_length = length;
4225 *call_used_count = count;
4226 hard_regno = -1;
4227 if (regnos[0] >= 0)
4229 hard_regno = reg_renumber[regnos[0]];
4231 *first_hard_regno = hard_regno;
4232 return cost;
4235 /* Return TRUE if spilling pseudo-registers whose numbers are in array
4236 REGNOS is better than spilling pseudo-registers with numbers in
4237 OTHER_REGNOS for reload with given IN and OUT for INSN. The
4238 function used by the reload pass to make better register spilling
4239 decisions. */
4240 bool
4241 ira_better_spill_reload_regno_p (int *regnos, int *other_regnos,
4242 rtx in, rtx out, rtx insn)
4244 int cost, other_cost;
4245 int length, other_length;
4246 int nrefs, other_nrefs;
4247 int call_used_count, other_call_used_count;
4248 int hard_regno, other_hard_regno;
4250 cost = calculate_spill_cost (regnos, in, out, insn,
4251 &length, &nrefs, &call_used_count, &hard_regno);
4252 other_cost = calculate_spill_cost (other_regnos, in, out, insn,
4253 &other_length, &other_nrefs,
4254 &other_call_used_count,
4255 &other_hard_regno);
4256 if (nrefs == 0 && other_nrefs != 0)
4257 return true;
4258 if (nrefs != 0 && other_nrefs == 0)
4259 return false;
4260 if (cost != other_cost)
4261 return cost < other_cost;
4262 if (length != other_length)
4263 return length > other_length;
4264 #ifdef REG_ALLOC_ORDER
4265 if (hard_regno >= 0 && other_hard_regno >= 0)
4266 return (inv_reg_alloc_order[hard_regno]
4267 < inv_reg_alloc_order[other_hard_regno]);
4268 #else
4269 if (call_used_count != other_call_used_count)
4270 return call_used_count > other_call_used_count;
4271 #endif
4272 return false;
4277 /* Allocate and initialize data necessary for assign_hard_reg. */
4278 void
4279 ira_initiate_assign (void)
4281 sorted_allocnos
4282 = (ira_allocno_t *) ira_allocate (sizeof (ira_allocno_t)
4283 * ira_allocnos_num);
4284 consideration_allocno_bitmap = ira_allocate_bitmap ();
4285 initiate_cost_update ();
4286 allocno_priorities = (int *) ira_allocate (sizeof (int) * ira_allocnos_num);
4289 /* Deallocate data used by assign_hard_reg. */
4290 void
4291 ira_finish_assign (void)
4293 ira_free (sorted_allocnos);
4294 ira_free_bitmap (consideration_allocno_bitmap);
4295 finish_cost_update ();
4296 ira_free (allocno_priorities);
4301 /* Entry function doing color-based register allocation. */
4302 static void
4303 color (void)
4305 allocno_stack_vec.create (ira_allocnos_num);
4306 memset (allocated_hardreg_p, 0, sizeof (allocated_hardreg_p));
4307 ira_initiate_assign ();
4308 do_coloring ();
4309 ira_finish_assign ();
4310 allocno_stack_vec.release ();
4311 move_spill_restore ();
4316 /* This page contains a simple register allocator without usage of
4317 allocno conflicts. This is used for fast allocation for -O0. */
4319 /* Do register allocation by not using allocno conflicts. It uses
4320 only allocno live ranges. The algorithm is close to Chow's
4321 priority coloring. */
4322 static void
4323 fast_allocation (void)
4325 int i, j, k, num, class_size, hard_regno;
4326 #ifdef STACK_REGS
4327 bool no_stack_reg_p;
4328 #endif
4329 enum reg_class aclass;
4330 enum machine_mode mode;
4331 ira_allocno_t a;
4332 ira_allocno_iterator ai;
4333 live_range_t r;
4334 HARD_REG_SET conflict_hard_regs, *used_hard_regs;
4336 sorted_allocnos = (ira_allocno_t *) ira_allocate (sizeof (ira_allocno_t)
4337 * ira_allocnos_num);
4338 num = 0;
4339 FOR_EACH_ALLOCNO (a, ai)
4340 sorted_allocnos[num++] = a;
4341 allocno_priorities = (int *) ira_allocate (sizeof (int) * ira_allocnos_num);
4342 setup_allocno_priorities (sorted_allocnos, num);
4343 used_hard_regs = (HARD_REG_SET *) ira_allocate (sizeof (HARD_REG_SET)
4344 * ira_max_point);
4345 for (i = 0; i < ira_max_point; i++)
4346 CLEAR_HARD_REG_SET (used_hard_regs[i]);
4347 qsort (sorted_allocnos, num, sizeof (ira_allocno_t),
4348 allocno_priority_compare_func);
4349 for (i = 0; i < num; i++)
4351 int nr, l;
4353 a = sorted_allocnos[i];
4354 nr = ALLOCNO_NUM_OBJECTS (a);
4355 CLEAR_HARD_REG_SET (conflict_hard_regs);
4356 for (l = 0; l < nr; l++)
4358 ira_object_t obj = ALLOCNO_OBJECT (a, l);
4359 IOR_HARD_REG_SET (conflict_hard_regs,
4360 OBJECT_CONFLICT_HARD_REGS (obj));
4361 for (r = OBJECT_LIVE_RANGES (obj); r != NULL; r = r->next)
4362 for (j = r->start; j <= r->finish; j++)
4363 IOR_HARD_REG_SET (conflict_hard_regs, used_hard_regs[j]);
4365 aclass = ALLOCNO_CLASS (a);
4366 ALLOCNO_ASSIGNED_P (a) = true;
4367 ALLOCNO_HARD_REGNO (a) = -1;
4368 if (hard_reg_set_subset_p (reg_class_contents[aclass],
4369 conflict_hard_regs))
4370 continue;
4371 mode = ALLOCNO_MODE (a);
4372 #ifdef STACK_REGS
4373 no_stack_reg_p = ALLOCNO_NO_STACK_REG_P (a);
4374 #endif
4375 class_size = ira_class_hard_regs_num[aclass];
4376 for (j = 0; j < class_size; j++)
4378 hard_regno = ira_class_hard_regs[aclass][j];
4379 #ifdef STACK_REGS
4380 if (no_stack_reg_p && FIRST_STACK_REG <= hard_regno
4381 && hard_regno <= LAST_STACK_REG)
4382 continue;
4383 #endif
4384 if (ira_hard_reg_set_intersection_p (hard_regno, mode, conflict_hard_regs)
4385 || (TEST_HARD_REG_BIT
4386 (ira_prohibited_class_mode_regs[aclass][mode], hard_regno)))
4387 continue;
4388 ALLOCNO_HARD_REGNO (a) = hard_regno;
4389 for (l = 0; l < nr; l++)
4391 ira_object_t obj = ALLOCNO_OBJECT (a, l);
4392 for (r = OBJECT_LIVE_RANGES (obj); r != NULL; r = r->next)
4393 for (k = r->start; k <= r->finish; k++)
4394 IOR_HARD_REG_SET (used_hard_regs[k],
4395 ira_reg_mode_hard_regset[hard_regno][mode]);
4397 break;
4400 ira_free (sorted_allocnos);
4401 ira_free (used_hard_regs);
4402 ira_free (allocno_priorities);
4403 if (internal_flag_ira_verbose > 1 && ira_dump_file != NULL)
4404 ira_print_disposition (ira_dump_file);
4409 /* Entry function doing coloring. */
4410 void
4411 ira_color (void)
4413 ira_allocno_t a;
4414 ira_allocno_iterator ai;
4416 /* Setup updated costs. */
4417 FOR_EACH_ALLOCNO (a, ai)
4419 ALLOCNO_UPDATED_MEMORY_COST (a) = ALLOCNO_MEMORY_COST (a);
4420 ALLOCNO_UPDATED_CLASS_COST (a) = ALLOCNO_CLASS_COST (a);
4422 if (ira_conflicts_p)
4423 color ();
4424 else
4425 fast_allocation ();