2013-11-13 Christophe Lyon <christophe.lyon@linaro.org>
[official-gcc.git] / gcc / ira-color.c
blob295cd5327d756c4fd167dfb89a916909180ac93b
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 "hash-table.h"
33 #include "hard-reg-set.h"
34 #include "basic-block.h"
35 #include "expr.h"
36 #include "diagnostic-core.h"
37 #include "reload.h"
38 #include "params.h"
39 #include "df.h"
40 #include "ira-int.h"
42 typedef struct allocno_hard_regs *allocno_hard_regs_t;
44 /* The structure contains information about hard registers can be
45 assigned to allocnos. Usually it is allocno profitable hard
46 registers but in some cases this set can be a bit different. Major
47 reason of the difference is a requirement to use hard register sets
48 that form a tree or a forest (set of trees), i.e. hard register set
49 of a node should contain hard register sets of its subnodes. */
50 struct allocno_hard_regs
52 /* Hard registers can be assigned to an allocno. */
53 HARD_REG_SET set;
54 /* Overall (spilling) cost of all allocnos with given register
55 set. */
56 HOST_WIDEST_INT cost;
59 typedef struct allocno_hard_regs_node *allocno_hard_regs_node_t;
61 /* A node representing allocno hard registers. Such nodes form a
62 forest (set of trees). Each subnode of given node in the forest
63 refers for hard register set (usually allocno profitable hard
64 register set) which is a subset of one referred from given
65 node. */
66 struct allocno_hard_regs_node
68 /* Set up number of the node in preorder traversing of the forest. */
69 int preorder_num;
70 /* Used for different calculation like finding conflict size of an
71 allocno. */
72 int check;
73 /* Used for calculation of conflict size of an allocno. The
74 conflict size of the allocno is maximal number of given allocno
75 hard registers needed for allocation of the conflicting allocnos.
76 Given allocno is trivially colored if this number plus the number
77 of hard registers needed for given allocno is not greater than
78 the number of given allocno hard register set. */
79 int conflict_size;
80 /* The number of hard registers given by member hard_regs. */
81 int hard_regs_num;
82 /* The following member is used to form the final forest. */
83 bool used_p;
84 /* Pointer to the corresponding profitable hard registers. */
85 allocno_hard_regs_t hard_regs;
86 /* Parent, first subnode, previous and next node with the same
87 parent in the forest. */
88 allocno_hard_regs_node_t parent, first, prev, next;
91 /* Info about changing hard reg costs of an allocno. */
92 struct update_cost_record
94 /* Hard regno for which we changed the cost. */
95 int hard_regno;
96 /* Divisor used when we changed the cost of HARD_REGNO. */
97 int divisor;
98 /* Next record for given allocno. */
99 struct update_cost_record *next;
102 /* To decrease footprint of ira_allocno structure we store all data
103 needed only for coloring in the following structure. */
104 struct allocno_color_data
106 /* TRUE value means that the allocno was not removed yet from the
107 conflicting graph during colouring. */
108 unsigned int in_graph_p : 1;
109 /* TRUE if it is put on the stack to make other allocnos
110 colorable. */
111 unsigned int may_be_spilled_p : 1;
112 /* TRUE if the allocno is trivially colorable. */
113 unsigned int colorable_p : 1;
114 /* Number of hard registers of the allocno class really
115 available for the allocno allocation. It is number of the
116 profitable hard regs. */
117 int available_regs_num;
118 /* Allocnos in a bucket (used in coloring) chained by the following
119 two members. */
120 ira_allocno_t next_bucket_allocno;
121 ira_allocno_t prev_bucket_allocno;
122 /* Used for temporary purposes. */
123 int temp;
124 /* Used to exclude repeated processing. */
125 int last_process;
126 /* Profitable hard regs available for this pseudo allocation. It
127 means that the set excludes unavailable hard regs and hard regs
128 conflicting with given pseudo. They should be of the allocno
129 class. */
130 HARD_REG_SET profitable_hard_regs;
131 /* The allocno hard registers node. */
132 allocno_hard_regs_node_t hard_regs_node;
133 /* Array of structures allocno_hard_regs_subnode representing
134 given allocno hard registers node (the 1st element in the array)
135 and all its subnodes in the tree (forest) of allocno hard
136 register nodes (see comments above). */
137 int hard_regs_subnodes_start;
138 /* The length of the previous array. */
139 int hard_regs_subnodes_num;
140 /* Records about updating allocno hard reg costs from copies. If
141 the allocno did not get expected hard register, these records are
142 used to restore original hard reg costs of allocnos connected to
143 this allocno by copies. */
144 struct update_cost_record *update_cost_records;
147 /* See above. */
148 typedef struct allocno_color_data *allocno_color_data_t;
150 /* Container for storing allocno data concerning coloring. */
151 static allocno_color_data_t allocno_color_data;
153 /* Macro to access the data concerning coloring. */
154 #define ALLOCNO_COLOR_DATA(a) ((allocno_color_data_t) ALLOCNO_ADD_DATA (a))
156 /* Used for finding allocno colorability to exclude repeated allocno
157 processing and for updating preferencing to exclude repeated
158 allocno processing during assignment. */
159 static int curr_allocno_process;
161 /* This file contains code for regional graph coloring, spill/restore
162 code placement optimization, and code helping the reload pass to do
163 a better job. */
165 /* Bitmap of allocnos which should be colored. */
166 static bitmap coloring_allocno_bitmap;
168 /* Bitmap of allocnos which should be taken into account during
169 coloring. In general case it contains allocnos from
170 coloring_allocno_bitmap plus other already colored conflicting
171 allocnos. */
172 static bitmap consideration_allocno_bitmap;
174 /* All allocnos sorted according their priorities. */
175 static ira_allocno_t *sorted_allocnos;
177 /* Vec representing the stack of allocnos used during coloring. */
178 static vec<ira_allocno_t> allocno_stack_vec;
180 /* Helper for qsort comparison callbacks - return a positive integer if
181 X > Y, or a negative value otherwise. Use a conditional expression
182 instead of a difference computation to insulate from possible overflow
183 issues, e.g. X - Y < 0 for some X > 0 and Y < 0. */
184 #define SORTGT(x,y) (((x) > (y)) ? 1 : -1)
188 /* Definition of vector of allocno hard registers. */
190 /* Vector of unique allocno hard registers. */
191 static vec<allocno_hard_regs_t> allocno_hard_regs_vec;
193 struct allocno_hard_regs_hasher : typed_noop_remove <allocno_hard_regs>
195 typedef allocno_hard_regs value_type;
196 typedef allocno_hard_regs compare_type;
197 static inline hashval_t hash (const value_type *);
198 static inline bool equal (const value_type *, const compare_type *);
201 /* Returns hash value for allocno hard registers V. */
202 inline hashval_t
203 allocno_hard_regs_hasher::hash (const value_type *hv)
205 return iterative_hash (&hv->set, sizeof (HARD_REG_SET), 0);
208 /* Compares allocno hard registers V1 and V2. */
209 inline bool
210 allocno_hard_regs_hasher::equal (const value_type *hv1, const compare_type *hv2)
212 return hard_reg_set_equal_p (hv1->set, hv2->set);
215 /* Hash table of unique allocno hard registers. */
216 static hash_table <allocno_hard_regs_hasher> allocno_hard_regs_htab;
218 /* Return allocno hard registers in the hash table equal to HV. */
219 static allocno_hard_regs_t
220 find_hard_regs (allocno_hard_regs_t hv)
222 return allocno_hard_regs_htab.find (hv);
225 /* Insert allocno hard registers HV in the hash table (if it is not
226 there yet) and return the value which in the table. */
227 static allocno_hard_regs_t
228 insert_hard_regs (allocno_hard_regs_t hv)
230 allocno_hard_regs **slot = allocno_hard_regs_htab.find_slot (hv, INSERT);
232 if (*slot == NULL)
233 *slot = hv;
234 return *slot;
237 /* Initialize data concerning allocno hard registers. */
238 static void
239 init_allocno_hard_regs (void)
241 allocno_hard_regs_vec.create (200);
242 allocno_hard_regs_htab.create (200);
245 /* Add (or update info about) allocno hard registers with SET and
246 COST. */
247 static allocno_hard_regs_t
248 add_allocno_hard_regs (HARD_REG_SET set, HOST_WIDEST_INT cost)
250 struct allocno_hard_regs temp;
251 allocno_hard_regs_t hv;
253 gcc_assert (! hard_reg_set_empty_p (set));
254 COPY_HARD_REG_SET (temp.set, set);
255 if ((hv = find_hard_regs (&temp)) != NULL)
256 hv->cost += cost;
257 else
259 hv = ((struct allocno_hard_regs *)
260 ira_allocate (sizeof (struct allocno_hard_regs)));
261 COPY_HARD_REG_SET (hv->set, set);
262 hv->cost = cost;
263 allocno_hard_regs_vec.safe_push (hv);
264 insert_hard_regs (hv);
266 return hv;
269 /* Finalize data concerning allocno hard registers. */
270 static void
271 finish_allocno_hard_regs (void)
273 int i;
274 allocno_hard_regs_t hv;
276 for (i = 0;
277 allocno_hard_regs_vec.iterate (i, &hv);
278 i++)
279 ira_free (hv);
280 allocno_hard_regs_htab.dispose ();
281 allocno_hard_regs_vec.release ();
284 /* Sort hard regs according to their frequency of usage. */
285 static int
286 allocno_hard_regs_compare (const void *v1p, const void *v2p)
288 allocno_hard_regs_t hv1 = *(const allocno_hard_regs_t *) v1p;
289 allocno_hard_regs_t hv2 = *(const allocno_hard_regs_t *) v2p;
291 if (hv2->cost > hv1->cost)
292 return 1;
293 else if (hv2->cost < hv1->cost)
294 return -1;
295 else
296 return 0;
301 /* Used for finding a common ancestor of two allocno hard registers
302 nodes in the forest. We use the current value of
303 'node_check_tick' to mark all nodes from one node to the top and
304 then walking up from another node until we find a marked node.
306 It is also used to figure out allocno colorability as a mark that
307 we already reset value of member 'conflict_size' for the forest
308 node corresponding to the processed allocno. */
309 static int node_check_tick;
311 /* Roots of the forest containing hard register sets can be assigned
312 to allocnos. */
313 static allocno_hard_regs_node_t hard_regs_roots;
315 /* Definition of vector of allocno hard register nodes. */
317 /* Vector used to create the forest. */
318 static vec<allocno_hard_regs_node_t> hard_regs_node_vec;
320 /* Create and return allocno hard registers node containing allocno
321 hard registers HV. */
322 static allocno_hard_regs_node_t
323 create_new_allocno_hard_regs_node (allocno_hard_regs_t hv)
325 allocno_hard_regs_node_t new_node;
327 new_node = ((struct allocno_hard_regs_node *)
328 ira_allocate (sizeof (struct allocno_hard_regs_node)));
329 new_node->check = 0;
330 new_node->hard_regs = hv;
331 new_node->hard_regs_num = hard_reg_set_size (hv->set);
332 new_node->first = NULL;
333 new_node->used_p = false;
334 return new_node;
337 /* Add allocno hard registers node NEW_NODE to the forest on its level
338 given by ROOTS. */
339 static void
340 add_new_allocno_hard_regs_node_to_forest (allocno_hard_regs_node_t *roots,
341 allocno_hard_regs_node_t new_node)
343 new_node->next = *roots;
344 if (new_node->next != NULL)
345 new_node->next->prev = new_node;
346 new_node->prev = NULL;
347 *roots = new_node;
350 /* Add allocno hard registers HV (or its best approximation if it is
351 not possible) to the forest on its level given by ROOTS. */
352 static void
353 add_allocno_hard_regs_to_forest (allocno_hard_regs_node_t *roots,
354 allocno_hard_regs_t hv)
356 unsigned int i, start;
357 allocno_hard_regs_node_t node, prev, new_node;
358 HARD_REG_SET temp_set;
359 allocno_hard_regs_t hv2;
361 start = hard_regs_node_vec.length ();
362 for (node = *roots; node != NULL; node = node->next)
364 if (hard_reg_set_equal_p (hv->set, node->hard_regs->set))
365 return;
366 if (hard_reg_set_subset_p (hv->set, node->hard_regs->set))
368 add_allocno_hard_regs_to_forest (&node->first, hv);
369 return;
371 if (hard_reg_set_subset_p (node->hard_regs->set, hv->set))
372 hard_regs_node_vec.safe_push (node);
373 else if (hard_reg_set_intersect_p (hv->set, node->hard_regs->set))
375 COPY_HARD_REG_SET (temp_set, hv->set);
376 AND_HARD_REG_SET (temp_set, node->hard_regs->set);
377 hv2 = add_allocno_hard_regs (temp_set, hv->cost);
378 add_allocno_hard_regs_to_forest (&node->first, hv2);
381 if (hard_regs_node_vec.length ()
382 > start + 1)
384 /* Create a new node which contains nodes in hard_regs_node_vec. */
385 CLEAR_HARD_REG_SET (temp_set);
386 for (i = start;
387 i < hard_regs_node_vec.length ();
388 i++)
390 node = hard_regs_node_vec[i];
391 IOR_HARD_REG_SET (temp_set, node->hard_regs->set);
393 hv = add_allocno_hard_regs (temp_set, hv->cost);
394 new_node = create_new_allocno_hard_regs_node (hv);
395 prev = NULL;
396 for (i = start;
397 i < hard_regs_node_vec.length ();
398 i++)
400 node = hard_regs_node_vec[i];
401 if (node->prev == NULL)
402 *roots = node->next;
403 else
404 node->prev->next = node->next;
405 if (node->next != NULL)
406 node->next->prev = node->prev;
407 if (prev == NULL)
408 new_node->first = node;
409 else
410 prev->next = node;
411 node->prev = prev;
412 node->next = NULL;
413 prev = node;
415 add_new_allocno_hard_regs_node_to_forest (roots, new_node);
417 hard_regs_node_vec.truncate (start);
420 /* Add allocno hard registers nodes starting with the forest level
421 given by FIRST which contains biggest set inside SET. */
422 static void
423 collect_allocno_hard_regs_cover (allocno_hard_regs_node_t first,
424 HARD_REG_SET set)
426 allocno_hard_regs_node_t node;
428 ira_assert (first != NULL);
429 for (node = first; node != NULL; node = node->next)
430 if (hard_reg_set_subset_p (node->hard_regs->set, set))
431 hard_regs_node_vec.safe_push (node);
432 else if (hard_reg_set_intersect_p (set, node->hard_regs->set))
433 collect_allocno_hard_regs_cover (node->first, set);
436 /* Set up field parent as PARENT in all allocno hard registers nodes
437 in forest given by FIRST. */
438 static void
439 setup_allocno_hard_regs_nodes_parent (allocno_hard_regs_node_t first,
440 allocno_hard_regs_node_t parent)
442 allocno_hard_regs_node_t node;
444 for (node = first; node != NULL; node = node->next)
446 node->parent = parent;
447 setup_allocno_hard_regs_nodes_parent (node->first, node);
451 /* Return allocno hard registers node which is a first common ancestor
452 node of FIRST and SECOND in the forest. */
453 static allocno_hard_regs_node_t
454 first_common_ancestor_node (allocno_hard_regs_node_t first,
455 allocno_hard_regs_node_t second)
457 allocno_hard_regs_node_t node;
459 node_check_tick++;
460 for (node = first; node != NULL; node = node->parent)
461 node->check = node_check_tick;
462 for (node = second; node != NULL; node = node->parent)
463 if (node->check == node_check_tick)
464 return node;
465 return first_common_ancestor_node (second, first);
468 /* Print hard reg set SET to F. */
469 static void
470 print_hard_reg_set (FILE *f, HARD_REG_SET set, bool new_line_p)
472 int i, start;
474 for (start = -1, i = 0; i < FIRST_PSEUDO_REGISTER; i++)
476 if (TEST_HARD_REG_BIT (set, i))
478 if (i == 0 || ! TEST_HARD_REG_BIT (set, i - 1))
479 start = i;
481 if (start >= 0
482 && (i == FIRST_PSEUDO_REGISTER - 1 || ! TEST_HARD_REG_BIT (set, i)))
484 if (start == i - 1)
485 fprintf (f, " %d", start);
486 else if (start == i - 2)
487 fprintf (f, " %d %d", start, start + 1);
488 else
489 fprintf (f, " %d-%d", start, i - 1);
490 start = -1;
493 if (new_line_p)
494 fprintf (f, "\n");
497 /* Print allocno hard register subforest given by ROOTS and its LEVEL
498 to F. */
499 static void
500 print_hard_regs_subforest (FILE *f, allocno_hard_regs_node_t roots,
501 int level)
503 int i;
504 allocno_hard_regs_node_t node;
506 for (node = roots; node != NULL; node = node->next)
508 fprintf (f, " ");
509 for (i = 0; i < level * 2; i++)
510 fprintf (f, " ");
511 fprintf (f, "%d:(", node->preorder_num);
512 print_hard_reg_set (f, node->hard_regs->set, false);
513 fprintf (f, ")@" HOST_WIDEST_INT_PRINT_DEC "\n", node->hard_regs->cost);
514 print_hard_regs_subforest (f, node->first, level + 1);
518 /* Print the allocno hard register forest to F. */
519 static void
520 print_hard_regs_forest (FILE *f)
522 fprintf (f, " Hard reg set forest:\n");
523 print_hard_regs_subforest (f, hard_regs_roots, 1);
526 /* Print the allocno hard register forest to stderr. */
527 void
528 ira_debug_hard_regs_forest (void)
530 print_hard_regs_forest (stderr);
533 /* Remove unused allocno hard registers nodes from forest given by its
534 *ROOTS. */
535 static void
536 remove_unused_allocno_hard_regs_nodes (allocno_hard_regs_node_t *roots)
538 allocno_hard_regs_node_t node, prev, next, last;
540 for (prev = NULL, node = *roots; node != NULL; node = next)
542 next = node->next;
543 if (node->used_p)
545 remove_unused_allocno_hard_regs_nodes (&node->first);
546 prev = node;
548 else
550 for (last = node->first;
551 last != NULL && last->next != NULL;
552 last = last->next)
554 if (last != NULL)
556 if (prev == NULL)
557 *roots = node->first;
558 else
559 prev->next = node->first;
560 if (next != NULL)
561 next->prev = last;
562 last->next = next;
563 next = node->first;
565 else
567 if (prev == NULL)
568 *roots = next;
569 else
570 prev->next = next;
571 if (next != NULL)
572 next->prev = prev;
574 ira_free (node);
579 /* Set up fields preorder_num starting with START_NUM in all allocno
580 hard registers nodes in forest given by FIRST. Return biggest set
581 PREORDER_NUM increased by 1. */
582 static int
583 enumerate_allocno_hard_regs_nodes (allocno_hard_regs_node_t first,
584 allocno_hard_regs_node_t parent,
585 int start_num)
587 allocno_hard_regs_node_t node;
589 for (node = first; node != NULL; node = node->next)
591 node->preorder_num = start_num++;
592 node->parent = parent;
593 start_num = enumerate_allocno_hard_regs_nodes (node->first, node,
594 start_num);
596 return start_num;
599 /* Number of allocno hard registers nodes in the forest. */
600 static int allocno_hard_regs_nodes_num;
602 /* Table preorder number of allocno hard registers node in the forest
603 -> the allocno hard registers node. */
604 static allocno_hard_regs_node_t *allocno_hard_regs_nodes;
606 /* See below. */
607 typedef struct allocno_hard_regs_subnode *allocno_hard_regs_subnode_t;
609 /* The structure is used to describes all subnodes (not only immediate
610 ones) in the mentioned above tree for given allocno hard register
611 node. The usage of such data accelerates calculation of
612 colorability of given allocno. */
613 struct allocno_hard_regs_subnode
615 /* The conflict size of conflicting allocnos whose hard register
616 sets are equal sets (plus supersets if given node is given
617 allocno hard registers node) of one in the given node. */
618 int left_conflict_size;
619 /* The summary conflict size of conflicting allocnos whose hard
620 register sets are strict subsets of one in the given node.
621 Overall conflict size is
622 left_conflict_subnodes_size
623 + MIN (max_node_impact - left_conflict_subnodes_size,
624 left_conflict_size)
626 short left_conflict_subnodes_size;
627 short max_node_impact;
630 /* Container for hard regs subnodes of all allocnos. */
631 static allocno_hard_regs_subnode_t allocno_hard_regs_subnodes;
633 /* Table (preorder number of allocno hard registers node in the
634 forest, preorder number of allocno hard registers subnode) -> index
635 of the subnode relative to the node. -1 if it is not a
636 subnode. */
637 static int *allocno_hard_regs_subnode_index;
639 /* Setup arrays ALLOCNO_HARD_REGS_NODES and
640 ALLOCNO_HARD_REGS_SUBNODE_INDEX. */
641 static void
642 setup_allocno_hard_regs_subnode_index (allocno_hard_regs_node_t first)
644 allocno_hard_regs_node_t node, parent;
645 int index;
647 for (node = first; node != NULL; node = node->next)
649 allocno_hard_regs_nodes[node->preorder_num] = node;
650 for (parent = node; parent != NULL; parent = parent->parent)
652 index = parent->preorder_num * allocno_hard_regs_nodes_num;
653 allocno_hard_regs_subnode_index[index + node->preorder_num]
654 = node->preorder_num - parent->preorder_num;
656 setup_allocno_hard_regs_subnode_index (node->first);
660 /* Count all allocno hard registers nodes in tree ROOT. */
661 static int
662 get_allocno_hard_regs_subnodes_num (allocno_hard_regs_node_t root)
664 int len = 1;
666 for (root = root->first; root != NULL; root = root->next)
667 len += get_allocno_hard_regs_subnodes_num (root);
668 return len;
671 /* Build the forest of allocno hard registers nodes and assign each
672 allocno a node from the forest. */
673 static void
674 form_allocno_hard_regs_nodes_forest (void)
676 unsigned int i, j, size, len;
677 int start;
678 ira_allocno_t a;
679 allocno_hard_regs_t hv;
680 bitmap_iterator bi;
681 HARD_REG_SET temp;
682 allocno_hard_regs_node_t node, allocno_hard_regs_node;
683 allocno_color_data_t allocno_data;
685 node_check_tick = 0;
686 init_allocno_hard_regs ();
687 hard_regs_roots = NULL;
688 hard_regs_node_vec.create (100);
689 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
690 if (! TEST_HARD_REG_BIT (ira_no_alloc_regs, i))
692 CLEAR_HARD_REG_SET (temp);
693 SET_HARD_REG_BIT (temp, i);
694 hv = add_allocno_hard_regs (temp, 0);
695 node = create_new_allocno_hard_regs_node (hv);
696 add_new_allocno_hard_regs_node_to_forest (&hard_regs_roots, node);
698 start = allocno_hard_regs_vec.length ();
699 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
701 a = ira_allocnos[i];
702 allocno_data = ALLOCNO_COLOR_DATA (a);
704 if (hard_reg_set_empty_p (allocno_data->profitable_hard_regs))
705 continue;
706 hv = (add_allocno_hard_regs
707 (allocno_data->profitable_hard_regs,
708 ALLOCNO_MEMORY_COST (a) - ALLOCNO_CLASS_COST (a)));
710 SET_HARD_REG_SET (temp);
711 AND_COMPL_HARD_REG_SET (temp, ira_no_alloc_regs);
712 add_allocno_hard_regs (temp, 0);
713 qsort (allocno_hard_regs_vec.address () + start,
714 allocno_hard_regs_vec.length () - start,
715 sizeof (allocno_hard_regs_t), allocno_hard_regs_compare);
716 for (i = start;
717 allocno_hard_regs_vec.iterate (i, &hv);
718 i++)
720 add_allocno_hard_regs_to_forest (&hard_regs_roots, hv);
721 ira_assert (hard_regs_node_vec.length () == 0);
723 /* We need to set up parent fields for right work of
724 first_common_ancestor_node. */
725 setup_allocno_hard_regs_nodes_parent (hard_regs_roots, NULL);
726 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
728 a = ira_allocnos[i];
729 allocno_data = ALLOCNO_COLOR_DATA (a);
730 if (hard_reg_set_empty_p (allocno_data->profitable_hard_regs))
731 continue;
732 hard_regs_node_vec.truncate (0);
733 collect_allocno_hard_regs_cover (hard_regs_roots,
734 allocno_data->profitable_hard_regs);
735 allocno_hard_regs_node = NULL;
736 for (j = 0; hard_regs_node_vec.iterate (j, &node); j++)
737 allocno_hard_regs_node
738 = (j == 0
739 ? node
740 : first_common_ancestor_node (node, allocno_hard_regs_node));
741 /* That is a temporary storage. */
742 allocno_hard_regs_node->used_p = true;
743 allocno_data->hard_regs_node = allocno_hard_regs_node;
745 ira_assert (hard_regs_roots->next == NULL);
746 hard_regs_roots->used_p = true;
747 remove_unused_allocno_hard_regs_nodes (&hard_regs_roots);
748 allocno_hard_regs_nodes_num
749 = enumerate_allocno_hard_regs_nodes (hard_regs_roots, NULL, 0);
750 allocno_hard_regs_nodes
751 = ((allocno_hard_regs_node_t *)
752 ira_allocate (allocno_hard_regs_nodes_num
753 * sizeof (allocno_hard_regs_node_t)));
754 size = allocno_hard_regs_nodes_num * allocno_hard_regs_nodes_num;
755 allocno_hard_regs_subnode_index
756 = (int *) ira_allocate (size * sizeof (int));
757 for (i = 0; i < size; i++)
758 allocno_hard_regs_subnode_index[i] = -1;
759 setup_allocno_hard_regs_subnode_index (hard_regs_roots);
760 start = 0;
761 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
763 a = ira_allocnos[i];
764 allocno_data = ALLOCNO_COLOR_DATA (a);
765 if (hard_reg_set_empty_p (allocno_data->profitable_hard_regs))
766 continue;
767 len = get_allocno_hard_regs_subnodes_num (allocno_data->hard_regs_node);
768 allocno_data->hard_regs_subnodes_start = start;
769 allocno_data->hard_regs_subnodes_num = len;
770 start += len;
772 allocno_hard_regs_subnodes
773 = ((allocno_hard_regs_subnode_t)
774 ira_allocate (sizeof (struct allocno_hard_regs_subnode) * start));
775 hard_regs_node_vec.release ();
778 /* Free tree of allocno hard registers nodes given by its ROOT. */
779 static void
780 finish_allocno_hard_regs_nodes_tree (allocno_hard_regs_node_t root)
782 allocno_hard_regs_node_t child, next;
784 for (child = root->first; child != NULL; child = next)
786 next = child->next;
787 finish_allocno_hard_regs_nodes_tree (child);
789 ira_free (root);
792 /* Finish work with the forest of allocno hard registers nodes. */
793 static void
794 finish_allocno_hard_regs_nodes_forest (void)
796 allocno_hard_regs_node_t node, next;
798 ira_free (allocno_hard_regs_subnodes);
799 for (node = hard_regs_roots; node != NULL; node = next)
801 next = node->next;
802 finish_allocno_hard_regs_nodes_tree (node);
804 ira_free (allocno_hard_regs_nodes);
805 ira_free (allocno_hard_regs_subnode_index);
806 finish_allocno_hard_regs ();
809 /* Set up left conflict sizes and left conflict subnodes sizes of hard
810 registers subnodes of allocno A. Return TRUE if allocno A is
811 trivially colorable. */
812 static bool
813 setup_left_conflict_sizes_p (ira_allocno_t a)
815 int i, k, nobj, start;
816 int conflict_size, left_conflict_subnodes_size, node_preorder_num;
817 allocno_color_data_t data;
818 HARD_REG_SET profitable_hard_regs;
819 allocno_hard_regs_subnode_t subnodes;
820 allocno_hard_regs_node_t node;
821 HARD_REG_SET node_set;
823 nobj = ALLOCNO_NUM_OBJECTS (a);
824 conflict_size = 0;
825 data = ALLOCNO_COLOR_DATA (a);
826 subnodes = allocno_hard_regs_subnodes + data->hard_regs_subnodes_start;
827 COPY_HARD_REG_SET (profitable_hard_regs, data->profitable_hard_regs);
828 node = data->hard_regs_node;
829 node_preorder_num = node->preorder_num;
830 COPY_HARD_REG_SET (node_set, node->hard_regs->set);
831 node_check_tick++;
832 for (k = 0; k < nobj; k++)
834 ira_object_t obj = ALLOCNO_OBJECT (a, k);
835 ira_object_t conflict_obj;
836 ira_object_conflict_iterator oci;
838 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
840 int size;
841 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
842 allocno_hard_regs_node_t conflict_node, temp_node;
843 HARD_REG_SET conflict_node_set;
844 allocno_color_data_t conflict_data;
846 conflict_data = ALLOCNO_COLOR_DATA (conflict_a);
847 if (! ALLOCNO_COLOR_DATA (conflict_a)->in_graph_p
848 || ! hard_reg_set_intersect_p (profitable_hard_regs,
849 conflict_data
850 ->profitable_hard_regs))
851 continue;
852 conflict_node = conflict_data->hard_regs_node;
853 COPY_HARD_REG_SET (conflict_node_set, conflict_node->hard_regs->set);
854 if (hard_reg_set_subset_p (node_set, conflict_node_set))
855 temp_node = node;
856 else
858 ira_assert (hard_reg_set_subset_p (conflict_node_set, node_set));
859 temp_node = conflict_node;
861 if (temp_node->check != node_check_tick)
863 temp_node->check = node_check_tick;
864 temp_node->conflict_size = 0;
866 size = (ira_reg_class_max_nregs
867 [ALLOCNO_CLASS (conflict_a)][ALLOCNO_MODE (conflict_a)]);
868 if (ALLOCNO_NUM_OBJECTS (conflict_a) > 1)
869 /* We will deal with the subwords individually. */
870 size = 1;
871 temp_node->conflict_size += size;
874 for (i = 0; i < data->hard_regs_subnodes_num; i++)
876 allocno_hard_regs_node_t temp_node;
878 temp_node = allocno_hard_regs_nodes[i + node_preorder_num];
879 ira_assert (temp_node->preorder_num == i + node_preorder_num);
880 subnodes[i].left_conflict_size = (temp_node->check != node_check_tick
881 ? 0 : temp_node->conflict_size);
882 if (hard_reg_set_subset_p (temp_node->hard_regs->set,
883 profitable_hard_regs))
884 subnodes[i].max_node_impact = temp_node->hard_regs_num;
885 else
887 HARD_REG_SET temp_set;
888 int j, n, hard_regno;
889 enum reg_class aclass;
891 COPY_HARD_REG_SET (temp_set, temp_node->hard_regs->set);
892 AND_HARD_REG_SET (temp_set, profitable_hard_regs);
893 aclass = ALLOCNO_CLASS (a);
894 for (n = 0, j = ira_class_hard_regs_num[aclass] - 1; j >= 0; j--)
896 hard_regno = ira_class_hard_regs[aclass][j];
897 if (TEST_HARD_REG_BIT (temp_set, hard_regno))
898 n++;
900 subnodes[i].max_node_impact = n;
902 subnodes[i].left_conflict_subnodes_size = 0;
904 start = node_preorder_num * allocno_hard_regs_nodes_num;
905 for (i = data->hard_regs_subnodes_num - 1; i >= 0; i--)
907 int size, parent_i;
908 allocno_hard_regs_node_t parent;
910 size = (subnodes[i].left_conflict_subnodes_size
911 + MIN (subnodes[i].max_node_impact
912 - subnodes[i].left_conflict_subnodes_size,
913 subnodes[i].left_conflict_size));
914 parent = allocno_hard_regs_nodes[i + node_preorder_num]->parent;
915 if (parent == NULL)
916 continue;
917 parent_i
918 = allocno_hard_regs_subnode_index[start + parent->preorder_num];
919 if (parent_i < 0)
920 continue;
921 subnodes[parent_i].left_conflict_subnodes_size += size;
923 left_conflict_subnodes_size = subnodes[0].left_conflict_subnodes_size;
924 conflict_size
925 += (left_conflict_subnodes_size
926 + MIN (subnodes[0].max_node_impact - left_conflict_subnodes_size,
927 subnodes[0].left_conflict_size));
928 conflict_size += ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)];
929 data->colorable_p = conflict_size <= data->available_regs_num;
930 return data->colorable_p;
933 /* Update left conflict sizes of hard registers subnodes of allocno A
934 after removing allocno REMOVED_A with SIZE from the conflict graph.
935 Return TRUE if A is trivially colorable. */
936 static bool
937 update_left_conflict_sizes_p (ira_allocno_t a,
938 ira_allocno_t removed_a, int size)
940 int i, conflict_size, before_conflict_size, diff, start;
941 int node_preorder_num, parent_i;
942 allocno_hard_regs_node_t node, removed_node, parent;
943 allocno_hard_regs_subnode_t subnodes;
944 allocno_color_data_t data = ALLOCNO_COLOR_DATA (a);
946 ira_assert (! data->colorable_p);
947 node = data->hard_regs_node;
948 node_preorder_num = node->preorder_num;
949 removed_node = ALLOCNO_COLOR_DATA (removed_a)->hard_regs_node;
950 ira_assert (hard_reg_set_subset_p (removed_node->hard_regs->set,
951 node->hard_regs->set)
952 || hard_reg_set_subset_p (node->hard_regs->set,
953 removed_node->hard_regs->set));
954 start = node_preorder_num * allocno_hard_regs_nodes_num;
955 i = allocno_hard_regs_subnode_index[start + removed_node->preorder_num];
956 if (i < 0)
957 i = 0;
958 subnodes = allocno_hard_regs_subnodes + data->hard_regs_subnodes_start;
959 before_conflict_size
960 = (subnodes[i].left_conflict_subnodes_size
961 + MIN (subnodes[i].max_node_impact
962 - subnodes[i].left_conflict_subnodes_size,
963 subnodes[i].left_conflict_size));
964 subnodes[i].left_conflict_size -= size;
965 for (;;)
967 conflict_size
968 = (subnodes[i].left_conflict_subnodes_size
969 + MIN (subnodes[i].max_node_impact
970 - subnodes[i].left_conflict_subnodes_size,
971 subnodes[i].left_conflict_size));
972 if ((diff = before_conflict_size - conflict_size) == 0)
973 break;
974 ira_assert (conflict_size < before_conflict_size);
975 parent = allocno_hard_regs_nodes[i + node_preorder_num]->parent;
976 if (parent == NULL)
977 break;
978 parent_i
979 = allocno_hard_regs_subnode_index[start + parent->preorder_num];
980 if (parent_i < 0)
981 break;
982 i = parent_i;
983 before_conflict_size
984 = (subnodes[i].left_conflict_subnodes_size
985 + MIN (subnodes[i].max_node_impact
986 - subnodes[i].left_conflict_subnodes_size,
987 subnodes[i].left_conflict_size));
988 subnodes[i].left_conflict_subnodes_size -= diff;
990 if (i != 0
991 || (conflict_size
992 + ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]
993 > data->available_regs_num))
994 return false;
995 data->colorable_p = true;
996 return true;
999 /* Return true if allocno A has empty profitable hard regs. */
1000 static bool
1001 empty_profitable_hard_regs (ira_allocno_t a)
1003 allocno_color_data_t data = ALLOCNO_COLOR_DATA (a);
1005 return hard_reg_set_empty_p (data->profitable_hard_regs);
1008 /* Set up profitable hard registers for each allocno being
1009 colored. */
1010 static void
1011 setup_profitable_hard_regs (void)
1013 unsigned int i;
1014 int j, k, nobj, hard_regno, nregs, class_size;
1015 ira_allocno_t a;
1016 bitmap_iterator bi;
1017 enum reg_class aclass;
1018 enum machine_mode mode;
1019 allocno_color_data_t data;
1021 /* Initial set up from allocno classes and explicitly conflicting
1022 hard regs. */
1023 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
1025 a = ira_allocnos[i];
1026 if ((aclass = ALLOCNO_CLASS (a)) == NO_REGS)
1027 continue;
1028 data = ALLOCNO_COLOR_DATA (a);
1029 if (ALLOCNO_UPDATED_HARD_REG_COSTS (a) == NULL
1030 && ALLOCNO_CLASS_COST (a) > ALLOCNO_MEMORY_COST (a))
1031 CLEAR_HARD_REG_SET (data->profitable_hard_regs);
1032 else
1034 mode = ALLOCNO_MODE (a);
1035 COPY_HARD_REG_SET (data->profitable_hard_regs,
1036 ira_useful_class_mode_regs[aclass][mode]);
1037 nobj = ALLOCNO_NUM_OBJECTS (a);
1038 for (k = 0; k < nobj; k++)
1040 ira_object_t obj = ALLOCNO_OBJECT (a, k);
1042 AND_COMPL_HARD_REG_SET (data->profitable_hard_regs,
1043 OBJECT_TOTAL_CONFLICT_HARD_REGS (obj));
1047 /* Exclude hard regs already assigned for conflicting objects. */
1048 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, i, bi)
1050 a = ira_allocnos[i];
1051 if ((aclass = ALLOCNO_CLASS (a)) == NO_REGS
1052 || ! ALLOCNO_ASSIGNED_P (a)
1053 || (hard_regno = ALLOCNO_HARD_REGNO (a)) < 0)
1054 continue;
1055 mode = ALLOCNO_MODE (a);
1056 nregs = hard_regno_nregs[hard_regno][mode];
1057 nobj = ALLOCNO_NUM_OBJECTS (a);
1058 for (k = 0; k < nobj; k++)
1060 ira_object_t obj = ALLOCNO_OBJECT (a, k);
1061 ira_object_t conflict_obj;
1062 ira_object_conflict_iterator oci;
1064 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
1066 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
1068 /* We can process the conflict allocno repeatedly with
1069 the same result. */
1070 if (nregs == nobj && nregs > 1)
1072 int num = OBJECT_SUBWORD (conflict_obj);
1074 if (REG_WORDS_BIG_ENDIAN)
1075 CLEAR_HARD_REG_BIT
1076 (ALLOCNO_COLOR_DATA (conflict_a)->profitable_hard_regs,
1077 hard_regno + nobj - num - 1);
1078 else
1079 CLEAR_HARD_REG_BIT
1080 (ALLOCNO_COLOR_DATA (conflict_a)->profitable_hard_regs,
1081 hard_regno + num);
1083 else
1084 AND_COMPL_HARD_REG_SET
1085 (ALLOCNO_COLOR_DATA (conflict_a)->profitable_hard_regs,
1086 ira_reg_mode_hard_regset[hard_regno][mode]);
1090 /* Exclude too costly hard regs. */
1091 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
1093 int min_cost = INT_MAX;
1094 int *costs;
1096 a = ira_allocnos[i];
1097 if ((aclass = ALLOCNO_CLASS (a)) == NO_REGS
1098 || empty_profitable_hard_regs (a))
1099 continue;
1100 data = ALLOCNO_COLOR_DATA (a);
1101 mode = ALLOCNO_MODE (a);
1102 if ((costs = ALLOCNO_UPDATED_HARD_REG_COSTS (a)) != NULL
1103 || (costs = ALLOCNO_HARD_REG_COSTS (a)) != NULL)
1105 class_size = ira_class_hard_regs_num[aclass];
1106 for (j = 0; j < class_size; j++)
1108 hard_regno = ira_class_hard_regs[aclass][j];
1109 if (! TEST_HARD_REG_BIT (data->profitable_hard_regs,
1110 hard_regno))
1111 continue;
1112 if (ALLOCNO_UPDATED_MEMORY_COST (a) < costs[j])
1113 CLEAR_HARD_REG_BIT (data->profitable_hard_regs,
1114 hard_regno);
1115 else if (min_cost > costs[j])
1116 min_cost = costs[j];
1119 else if (ALLOCNO_UPDATED_MEMORY_COST (a)
1120 < ALLOCNO_UPDATED_CLASS_COST (a))
1121 CLEAR_HARD_REG_SET (data->profitable_hard_regs);
1122 if (ALLOCNO_UPDATED_CLASS_COST (a) > min_cost)
1123 ALLOCNO_UPDATED_CLASS_COST (a) = min_cost;
1129 /* This page contains functions used to choose hard registers for
1130 allocnos. */
1132 /* Pool for update cost records. */
1133 static alloc_pool update_cost_record_pool;
1135 /* Initiate update cost records. */
1136 static void
1137 init_update_cost_records (void)
1139 update_cost_record_pool
1140 = create_alloc_pool ("update cost records",
1141 sizeof (struct update_cost_record), 100);
1144 /* Return new update cost record with given params. */
1145 static struct update_cost_record *
1146 get_update_cost_record (int hard_regno, int divisor,
1147 struct update_cost_record *next)
1149 struct update_cost_record *record;
1151 record = (struct update_cost_record *) pool_alloc (update_cost_record_pool);
1152 record->hard_regno = hard_regno;
1153 record->divisor = divisor;
1154 record->next = next;
1155 return record;
1158 /* Free memory for all records in LIST. */
1159 static void
1160 free_update_cost_record_list (struct update_cost_record *list)
1162 struct update_cost_record *next;
1164 while (list != NULL)
1166 next = list->next;
1167 pool_free (update_cost_record_pool, list);
1168 list = next;
1172 /* Free memory allocated for all update cost records. */
1173 static void
1174 finish_update_cost_records (void)
1176 free_alloc_pool (update_cost_record_pool);
1179 /* Array whose element value is TRUE if the corresponding hard
1180 register was already allocated for an allocno. */
1181 static bool allocated_hardreg_p[FIRST_PSEUDO_REGISTER];
1183 /* Describes one element in a queue of allocnos whose costs need to be
1184 updated. Each allocno in the queue is known to have an allocno
1185 class. */
1186 struct update_cost_queue_elem
1188 /* This element is in the queue iff CHECK == update_cost_check. */
1189 int check;
1191 /* COST_HOP_DIVISOR**N, where N is the length of the shortest path
1192 connecting this allocno to the one being allocated. */
1193 int divisor;
1195 /* Allocno from which we are chaning costs of connected allocnos.
1196 It is used not go back in graph of allocnos connected by
1197 copies. */
1198 ira_allocno_t from;
1200 /* The next allocno in the queue, or null if this is the last element. */
1201 ira_allocno_t next;
1204 /* The first element in a queue of allocnos whose copy costs need to be
1205 updated. Null if the queue is empty. */
1206 static ira_allocno_t update_cost_queue;
1208 /* The last element in the queue described by update_cost_queue.
1209 Not valid if update_cost_queue is null. */
1210 static struct update_cost_queue_elem *update_cost_queue_tail;
1212 /* A pool of elements in the queue described by update_cost_queue.
1213 Elements are indexed by ALLOCNO_NUM. */
1214 static struct update_cost_queue_elem *update_cost_queue_elems;
1216 /* The current value of update_costs_from_copies call count. */
1217 static int update_cost_check;
1219 /* Allocate and initialize data necessary for function
1220 update_costs_from_copies. */
1221 static void
1222 initiate_cost_update (void)
1224 size_t size;
1226 size = ira_allocnos_num * sizeof (struct update_cost_queue_elem);
1227 update_cost_queue_elems
1228 = (struct update_cost_queue_elem *) ira_allocate (size);
1229 memset (update_cost_queue_elems, 0, size);
1230 update_cost_check = 0;
1231 init_update_cost_records ();
1234 /* Deallocate data used by function update_costs_from_copies. */
1235 static void
1236 finish_cost_update (void)
1238 ira_free (update_cost_queue_elems);
1239 finish_update_cost_records ();
1242 /* When we traverse allocnos to update hard register costs, the cost
1243 divisor will be multiplied by the following macro value for each
1244 hop from given allocno to directly connected allocnos. */
1245 #define COST_HOP_DIVISOR 4
1247 /* Start a new cost-updating pass. */
1248 static void
1249 start_update_cost (void)
1251 update_cost_check++;
1252 update_cost_queue = NULL;
1255 /* Add (ALLOCNO, FROM, DIVISOR) to the end of update_cost_queue, unless
1256 ALLOCNO is already in the queue, or has NO_REGS class. */
1257 static inline void
1258 queue_update_cost (ira_allocno_t allocno, ira_allocno_t from, int divisor)
1260 struct update_cost_queue_elem *elem;
1262 elem = &update_cost_queue_elems[ALLOCNO_NUM (allocno)];
1263 if (elem->check != update_cost_check
1264 && ALLOCNO_CLASS (allocno) != NO_REGS)
1266 elem->check = update_cost_check;
1267 elem->from = from;
1268 elem->divisor = divisor;
1269 elem->next = NULL;
1270 if (update_cost_queue == NULL)
1271 update_cost_queue = allocno;
1272 else
1273 update_cost_queue_tail->next = allocno;
1274 update_cost_queue_tail = elem;
1278 /* Try to remove the first element from update_cost_queue. Return
1279 false if the queue was empty, otherwise make (*ALLOCNO, *FROM,
1280 *DIVISOR) describe the removed element. */
1281 static inline bool
1282 get_next_update_cost (ira_allocno_t *allocno, ira_allocno_t *from, int *divisor)
1284 struct update_cost_queue_elem *elem;
1286 if (update_cost_queue == NULL)
1287 return false;
1289 *allocno = update_cost_queue;
1290 elem = &update_cost_queue_elems[ALLOCNO_NUM (*allocno)];
1291 *from = elem->from;
1292 *divisor = elem->divisor;
1293 update_cost_queue = elem->next;
1294 return true;
1297 /* Increase costs of HARD_REGNO by UPDATE_COST for ALLOCNO. Return
1298 true if we really modified the cost. */
1299 static bool
1300 update_allocno_cost (ira_allocno_t allocno, int hard_regno, int update_cost)
1302 int i;
1303 enum reg_class aclass = ALLOCNO_CLASS (allocno);
1305 i = ira_class_hard_reg_index[aclass][hard_regno];
1306 if (i < 0)
1307 return false;
1308 ira_allocate_and_set_or_copy_costs
1309 (&ALLOCNO_UPDATED_HARD_REG_COSTS (allocno), aclass,
1310 ALLOCNO_UPDATED_CLASS_COST (allocno),
1311 ALLOCNO_HARD_REG_COSTS (allocno));
1312 ira_allocate_and_set_or_copy_costs
1313 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (allocno),
1314 aclass, 0, ALLOCNO_CONFLICT_HARD_REG_COSTS (allocno));
1315 ALLOCNO_UPDATED_HARD_REG_COSTS (allocno)[i] += update_cost;
1316 ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (allocno)[i] += update_cost;
1317 return true;
1320 /* Update (decrease if DECR_P) HARD_REGNO cost of allocnos connected
1321 by copies to ALLOCNO to increase chances to remove some copies as
1322 the result of subsequent assignment. Record cost updates if
1323 RECORD_P is true. */
1324 static void
1325 update_costs_from_allocno (ira_allocno_t allocno, int hard_regno,
1326 int divisor, bool decr_p, bool record_p)
1328 int cost, update_cost;
1329 enum machine_mode mode;
1330 enum reg_class rclass, aclass;
1331 ira_allocno_t another_allocno, from = NULL;
1332 ira_copy_t cp, next_cp;
1334 rclass = REGNO_REG_CLASS (hard_regno);
1337 mode = ALLOCNO_MODE (allocno);
1338 ira_init_register_move_cost_if_necessary (mode);
1339 for (cp = ALLOCNO_COPIES (allocno); cp != NULL; cp = next_cp)
1341 if (cp->first == allocno)
1343 next_cp = cp->next_first_allocno_copy;
1344 another_allocno = cp->second;
1346 else if (cp->second == allocno)
1348 next_cp = cp->next_second_allocno_copy;
1349 another_allocno = cp->first;
1351 else
1352 gcc_unreachable ();
1354 if (another_allocno == from)
1355 continue;
1357 aclass = ALLOCNO_CLASS (another_allocno);
1358 if (! TEST_HARD_REG_BIT (reg_class_contents[aclass],
1359 hard_regno)
1360 || ALLOCNO_ASSIGNED_P (another_allocno))
1361 continue;
1363 cost = (cp->second == allocno
1364 ? ira_register_move_cost[mode][rclass][aclass]
1365 : ira_register_move_cost[mode][aclass][rclass]);
1366 if (decr_p)
1367 cost = -cost;
1369 update_cost = cp->freq * cost / divisor;
1370 if (update_cost == 0)
1371 continue;
1373 if (! update_allocno_cost (another_allocno, hard_regno, update_cost))
1374 continue;
1375 queue_update_cost (another_allocno, allocno, divisor * COST_HOP_DIVISOR);
1376 if (record_p && ALLOCNO_COLOR_DATA (another_allocno) != NULL)
1377 ALLOCNO_COLOR_DATA (another_allocno)->update_cost_records
1378 = get_update_cost_record (hard_regno, divisor,
1379 ALLOCNO_COLOR_DATA (another_allocno)
1380 ->update_cost_records);
1383 while (get_next_update_cost (&allocno, &from, &divisor));
1386 /* Decrease preferred ALLOCNO hard register costs and costs of
1387 allocnos connected to ALLOCNO through copy. */
1388 static void
1389 update_costs_from_prefs (ira_allocno_t allocno)
1391 ira_pref_t pref;
1393 start_update_cost ();
1394 for (pref = ALLOCNO_PREFS (allocno); pref != NULL; pref = pref->next_pref)
1395 update_costs_from_allocno (allocno, pref->hard_regno,
1396 COST_HOP_DIVISOR, true, true);
1399 /* Update (decrease if DECR_P) the cost of allocnos connected to
1400 ALLOCNO through copies to increase chances to remove some copies as
1401 the result of subsequent assignment. ALLOCNO was just assigned to
1402 a hard register. Record cost updates if RECORD_P is true. */
1403 static void
1404 update_costs_from_copies (ira_allocno_t allocno, bool decr_p, bool record_p)
1406 int hard_regno;
1408 hard_regno = ALLOCNO_HARD_REGNO (allocno);
1409 ira_assert (hard_regno >= 0 && ALLOCNO_CLASS (allocno) != NO_REGS);
1410 start_update_cost ();
1411 update_costs_from_allocno (allocno, hard_regno, 1, decr_p, record_p);
1414 /* Restore costs of allocnos connected to ALLOCNO by copies as it was
1415 before updating costs of these allocnos from given allocno. This
1416 is a wise thing to do as if given allocno did not get an expected
1417 hard reg, using smaller cost of the hard reg for allocnos connected
1418 by copies to given allocno becomes actually misleading. Free all
1419 update cost records for ALLOCNO as we don't need them anymore. */
1420 static void
1421 restore_costs_from_copies (ira_allocno_t allocno)
1423 struct update_cost_record *records, *curr;
1425 if (ALLOCNO_COLOR_DATA (allocno) == NULL)
1426 return;
1427 records = ALLOCNO_COLOR_DATA (allocno)->update_cost_records;
1428 start_update_cost ();
1429 for (curr = records; curr != NULL; curr = curr->next)
1430 update_costs_from_allocno (allocno, curr->hard_regno,
1431 curr->divisor, true, false);
1432 free_update_cost_record_list (records);
1433 ALLOCNO_COLOR_DATA (allocno)->update_cost_records = NULL;
1436 /* This function updates COSTS (decrease if DECR_P) for hard_registers
1437 of ACLASS by conflict costs of the unassigned allocnos
1438 connected by copies with allocnos in update_cost_queue. This
1439 update increases chances to remove some copies. */
1440 static void
1441 update_conflict_hard_regno_costs (int *costs, enum reg_class aclass,
1442 bool decr_p)
1444 int i, cost, class_size, freq, mult, div, divisor;
1445 int index, hard_regno;
1446 int *conflict_costs;
1447 bool cont_p;
1448 enum reg_class another_aclass;
1449 ira_allocno_t allocno, another_allocno, from;
1450 ira_copy_t cp, next_cp;
1452 while (get_next_update_cost (&allocno, &from, &divisor))
1453 for (cp = ALLOCNO_COPIES (allocno); cp != NULL; cp = next_cp)
1455 if (cp->first == allocno)
1457 next_cp = cp->next_first_allocno_copy;
1458 another_allocno = cp->second;
1460 else if (cp->second == allocno)
1462 next_cp = cp->next_second_allocno_copy;
1463 another_allocno = cp->first;
1465 else
1466 gcc_unreachable ();
1468 if (another_allocno == from)
1469 continue;
1471 another_aclass = ALLOCNO_CLASS (another_allocno);
1472 if (! ira_reg_classes_intersect_p[aclass][another_aclass]
1473 || ALLOCNO_ASSIGNED_P (another_allocno)
1474 || ALLOCNO_COLOR_DATA (another_allocno)->may_be_spilled_p)
1475 continue;
1476 class_size = ira_class_hard_regs_num[another_aclass];
1477 ira_allocate_and_copy_costs
1478 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (another_allocno),
1479 another_aclass, ALLOCNO_CONFLICT_HARD_REG_COSTS (another_allocno));
1480 conflict_costs
1481 = ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (another_allocno);
1482 if (conflict_costs == NULL)
1483 cont_p = true;
1484 else
1486 mult = cp->freq;
1487 freq = ALLOCNO_FREQ (another_allocno);
1488 if (freq == 0)
1489 freq = 1;
1490 div = freq * divisor;
1491 cont_p = false;
1492 for (i = class_size - 1; i >= 0; i--)
1494 hard_regno = ira_class_hard_regs[another_aclass][i];
1495 ira_assert (hard_regno >= 0);
1496 index = ira_class_hard_reg_index[aclass][hard_regno];
1497 if (index < 0)
1498 continue;
1499 cost = conflict_costs [i] * mult / div;
1500 if (cost == 0)
1501 continue;
1502 cont_p = true;
1503 if (decr_p)
1504 cost = -cost;
1505 costs[index] += cost;
1508 /* Probably 5 hops will be enough. */
1509 if (cont_p
1510 && divisor <= (COST_HOP_DIVISOR
1511 * COST_HOP_DIVISOR
1512 * COST_HOP_DIVISOR
1513 * COST_HOP_DIVISOR))
1514 queue_update_cost (another_allocno, allocno, divisor * COST_HOP_DIVISOR);
1518 /* Set up conflicting (through CONFLICT_REGS) for each object of
1519 allocno A and the start allocno profitable regs (through
1520 START_PROFITABLE_REGS). Remember that the start profitable regs
1521 exclude hard regs which can not hold value of mode of allocno A.
1522 This covers mostly cases when multi-register value should be
1523 aligned. */
1524 static inline void
1525 get_conflict_and_start_profitable_regs (ira_allocno_t a, bool retry_p,
1526 HARD_REG_SET *conflict_regs,
1527 HARD_REG_SET *start_profitable_regs)
1529 int i, nwords;
1530 ira_object_t obj;
1532 nwords = ALLOCNO_NUM_OBJECTS (a);
1533 for (i = 0; i < nwords; i++)
1535 obj = ALLOCNO_OBJECT (a, i);
1536 COPY_HARD_REG_SET (conflict_regs[i],
1537 OBJECT_TOTAL_CONFLICT_HARD_REGS (obj));
1539 if (retry_p)
1541 COPY_HARD_REG_SET (*start_profitable_regs,
1542 reg_class_contents[ALLOCNO_CLASS (a)]);
1543 AND_COMPL_HARD_REG_SET (*start_profitable_regs,
1544 ira_prohibited_class_mode_regs
1545 [ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]);
1547 else
1548 COPY_HARD_REG_SET (*start_profitable_regs,
1549 ALLOCNO_COLOR_DATA (a)->profitable_hard_regs);
1552 /* Return true if HARD_REGNO is ok for assigning to allocno A with
1553 PROFITABLE_REGS and whose objects have CONFLICT_REGS. */
1554 static inline bool
1555 check_hard_reg_p (ira_allocno_t a, int hard_regno,
1556 HARD_REG_SET *conflict_regs, HARD_REG_SET profitable_regs)
1558 int j, nwords, nregs;
1559 enum reg_class aclass;
1560 enum machine_mode mode;
1562 aclass = ALLOCNO_CLASS (a);
1563 mode = ALLOCNO_MODE (a);
1564 if (TEST_HARD_REG_BIT (ira_prohibited_class_mode_regs[aclass][mode],
1565 hard_regno))
1566 return false;
1567 /* Checking only profitable hard regs. */
1568 if (! TEST_HARD_REG_BIT (profitable_regs, hard_regno))
1569 return false;
1570 nregs = hard_regno_nregs[hard_regno][mode];
1571 nwords = ALLOCNO_NUM_OBJECTS (a);
1572 for (j = 0; j < nregs; j++)
1574 int k;
1575 int set_to_test_start = 0, set_to_test_end = nwords;
1577 if (nregs == nwords)
1579 if (REG_WORDS_BIG_ENDIAN)
1580 set_to_test_start = nwords - j - 1;
1581 else
1582 set_to_test_start = j;
1583 set_to_test_end = set_to_test_start + 1;
1585 for (k = set_to_test_start; k < set_to_test_end; k++)
1586 if (TEST_HARD_REG_BIT (conflict_regs[k], hard_regno + j))
1587 break;
1588 if (k != set_to_test_end)
1589 break;
1591 return j == nregs;
1593 #ifndef HONOR_REG_ALLOC_ORDER
1595 /* Return number of registers needed to be saved and restored at
1596 function prologue/epilogue if we allocate HARD_REGNO to hold value
1597 of MODE. */
1598 static int
1599 calculate_saved_nregs (int hard_regno, enum machine_mode mode)
1601 int i;
1602 int nregs = 0;
1604 ira_assert (hard_regno >= 0);
1605 for (i = hard_regno_nregs[hard_regno][mode] - 1; i >= 0; i--)
1606 if (!allocated_hardreg_p[hard_regno + i]
1607 && !TEST_HARD_REG_BIT (call_used_reg_set, hard_regno + i)
1608 && !LOCAL_REGNO (hard_regno + i))
1609 nregs++;
1610 return nregs;
1612 #endif
1614 /* Choose a hard register for allocno A. If RETRY_P is TRUE, it means
1615 that the function called from function
1616 `ira_reassign_conflict_allocnos' and `allocno_reload_assign'. In
1617 this case some allocno data are not defined or updated and we
1618 should not touch these data. The function returns true if we
1619 managed to assign a hard register to the allocno.
1621 To assign a hard register, first of all we calculate all conflict
1622 hard registers which can come from conflicting allocnos with
1623 already assigned hard registers. After that we find first free
1624 hard register with the minimal cost. During hard register cost
1625 calculation we take conflict hard register costs into account to
1626 give a chance for conflicting allocnos to get a better hard
1627 register in the future.
1629 If the best hard register cost is bigger than cost of memory usage
1630 for the allocno, we don't assign a hard register to given allocno
1631 at all.
1633 If we assign a hard register to the allocno, we update costs of the
1634 hard register for allocnos connected by copies to improve a chance
1635 to coalesce insns represented by the copies when we assign hard
1636 registers to the allocnos connected by the copies. */
1637 static bool
1638 assign_hard_reg (ira_allocno_t a, bool retry_p)
1640 HARD_REG_SET conflicting_regs[2], profitable_hard_regs;
1641 int i, j, hard_regno, best_hard_regno, class_size;
1642 int cost, mem_cost, min_cost, full_cost, min_full_cost, nwords, word;
1643 int *a_costs;
1644 enum reg_class aclass;
1645 enum machine_mode mode;
1646 static int costs[FIRST_PSEUDO_REGISTER], full_costs[FIRST_PSEUDO_REGISTER];
1647 #ifndef HONOR_REG_ALLOC_ORDER
1648 int saved_nregs;
1649 enum reg_class rclass;
1650 int add_cost;
1651 #endif
1652 #ifdef STACK_REGS
1653 bool no_stack_reg_p;
1654 #endif
1656 ira_assert (! ALLOCNO_ASSIGNED_P (a));
1657 get_conflict_and_start_profitable_regs (a, retry_p,
1658 conflicting_regs,
1659 &profitable_hard_regs);
1660 aclass = ALLOCNO_CLASS (a);
1661 class_size = ira_class_hard_regs_num[aclass];
1662 best_hard_regno = -1;
1663 memset (full_costs, 0, sizeof (int) * class_size);
1664 mem_cost = 0;
1665 memset (costs, 0, sizeof (int) * class_size);
1666 memset (full_costs, 0, sizeof (int) * class_size);
1667 #ifdef STACK_REGS
1668 no_stack_reg_p = false;
1669 #endif
1670 if (! retry_p)
1671 start_update_cost ();
1672 mem_cost += ALLOCNO_UPDATED_MEMORY_COST (a);
1674 ira_allocate_and_copy_costs (&ALLOCNO_UPDATED_HARD_REG_COSTS (a),
1675 aclass, ALLOCNO_HARD_REG_COSTS (a));
1676 a_costs = ALLOCNO_UPDATED_HARD_REG_COSTS (a);
1677 #ifdef STACK_REGS
1678 no_stack_reg_p = no_stack_reg_p || ALLOCNO_TOTAL_NO_STACK_REG_P (a);
1679 #endif
1680 cost = ALLOCNO_UPDATED_CLASS_COST (a);
1681 for (i = 0; i < class_size; i++)
1682 if (a_costs != NULL)
1684 costs[i] += a_costs[i];
1685 full_costs[i] += a_costs[i];
1687 else
1689 costs[i] += cost;
1690 full_costs[i] += cost;
1692 nwords = ALLOCNO_NUM_OBJECTS (a);
1693 curr_allocno_process++;
1694 for (word = 0; word < nwords; word++)
1696 ira_object_t conflict_obj;
1697 ira_object_t obj = ALLOCNO_OBJECT (a, word);
1698 ira_object_conflict_iterator oci;
1700 /* Take preferences of conflicting allocnos into account. */
1701 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
1703 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
1704 enum reg_class conflict_aclass;
1706 /* Reload can give another class so we need to check all
1707 allocnos. */
1708 if (!retry_p
1709 && (!bitmap_bit_p (consideration_allocno_bitmap,
1710 ALLOCNO_NUM (conflict_a))
1711 || ((!ALLOCNO_ASSIGNED_P (conflict_a)
1712 || ALLOCNO_HARD_REGNO (conflict_a) < 0)
1713 && !(hard_reg_set_intersect_p
1714 (profitable_hard_regs,
1715 ALLOCNO_COLOR_DATA
1716 (conflict_a)->profitable_hard_regs)))))
1717 continue;
1718 conflict_aclass = ALLOCNO_CLASS (conflict_a);
1719 ira_assert (ira_reg_classes_intersect_p
1720 [aclass][conflict_aclass]);
1721 if (ALLOCNO_ASSIGNED_P (conflict_a))
1723 hard_regno = ALLOCNO_HARD_REGNO (conflict_a);
1724 if (hard_regno >= 0
1725 && (ira_hard_reg_set_intersection_p
1726 (hard_regno, ALLOCNO_MODE (conflict_a),
1727 reg_class_contents[aclass])))
1729 int n_objects = ALLOCNO_NUM_OBJECTS (conflict_a);
1730 int conflict_nregs;
1732 mode = ALLOCNO_MODE (conflict_a);
1733 conflict_nregs = hard_regno_nregs[hard_regno][mode];
1734 if (conflict_nregs == n_objects && conflict_nregs > 1)
1736 int num = OBJECT_SUBWORD (conflict_obj);
1738 if (REG_WORDS_BIG_ENDIAN)
1739 SET_HARD_REG_BIT (conflicting_regs[word],
1740 hard_regno + n_objects - num - 1);
1741 else
1742 SET_HARD_REG_BIT (conflicting_regs[word],
1743 hard_regno + num);
1745 else
1746 IOR_HARD_REG_SET
1747 (conflicting_regs[word],
1748 ira_reg_mode_hard_regset[hard_regno][mode]);
1749 if (hard_reg_set_subset_p (profitable_hard_regs,
1750 conflicting_regs[word]))
1751 goto fail;
1754 else if (! retry_p
1755 && ! ALLOCNO_COLOR_DATA (conflict_a)->may_be_spilled_p
1756 /* Don't process the conflict allocno twice. */
1757 && (ALLOCNO_COLOR_DATA (conflict_a)->last_process
1758 != curr_allocno_process))
1760 int k, *conflict_costs;
1762 ALLOCNO_COLOR_DATA (conflict_a)->last_process
1763 = curr_allocno_process;
1764 ira_allocate_and_copy_costs
1765 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (conflict_a),
1766 conflict_aclass,
1767 ALLOCNO_CONFLICT_HARD_REG_COSTS (conflict_a));
1768 conflict_costs
1769 = ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (conflict_a);
1770 if (conflict_costs != NULL)
1771 for (j = class_size - 1; j >= 0; j--)
1773 hard_regno = ira_class_hard_regs[aclass][j];
1774 ira_assert (hard_regno >= 0);
1775 k = ira_class_hard_reg_index[conflict_aclass][hard_regno];
1776 if (k < 0)
1777 continue;
1778 full_costs[j] -= conflict_costs[k];
1780 queue_update_cost (conflict_a, NULL, COST_HOP_DIVISOR);
1785 if (! retry_p)
1786 /* Take into account preferences of allocnos connected by copies to
1787 the conflict allocnos. */
1788 update_conflict_hard_regno_costs (full_costs, aclass, true);
1790 /* Take preferences of allocnos connected by copies into
1791 account. */
1792 if (! retry_p)
1794 start_update_cost ();
1795 queue_update_cost (a, NULL, COST_HOP_DIVISOR);
1796 update_conflict_hard_regno_costs (full_costs, aclass, false);
1798 min_cost = min_full_cost = INT_MAX;
1799 /* We don't care about giving callee saved registers to allocnos no
1800 living through calls because call clobbered registers are
1801 allocated first (it is usual practice to put them first in
1802 REG_ALLOC_ORDER). */
1803 mode = ALLOCNO_MODE (a);
1804 for (i = 0; i < class_size; i++)
1806 hard_regno = ira_class_hard_regs[aclass][i];
1807 #ifdef STACK_REGS
1808 if (no_stack_reg_p
1809 && FIRST_STACK_REG <= hard_regno && hard_regno <= LAST_STACK_REG)
1810 continue;
1811 #endif
1812 if (! check_hard_reg_p (a, hard_regno,
1813 conflicting_regs, profitable_hard_regs))
1814 continue;
1815 cost = costs[i];
1816 full_cost = full_costs[i];
1817 #ifndef HONOR_REG_ALLOC_ORDER
1818 if ((saved_nregs = calculate_saved_nregs (hard_regno, mode)) != 0)
1819 /* We need to save/restore the hard register in
1820 epilogue/prologue. Therefore we increase the cost. */
1822 rclass = REGNO_REG_CLASS (hard_regno);
1823 add_cost = ((ira_memory_move_cost[mode][rclass][0]
1824 + ira_memory_move_cost[mode][rclass][1])
1825 * saved_nregs / hard_regno_nregs[hard_regno][mode] - 1);
1826 cost += add_cost;
1827 full_cost += add_cost;
1829 #endif
1830 if (min_cost > cost)
1831 min_cost = cost;
1832 if (min_full_cost > full_cost)
1834 min_full_cost = full_cost;
1835 best_hard_regno = hard_regno;
1836 ira_assert (hard_regno >= 0);
1839 if (min_full_cost > mem_cost)
1841 if (! retry_p && internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
1842 fprintf (ira_dump_file, "(memory is more profitable %d vs %d) ",
1843 mem_cost, min_full_cost);
1844 best_hard_regno = -1;
1846 fail:
1847 if (best_hard_regno >= 0)
1849 for (i = hard_regno_nregs[best_hard_regno][mode] - 1; i >= 0; i--)
1850 allocated_hardreg_p[best_hard_regno + i] = true;
1852 if (! retry_p)
1853 restore_costs_from_copies (a);
1854 ALLOCNO_HARD_REGNO (a) = best_hard_regno;
1855 ALLOCNO_ASSIGNED_P (a) = true;
1856 if (best_hard_regno >= 0)
1857 update_costs_from_copies (a, true, ! retry_p);
1858 ira_assert (ALLOCNO_CLASS (a) == aclass);
1859 /* We don't need updated costs anymore: */
1860 ira_free_allocno_updated_costs (a);
1861 return best_hard_regno >= 0;
1866 /* This page contains the allocator based on the Chaitin-Briggs algorithm. */
1868 /* Bucket of allocnos that can colored currently without spilling. */
1869 static ira_allocno_t colorable_allocno_bucket;
1871 /* Bucket of allocnos that might be not colored currently without
1872 spilling. */
1873 static ira_allocno_t uncolorable_allocno_bucket;
1875 /* The current number of allocnos in the uncolorable_bucket. */
1876 static int uncolorable_allocnos_num;
1878 /* Return the current spill priority of allocno A. The less the
1879 number, the more preferable the allocno for spilling. */
1880 static inline int
1881 allocno_spill_priority (ira_allocno_t a)
1883 allocno_color_data_t data = ALLOCNO_COLOR_DATA (a);
1885 return (data->temp
1886 / (ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a)
1887 * ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]
1888 + 1));
1891 /* Add allocno A to bucket *BUCKET_PTR. A should be not in a bucket
1892 before the call. */
1893 static void
1894 add_allocno_to_bucket (ira_allocno_t a, ira_allocno_t *bucket_ptr)
1896 ira_allocno_t first_a;
1897 allocno_color_data_t data;
1899 if (bucket_ptr == &uncolorable_allocno_bucket
1900 && ALLOCNO_CLASS (a) != NO_REGS)
1902 uncolorable_allocnos_num++;
1903 ira_assert (uncolorable_allocnos_num > 0);
1905 first_a = *bucket_ptr;
1906 data = ALLOCNO_COLOR_DATA (a);
1907 data->next_bucket_allocno = first_a;
1908 data->prev_bucket_allocno = NULL;
1909 if (first_a != NULL)
1910 ALLOCNO_COLOR_DATA (first_a)->prev_bucket_allocno = a;
1911 *bucket_ptr = a;
1914 /* Compare two allocnos to define which allocno should be pushed first
1915 into the coloring stack. If the return is a negative number, the
1916 allocno given by the first parameter will be pushed first. In this
1917 case such allocno has less priority than the second one and the
1918 hard register will be assigned to it after assignment to the second
1919 one. As the result of such assignment order, the second allocno
1920 has a better chance to get the best hard register. */
1921 static int
1922 bucket_allocno_compare_func (const void *v1p, const void *v2p)
1924 ira_allocno_t a1 = *(const ira_allocno_t *) v1p;
1925 ira_allocno_t a2 = *(const ira_allocno_t *) v2p;
1926 int diff, a1_freq, a2_freq, a1_num, a2_num;
1927 int cl1 = ALLOCNO_CLASS (a1), cl2 = ALLOCNO_CLASS (a2);
1929 /* Push pseudos requiring less hard registers first. It means that
1930 we will assign pseudos requiring more hard registers first
1931 avoiding creation small holes in free hard register file into
1932 which the pseudos requiring more hard registers can not fit. */
1933 if ((diff = (ira_reg_class_max_nregs[cl1][ALLOCNO_MODE (a1)]
1934 - ira_reg_class_max_nregs[cl2][ALLOCNO_MODE (a2)])) != 0)
1935 return diff;
1936 a1_freq = ALLOCNO_FREQ (a1);
1937 a2_freq = ALLOCNO_FREQ (a2);
1938 if ((diff = a1_freq - a2_freq) != 0)
1939 return diff;
1940 a1_num = ALLOCNO_COLOR_DATA (a1)->available_regs_num;
1941 a2_num = ALLOCNO_COLOR_DATA (a2)->available_regs_num;
1942 if ((diff = a2_num - a1_num) != 0)
1943 return diff;
1944 return ALLOCNO_NUM (a2) - ALLOCNO_NUM (a1);
1947 /* Sort bucket *BUCKET_PTR and return the result through
1948 BUCKET_PTR. */
1949 static void
1950 sort_bucket (ira_allocno_t *bucket_ptr,
1951 int (*compare_func) (const void *, const void *))
1953 ira_allocno_t a, head;
1954 int n;
1956 for (n = 0, a = *bucket_ptr;
1957 a != NULL;
1958 a = ALLOCNO_COLOR_DATA (a)->next_bucket_allocno)
1959 sorted_allocnos[n++] = a;
1960 if (n <= 1)
1961 return;
1962 qsort (sorted_allocnos, n, sizeof (ira_allocno_t), compare_func);
1963 head = NULL;
1964 for (n--; n >= 0; n--)
1966 a = sorted_allocnos[n];
1967 ALLOCNO_COLOR_DATA (a)->next_bucket_allocno = head;
1968 ALLOCNO_COLOR_DATA (a)->prev_bucket_allocno = NULL;
1969 if (head != NULL)
1970 ALLOCNO_COLOR_DATA (head)->prev_bucket_allocno = a;
1971 head = a;
1973 *bucket_ptr = head;
1976 /* Add ALLOCNO to bucket *BUCKET_PTR maintaining the order according
1977 their priority. ALLOCNO should be not in a bucket before the
1978 call. */
1979 static void
1980 add_allocno_to_ordered_bucket (ira_allocno_t allocno,
1981 ira_allocno_t *bucket_ptr)
1983 ira_allocno_t before, after;
1985 if (bucket_ptr == &uncolorable_allocno_bucket
1986 && ALLOCNO_CLASS (allocno) != NO_REGS)
1988 uncolorable_allocnos_num++;
1989 ira_assert (uncolorable_allocnos_num > 0);
1991 for (before = *bucket_ptr, after = NULL;
1992 before != NULL;
1993 after = before,
1994 before = ALLOCNO_COLOR_DATA (before)->next_bucket_allocno)
1995 if (bucket_allocno_compare_func (&allocno, &before) < 0)
1996 break;
1997 ALLOCNO_COLOR_DATA (allocno)->next_bucket_allocno = before;
1998 ALLOCNO_COLOR_DATA (allocno)->prev_bucket_allocno = after;
1999 if (after == NULL)
2000 *bucket_ptr = allocno;
2001 else
2002 ALLOCNO_COLOR_DATA (after)->next_bucket_allocno = allocno;
2003 if (before != NULL)
2004 ALLOCNO_COLOR_DATA (before)->prev_bucket_allocno = allocno;
2007 /* Delete ALLOCNO from bucket *BUCKET_PTR. It should be there before
2008 the call. */
2009 static void
2010 delete_allocno_from_bucket (ira_allocno_t allocno, ira_allocno_t *bucket_ptr)
2012 ira_allocno_t prev_allocno, next_allocno;
2014 if (bucket_ptr == &uncolorable_allocno_bucket
2015 && ALLOCNO_CLASS (allocno) != NO_REGS)
2017 uncolorable_allocnos_num--;
2018 ira_assert (uncolorable_allocnos_num >= 0);
2020 prev_allocno = ALLOCNO_COLOR_DATA (allocno)->prev_bucket_allocno;
2021 next_allocno = ALLOCNO_COLOR_DATA (allocno)->next_bucket_allocno;
2022 if (prev_allocno != NULL)
2023 ALLOCNO_COLOR_DATA (prev_allocno)->next_bucket_allocno = next_allocno;
2024 else
2026 ira_assert (*bucket_ptr == allocno);
2027 *bucket_ptr = next_allocno;
2029 if (next_allocno != NULL)
2030 ALLOCNO_COLOR_DATA (next_allocno)->prev_bucket_allocno = prev_allocno;
2033 /* Put allocno A onto the coloring stack without removing it from its
2034 bucket. Pushing allocno to the coloring stack can result in moving
2035 conflicting allocnos from the uncolorable bucket to the colorable
2036 one. */
2037 static void
2038 push_allocno_to_stack (ira_allocno_t a)
2040 enum reg_class aclass;
2041 allocno_color_data_t data, conflict_data;
2042 int size, i, n = ALLOCNO_NUM_OBJECTS (a);
2044 data = ALLOCNO_COLOR_DATA (a);
2045 data->in_graph_p = false;
2046 allocno_stack_vec.safe_push (a);
2047 aclass = ALLOCNO_CLASS (a);
2048 if (aclass == NO_REGS)
2049 return;
2050 size = ira_reg_class_max_nregs[aclass][ALLOCNO_MODE (a)];
2051 if (n > 1)
2053 /* We will deal with the subwords individually. */
2054 gcc_assert (size == ALLOCNO_NUM_OBJECTS (a));
2055 size = 1;
2057 for (i = 0; i < n; i++)
2059 ira_object_t obj = ALLOCNO_OBJECT (a, i);
2060 ira_object_t conflict_obj;
2061 ira_object_conflict_iterator oci;
2063 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
2065 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
2067 conflict_data = ALLOCNO_COLOR_DATA (conflict_a);
2068 if (conflict_data->colorable_p
2069 || ! conflict_data->in_graph_p
2070 || ALLOCNO_ASSIGNED_P (conflict_a)
2071 || !(hard_reg_set_intersect_p
2072 (ALLOCNO_COLOR_DATA (a)->profitable_hard_regs,
2073 conflict_data->profitable_hard_regs)))
2074 continue;
2075 ira_assert (bitmap_bit_p (coloring_allocno_bitmap,
2076 ALLOCNO_NUM (conflict_a)));
2077 if (update_left_conflict_sizes_p (conflict_a, a, size))
2079 delete_allocno_from_bucket
2080 (conflict_a, &uncolorable_allocno_bucket);
2081 add_allocno_to_ordered_bucket
2082 (conflict_a, &colorable_allocno_bucket);
2083 if (internal_flag_ira_verbose > 4 && ira_dump_file != NULL)
2085 fprintf (ira_dump_file, " Making");
2086 ira_print_expanded_allocno (conflict_a);
2087 fprintf (ira_dump_file, " colorable\n");
2095 /* Put ALLOCNO onto the coloring stack and remove it from its bucket.
2096 The allocno is in the colorable bucket if COLORABLE_P is TRUE. */
2097 static void
2098 remove_allocno_from_bucket_and_push (ira_allocno_t allocno, bool colorable_p)
2100 if (colorable_p)
2101 delete_allocno_from_bucket (allocno, &colorable_allocno_bucket);
2102 else
2103 delete_allocno_from_bucket (allocno, &uncolorable_allocno_bucket);
2104 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2106 fprintf (ira_dump_file, " Pushing");
2107 ira_print_expanded_allocno (allocno);
2108 if (colorable_p)
2109 fprintf (ira_dump_file, "(cost %d)\n",
2110 ALLOCNO_COLOR_DATA (allocno)->temp);
2111 else
2112 fprintf (ira_dump_file, "(potential spill: %spri=%d, cost=%d)\n",
2113 ALLOCNO_BAD_SPILL_P (allocno) ? "bad spill, " : "",
2114 allocno_spill_priority (allocno),
2115 ALLOCNO_COLOR_DATA (allocno)->temp);
2117 if (! colorable_p)
2118 ALLOCNO_COLOR_DATA (allocno)->may_be_spilled_p = true;
2119 push_allocno_to_stack (allocno);
2122 /* Put all allocnos from colorable bucket onto the coloring stack. */
2123 static void
2124 push_only_colorable (void)
2126 sort_bucket (&colorable_allocno_bucket, bucket_allocno_compare_func);
2127 for (;colorable_allocno_bucket != NULL;)
2128 remove_allocno_from_bucket_and_push (colorable_allocno_bucket, true);
2131 /* Return the frequency of exit edges (if EXIT_P) or entry from/to the
2132 loop given by its LOOP_NODE. */
2134 ira_loop_edge_freq (ira_loop_tree_node_t loop_node, int regno, bool exit_p)
2136 int freq, i;
2137 edge_iterator ei;
2138 edge e;
2139 vec<edge> edges;
2141 ira_assert (current_loops != NULL && loop_node->loop != NULL
2142 && (regno < 0 || regno >= FIRST_PSEUDO_REGISTER));
2143 freq = 0;
2144 if (! exit_p)
2146 FOR_EACH_EDGE (e, ei, loop_node->loop->header->preds)
2147 if (e->src != loop_node->loop->latch
2148 && (regno < 0
2149 || (bitmap_bit_p (df_get_live_out (e->src), regno)
2150 && bitmap_bit_p (df_get_live_in (e->dest), regno))))
2151 freq += EDGE_FREQUENCY (e);
2153 else
2155 edges = get_loop_exit_edges (loop_node->loop);
2156 FOR_EACH_VEC_ELT (edges, i, e)
2157 if (regno < 0
2158 || (bitmap_bit_p (df_get_live_out (e->src), regno)
2159 && bitmap_bit_p (df_get_live_in (e->dest), regno)))
2160 freq += EDGE_FREQUENCY (e);
2161 edges.release ();
2164 return REG_FREQ_FROM_EDGE_FREQ (freq);
2167 /* Calculate and return the cost of putting allocno A into memory. */
2168 static int
2169 calculate_allocno_spill_cost (ira_allocno_t a)
2171 int regno, cost;
2172 enum machine_mode mode;
2173 enum reg_class rclass;
2174 ira_allocno_t parent_allocno;
2175 ira_loop_tree_node_t parent_node, loop_node;
2177 regno = ALLOCNO_REGNO (a);
2178 cost = ALLOCNO_UPDATED_MEMORY_COST (a) - ALLOCNO_UPDATED_CLASS_COST (a);
2179 if (ALLOCNO_CAP (a) != NULL)
2180 return cost;
2181 loop_node = ALLOCNO_LOOP_TREE_NODE (a);
2182 if ((parent_node = loop_node->parent) == NULL)
2183 return cost;
2184 if ((parent_allocno = parent_node->regno_allocno_map[regno]) == NULL)
2185 return cost;
2186 mode = ALLOCNO_MODE (a);
2187 rclass = ALLOCNO_CLASS (a);
2188 if (ALLOCNO_HARD_REGNO (parent_allocno) < 0)
2189 cost -= (ira_memory_move_cost[mode][rclass][0]
2190 * ira_loop_edge_freq (loop_node, regno, true)
2191 + ira_memory_move_cost[mode][rclass][1]
2192 * ira_loop_edge_freq (loop_node, regno, false));
2193 else
2195 ira_init_register_move_cost_if_necessary (mode);
2196 cost += ((ira_memory_move_cost[mode][rclass][1]
2197 * ira_loop_edge_freq (loop_node, regno, true)
2198 + ira_memory_move_cost[mode][rclass][0]
2199 * ira_loop_edge_freq (loop_node, regno, false))
2200 - (ira_register_move_cost[mode][rclass][rclass]
2201 * (ira_loop_edge_freq (loop_node, regno, false)
2202 + ira_loop_edge_freq (loop_node, regno, true))));
2204 return cost;
2207 /* Used for sorting allocnos for spilling. */
2208 static inline int
2209 allocno_spill_priority_compare (ira_allocno_t a1, ira_allocno_t a2)
2211 int pri1, pri2, diff;
2213 if (ALLOCNO_BAD_SPILL_P (a1) && ! ALLOCNO_BAD_SPILL_P (a2))
2214 return 1;
2215 if (ALLOCNO_BAD_SPILL_P (a2) && ! ALLOCNO_BAD_SPILL_P (a1))
2216 return -1;
2217 pri1 = allocno_spill_priority (a1);
2218 pri2 = allocno_spill_priority (a2);
2219 if ((diff = pri1 - pri2) != 0)
2220 return diff;
2221 if ((diff
2222 = ALLOCNO_COLOR_DATA (a1)->temp - ALLOCNO_COLOR_DATA (a2)->temp) != 0)
2223 return diff;
2224 return ALLOCNO_NUM (a1) - ALLOCNO_NUM (a2);
2227 /* Used for sorting allocnos for spilling. */
2228 static int
2229 allocno_spill_sort_compare (const void *v1p, const void *v2p)
2231 ira_allocno_t p1 = *(const ira_allocno_t *) v1p;
2232 ira_allocno_t p2 = *(const ira_allocno_t *) v2p;
2234 return allocno_spill_priority_compare (p1, p2);
2237 /* Push allocnos to the coloring stack. The order of allocnos in the
2238 stack defines the order for the subsequent coloring. */
2239 static void
2240 push_allocnos_to_stack (void)
2242 ira_allocno_t a;
2243 int cost;
2245 /* Calculate uncolorable allocno spill costs. */
2246 for (a = uncolorable_allocno_bucket;
2247 a != NULL;
2248 a = ALLOCNO_COLOR_DATA (a)->next_bucket_allocno)
2249 if (ALLOCNO_CLASS (a) != NO_REGS)
2251 cost = calculate_allocno_spill_cost (a);
2252 /* ??? Remove cost of copies between the coalesced
2253 allocnos. */
2254 ALLOCNO_COLOR_DATA (a)->temp = cost;
2256 sort_bucket (&uncolorable_allocno_bucket, allocno_spill_sort_compare);
2257 for (;;)
2259 push_only_colorable ();
2260 a = uncolorable_allocno_bucket;
2261 if (a == NULL)
2262 break;
2263 remove_allocno_from_bucket_and_push (a, false);
2265 ira_assert (colorable_allocno_bucket == NULL
2266 && uncolorable_allocno_bucket == NULL);
2267 ira_assert (uncolorable_allocnos_num == 0);
2270 /* Pop the coloring stack and assign hard registers to the popped
2271 allocnos. */
2272 static void
2273 pop_allocnos_from_stack (void)
2275 ira_allocno_t allocno;
2276 enum reg_class aclass;
2278 for (;allocno_stack_vec.length () != 0;)
2280 allocno = allocno_stack_vec.pop ();
2281 aclass = ALLOCNO_CLASS (allocno);
2282 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2284 fprintf (ira_dump_file, " Popping");
2285 ira_print_expanded_allocno (allocno);
2286 fprintf (ira_dump_file, " -- ");
2288 if (aclass == NO_REGS)
2290 ALLOCNO_HARD_REGNO (allocno) = -1;
2291 ALLOCNO_ASSIGNED_P (allocno) = true;
2292 ira_assert (ALLOCNO_UPDATED_HARD_REG_COSTS (allocno) == NULL);
2293 ira_assert
2294 (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (allocno) == NULL);
2295 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2296 fprintf (ira_dump_file, "assign memory\n");
2298 else if (assign_hard_reg (allocno, false))
2300 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2301 fprintf (ira_dump_file, "assign reg %d\n",
2302 ALLOCNO_HARD_REGNO (allocno));
2304 else if (ALLOCNO_ASSIGNED_P (allocno))
2306 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2307 fprintf (ira_dump_file, "spill%s\n",
2308 ALLOCNO_COLOR_DATA (allocno)->may_be_spilled_p
2309 ? "" : "!");
2311 ALLOCNO_COLOR_DATA (allocno)->in_graph_p = true;
2315 /* Set up number of available hard registers for allocno A. */
2316 static void
2317 setup_allocno_available_regs_num (ira_allocno_t a)
2319 int i, n, hard_regno, hard_regs_num, nwords;
2320 enum reg_class aclass;
2321 allocno_color_data_t data;
2323 aclass = ALLOCNO_CLASS (a);
2324 data = ALLOCNO_COLOR_DATA (a);
2325 data->available_regs_num = 0;
2326 if (aclass == NO_REGS)
2327 return;
2328 hard_regs_num = ira_class_hard_regs_num[aclass];
2329 nwords = ALLOCNO_NUM_OBJECTS (a);
2330 for (n = 0, i = hard_regs_num - 1; i >= 0; i--)
2332 hard_regno = ira_class_hard_regs[aclass][i];
2333 /* Checking only profitable hard regs. */
2334 if (TEST_HARD_REG_BIT (data->profitable_hard_regs, hard_regno))
2335 n++;
2337 data->available_regs_num = n;
2338 if (internal_flag_ira_verbose <= 2 || ira_dump_file == NULL)
2339 return;
2340 fprintf
2341 (ira_dump_file,
2342 " Allocno a%dr%d of %s(%d) has %d avail. regs ",
2343 ALLOCNO_NUM (a), ALLOCNO_REGNO (a),
2344 reg_class_names[aclass], ira_class_hard_regs_num[aclass], n);
2345 print_hard_reg_set (ira_dump_file, data->profitable_hard_regs, false);
2346 fprintf (ira_dump_file, ", %snode: ",
2347 hard_reg_set_equal_p (data->profitable_hard_regs,
2348 data->hard_regs_node->hard_regs->set)
2349 ? "" : "^");
2350 print_hard_reg_set (ira_dump_file,
2351 data->hard_regs_node->hard_regs->set, false);
2352 for (i = 0; i < nwords; i++)
2354 ira_object_t obj = ALLOCNO_OBJECT (a, i);
2356 if (nwords != 1)
2358 if (i != 0)
2359 fprintf (ira_dump_file, ", ");
2360 fprintf (ira_dump_file, " obj %d", i);
2362 fprintf (ira_dump_file, " (confl regs = ");
2363 print_hard_reg_set (ira_dump_file, OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
2364 false);
2365 fprintf (ira_dump_file, ")");
2367 fprintf (ira_dump_file, "\n");
2370 /* Put ALLOCNO in a bucket corresponding to its number and size of its
2371 conflicting allocnos and hard registers. */
2372 static void
2373 put_allocno_into_bucket (ira_allocno_t allocno)
2375 ALLOCNO_COLOR_DATA (allocno)->in_graph_p = true;
2376 setup_allocno_available_regs_num (allocno);
2377 if (setup_left_conflict_sizes_p (allocno))
2378 add_allocno_to_bucket (allocno, &colorable_allocno_bucket);
2379 else
2380 add_allocno_to_bucket (allocno, &uncolorable_allocno_bucket);
2383 /* Map: allocno number -> allocno priority. */
2384 static int *allocno_priorities;
2386 /* Set up priorities for N allocnos in array
2387 CONSIDERATION_ALLOCNOS. */
2388 static void
2389 setup_allocno_priorities (ira_allocno_t *consideration_allocnos, int n)
2391 int i, length, nrefs, priority, max_priority, mult;
2392 ira_allocno_t a;
2394 max_priority = 0;
2395 for (i = 0; i < n; i++)
2397 a = consideration_allocnos[i];
2398 nrefs = ALLOCNO_NREFS (a);
2399 ira_assert (nrefs >= 0);
2400 mult = floor_log2 (ALLOCNO_NREFS (a)) + 1;
2401 ira_assert (mult >= 0);
2402 allocno_priorities[ALLOCNO_NUM (a)]
2403 = priority
2404 = (mult
2405 * (ALLOCNO_MEMORY_COST (a) - ALLOCNO_CLASS_COST (a))
2406 * ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]);
2407 if (priority < 0)
2408 priority = -priority;
2409 if (max_priority < priority)
2410 max_priority = priority;
2412 mult = max_priority == 0 ? 1 : INT_MAX / max_priority;
2413 for (i = 0; i < n; i++)
2415 a = consideration_allocnos[i];
2416 length = ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a);
2417 if (ALLOCNO_NUM_OBJECTS (a) > 1)
2418 length /= ALLOCNO_NUM_OBJECTS (a);
2419 if (length <= 0)
2420 length = 1;
2421 allocno_priorities[ALLOCNO_NUM (a)]
2422 = allocno_priorities[ALLOCNO_NUM (a)] * mult / length;
2426 /* Sort allocnos according to the profit of usage of a hard register
2427 instead of memory for them. */
2428 static int
2429 allocno_cost_compare_func (const void *v1p, const void *v2p)
2431 ira_allocno_t p1 = *(const ira_allocno_t *) v1p;
2432 ira_allocno_t p2 = *(const ira_allocno_t *) v2p;
2433 int c1, c2;
2435 c1 = ALLOCNO_UPDATED_MEMORY_COST (p1) - ALLOCNO_UPDATED_CLASS_COST (p1);
2436 c2 = ALLOCNO_UPDATED_MEMORY_COST (p2) - ALLOCNO_UPDATED_CLASS_COST (p2);
2437 if (c1 - c2)
2438 return c1 - c2;
2440 /* If regs are equally good, sort by allocno numbers, so that the
2441 results of qsort leave nothing to chance. */
2442 return ALLOCNO_NUM (p1) - ALLOCNO_NUM (p2);
2445 /* We used Chaitin-Briggs coloring to assign as many pseudos as
2446 possible to hard registers. Let us try to improve allocation with
2447 cost point of view. This function improves the allocation by
2448 spilling some allocnos and assigning the freed hard registers to
2449 other allocnos if it decreases the overall allocation cost. */
2450 static void
2451 improve_allocation (void)
2453 unsigned int i;
2454 int j, k, n, hregno, conflict_hregno, base_cost, class_size, word, nwords;
2455 int check, spill_cost, min_cost, nregs, conflict_nregs, r, best;
2456 bool try_p;
2457 enum reg_class aclass;
2458 enum machine_mode mode;
2459 int *allocno_costs;
2460 int costs[FIRST_PSEUDO_REGISTER];
2461 HARD_REG_SET conflicting_regs[2], profitable_hard_regs;
2462 ira_allocno_t a;
2463 bitmap_iterator bi;
2465 /* Clear counts used to process conflicting allocnos only once for
2466 each allocno. */
2467 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
2468 ALLOCNO_COLOR_DATA (ira_allocnos[i])->temp = 0;
2469 check = n = 0;
2470 /* Process each allocno and try to assign a hard register to it by
2471 spilling some its conflicting allocnos. */
2472 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
2474 a = ira_allocnos[i];
2475 ALLOCNO_COLOR_DATA (a)->temp = 0;
2476 if (empty_profitable_hard_regs (a))
2477 continue;
2478 check++;
2479 aclass = ALLOCNO_CLASS (a);
2480 allocno_costs = ALLOCNO_UPDATED_HARD_REG_COSTS (a);
2481 if (allocno_costs == NULL)
2482 allocno_costs = ALLOCNO_HARD_REG_COSTS (a);
2483 if ((hregno = ALLOCNO_HARD_REGNO (a)) < 0)
2484 base_cost = ALLOCNO_UPDATED_MEMORY_COST (a);
2485 else if (allocno_costs == NULL)
2486 /* It means that assigning a hard register is not profitable
2487 (we don't waste memory for hard register costs in this
2488 case). */
2489 continue;
2490 else
2491 base_cost = allocno_costs[ira_class_hard_reg_index[aclass][hregno]];
2492 try_p = false;
2493 get_conflict_and_start_profitable_regs (a, false,
2494 conflicting_regs,
2495 &profitable_hard_regs);
2496 class_size = ira_class_hard_regs_num[aclass];
2497 /* Set up cost improvement for usage of each profitable hard
2498 register for allocno A. */
2499 for (j = 0; j < class_size; j++)
2501 hregno = ira_class_hard_regs[aclass][j];
2502 if (! check_hard_reg_p (a, hregno,
2503 conflicting_regs, profitable_hard_regs))
2504 continue;
2505 ira_assert (ira_class_hard_reg_index[aclass][hregno] == j);
2506 k = allocno_costs == NULL ? 0 : j;
2507 costs[hregno] = (allocno_costs == NULL
2508 ? ALLOCNO_UPDATED_CLASS_COST (a) : allocno_costs[k]);
2509 costs[hregno] -= base_cost;
2510 if (costs[hregno] < 0)
2511 try_p = true;
2513 if (! try_p)
2514 /* There is no chance to improve the allocation cost by
2515 assigning hard register to allocno A even without spilling
2516 conflicting allocnos. */
2517 continue;
2518 mode = ALLOCNO_MODE (a);
2519 nwords = ALLOCNO_NUM_OBJECTS (a);
2520 /* Process each allocno conflicting with A and update the cost
2521 improvement for profitable hard registers of A. To use a
2522 hard register for A we need to spill some conflicting
2523 allocnos and that creates penalty for the cost
2524 improvement. */
2525 for (word = 0; word < nwords; word++)
2527 ira_object_t conflict_obj;
2528 ira_object_t obj = ALLOCNO_OBJECT (a, word);
2529 ira_object_conflict_iterator oci;
2531 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
2533 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
2535 if (ALLOCNO_COLOR_DATA (conflict_a)->temp == check)
2536 /* We already processed this conflicting allocno
2537 because we processed earlier another object of the
2538 conflicting allocno. */
2539 continue;
2540 ALLOCNO_COLOR_DATA (conflict_a)->temp = check;
2541 if ((conflict_hregno = ALLOCNO_HARD_REGNO (conflict_a)) < 0)
2542 continue;
2543 spill_cost = ALLOCNO_UPDATED_MEMORY_COST (conflict_a);
2544 k = (ira_class_hard_reg_index
2545 [ALLOCNO_CLASS (conflict_a)][conflict_hregno]);
2546 ira_assert (k >= 0);
2547 if ((allocno_costs = ALLOCNO_UPDATED_HARD_REG_COSTS (conflict_a))
2548 != NULL)
2549 spill_cost -= allocno_costs[k];
2550 else if ((allocno_costs = ALLOCNO_HARD_REG_COSTS (conflict_a))
2551 != NULL)
2552 spill_cost -= allocno_costs[k];
2553 else
2554 spill_cost -= ALLOCNO_UPDATED_CLASS_COST (conflict_a);
2555 conflict_nregs
2556 = hard_regno_nregs[conflict_hregno][ALLOCNO_MODE (conflict_a)];
2557 for (r = conflict_hregno;
2558 r >= 0 && r + hard_regno_nregs[r][mode] > conflict_hregno;
2559 r--)
2560 if (check_hard_reg_p (a, r,
2561 conflicting_regs, profitable_hard_regs))
2562 costs[r] += spill_cost;
2563 for (r = conflict_hregno + 1;
2564 r < conflict_hregno + conflict_nregs;
2565 r++)
2566 if (check_hard_reg_p (a, r,
2567 conflicting_regs, profitable_hard_regs))
2568 costs[r] += spill_cost;
2571 min_cost = INT_MAX;
2572 best = -1;
2573 /* Now we choose hard register for A which results in highest
2574 allocation cost improvement. */
2575 for (j = 0; j < class_size; j++)
2577 hregno = ira_class_hard_regs[aclass][j];
2578 if (check_hard_reg_p (a, hregno,
2579 conflicting_regs, profitable_hard_regs)
2580 && min_cost > costs[hregno])
2582 best = hregno;
2583 min_cost = costs[hregno];
2586 if (min_cost >= 0)
2587 /* We are in a situation when assigning any hard register to A
2588 by spilling some conflicting allocnos does not improve the
2589 allocation cost. */
2590 continue;
2591 nregs = hard_regno_nregs[best][mode];
2592 /* Now spill conflicting allocnos which contain a hard register
2593 of A when we assign the best chosen hard register to it. */
2594 for (word = 0; word < nwords; word++)
2596 ira_object_t conflict_obj;
2597 ira_object_t obj = ALLOCNO_OBJECT (a, word);
2598 ira_object_conflict_iterator oci;
2600 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
2602 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
2604 if ((conflict_hregno = ALLOCNO_HARD_REGNO (conflict_a)) < 0)
2605 continue;
2606 conflict_nregs
2607 = hard_regno_nregs[conflict_hregno][ALLOCNO_MODE (conflict_a)];
2608 if (best + nregs <= conflict_hregno
2609 || conflict_hregno + conflict_nregs <= best)
2610 /* No intersection. */
2611 continue;
2612 ALLOCNO_HARD_REGNO (conflict_a) = -1;
2613 sorted_allocnos[n++] = conflict_a;
2614 if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
2615 fprintf (ira_dump_file, "Spilling a%dr%d for a%dr%d\n",
2616 ALLOCNO_NUM (conflict_a), ALLOCNO_REGNO (conflict_a),
2617 ALLOCNO_NUM (a), ALLOCNO_REGNO (a));
2620 /* Assign the best chosen hard register to A. */
2621 ALLOCNO_HARD_REGNO (a) = best;
2622 if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
2623 fprintf (ira_dump_file, "Assigning %d to a%dr%d\n",
2624 best, ALLOCNO_NUM (a), ALLOCNO_REGNO (a));
2626 if (n == 0)
2627 return;
2628 /* We spilled some allocnos to assign their hard registers to other
2629 allocnos. The spilled allocnos are now in array
2630 'sorted_allocnos'. There is still a possibility that some of the
2631 spilled allocnos can get hard registers. So let us try assign
2632 them hard registers again (just a reminder -- function
2633 'assign_hard_reg' assigns hard registers only if it is possible
2634 and profitable). We process the spilled allocnos with biggest
2635 benefit to get hard register first -- see function
2636 'allocno_cost_compare_func'. */
2637 qsort (sorted_allocnos, n, sizeof (ira_allocno_t),
2638 allocno_cost_compare_func);
2639 for (j = 0; j < n; j++)
2641 a = sorted_allocnos[j];
2642 ALLOCNO_ASSIGNED_P (a) = false;
2643 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2645 fprintf (ira_dump_file, " ");
2646 ira_print_expanded_allocno (a);
2647 fprintf (ira_dump_file, " -- ");
2649 if (assign_hard_reg (a, false))
2651 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2652 fprintf (ira_dump_file, "assign hard reg %d\n",
2653 ALLOCNO_HARD_REGNO (a));
2655 else
2657 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2658 fprintf (ira_dump_file, "assign memory\n");
2663 /* Sort allocnos according to their priorities. */
2664 static int
2665 allocno_priority_compare_func (const void *v1p, const void *v2p)
2667 ira_allocno_t a1 = *(const ira_allocno_t *) v1p;
2668 ira_allocno_t a2 = *(const ira_allocno_t *) v2p;
2669 int pri1, pri2;
2671 pri1 = allocno_priorities[ALLOCNO_NUM (a1)];
2672 pri2 = allocno_priorities[ALLOCNO_NUM (a2)];
2673 if (pri2 != pri1)
2674 return SORTGT (pri2, pri1);
2676 /* If regs are equally good, sort by allocnos, so that the results of
2677 qsort leave nothing to chance. */
2678 return ALLOCNO_NUM (a1) - ALLOCNO_NUM (a2);
2681 /* Chaitin-Briggs coloring for allocnos in COLORING_ALLOCNO_BITMAP
2682 taking into account allocnos in CONSIDERATION_ALLOCNO_BITMAP. */
2683 static void
2684 color_allocnos (void)
2686 unsigned int i, n;
2687 bitmap_iterator bi;
2688 ira_allocno_t a;
2690 setup_profitable_hard_regs ();
2691 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
2693 int l, nr;
2694 HARD_REG_SET conflict_hard_regs;
2695 allocno_color_data_t data;
2696 ira_pref_t pref, next_pref;
2698 a = ira_allocnos[i];
2699 nr = ALLOCNO_NUM_OBJECTS (a);
2700 CLEAR_HARD_REG_SET (conflict_hard_regs);
2701 for (l = 0; l < nr; l++)
2703 ira_object_t obj = ALLOCNO_OBJECT (a, l);
2704 IOR_HARD_REG_SET (conflict_hard_regs,
2705 OBJECT_CONFLICT_HARD_REGS (obj));
2707 data = ALLOCNO_COLOR_DATA (a);
2708 for (pref = ALLOCNO_PREFS (a); pref != NULL; pref = next_pref)
2710 next_pref = pref->next_pref;
2711 if (! ira_hard_reg_in_set_p (pref->hard_regno,
2712 ALLOCNO_MODE (a),
2713 data->profitable_hard_regs))
2714 ira_remove_pref (pref);
2717 if (flag_ira_algorithm == IRA_ALGORITHM_PRIORITY)
2719 n = 0;
2720 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
2722 a = ira_allocnos[i];
2723 if (ALLOCNO_CLASS (a) == NO_REGS)
2725 ALLOCNO_HARD_REGNO (a) = -1;
2726 ALLOCNO_ASSIGNED_P (a) = true;
2727 ira_assert (ALLOCNO_UPDATED_HARD_REG_COSTS (a) == NULL);
2728 ira_assert (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a) == NULL);
2729 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2731 fprintf (ira_dump_file, " Spill");
2732 ira_print_expanded_allocno (a);
2733 fprintf (ira_dump_file, "\n");
2735 continue;
2737 sorted_allocnos[n++] = a;
2739 if (n != 0)
2741 setup_allocno_priorities (sorted_allocnos, n);
2742 qsort (sorted_allocnos, n, sizeof (ira_allocno_t),
2743 allocno_priority_compare_func);
2744 for (i = 0; i < n; i++)
2746 a = sorted_allocnos[i];
2747 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2749 fprintf (ira_dump_file, " ");
2750 ira_print_expanded_allocno (a);
2751 fprintf (ira_dump_file, " -- ");
2753 if (assign_hard_reg (a, false))
2755 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2756 fprintf (ira_dump_file, "assign hard reg %d\n",
2757 ALLOCNO_HARD_REGNO (a));
2759 else
2761 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2762 fprintf (ira_dump_file, "assign memory\n");
2767 else
2769 form_allocno_hard_regs_nodes_forest ();
2770 if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
2771 print_hard_regs_forest (ira_dump_file);
2772 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
2774 a = ira_allocnos[i];
2775 if (ALLOCNO_CLASS (a) != NO_REGS && ! empty_profitable_hard_regs (a))
2777 ALLOCNO_COLOR_DATA (a)->in_graph_p = true;
2778 update_costs_from_prefs (a);
2780 else
2782 ALLOCNO_HARD_REGNO (a) = -1;
2783 ALLOCNO_ASSIGNED_P (a) = true;
2784 /* We don't need updated costs anymore. */
2785 ira_free_allocno_updated_costs (a);
2786 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2788 fprintf (ira_dump_file, " Spill");
2789 ira_print_expanded_allocno (a);
2790 fprintf (ira_dump_file, "\n");
2794 /* Put the allocnos into the corresponding buckets. */
2795 colorable_allocno_bucket = NULL;
2796 uncolorable_allocno_bucket = NULL;
2797 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
2799 a = ira_allocnos[i];
2800 if (ALLOCNO_COLOR_DATA (a)->in_graph_p)
2801 put_allocno_into_bucket (a);
2803 push_allocnos_to_stack ();
2804 pop_allocnos_from_stack ();
2805 finish_allocno_hard_regs_nodes_forest ();
2807 improve_allocation ();
2812 /* Output information about the loop given by its LOOP_TREE_NODE. */
2813 static void
2814 print_loop_title (ira_loop_tree_node_t loop_tree_node)
2816 unsigned int j;
2817 bitmap_iterator bi;
2818 ira_loop_tree_node_t subloop_node, dest_loop_node;
2819 edge e;
2820 edge_iterator ei;
2822 if (loop_tree_node->parent == NULL)
2823 fprintf (ira_dump_file,
2824 "\n Loop 0 (parent -1, header bb%d, depth 0)\n bbs:",
2825 NUM_FIXED_BLOCKS);
2826 else
2828 ira_assert (current_loops != NULL && loop_tree_node->loop != NULL);
2829 fprintf (ira_dump_file,
2830 "\n Loop %d (parent %d, header bb%d, depth %d)\n bbs:",
2831 loop_tree_node->loop_num, loop_tree_node->parent->loop_num,
2832 loop_tree_node->loop->header->index,
2833 loop_depth (loop_tree_node->loop));
2835 for (subloop_node = loop_tree_node->children;
2836 subloop_node != NULL;
2837 subloop_node = subloop_node->next)
2838 if (subloop_node->bb != NULL)
2840 fprintf (ira_dump_file, " %d", subloop_node->bb->index);
2841 FOR_EACH_EDGE (e, ei, subloop_node->bb->succs)
2842 if (e->dest != EXIT_BLOCK_PTR
2843 && ((dest_loop_node = IRA_BB_NODE (e->dest)->parent)
2844 != loop_tree_node))
2845 fprintf (ira_dump_file, "(->%d:l%d)",
2846 e->dest->index, dest_loop_node->loop_num);
2848 fprintf (ira_dump_file, "\n all:");
2849 EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->all_allocnos, 0, j, bi)
2850 fprintf (ira_dump_file, " %dr%d", j, ALLOCNO_REGNO (ira_allocnos[j]));
2851 fprintf (ira_dump_file, "\n modified regnos:");
2852 EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->modified_regnos, 0, j, bi)
2853 fprintf (ira_dump_file, " %d", j);
2854 fprintf (ira_dump_file, "\n border:");
2855 EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->border_allocnos, 0, j, bi)
2856 fprintf (ira_dump_file, " %dr%d", j, ALLOCNO_REGNO (ira_allocnos[j]));
2857 fprintf (ira_dump_file, "\n Pressure:");
2858 for (j = 0; (int) j < ira_pressure_classes_num; j++)
2860 enum reg_class pclass;
2862 pclass = ira_pressure_classes[j];
2863 if (loop_tree_node->reg_pressure[pclass] == 0)
2864 continue;
2865 fprintf (ira_dump_file, " %s=%d", reg_class_names[pclass],
2866 loop_tree_node->reg_pressure[pclass]);
2868 fprintf (ira_dump_file, "\n");
2871 /* Color the allocnos inside loop (in the extreme case it can be all
2872 of the function) given the corresponding LOOP_TREE_NODE. The
2873 function is called for each loop during top-down traverse of the
2874 loop tree. */
2875 static void
2876 color_pass (ira_loop_tree_node_t loop_tree_node)
2878 int regno, hard_regno, index = -1, n;
2879 int cost, exit_freq, enter_freq;
2880 unsigned int j;
2881 bitmap_iterator bi;
2882 enum machine_mode mode;
2883 enum reg_class rclass, aclass, pclass;
2884 ira_allocno_t a, subloop_allocno;
2885 ira_loop_tree_node_t subloop_node;
2887 ira_assert (loop_tree_node->bb == NULL);
2888 if (internal_flag_ira_verbose > 1 && ira_dump_file != NULL)
2889 print_loop_title (loop_tree_node);
2891 bitmap_copy (coloring_allocno_bitmap, loop_tree_node->all_allocnos);
2892 bitmap_copy (consideration_allocno_bitmap, coloring_allocno_bitmap);
2893 n = 0;
2894 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
2896 a = ira_allocnos[j];
2897 n++;
2898 if (! ALLOCNO_ASSIGNED_P (a))
2899 continue;
2900 bitmap_clear_bit (coloring_allocno_bitmap, ALLOCNO_NUM (a));
2902 allocno_color_data
2903 = (allocno_color_data_t) ira_allocate (sizeof (struct allocno_color_data)
2904 * n);
2905 memset (allocno_color_data, 0, sizeof (struct allocno_color_data) * n);
2906 curr_allocno_process = 0;
2907 n = 0;
2908 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
2910 a = ira_allocnos[j];
2911 ALLOCNO_ADD_DATA (a) = allocno_color_data + n;
2912 n++;
2914 /* Color all mentioned allocnos including transparent ones. */
2915 color_allocnos ();
2916 /* Process caps. They are processed just once. */
2917 if (flag_ira_region == IRA_REGION_MIXED
2918 || flag_ira_region == IRA_REGION_ALL)
2919 EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->all_allocnos, 0, j, bi)
2921 a = ira_allocnos[j];
2922 if (ALLOCNO_CAP_MEMBER (a) == NULL)
2923 continue;
2924 /* Remove from processing in the next loop. */
2925 bitmap_clear_bit (consideration_allocno_bitmap, j);
2926 rclass = ALLOCNO_CLASS (a);
2927 pclass = ira_pressure_class_translate[rclass];
2928 if (flag_ira_region == IRA_REGION_MIXED
2929 && (loop_tree_node->reg_pressure[pclass]
2930 <= ira_class_hard_regs_num[pclass]))
2932 mode = ALLOCNO_MODE (a);
2933 hard_regno = ALLOCNO_HARD_REGNO (a);
2934 if (hard_regno >= 0)
2936 index = ira_class_hard_reg_index[rclass][hard_regno];
2937 ira_assert (index >= 0);
2939 regno = ALLOCNO_REGNO (a);
2940 subloop_allocno = ALLOCNO_CAP_MEMBER (a);
2941 subloop_node = ALLOCNO_LOOP_TREE_NODE (subloop_allocno);
2942 ira_assert (!ALLOCNO_ASSIGNED_P (subloop_allocno));
2943 ALLOCNO_HARD_REGNO (subloop_allocno) = hard_regno;
2944 ALLOCNO_ASSIGNED_P (subloop_allocno) = true;
2945 if (hard_regno >= 0)
2946 update_costs_from_copies (subloop_allocno, true, true);
2947 /* We don't need updated costs anymore: */
2948 ira_free_allocno_updated_costs (subloop_allocno);
2951 /* Update costs of the corresponding allocnos (not caps) in the
2952 subloops. */
2953 for (subloop_node = loop_tree_node->subloops;
2954 subloop_node != NULL;
2955 subloop_node = subloop_node->subloop_next)
2957 ira_assert (subloop_node->bb == NULL);
2958 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
2960 a = ira_allocnos[j];
2961 ira_assert (ALLOCNO_CAP_MEMBER (a) == NULL);
2962 mode = ALLOCNO_MODE (a);
2963 rclass = ALLOCNO_CLASS (a);
2964 pclass = ira_pressure_class_translate[rclass];
2965 hard_regno = ALLOCNO_HARD_REGNO (a);
2966 /* Use hard register class here. ??? */
2967 if (hard_regno >= 0)
2969 index = ira_class_hard_reg_index[rclass][hard_regno];
2970 ira_assert (index >= 0);
2972 regno = ALLOCNO_REGNO (a);
2973 /* ??? conflict costs */
2974 subloop_allocno = subloop_node->regno_allocno_map[regno];
2975 if (subloop_allocno == NULL
2976 || ALLOCNO_CAP (subloop_allocno) != NULL)
2977 continue;
2978 ira_assert (ALLOCNO_CLASS (subloop_allocno) == rclass);
2979 ira_assert (bitmap_bit_p (subloop_node->all_allocnos,
2980 ALLOCNO_NUM (subloop_allocno)));
2981 if ((flag_ira_region == IRA_REGION_MIXED)
2982 && (loop_tree_node->reg_pressure[pclass]
2983 <= ira_class_hard_regs_num[pclass]))
2985 if (! ALLOCNO_ASSIGNED_P (subloop_allocno))
2987 ALLOCNO_HARD_REGNO (subloop_allocno) = hard_regno;
2988 ALLOCNO_ASSIGNED_P (subloop_allocno) = true;
2989 if (hard_regno >= 0)
2990 update_costs_from_copies (subloop_allocno, true, true);
2991 /* We don't need updated costs anymore: */
2992 ira_free_allocno_updated_costs (subloop_allocno);
2994 continue;
2996 exit_freq = ira_loop_edge_freq (subloop_node, regno, true);
2997 enter_freq = ira_loop_edge_freq (subloop_node, regno, false);
2998 ira_assert (regno < ira_reg_equiv_len);
2999 if (ira_equiv_no_lvalue_p (regno))
3001 if (! ALLOCNO_ASSIGNED_P (subloop_allocno))
3003 ALLOCNO_HARD_REGNO (subloop_allocno) = hard_regno;
3004 ALLOCNO_ASSIGNED_P (subloop_allocno) = true;
3005 if (hard_regno >= 0)
3006 update_costs_from_copies (subloop_allocno, true, true);
3007 /* We don't need updated costs anymore: */
3008 ira_free_allocno_updated_costs (subloop_allocno);
3011 else if (hard_regno < 0)
3013 ALLOCNO_UPDATED_MEMORY_COST (subloop_allocno)
3014 -= ((ira_memory_move_cost[mode][rclass][1] * enter_freq)
3015 + (ira_memory_move_cost[mode][rclass][0] * exit_freq));
3017 else
3019 aclass = ALLOCNO_CLASS (subloop_allocno);
3020 ira_init_register_move_cost_if_necessary (mode);
3021 cost = (ira_register_move_cost[mode][rclass][rclass]
3022 * (exit_freq + enter_freq));
3023 ira_allocate_and_set_or_copy_costs
3024 (&ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno), aclass,
3025 ALLOCNO_UPDATED_CLASS_COST (subloop_allocno),
3026 ALLOCNO_HARD_REG_COSTS (subloop_allocno));
3027 ira_allocate_and_set_or_copy_costs
3028 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (subloop_allocno),
3029 aclass, 0, ALLOCNO_CONFLICT_HARD_REG_COSTS (subloop_allocno));
3030 ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno)[index] -= cost;
3031 ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (subloop_allocno)[index]
3032 -= cost;
3033 if (ALLOCNO_UPDATED_CLASS_COST (subloop_allocno)
3034 > ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno)[index])
3035 ALLOCNO_UPDATED_CLASS_COST (subloop_allocno)
3036 = ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno)[index];
3037 ALLOCNO_UPDATED_MEMORY_COST (subloop_allocno)
3038 += (ira_memory_move_cost[mode][rclass][0] * enter_freq
3039 + ira_memory_move_cost[mode][rclass][1] * exit_freq);
3043 ira_free (allocno_color_data);
3044 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, j, bi)
3046 a = ira_allocnos[j];
3047 ALLOCNO_ADD_DATA (a) = NULL;
3051 /* Initialize the common data for coloring and calls functions to do
3052 Chaitin-Briggs and regional coloring. */
3053 static void
3054 do_coloring (void)
3056 coloring_allocno_bitmap = ira_allocate_bitmap ();
3057 if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
3058 fprintf (ira_dump_file, "\n**** Allocnos coloring:\n\n");
3060 ira_traverse_loop_tree (false, ira_loop_tree_root, color_pass, NULL);
3062 if (internal_flag_ira_verbose > 1 && ira_dump_file != NULL)
3063 ira_print_disposition (ira_dump_file);
3065 ira_free_bitmap (coloring_allocno_bitmap);
3070 /* Move spill/restore code, which are to be generated in ira-emit.c,
3071 to less frequent points (if it is profitable) by reassigning some
3072 allocnos (in loop with subloops containing in another loop) to
3073 memory which results in longer live-range where the corresponding
3074 pseudo-registers will be in memory. */
3075 static void
3076 move_spill_restore (void)
3078 int cost, regno, hard_regno, hard_regno2, index;
3079 bool changed_p;
3080 int enter_freq, exit_freq;
3081 enum machine_mode mode;
3082 enum reg_class rclass;
3083 ira_allocno_t a, parent_allocno, subloop_allocno;
3084 ira_loop_tree_node_t parent, loop_node, subloop_node;
3085 ira_allocno_iterator ai;
3087 for (;;)
3089 changed_p = false;
3090 if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
3091 fprintf (ira_dump_file, "New iteration of spill/restore move\n");
3092 FOR_EACH_ALLOCNO (a, ai)
3094 regno = ALLOCNO_REGNO (a);
3095 loop_node = ALLOCNO_LOOP_TREE_NODE (a);
3096 if (ALLOCNO_CAP_MEMBER (a) != NULL
3097 || ALLOCNO_CAP (a) != NULL
3098 || (hard_regno = ALLOCNO_HARD_REGNO (a)) < 0
3099 || loop_node->children == NULL
3100 /* don't do the optimization because it can create
3101 copies and the reload pass can spill the allocno set
3102 by copy although the allocno will not get memory
3103 slot. */
3104 || ira_equiv_no_lvalue_p (regno)
3105 || !bitmap_bit_p (loop_node->border_allocnos, ALLOCNO_NUM (a)))
3106 continue;
3107 mode = ALLOCNO_MODE (a);
3108 rclass = ALLOCNO_CLASS (a);
3109 index = ira_class_hard_reg_index[rclass][hard_regno];
3110 ira_assert (index >= 0);
3111 cost = (ALLOCNO_MEMORY_COST (a)
3112 - (ALLOCNO_HARD_REG_COSTS (a) == NULL
3113 ? ALLOCNO_CLASS_COST (a)
3114 : ALLOCNO_HARD_REG_COSTS (a)[index]));
3115 ira_init_register_move_cost_if_necessary (mode);
3116 for (subloop_node = loop_node->subloops;
3117 subloop_node != NULL;
3118 subloop_node = subloop_node->subloop_next)
3120 ira_assert (subloop_node->bb == NULL);
3121 subloop_allocno = subloop_node->regno_allocno_map[regno];
3122 if (subloop_allocno == NULL)
3123 continue;
3124 ira_assert (rclass == ALLOCNO_CLASS (subloop_allocno));
3125 /* We have accumulated cost. To get the real cost of
3126 allocno usage in the loop we should subtract costs of
3127 the subloop allocnos. */
3128 cost -= (ALLOCNO_MEMORY_COST (subloop_allocno)
3129 - (ALLOCNO_HARD_REG_COSTS (subloop_allocno) == NULL
3130 ? ALLOCNO_CLASS_COST (subloop_allocno)
3131 : ALLOCNO_HARD_REG_COSTS (subloop_allocno)[index]));
3132 exit_freq = ira_loop_edge_freq (subloop_node, regno, true);
3133 enter_freq = ira_loop_edge_freq (subloop_node, regno, false);
3134 if ((hard_regno2 = ALLOCNO_HARD_REGNO (subloop_allocno)) < 0)
3135 cost -= (ira_memory_move_cost[mode][rclass][0] * exit_freq
3136 + ira_memory_move_cost[mode][rclass][1] * enter_freq);
3137 else
3139 cost
3140 += (ira_memory_move_cost[mode][rclass][0] * exit_freq
3141 + ira_memory_move_cost[mode][rclass][1] * enter_freq);
3142 if (hard_regno2 != hard_regno)
3143 cost -= (ira_register_move_cost[mode][rclass][rclass]
3144 * (exit_freq + enter_freq));
3147 if ((parent = loop_node->parent) != NULL
3148 && (parent_allocno = parent->regno_allocno_map[regno]) != NULL)
3150 ira_assert (rclass == ALLOCNO_CLASS (parent_allocno));
3151 exit_freq = ira_loop_edge_freq (loop_node, regno, true);
3152 enter_freq = ira_loop_edge_freq (loop_node, regno, false);
3153 if ((hard_regno2 = ALLOCNO_HARD_REGNO (parent_allocno)) < 0)
3154 cost -= (ira_memory_move_cost[mode][rclass][0] * exit_freq
3155 + ira_memory_move_cost[mode][rclass][1] * enter_freq);
3156 else
3158 cost
3159 += (ira_memory_move_cost[mode][rclass][1] * exit_freq
3160 + ira_memory_move_cost[mode][rclass][0] * enter_freq);
3161 if (hard_regno2 != hard_regno)
3162 cost -= (ira_register_move_cost[mode][rclass][rclass]
3163 * (exit_freq + enter_freq));
3166 if (cost < 0)
3168 ALLOCNO_HARD_REGNO (a) = -1;
3169 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3171 fprintf
3172 (ira_dump_file,
3173 " Moving spill/restore for a%dr%d up from loop %d",
3174 ALLOCNO_NUM (a), regno, loop_node->loop_num);
3175 fprintf (ira_dump_file, " - profit %d\n", -cost);
3177 changed_p = true;
3180 if (! changed_p)
3181 break;
3187 /* Update current hard reg costs and current conflict hard reg costs
3188 for allocno A. It is done by processing its copies containing
3189 other allocnos already assigned. */
3190 static void
3191 update_curr_costs (ira_allocno_t a)
3193 int i, hard_regno, cost;
3194 enum machine_mode mode;
3195 enum reg_class aclass, rclass;
3196 ira_allocno_t another_a;
3197 ira_copy_t cp, next_cp;
3199 ira_free_allocno_updated_costs (a);
3200 ira_assert (! ALLOCNO_ASSIGNED_P (a));
3201 aclass = ALLOCNO_CLASS (a);
3202 if (aclass == NO_REGS)
3203 return;
3204 mode = ALLOCNO_MODE (a);
3205 ira_init_register_move_cost_if_necessary (mode);
3206 for (cp = ALLOCNO_COPIES (a); cp != NULL; cp = next_cp)
3208 if (cp->first == a)
3210 next_cp = cp->next_first_allocno_copy;
3211 another_a = cp->second;
3213 else if (cp->second == a)
3215 next_cp = cp->next_second_allocno_copy;
3216 another_a = cp->first;
3218 else
3219 gcc_unreachable ();
3220 if (! ira_reg_classes_intersect_p[aclass][ALLOCNO_CLASS (another_a)]
3221 || ! ALLOCNO_ASSIGNED_P (another_a)
3222 || (hard_regno = ALLOCNO_HARD_REGNO (another_a)) < 0)
3223 continue;
3224 rclass = REGNO_REG_CLASS (hard_regno);
3225 i = ira_class_hard_reg_index[aclass][hard_regno];
3226 if (i < 0)
3227 continue;
3228 cost = (cp->first == a
3229 ? ira_register_move_cost[mode][rclass][aclass]
3230 : ira_register_move_cost[mode][aclass][rclass]);
3231 ira_allocate_and_set_or_copy_costs
3232 (&ALLOCNO_UPDATED_HARD_REG_COSTS (a), aclass, ALLOCNO_CLASS_COST (a),
3233 ALLOCNO_HARD_REG_COSTS (a));
3234 ira_allocate_and_set_or_copy_costs
3235 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a),
3236 aclass, 0, ALLOCNO_CONFLICT_HARD_REG_COSTS (a));
3237 ALLOCNO_UPDATED_HARD_REG_COSTS (a)[i] -= cp->freq * cost;
3238 ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a)[i] -= cp->freq * cost;
3242 /* Try to assign hard registers to the unassigned allocnos and
3243 allocnos conflicting with them or conflicting with allocnos whose
3244 regno >= START_REGNO. The function is called after ira_flattening,
3245 so more allocnos (including ones created in ira-emit.c) will have a
3246 chance to get a hard register. We use simple assignment algorithm
3247 based on priorities. */
3248 void
3249 ira_reassign_conflict_allocnos (int start_regno)
3251 int i, allocnos_to_color_num;
3252 ira_allocno_t a;
3253 enum reg_class aclass;
3254 bitmap allocnos_to_color;
3255 ira_allocno_iterator ai;
3257 allocnos_to_color = ira_allocate_bitmap ();
3258 allocnos_to_color_num = 0;
3259 FOR_EACH_ALLOCNO (a, ai)
3261 int n = ALLOCNO_NUM_OBJECTS (a);
3263 if (! ALLOCNO_ASSIGNED_P (a)
3264 && ! bitmap_bit_p (allocnos_to_color, ALLOCNO_NUM (a)))
3266 if (ALLOCNO_CLASS (a) != NO_REGS)
3267 sorted_allocnos[allocnos_to_color_num++] = a;
3268 else
3270 ALLOCNO_ASSIGNED_P (a) = true;
3271 ALLOCNO_HARD_REGNO (a) = -1;
3272 ira_assert (ALLOCNO_UPDATED_HARD_REG_COSTS (a) == NULL);
3273 ira_assert (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a) == NULL);
3275 bitmap_set_bit (allocnos_to_color, ALLOCNO_NUM (a));
3277 if (ALLOCNO_REGNO (a) < start_regno
3278 || (aclass = ALLOCNO_CLASS (a)) == NO_REGS)
3279 continue;
3280 for (i = 0; i < n; i++)
3282 ira_object_t obj = ALLOCNO_OBJECT (a, i);
3283 ira_object_t conflict_obj;
3284 ira_object_conflict_iterator oci;
3286 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
3288 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
3290 ira_assert (ira_reg_classes_intersect_p
3291 [aclass][ALLOCNO_CLASS (conflict_a)]);
3292 if (!bitmap_set_bit (allocnos_to_color, ALLOCNO_NUM (conflict_a)))
3293 continue;
3294 sorted_allocnos[allocnos_to_color_num++] = conflict_a;
3298 ira_free_bitmap (allocnos_to_color);
3299 if (allocnos_to_color_num > 1)
3301 setup_allocno_priorities (sorted_allocnos, allocnos_to_color_num);
3302 qsort (sorted_allocnos, allocnos_to_color_num, sizeof (ira_allocno_t),
3303 allocno_priority_compare_func);
3305 for (i = 0; i < allocnos_to_color_num; i++)
3307 a = sorted_allocnos[i];
3308 ALLOCNO_ASSIGNED_P (a) = false;
3309 update_curr_costs (a);
3311 for (i = 0; i < allocnos_to_color_num; i++)
3313 a = sorted_allocnos[i];
3314 if (assign_hard_reg (a, true))
3316 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3317 fprintf
3318 (ira_dump_file,
3319 " Secondary allocation: assign hard reg %d to reg %d\n",
3320 ALLOCNO_HARD_REGNO (a), ALLOCNO_REGNO (a));
3327 /* This page contains functions used to find conflicts using allocno
3328 live ranges. */
3330 /* Return TRUE if live ranges of allocnos A1 and A2 intersect. It is
3331 used to find a conflict for new allocnos or allocnos with the
3332 different allocno classes. */
3333 static bool
3334 allocnos_conflict_by_live_ranges_p (ira_allocno_t a1, ira_allocno_t a2)
3336 rtx reg1, reg2;
3337 int i, j;
3338 int n1 = ALLOCNO_NUM_OBJECTS (a1);
3339 int n2 = ALLOCNO_NUM_OBJECTS (a2);
3341 if (a1 == a2)
3342 return false;
3343 reg1 = regno_reg_rtx[ALLOCNO_REGNO (a1)];
3344 reg2 = regno_reg_rtx[ALLOCNO_REGNO (a2)];
3345 if (reg1 != NULL && reg2 != NULL
3346 && ORIGINAL_REGNO (reg1) == ORIGINAL_REGNO (reg2))
3347 return false;
3349 for (i = 0; i < n1; i++)
3351 ira_object_t c1 = ALLOCNO_OBJECT (a1, i);
3353 for (j = 0; j < n2; j++)
3355 ira_object_t c2 = ALLOCNO_OBJECT (a2, j);
3357 if (ira_live_ranges_intersect_p (OBJECT_LIVE_RANGES (c1),
3358 OBJECT_LIVE_RANGES (c2)))
3359 return true;
3362 return false;
3365 #ifdef ENABLE_IRA_CHECKING
3367 /* Return TRUE if live ranges of pseudo-registers REGNO1 and REGNO2
3368 intersect. This should be used when there is only one region.
3369 Currently this is used during reload. */
3370 static bool
3371 conflict_by_live_ranges_p (int regno1, int regno2)
3373 ira_allocno_t a1, a2;
3375 ira_assert (regno1 >= FIRST_PSEUDO_REGISTER
3376 && regno2 >= FIRST_PSEUDO_REGISTER);
3377 /* Reg info caclulated by dataflow infrastructure can be different
3378 from one calculated by regclass. */
3379 if ((a1 = ira_loop_tree_root->regno_allocno_map[regno1]) == NULL
3380 || (a2 = ira_loop_tree_root->regno_allocno_map[regno2]) == NULL)
3381 return false;
3382 return allocnos_conflict_by_live_ranges_p (a1, a2);
3385 #endif
3389 /* This page contains code to coalesce memory stack slots used by
3390 spilled allocnos. This results in smaller stack frame, better data
3391 locality, and in smaller code for some architectures like
3392 x86/x86_64 where insn size depends on address displacement value.
3393 On the other hand, it can worsen insn scheduling after the RA but
3394 in practice it is less important than smaller stack frames. */
3396 /* TRUE if we coalesced some allocnos. In other words, if we got
3397 loops formed by members first_coalesced_allocno and
3398 next_coalesced_allocno containing more one allocno. */
3399 static bool allocno_coalesced_p;
3401 /* Bitmap used to prevent a repeated allocno processing because of
3402 coalescing. */
3403 static bitmap processed_coalesced_allocno_bitmap;
3405 /* See below. */
3406 typedef struct coalesce_data *coalesce_data_t;
3408 /* To decrease footprint of ira_allocno structure we store all data
3409 needed only for coalescing in the following structure. */
3410 struct coalesce_data
3412 /* Coalesced allocnos form a cyclic list. One allocno given by
3413 FIRST represents all coalesced allocnos. The
3414 list is chained by NEXT. */
3415 ira_allocno_t first;
3416 ira_allocno_t next;
3417 int temp;
3420 /* Container for storing allocno data concerning coalescing. */
3421 static coalesce_data_t allocno_coalesce_data;
3423 /* Macro to access the data concerning coalescing. */
3424 #define ALLOCNO_COALESCE_DATA(a) ((coalesce_data_t) ALLOCNO_ADD_DATA (a))
3426 /* The function is used to sort allocnos according to their execution
3427 frequencies. */
3428 static int
3429 copy_freq_compare_func (const void *v1p, const void *v2p)
3431 ira_copy_t cp1 = *(const ira_copy_t *) v1p, cp2 = *(const ira_copy_t *) v2p;
3432 int pri1, pri2;
3434 pri1 = cp1->freq;
3435 pri2 = cp2->freq;
3436 if (pri2 - pri1)
3437 return pri2 - pri1;
3439 /* If freqencies are equal, sort by copies, so that the results of
3440 qsort leave nothing to chance. */
3441 return cp1->num - cp2->num;
3444 /* Merge two sets of coalesced allocnos given correspondingly by
3445 allocnos A1 and A2 (more accurately merging A2 set into A1
3446 set). */
3447 static void
3448 merge_allocnos (ira_allocno_t a1, ira_allocno_t a2)
3450 ira_allocno_t a, first, last, next;
3452 first = ALLOCNO_COALESCE_DATA (a1)->first;
3453 a = ALLOCNO_COALESCE_DATA (a2)->first;
3454 if (first == a)
3455 return;
3456 for (last = a2, a = ALLOCNO_COALESCE_DATA (a2)->next;;
3457 a = ALLOCNO_COALESCE_DATA (a)->next)
3459 ALLOCNO_COALESCE_DATA (a)->first = first;
3460 if (a == a2)
3461 break;
3462 last = a;
3464 next = allocno_coalesce_data[ALLOCNO_NUM (first)].next;
3465 allocno_coalesce_data[ALLOCNO_NUM (first)].next = a2;
3466 allocno_coalesce_data[ALLOCNO_NUM (last)].next = next;
3469 /* Return TRUE if there are conflicting allocnos from two sets of
3470 coalesced allocnos given correspondingly by allocnos A1 and A2. We
3471 use live ranges to find conflicts because conflicts are represented
3472 only for allocnos of the same allocno class and during the reload
3473 pass we coalesce allocnos for sharing stack memory slots. */
3474 static bool
3475 coalesced_allocno_conflict_p (ira_allocno_t a1, ira_allocno_t a2)
3477 ira_allocno_t a, conflict_a;
3479 if (allocno_coalesced_p)
3481 bitmap_clear (processed_coalesced_allocno_bitmap);
3482 for (a = ALLOCNO_COALESCE_DATA (a1)->next;;
3483 a = ALLOCNO_COALESCE_DATA (a)->next)
3485 bitmap_set_bit (processed_coalesced_allocno_bitmap, ALLOCNO_NUM (a));
3486 if (a == a1)
3487 break;
3490 for (a = ALLOCNO_COALESCE_DATA (a2)->next;;
3491 a = ALLOCNO_COALESCE_DATA (a)->next)
3493 for (conflict_a = ALLOCNO_COALESCE_DATA (a1)->next;;
3494 conflict_a = ALLOCNO_COALESCE_DATA (conflict_a)->next)
3496 if (allocnos_conflict_by_live_ranges_p (a, conflict_a))
3497 return true;
3498 if (conflict_a == a1)
3499 break;
3501 if (a == a2)
3502 break;
3504 return false;
3507 /* The major function for aggressive allocno coalescing. We coalesce
3508 only spilled allocnos. If some allocnos have been coalesced, we
3509 set up flag allocno_coalesced_p. */
3510 static void
3511 coalesce_allocnos (void)
3513 ira_allocno_t a;
3514 ira_copy_t cp, next_cp, *sorted_copies;
3515 unsigned int j;
3516 int i, n, cp_num, regno;
3517 bitmap_iterator bi;
3519 sorted_copies = (ira_copy_t *) ira_allocate (ira_copies_num
3520 * sizeof (ira_copy_t));
3521 cp_num = 0;
3522 /* Collect copies. */
3523 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, j, bi)
3525 a = ira_allocnos[j];
3526 regno = ALLOCNO_REGNO (a);
3527 if (! ALLOCNO_ASSIGNED_P (a) || ALLOCNO_HARD_REGNO (a) >= 0
3528 || ira_equiv_no_lvalue_p (regno))
3529 continue;
3530 for (cp = ALLOCNO_COPIES (a); cp != NULL; cp = next_cp)
3532 if (cp->first == a)
3534 next_cp = cp->next_first_allocno_copy;
3535 regno = ALLOCNO_REGNO (cp->second);
3536 /* For priority coloring we coalesce allocnos only with
3537 the same allocno class not with intersected allocno
3538 classes as it were possible. It is done for
3539 simplicity. */
3540 if ((cp->insn != NULL || cp->constraint_p)
3541 && ALLOCNO_ASSIGNED_P (cp->second)
3542 && ALLOCNO_HARD_REGNO (cp->second) < 0
3543 && ! ira_equiv_no_lvalue_p (regno))
3544 sorted_copies[cp_num++] = cp;
3546 else if (cp->second == a)
3547 next_cp = cp->next_second_allocno_copy;
3548 else
3549 gcc_unreachable ();
3552 qsort (sorted_copies, cp_num, sizeof (ira_copy_t), copy_freq_compare_func);
3553 /* Coalesced copies, most frequently executed first. */
3554 for (; cp_num != 0;)
3556 for (i = 0; i < cp_num; i++)
3558 cp = sorted_copies[i];
3559 if (! coalesced_allocno_conflict_p (cp->first, cp->second))
3561 allocno_coalesced_p = true;
3562 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3563 fprintf
3564 (ira_dump_file,
3565 " Coalescing copy %d:a%dr%d-a%dr%d (freq=%d)\n",
3566 cp->num, ALLOCNO_NUM (cp->first), ALLOCNO_REGNO (cp->first),
3567 ALLOCNO_NUM (cp->second), ALLOCNO_REGNO (cp->second),
3568 cp->freq);
3569 merge_allocnos (cp->first, cp->second);
3570 i++;
3571 break;
3574 /* Collect the rest of copies. */
3575 for (n = 0; i < cp_num; i++)
3577 cp = sorted_copies[i];
3578 if (allocno_coalesce_data[ALLOCNO_NUM (cp->first)].first
3579 != allocno_coalesce_data[ALLOCNO_NUM (cp->second)].first)
3580 sorted_copies[n++] = cp;
3582 cp_num = n;
3584 ira_free (sorted_copies);
3587 /* Usage cost and order number of coalesced allocno set to which
3588 given pseudo register belongs to. */
3589 static int *regno_coalesced_allocno_cost;
3590 static int *regno_coalesced_allocno_num;
3592 /* Sort pseudos according frequencies of coalesced allocno sets they
3593 belong to (putting most frequently ones first), and according to
3594 coalesced allocno set order numbers. */
3595 static int
3596 coalesced_pseudo_reg_freq_compare (const void *v1p, const void *v2p)
3598 const int regno1 = *(const int *) v1p;
3599 const int regno2 = *(const int *) v2p;
3600 int diff;
3602 if ((diff = (regno_coalesced_allocno_cost[regno2]
3603 - regno_coalesced_allocno_cost[regno1])) != 0)
3604 return diff;
3605 if ((diff = (regno_coalesced_allocno_num[regno1]
3606 - regno_coalesced_allocno_num[regno2])) != 0)
3607 return diff;
3608 return regno1 - regno2;
3611 /* Widest width in which each pseudo reg is referred to (via subreg).
3612 It is used for sorting pseudo registers. */
3613 static unsigned int *regno_max_ref_width;
3615 /* Redefine STACK_GROWS_DOWNWARD in terms of 0 or 1. */
3616 #ifdef STACK_GROWS_DOWNWARD
3617 # undef STACK_GROWS_DOWNWARD
3618 # define STACK_GROWS_DOWNWARD 1
3619 #else
3620 # define STACK_GROWS_DOWNWARD 0
3621 #endif
3623 /* Sort pseudos according their slot numbers (putting ones with
3624 smaller numbers first, or last when the frame pointer is not
3625 needed). */
3626 static int
3627 coalesced_pseudo_reg_slot_compare (const void *v1p, const void *v2p)
3629 const int regno1 = *(const int *) v1p;
3630 const int regno2 = *(const int *) v2p;
3631 ira_allocno_t a1 = ira_regno_allocno_map[regno1];
3632 ira_allocno_t a2 = ira_regno_allocno_map[regno2];
3633 int diff, slot_num1, slot_num2;
3634 int total_size1, total_size2;
3636 if (a1 == NULL || ALLOCNO_HARD_REGNO (a1) >= 0)
3638 if (a2 == NULL || ALLOCNO_HARD_REGNO (a2) >= 0)
3639 return regno1 - regno2;
3640 return 1;
3642 else if (a2 == NULL || ALLOCNO_HARD_REGNO (a2) >= 0)
3643 return -1;
3644 slot_num1 = -ALLOCNO_HARD_REGNO (a1);
3645 slot_num2 = -ALLOCNO_HARD_REGNO (a2);
3646 if ((diff = slot_num1 - slot_num2) != 0)
3647 return (frame_pointer_needed
3648 || !FRAME_GROWS_DOWNWARD == STACK_GROWS_DOWNWARD ? diff : -diff);
3649 total_size1 = MAX (PSEUDO_REGNO_BYTES (regno1),
3650 regno_max_ref_width[regno1]);
3651 total_size2 = MAX (PSEUDO_REGNO_BYTES (regno2),
3652 regno_max_ref_width[regno2]);
3653 if ((diff = total_size2 - total_size1) != 0)
3654 return diff;
3655 return regno1 - regno2;
3658 /* Setup REGNO_COALESCED_ALLOCNO_COST and REGNO_COALESCED_ALLOCNO_NUM
3659 for coalesced allocno sets containing allocnos with their regnos
3660 given in array PSEUDO_REGNOS of length N. */
3661 static void
3662 setup_coalesced_allocno_costs_and_nums (int *pseudo_regnos, int n)
3664 int i, num, regno, cost;
3665 ira_allocno_t allocno, a;
3667 for (num = i = 0; i < n; i++)
3669 regno = pseudo_regnos[i];
3670 allocno = ira_regno_allocno_map[regno];
3671 if (allocno == NULL)
3673 regno_coalesced_allocno_cost[regno] = 0;
3674 regno_coalesced_allocno_num[regno] = ++num;
3675 continue;
3677 if (ALLOCNO_COALESCE_DATA (allocno)->first != allocno)
3678 continue;
3679 num++;
3680 for (cost = 0, a = ALLOCNO_COALESCE_DATA (allocno)->next;;
3681 a = ALLOCNO_COALESCE_DATA (a)->next)
3683 cost += ALLOCNO_FREQ (a);
3684 if (a == allocno)
3685 break;
3687 for (a = ALLOCNO_COALESCE_DATA (allocno)->next;;
3688 a = ALLOCNO_COALESCE_DATA (a)->next)
3690 regno_coalesced_allocno_num[ALLOCNO_REGNO (a)] = num;
3691 regno_coalesced_allocno_cost[ALLOCNO_REGNO (a)] = cost;
3692 if (a == allocno)
3693 break;
3698 /* Collect spilled allocnos representing coalesced allocno sets (the
3699 first coalesced allocno). The collected allocnos are returned
3700 through array SPILLED_COALESCED_ALLOCNOS. The function returns the
3701 number of the collected allocnos. The allocnos are given by their
3702 regnos in array PSEUDO_REGNOS of length N. */
3703 static int
3704 collect_spilled_coalesced_allocnos (int *pseudo_regnos, int n,
3705 ira_allocno_t *spilled_coalesced_allocnos)
3707 int i, num, regno;
3708 ira_allocno_t allocno;
3710 for (num = i = 0; i < n; i++)
3712 regno = pseudo_regnos[i];
3713 allocno = ira_regno_allocno_map[regno];
3714 if (allocno == NULL || ALLOCNO_HARD_REGNO (allocno) >= 0
3715 || ALLOCNO_COALESCE_DATA (allocno)->first != allocno)
3716 continue;
3717 spilled_coalesced_allocnos[num++] = allocno;
3719 return num;
3722 /* Array of live ranges of size IRA_ALLOCNOS_NUM. Live range for
3723 given slot contains live ranges of coalesced allocnos assigned to
3724 given slot. */
3725 static live_range_t *slot_coalesced_allocnos_live_ranges;
3727 /* Return TRUE if coalesced allocnos represented by ALLOCNO has live
3728 ranges intersected with live ranges of coalesced allocnos assigned
3729 to slot with number N. */
3730 static bool
3731 slot_coalesced_allocno_live_ranges_intersect_p (ira_allocno_t allocno, int n)
3733 ira_allocno_t a;
3735 for (a = ALLOCNO_COALESCE_DATA (allocno)->next;;
3736 a = ALLOCNO_COALESCE_DATA (a)->next)
3738 int i;
3739 int nr = ALLOCNO_NUM_OBJECTS (a);
3741 for (i = 0; i < nr; i++)
3743 ira_object_t obj = ALLOCNO_OBJECT (a, i);
3745 if (ira_live_ranges_intersect_p
3746 (slot_coalesced_allocnos_live_ranges[n],
3747 OBJECT_LIVE_RANGES (obj)))
3748 return true;
3750 if (a == allocno)
3751 break;
3753 return false;
3756 /* Update live ranges of slot to which coalesced allocnos represented
3757 by ALLOCNO were assigned. */
3758 static void
3759 setup_slot_coalesced_allocno_live_ranges (ira_allocno_t allocno)
3761 int i, n;
3762 ira_allocno_t a;
3763 live_range_t r;
3765 n = ALLOCNO_COALESCE_DATA (allocno)->temp;
3766 for (a = ALLOCNO_COALESCE_DATA (allocno)->next;;
3767 a = ALLOCNO_COALESCE_DATA (a)->next)
3769 int nr = ALLOCNO_NUM_OBJECTS (a);
3770 for (i = 0; i < nr; i++)
3772 ira_object_t obj = ALLOCNO_OBJECT (a, i);
3774 r = ira_copy_live_range_list (OBJECT_LIVE_RANGES (obj));
3775 slot_coalesced_allocnos_live_ranges[n]
3776 = ira_merge_live_ranges
3777 (slot_coalesced_allocnos_live_ranges[n], r);
3779 if (a == allocno)
3780 break;
3784 /* We have coalesced allocnos involving in copies. Coalesce allocnos
3785 further in order to share the same memory stack slot. Allocnos
3786 representing sets of allocnos coalesced before the call are given
3787 in array SPILLED_COALESCED_ALLOCNOS of length NUM. Return TRUE if
3788 some allocnos were coalesced in the function. */
3789 static bool
3790 coalesce_spill_slots (ira_allocno_t *spilled_coalesced_allocnos, int num)
3792 int i, j, n, last_coalesced_allocno_num;
3793 ira_allocno_t allocno, a;
3794 bool merged_p = false;
3795 bitmap set_jump_crosses = regstat_get_setjmp_crosses ();
3797 slot_coalesced_allocnos_live_ranges
3798 = (live_range_t *) ira_allocate (sizeof (live_range_t) * ira_allocnos_num);
3799 memset (slot_coalesced_allocnos_live_ranges, 0,
3800 sizeof (live_range_t) * ira_allocnos_num);
3801 last_coalesced_allocno_num = 0;
3802 /* Coalesce non-conflicting spilled allocnos preferring most
3803 frequently used. */
3804 for (i = 0; i < num; i++)
3806 allocno = spilled_coalesced_allocnos[i];
3807 if (ALLOCNO_COALESCE_DATA (allocno)->first != allocno
3808 || bitmap_bit_p (set_jump_crosses, ALLOCNO_REGNO (allocno))
3809 || ira_equiv_no_lvalue_p (ALLOCNO_REGNO (allocno)))
3810 continue;
3811 for (j = 0; j < i; j++)
3813 a = spilled_coalesced_allocnos[j];
3814 n = ALLOCNO_COALESCE_DATA (a)->temp;
3815 if (ALLOCNO_COALESCE_DATA (a)->first == a
3816 && ! bitmap_bit_p (set_jump_crosses, ALLOCNO_REGNO (a))
3817 && ! ira_equiv_no_lvalue_p (ALLOCNO_REGNO (a))
3818 && ! slot_coalesced_allocno_live_ranges_intersect_p (allocno, n))
3819 break;
3821 if (j >= i)
3823 /* No coalescing: set up number for coalesced allocnos
3824 represented by ALLOCNO. */
3825 ALLOCNO_COALESCE_DATA (allocno)->temp = last_coalesced_allocno_num++;
3826 setup_slot_coalesced_allocno_live_ranges (allocno);
3828 else
3830 allocno_coalesced_p = true;
3831 merged_p = true;
3832 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3833 fprintf (ira_dump_file,
3834 " Coalescing spilled allocnos a%dr%d->a%dr%d\n",
3835 ALLOCNO_NUM (allocno), ALLOCNO_REGNO (allocno),
3836 ALLOCNO_NUM (a), ALLOCNO_REGNO (a));
3837 ALLOCNO_COALESCE_DATA (allocno)->temp
3838 = ALLOCNO_COALESCE_DATA (a)->temp;
3839 setup_slot_coalesced_allocno_live_ranges (allocno);
3840 merge_allocnos (a, allocno);
3841 ira_assert (ALLOCNO_COALESCE_DATA (a)->first == a);
3844 for (i = 0; i < ira_allocnos_num; i++)
3845 ira_finish_live_range_list (slot_coalesced_allocnos_live_ranges[i]);
3846 ira_free (slot_coalesced_allocnos_live_ranges);
3847 return merged_p;
3850 /* Sort pseudo-register numbers in array PSEUDO_REGNOS of length N for
3851 subsequent assigning stack slots to them in the reload pass. To do
3852 this we coalesce spilled allocnos first to decrease the number of
3853 memory-memory move insns. This function is called by the
3854 reload. */
3855 void
3856 ira_sort_regnos_for_alter_reg (int *pseudo_regnos, int n,
3857 unsigned int *reg_max_ref_width)
3859 int max_regno = max_reg_num ();
3860 int i, regno, num, slot_num;
3861 ira_allocno_t allocno, a;
3862 ira_allocno_iterator ai;
3863 ira_allocno_t *spilled_coalesced_allocnos;
3865 /* Set up allocnos can be coalesced. */
3866 coloring_allocno_bitmap = ira_allocate_bitmap ();
3867 for (i = 0; i < n; i++)
3869 regno = pseudo_regnos[i];
3870 allocno = ira_regno_allocno_map[regno];
3871 if (allocno != NULL)
3872 bitmap_set_bit (coloring_allocno_bitmap, ALLOCNO_NUM (allocno));
3874 allocno_coalesced_p = false;
3875 processed_coalesced_allocno_bitmap = ira_allocate_bitmap ();
3876 allocno_coalesce_data
3877 = (coalesce_data_t) ira_allocate (sizeof (struct coalesce_data)
3878 * ira_allocnos_num);
3879 /* Initialize coalesce data for allocnos. */
3880 FOR_EACH_ALLOCNO (a, ai)
3882 ALLOCNO_ADD_DATA (a) = allocno_coalesce_data + ALLOCNO_NUM (a);
3883 ALLOCNO_COALESCE_DATA (a)->first = a;
3884 ALLOCNO_COALESCE_DATA (a)->next = a;
3886 coalesce_allocnos ();
3887 ira_free_bitmap (coloring_allocno_bitmap);
3888 regno_coalesced_allocno_cost
3889 = (int *) ira_allocate (max_regno * sizeof (int));
3890 regno_coalesced_allocno_num
3891 = (int *) ira_allocate (max_regno * sizeof (int));
3892 memset (regno_coalesced_allocno_num, 0, max_regno * sizeof (int));
3893 setup_coalesced_allocno_costs_and_nums (pseudo_regnos, n);
3894 /* Sort regnos according frequencies of the corresponding coalesced
3895 allocno sets. */
3896 qsort (pseudo_regnos, n, sizeof (int), coalesced_pseudo_reg_freq_compare);
3897 spilled_coalesced_allocnos
3898 = (ira_allocno_t *) ira_allocate (ira_allocnos_num
3899 * sizeof (ira_allocno_t));
3900 /* Collect allocnos representing the spilled coalesced allocno
3901 sets. */
3902 num = collect_spilled_coalesced_allocnos (pseudo_regnos, n,
3903 spilled_coalesced_allocnos);
3904 if (flag_ira_share_spill_slots
3905 && coalesce_spill_slots (spilled_coalesced_allocnos, num))
3907 setup_coalesced_allocno_costs_and_nums (pseudo_regnos, n);
3908 qsort (pseudo_regnos, n, sizeof (int),
3909 coalesced_pseudo_reg_freq_compare);
3910 num = collect_spilled_coalesced_allocnos (pseudo_regnos, n,
3911 spilled_coalesced_allocnos);
3913 ira_free_bitmap (processed_coalesced_allocno_bitmap);
3914 allocno_coalesced_p = false;
3915 /* Assign stack slot numbers to spilled allocno sets, use smaller
3916 numbers for most frequently used coalesced allocnos. -1 is
3917 reserved for dynamic search of stack slots for pseudos spilled by
3918 the reload. */
3919 slot_num = 1;
3920 for (i = 0; i < num; i++)
3922 allocno = spilled_coalesced_allocnos[i];
3923 if (ALLOCNO_COALESCE_DATA (allocno)->first != allocno
3924 || ALLOCNO_HARD_REGNO (allocno) >= 0
3925 || ira_equiv_no_lvalue_p (ALLOCNO_REGNO (allocno)))
3926 continue;
3927 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3928 fprintf (ira_dump_file, " Slot %d (freq,size):", slot_num);
3929 slot_num++;
3930 for (a = ALLOCNO_COALESCE_DATA (allocno)->next;;
3931 a = ALLOCNO_COALESCE_DATA (a)->next)
3933 ira_assert (ALLOCNO_HARD_REGNO (a) < 0);
3934 ALLOCNO_HARD_REGNO (a) = -slot_num;
3935 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3936 fprintf (ira_dump_file, " a%dr%d(%d,%d)",
3937 ALLOCNO_NUM (a), ALLOCNO_REGNO (a), ALLOCNO_FREQ (a),
3938 MAX (PSEUDO_REGNO_BYTES (ALLOCNO_REGNO (a)),
3939 reg_max_ref_width[ALLOCNO_REGNO (a)]));
3941 if (a == allocno)
3942 break;
3944 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3945 fprintf (ira_dump_file, "\n");
3947 ira_spilled_reg_stack_slots_num = slot_num - 1;
3948 ira_free (spilled_coalesced_allocnos);
3949 /* Sort regnos according the slot numbers. */
3950 regno_max_ref_width = reg_max_ref_width;
3951 qsort (pseudo_regnos, n, sizeof (int), coalesced_pseudo_reg_slot_compare);
3952 FOR_EACH_ALLOCNO (a, ai)
3953 ALLOCNO_ADD_DATA (a) = NULL;
3954 ira_free (allocno_coalesce_data);
3955 ira_free (regno_coalesced_allocno_num);
3956 ira_free (regno_coalesced_allocno_cost);
3961 /* This page contains code used by the reload pass to improve the
3962 final code. */
3964 /* The function is called from reload to mark changes in the
3965 allocation of REGNO made by the reload. Remember that reg_renumber
3966 reflects the change result. */
3967 void
3968 ira_mark_allocation_change (int regno)
3970 ira_allocno_t a = ira_regno_allocno_map[regno];
3971 int old_hard_regno, hard_regno, cost;
3972 enum reg_class aclass = ALLOCNO_CLASS (a);
3974 ira_assert (a != NULL);
3975 hard_regno = reg_renumber[regno];
3976 if ((old_hard_regno = ALLOCNO_HARD_REGNO (a)) == hard_regno)
3977 return;
3978 if (old_hard_regno < 0)
3979 cost = -ALLOCNO_MEMORY_COST (a);
3980 else
3982 ira_assert (ira_class_hard_reg_index[aclass][old_hard_regno] >= 0);
3983 cost = -(ALLOCNO_HARD_REG_COSTS (a) == NULL
3984 ? ALLOCNO_CLASS_COST (a)
3985 : ALLOCNO_HARD_REG_COSTS (a)
3986 [ira_class_hard_reg_index[aclass][old_hard_regno]]);
3987 update_costs_from_copies (a, false, false);
3989 ira_overall_cost -= cost;
3990 ALLOCNO_HARD_REGNO (a) = hard_regno;
3991 if (hard_regno < 0)
3993 ALLOCNO_HARD_REGNO (a) = -1;
3994 cost += ALLOCNO_MEMORY_COST (a);
3996 else if (ira_class_hard_reg_index[aclass][hard_regno] >= 0)
3998 cost += (ALLOCNO_HARD_REG_COSTS (a) == NULL
3999 ? ALLOCNO_CLASS_COST (a)
4000 : ALLOCNO_HARD_REG_COSTS (a)
4001 [ira_class_hard_reg_index[aclass][hard_regno]]);
4002 update_costs_from_copies (a, true, false);
4004 else
4005 /* Reload changed class of the allocno. */
4006 cost = 0;
4007 ira_overall_cost += cost;
4010 /* This function is called when reload deletes memory-memory move. In
4011 this case we marks that the allocation of the corresponding
4012 allocnos should be not changed in future. Otherwise we risk to get
4013 a wrong code. */
4014 void
4015 ira_mark_memory_move_deletion (int dst_regno, int src_regno)
4017 ira_allocno_t dst = ira_regno_allocno_map[dst_regno];
4018 ira_allocno_t src = ira_regno_allocno_map[src_regno];
4020 ira_assert (dst != NULL && src != NULL
4021 && ALLOCNO_HARD_REGNO (dst) < 0
4022 && ALLOCNO_HARD_REGNO (src) < 0);
4023 ALLOCNO_DONT_REASSIGN_P (dst) = true;
4024 ALLOCNO_DONT_REASSIGN_P (src) = true;
4027 /* Try to assign a hard register (except for FORBIDDEN_REGS) to
4028 allocno A and return TRUE in the case of success. */
4029 static bool
4030 allocno_reload_assign (ira_allocno_t a, HARD_REG_SET forbidden_regs)
4032 int hard_regno;
4033 enum reg_class aclass;
4034 int regno = ALLOCNO_REGNO (a);
4035 HARD_REG_SET saved[2];
4036 int i, n;
4038 n = ALLOCNO_NUM_OBJECTS (a);
4039 for (i = 0; i < n; i++)
4041 ira_object_t obj = ALLOCNO_OBJECT (a, i);
4042 COPY_HARD_REG_SET (saved[i], OBJECT_TOTAL_CONFLICT_HARD_REGS (obj));
4043 IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), forbidden_regs);
4044 if (! flag_caller_saves && ALLOCNO_CALLS_CROSSED_NUM (a) != 0)
4045 IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
4046 call_used_reg_set);
4048 ALLOCNO_ASSIGNED_P (a) = false;
4049 aclass = ALLOCNO_CLASS (a);
4050 update_curr_costs (a);
4051 assign_hard_reg (a, true);
4052 hard_regno = ALLOCNO_HARD_REGNO (a);
4053 reg_renumber[regno] = hard_regno;
4054 if (hard_regno < 0)
4055 ALLOCNO_HARD_REGNO (a) = -1;
4056 else
4058 ira_assert (ira_class_hard_reg_index[aclass][hard_regno] >= 0);
4059 ira_overall_cost
4060 -= (ALLOCNO_MEMORY_COST (a)
4061 - (ALLOCNO_HARD_REG_COSTS (a) == NULL
4062 ? ALLOCNO_CLASS_COST (a)
4063 : ALLOCNO_HARD_REG_COSTS (a)[ira_class_hard_reg_index
4064 [aclass][hard_regno]]));
4065 if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0
4066 && ira_hard_reg_set_intersection_p (hard_regno, ALLOCNO_MODE (a),
4067 call_used_reg_set))
4069 ira_assert (flag_caller_saves);
4070 caller_save_needed = 1;
4074 /* If we found a hard register, modify the RTL for the pseudo
4075 register to show the hard register, and mark the pseudo register
4076 live. */
4077 if (reg_renumber[regno] >= 0)
4079 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4080 fprintf (ira_dump_file, ": reassign to %d\n", reg_renumber[regno]);
4081 SET_REGNO (regno_reg_rtx[regno], reg_renumber[regno]);
4082 mark_home_live (regno);
4084 else if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4085 fprintf (ira_dump_file, "\n");
4086 for (i = 0; i < n; i++)
4088 ira_object_t obj = ALLOCNO_OBJECT (a, i);
4089 COPY_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), saved[i]);
4091 return reg_renumber[regno] >= 0;
4094 /* Sort pseudos according their usage frequencies (putting most
4095 frequently ones first). */
4096 static int
4097 pseudo_reg_compare (const void *v1p, const void *v2p)
4099 int regno1 = *(const int *) v1p;
4100 int regno2 = *(const int *) v2p;
4101 int diff;
4103 if ((diff = REG_FREQ (regno2) - REG_FREQ (regno1)) != 0)
4104 return diff;
4105 return regno1 - regno2;
4108 /* Try to allocate hard registers to SPILLED_PSEUDO_REGS (there are
4109 NUM of them) or spilled pseudos conflicting with pseudos in
4110 SPILLED_PSEUDO_REGS. Return TRUE and update SPILLED, if the
4111 allocation has been changed. The function doesn't use
4112 BAD_SPILL_REGS and hard registers in PSEUDO_FORBIDDEN_REGS and
4113 PSEUDO_PREVIOUS_REGS for the corresponding pseudos. The function
4114 is called by the reload pass at the end of each reload
4115 iteration. */
4116 bool
4117 ira_reassign_pseudos (int *spilled_pseudo_regs, int num,
4118 HARD_REG_SET bad_spill_regs,
4119 HARD_REG_SET *pseudo_forbidden_regs,
4120 HARD_REG_SET *pseudo_previous_regs,
4121 bitmap spilled)
4123 int i, n, regno;
4124 bool changed_p;
4125 ira_allocno_t a;
4126 HARD_REG_SET forbidden_regs;
4127 bitmap temp = BITMAP_ALLOC (NULL);
4129 /* Add pseudos which conflict with pseudos already in
4130 SPILLED_PSEUDO_REGS to SPILLED_PSEUDO_REGS. This is preferable
4131 to allocating in two steps as some of the conflicts might have
4132 a higher priority than the pseudos passed in SPILLED_PSEUDO_REGS. */
4133 for (i = 0; i < num; i++)
4134 bitmap_set_bit (temp, spilled_pseudo_regs[i]);
4136 for (i = 0, n = num; i < n; i++)
4138 int nr, j;
4139 int regno = spilled_pseudo_regs[i];
4140 bitmap_set_bit (temp, regno);
4142 a = ira_regno_allocno_map[regno];
4143 nr = ALLOCNO_NUM_OBJECTS (a);
4144 for (j = 0; j < nr; j++)
4146 ira_object_t conflict_obj;
4147 ira_object_t obj = ALLOCNO_OBJECT (a, j);
4148 ira_object_conflict_iterator oci;
4150 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
4152 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
4153 if (ALLOCNO_HARD_REGNO (conflict_a) < 0
4154 && ! ALLOCNO_DONT_REASSIGN_P (conflict_a)
4155 && bitmap_set_bit (temp, ALLOCNO_REGNO (conflict_a)))
4157 spilled_pseudo_regs[num++] = ALLOCNO_REGNO (conflict_a);
4158 /* ?!? This seems wrong. */
4159 bitmap_set_bit (consideration_allocno_bitmap,
4160 ALLOCNO_NUM (conflict_a));
4166 if (num > 1)
4167 qsort (spilled_pseudo_regs, num, sizeof (int), pseudo_reg_compare);
4168 changed_p = false;
4169 /* Try to assign hard registers to pseudos from
4170 SPILLED_PSEUDO_REGS. */
4171 for (i = 0; i < num; i++)
4173 regno = spilled_pseudo_regs[i];
4174 COPY_HARD_REG_SET (forbidden_regs, bad_spill_regs);
4175 IOR_HARD_REG_SET (forbidden_regs, pseudo_forbidden_regs[regno]);
4176 IOR_HARD_REG_SET (forbidden_regs, pseudo_previous_regs[regno]);
4177 gcc_assert (reg_renumber[regno] < 0);
4178 a = ira_regno_allocno_map[regno];
4179 ira_mark_allocation_change (regno);
4180 ira_assert (reg_renumber[regno] < 0);
4181 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4182 fprintf (ira_dump_file,
4183 " Try Assign %d(a%d), cost=%d", regno, ALLOCNO_NUM (a),
4184 ALLOCNO_MEMORY_COST (a)
4185 - ALLOCNO_CLASS_COST (a));
4186 allocno_reload_assign (a, forbidden_regs);
4187 if (reg_renumber[regno] >= 0)
4189 CLEAR_REGNO_REG_SET (spilled, regno);
4190 changed_p = true;
4193 BITMAP_FREE (temp);
4194 return changed_p;
4197 /* The function is called by reload and returns already allocated
4198 stack slot (if any) for REGNO with given INHERENT_SIZE and
4199 TOTAL_SIZE. In the case of failure to find a slot which can be
4200 used for REGNO, the function returns NULL. */
4202 ira_reuse_stack_slot (int regno, unsigned int inherent_size,
4203 unsigned int total_size)
4205 unsigned int i;
4206 int slot_num, best_slot_num;
4207 int cost, best_cost;
4208 ira_copy_t cp, next_cp;
4209 ira_allocno_t another_allocno, allocno = ira_regno_allocno_map[regno];
4210 rtx x;
4211 bitmap_iterator bi;
4212 struct ira_spilled_reg_stack_slot *slot = NULL;
4214 ira_assert (inherent_size == PSEUDO_REGNO_BYTES (regno)
4215 && inherent_size <= total_size
4216 && ALLOCNO_HARD_REGNO (allocno) < 0);
4217 if (! flag_ira_share_spill_slots)
4218 return NULL_RTX;
4219 slot_num = -ALLOCNO_HARD_REGNO (allocno) - 2;
4220 if (slot_num != -1)
4222 slot = &ira_spilled_reg_stack_slots[slot_num];
4223 x = slot->mem;
4225 else
4227 best_cost = best_slot_num = -1;
4228 x = NULL_RTX;
4229 /* It means that the pseudo was spilled in the reload pass, try
4230 to reuse a slot. */
4231 for (slot_num = 0;
4232 slot_num < ira_spilled_reg_stack_slots_num;
4233 slot_num++)
4235 slot = &ira_spilled_reg_stack_slots[slot_num];
4236 if (slot->mem == NULL_RTX)
4237 continue;
4238 if (slot->width < total_size
4239 || GET_MODE_SIZE (GET_MODE (slot->mem)) < inherent_size)
4240 continue;
4242 EXECUTE_IF_SET_IN_BITMAP (&slot->spilled_regs,
4243 FIRST_PSEUDO_REGISTER, i, bi)
4245 another_allocno = ira_regno_allocno_map[i];
4246 if (allocnos_conflict_by_live_ranges_p (allocno,
4247 another_allocno))
4248 goto cont;
4250 for (cost = 0, cp = ALLOCNO_COPIES (allocno);
4251 cp != NULL;
4252 cp = next_cp)
4254 if (cp->first == allocno)
4256 next_cp = cp->next_first_allocno_copy;
4257 another_allocno = cp->second;
4259 else if (cp->second == allocno)
4261 next_cp = cp->next_second_allocno_copy;
4262 another_allocno = cp->first;
4264 else
4265 gcc_unreachable ();
4266 if (cp->insn == NULL_RTX)
4267 continue;
4268 if (bitmap_bit_p (&slot->spilled_regs,
4269 ALLOCNO_REGNO (another_allocno)))
4270 cost += cp->freq;
4272 if (cost > best_cost)
4274 best_cost = cost;
4275 best_slot_num = slot_num;
4277 cont:
4280 if (best_cost >= 0)
4282 slot_num = best_slot_num;
4283 slot = &ira_spilled_reg_stack_slots[slot_num];
4284 SET_REGNO_REG_SET (&slot->spilled_regs, regno);
4285 x = slot->mem;
4286 ALLOCNO_HARD_REGNO (allocno) = -slot_num - 2;
4289 if (x != NULL_RTX)
4291 ira_assert (slot->width >= total_size);
4292 #ifdef ENABLE_IRA_CHECKING
4293 EXECUTE_IF_SET_IN_BITMAP (&slot->spilled_regs,
4294 FIRST_PSEUDO_REGISTER, i, bi)
4296 ira_assert (! conflict_by_live_ranges_p (regno, i));
4298 #endif
4299 SET_REGNO_REG_SET (&slot->spilled_regs, regno);
4300 if (internal_flag_ira_verbose > 3 && ira_dump_file)
4302 fprintf (ira_dump_file, " Assigning %d(freq=%d) slot %d of",
4303 regno, REG_FREQ (regno), slot_num);
4304 EXECUTE_IF_SET_IN_BITMAP (&slot->spilled_regs,
4305 FIRST_PSEUDO_REGISTER, i, bi)
4307 if ((unsigned) regno != i)
4308 fprintf (ira_dump_file, " %d", i);
4310 fprintf (ira_dump_file, "\n");
4313 return x;
4316 /* This is called by reload every time a new stack slot X with
4317 TOTAL_SIZE was allocated for REGNO. We store this info for
4318 subsequent ira_reuse_stack_slot calls. */
4319 void
4320 ira_mark_new_stack_slot (rtx x, int regno, unsigned int total_size)
4322 struct ira_spilled_reg_stack_slot *slot;
4323 int slot_num;
4324 ira_allocno_t allocno;
4326 ira_assert (PSEUDO_REGNO_BYTES (regno) <= total_size);
4327 allocno = ira_regno_allocno_map[regno];
4328 slot_num = -ALLOCNO_HARD_REGNO (allocno) - 2;
4329 if (slot_num == -1)
4331 slot_num = ira_spilled_reg_stack_slots_num++;
4332 ALLOCNO_HARD_REGNO (allocno) = -slot_num - 2;
4334 slot = &ira_spilled_reg_stack_slots[slot_num];
4335 INIT_REG_SET (&slot->spilled_regs);
4336 SET_REGNO_REG_SET (&slot->spilled_regs, regno);
4337 slot->mem = x;
4338 slot->width = total_size;
4339 if (internal_flag_ira_verbose > 3 && ira_dump_file)
4340 fprintf (ira_dump_file, " Assigning %d(freq=%d) a new slot %d\n",
4341 regno, REG_FREQ (regno), slot_num);
4345 /* Return spill cost for pseudo-registers whose numbers are in array
4346 REGNOS (with a negative number as an end marker) for reload with
4347 given IN and OUT for INSN. Return also number points (through
4348 EXCESS_PRESSURE_LIVE_LENGTH) where the pseudo-register lives and
4349 the register pressure is high, number of references of the
4350 pseudo-registers (through NREFS), number of callee-clobbered
4351 hard-registers occupied by the pseudo-registers (through
4352 CALL_USED_COUNT), and the first hard regno occupied by the
4353 pseudo-registers (through FIRST_HARD_REGNO). */
4354 static int
4355 calculate_spill_cost (int *regnos, rtx in, rtx out, rtx insn,
4356 int *excess_pressure_live_length,
4357 int *nrefs, int *call_used_count, int *first_hard_regno)
4359 int i, cost, regno, hard_regno, j, count, saved_cost, nregs;
4360 bool in_p, out_p;
4361 int length;
4362 ira_allocno_t a;
4364 *nrefs = 0;
4365 for (length = count = cost = i = 0;; i++)
4367 regno = regnos[i];
4368 if (regno < 0)
4369 break;
4370 *nrefs += REG_N_REFS (regno);
4371 hard_regno = reg_renumber[regno];
4372 ira_assert (hard_regno >= 0);
4373 a = ira_regno_allocno_map[regno];
4374 length += ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a) / ALLOCNO_NUM_OBJECTS (a);
4375 cost += ALLOCNO_MEMORY_COST (a) - ALLOCNO_CLASS_COST (a);
4376 nregs = hard_regno_nregs[hard_regno][ALLOCNO_MODE (a)];
4377 for (j = 0; j < nregs; j++)
4378 if (! TEST_HARD_REG_BIT (call_used_reg_set, hard_regno + j))
4379 break;
4380 if (j == nregs)
4381 count++;
4382 in_p = in && REG_P (in) && (int) REGNO (in) == hard_regno;
4383 out_p = out && REG_P (out) && (int) REGNO (out) == hard_regno;
4384 if ((in_p || out_p)
4385 && find_regno_note (insn, REG_DEAD, hard_regno) != NULL_RTX)
4387 saved_cost = 0;
4388 if (in_p)
4389 saved_cost += ira_memory_move_cost
4390 [ALLOCNO_MODE (a)][ALLOCNO_CLASS (a)][1];
4391 if (out_p)
4392 saved_cost
4393 += ira_memory_move_cost
4394 [ALLOCNO_MODE (a)][ALLOCNO_CLASS (a)][0];
4395 cost -= REG_FREQ_FROM_BB (BLOCK_FOR_INSN (insn)) * saved_cost;
4398 *excess_pressure_live_length = length;
4399 *call_used_count = count;
4400 hard_regno = -1;
4401 if (regnos[0] >= 0)
4403 hard_regno = reg_renumber[regnos[0]];
4405 *first_hard_regno = hard_regno;
4406 return cost;
4409 /* Return TRUE if spilling pseudo-registers whose numbers are in array
4410 REGNOS is better than spilling pseudo-registers with numbers in
4411 OTHER_REGNOS for reload with given IN and OUT for INSN. The
4412 function used by the reload pass to make better register spilling
4413 decisions. */
4414 bool
4415 ira_better_spill_reload_regno_p (int *regnos, int *other_regnos,
4416 rtx in, rtx out, rtx insn)
4418 int cost, other_cost;
4419 int length, other_length;
4420 int nrefs, other_nrefs;
4421 int call_used_count, other_call_used_count;
4422 int hard_regno, other_hard_regno;
4424 cost = calculate_spill_cost (regnos, in, out, insn,
4425 &length, &nrefs, &call_used_count, &hard_regno);
4426 other_cost = calculate_spill_cost (other_regnos, in, out, insn,
4427 &other_length, &other_nrefs,
4428 &other_call_used_count,
4429 &other_hard_regno);
4430 if (nrefs == 0 && other_nrefs != 0)
4431 return true;
4432 if (nrefs != 0 && other_nrefs == 0)
4433 return false;
4434 if (cost != other_cost)
4435 return cost < other_cost;
4436 if (length != other_length)
4437 return length > other_length;
4438 #ifdef REG_ALLOC_ORDER
4439 if (hard_regno >= 0 && other_hard_regno >= 0)
4440 return (inv_reg_alloc_order[hard_regno]
4441 < inv_reg_alloc_order[other_hard_regno]);
4442 #else
4443 if (call_used_count != other_call_used_count)
4444 return call_used_count > other_call_used_count;
4445 #endif
4446 return false;
4451 /* Allocate and initialize data necessary for assign_hard_reg. */
4452 void
4453 ira_initiate_assign (void)
4455 sorted_allocnos
4456 = (ira_allocno_t *) ira_allocate (sizeof (ira_allocno_t)
4457 * ira_allocnos_num);
4458 consideration_allocno_bitmap = ira_allocate_bitmap ();
4459 initiate_cost_update ();
4460 allocno_priorities = (int *) ira_allocate (sizeof (int) * ira_allocnos_num);
4463 /* Deallocate data used by assign_hard_reg. */
4464 void
4465 ira_finish_assign (void)
4467 ira_free (sorted_allocnos);
4468 ira_free_bitmap (consideration_allocno_bitmap);
4469 finish_cost_update ();
4470 ira_free (allocno_priorities);
4475 /* Entry function doing color-based register allocation. */
4476 static void
4477 color (void)
4479 allocno_stack_vec.create (ira_allocnos_num);
4480 memset (allocated_hardreg_p, 0, sizeof (allocated_hardreg_p));
4481 ira_initiate_assign ();
4482 do_coloring ();
4483 ira_finish_assign ();
4484 allocno_stack_vec.release ();
4485 move_spill_restore ();
4490 /* This page contains a simple register allocator without usage of
4491 allocno conflicts. This is used for fast allocation for -O0. */
4493 /* Do register allocation by not using allocno conflicts. It uses
4494 only allocno live ranges. The algorithm is close to Chow's
4495 priority coloring. */
4496 static void
4497 fast_allocation (void)
4499 int i, j, k, num, class_size, hard_regno;
4500 #ifdef STACK_REGS
4501 bool no_stack_reg_p;
4502 #endif
4503 enum reg_class aclass;
4504 enum machine_mode mode;
4505 ira_allocno_t a;
4506 ira_allocno_iterator ai;
4507 live_range_t r;
4508 HARD_REG_SET conflict_hard_regs, *used_hard_regs;
4510 sorted_allocnos = (ira_allocno_t *) ira_allocate (sizeof (ira_allocno_t)
4511 * ira_allocnos_num);
4512 num = 0;
4513 FOR_EACH_ALLOCNO (a, ai)
4514 sorted_allocnos[num++] = a;
4515 allocno_priorities = (int *) ira_allocate (sizeof (int) * ira_allocnos_num);
4516 setup_allocno_priorities (sorted_allocnos, num);
4517 used_hard_regs = (HARD_REG_SET *) ira_allocate (sizeof (HARD_REG_SET)
4518 * ira_max_point);
4519 for (i = 0; i < ira_max_point; i++)
4520 CLEAR_HARD_REG_SET (used_hard_regs[i]);
4521 qsort (sorted_allocnos, num, sizeof (ira_allocno_t),
4522 allocno_priority_compare_func);
4523 for (i = 0; i < num; i++)
4525 int nr, l;
4527 a = sorted_allocnos[i];
4528 nr = ALLOCNO_NUM_OBJECTS (a);
4529 CLEAR_HARD_REG_SET (conflict_hard_regs);
4530 for (l = 0; l < nr; l++)
4532 ira_object_t obj = ALLOCNO_OBJECT (a, l);
4533 IOR_HARD_REG_SET (conflict_hard_regs,
4534 OBJECT_CONFLICT_HARD_REGS (obj));
4535 for (r = OBJECT_LIVE_RANGES (obj); r != NULL; r = r->next)
4536 for (j = r->start; j <= r->finish; j++)
4537 IOR_HARD_REG_SET (conflict_hard_regs, used_hard_regs[j]);
4539 aclass = ALLOCNO_CLASS (a);
4540 ALLOCNO_ASSIGNED_P (a) = true;
4541 ALLOCNO_HARD_REGNO (a) = -1;
4542 if (hard_reg_set_subset_p (reg_class_contents[aclass],
4543 conflict_hard_regs))
4544 continue;
4545 mode = ALLOCNO_MODE (a);
4546 #ifdef STACK_REGS
4547 no_stack_reg_p = ALLOCNO_NO_STACK_REG_P (a);
4548 #endif
4549 class_size = ira_class_hard_regs_num[aclass];
4550 for (j = 0; j < class_size; j++)
4552 hard_regno = ira_class_hard_regs[aclass][j];
4553 #ifdef STACK_REGS
4554 if (no_stack_reg_p && FIRST_STACK_REG <= hard_regno
4555 && hard_regno <= LAST_STACK_REG)
4556 continue;
4557 #endif
4558 if (ira_hard_reg_set_intersection_p (hard_regno, mode, conflict_hard_regs)
4559 || (TEST_HARD_REG_BIT
4560 (ira_prohibited_class_mode_regs[aclass][mode], hard_regno)))
4561 continue;
4562 ALLOCNO_HARD_REGNO (a) = hard_regno;
4563 for (l = 0; l < nr; l++)
4565 ira_object_t obj = ALLOCNO_OBJECT (a, l);
4566 for (r = OBJECT_LIVE_RANGES (obj); r != NULL; r = r->next)
4567 for (k = r->start; k <= r->finish; k++)
4568 IOR_HARD_REG_SET (used_hard_regs[k],
4569 ira_reg_mode_hard_regset[hard_regno][mode]);
4571 break;
4574 ira_free (sorted_allocnos);
4575 ira_free (used_hard_regs);
4576 ira_free (allocno_priorities);
4577 if (internal_flag_ira_verbose > 1 && ira_dump_file != NULL)
4578 ira_print_disposition (ira_dump_file);
4583 /* Entry function doing coloring. */
4584 void
4585 ira_color (void)
4587 ira_allocno_t a;
4588 ira_allocno_iterator ai;
4590 /* Setup updated costs. */
4591 FOR_EACH_ALLOCNO (a, ai)
4593 ALLOCNO_UPDATED_MEMORY_COST (a) = ALLOCNO_MEMORY_COST (a);
4594 ALLOCNO_UPDATED_CLASS_COST (a) = ALLOCNO_CLASS_COST (a);
4596 if (ira_conflicts_p)
4597 color ();
4598 else
4599 fast_allocation ();