c-family/
[official-gcc.git] / gcc / ira-color.c
blobdd4c73b9482aa7d94846b62840b0b2d9001d568e
1 /* IRA allocation based on graph coloring.
2 Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012
3 Free Software Foundation, Inc.
4 Contributed by Vladimir Makarov <vmakarov@redhat.com>.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "rtl.h"
27 #include "tm_p.h"
28 #include "target.h"
29 #include "regs.h"
30 #include "flags.h"
31 #include "sbitmap.h"
32 #include "bitmap.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 /* To decrease footprint of ira_allocno structure we store all data
92 needed only for coloring in the following structure. */
93 struct allocno_color_data
95 /* TRUE value means that the allocno was not removed yet from the
96 conflicting graph during colouring. */
97 unsigned int in_graph_p : 1;
98 /* TRUE if it is put on the stack to make other allocnos
99 colorable. */
100 unsigned int may_be_spilled_p : 1;
101 /* TRUE if the allocno is trivially colorable. */
102 unsigned int colorable_p : 1;
103 /* Number of hard registers of the allocno class really
104 available for the allocno allocation. It is number of the
105 profitable hard regs. */
106 int available_regs_num;
107 /* Allocnos in a bucket (used in coloring) chained by the following
108 two members. */
109 ira_allocno_t next_bucket_allocno;
110 ira_allocno_t prev_bucket_allocno;
111 /* Used for temporary purposes. */
112 int temp;
113 /* Used to exclude repeated processing. */
114 int last_process;
115 /* Profitable hard regs available for this pseudo allocation. It
116 means that the set excludes unavailable hard regs and hard regs
117 conflicting with given pseudo. They should be of the allocno
118 class. */
119 HARD_REG_SET profitable_hard_regs;
120 /* The allocno hard registers node. */
121 allocno_hard_regs_node_t hard_regs_node;
122 /* Array of structures allocno_hard_regs_subnode representing
123 given allocno hard registers node (the 1st element in the array)
124 and all its subnodes in the tree (forest) of allocno hard
125 register nodes (see comments above). */
126 int hard_regs_subnodes_start;
127 /* The length of the previous array. */
128 int hard_regs_subnodes_num;
131 /* See above. */
132 typedef struct allocno_color_data *allocno_color_data_t;
134 /* Container for storing allocno data concerning coloring. */
135 static allocno_color_data_t allocno_color_data;
137 /* Macro to access the data concerning coloring. */
138 #define ALLOCNO_COLOR_DATA(a) ((allocno_color_data_t) ALLOCNO_ADD_DATA (a))
140 /* Used for finding allocno colorability to exclude repeated allocno
141 processing and for updating preferencing to exclude repeated
142 allocno processing during assignment. */
143 static int curr_allocno_process;
145 /* This file contains code for regional graph coloring, spill/restore
146 code placement optimization, and code helping the reload pass to do
147 a better job. */
149 /* Bitmap of allocnos which should be colored. */
150 static bitmap coloring_allocno_bitmap;
152 /* Bitmap of allocnos which should be taken into account during
153 coloring. In general case it contains allocnos from
154 coloring_allocno_bitmap plus other already colored conflicting
155 allocnos. */
156 static bitmap consideration_allocno_bitmap;
158 /* All allocnos sorted according their priorities. */
159 static ira_allocno_t *sorted_allocnos;
161 /* Vec representing the stack of allocnos used during coloring. */
162 static VEC(ira_allocno_t,heap) *allocno_stack_vec;
164 /* Helper for qsort comparison callbacks - return a positive integer if
165 X > Y, or a negative value otherwise. Use a conditional expression
166 instead of a difference computation to insulate from possible overflow
167 issues, e.g. X - Y < 0 for some X > 0 and Y < 0. */
168 #define SORTGT(x,y) (((x) > (y)) ? 1 : -1)
172 /* Definition of vector of allocno hard registers. */
173 DEF_VEC_P(allocno_hard_regs_t);
174 DEF_VEC_ALLOC_P(allocno_hard_regs_t, heap);
176 /* Vector of unique allocno hard registers. */
177 static VEC(allocno_hard_regs_t, heap) *allocno_hard_regs_vec;
179 /* Returns hash value for allocno hard registers V. */
180 static hashval_t
181 allocno_hard_regs_hash (const void *v)
183 const struct allocno_hard_regs *hv = (const struct allocno_hard_regs *) v;
185 return iterative_hash (&hv->set, sizeof (HARD_REG_SET), 0);
188 /* Compares allocno hard registers V1 and V2. */
189 static int
190 allocno_hard_regs_eq (const void *v1, const void *v2)
192 const struct allocno_hard_regs *hv1 = (const struct allocno_hard_regs *) v1;
193 const struct allocno_hard_regs *hv2 = (const struct allocno_hard_regs *) v2;
195 return hard_reg_set_equal_p (hv1->set, hv2->set);
198 /* Hash table of unique allocno hard registers. */
199 static htab_t allocno_hard_regs_htab;
201 /* Return allocno hard registers in the hash table equal to HV. */
202 static allocno_hard_regs_t
203 find_hard_regs (allocno_hard_regs_t hv)
205 return (allocno_hard_regs_t) htab_find (allocno_hard_regs_htab, hv);
208 /* Insert allocno hard registers HV in the hash table (if it is not
209 there yet) and return the value which in the table. */
210 static allocno_hard_regs_t
211 insert_hard_regs (allocno_hard_regs_t hv)
213 PTR *slot = htab_find_slot (allocno_hard_regs_htab, hv, INSERT);
215 if (*slot == NULL)
216 *slot = hv;
217 return (allocno_hard_regs_t) *slot;
220 /* Initialize data concerning allocno hard registers. */
221 static void
222 init_allocno_hard_regs (void)
224 allocno_hard_regs_vec = VEC_alloc (allocno_hard_regs_t, heap, 200);
225 allocno_hard_regs_htab
226 = htab_create (200, allocno_hard_regs_hash, allocno_hard_regs_eq, NULL);
229 /* Add (or update info about) allocno hard registers with SET and
230 COST. */
231 static allocno_hard_regs_t
232 add_allocno_hard_regs (HARD_REG_SET set, HOST_WIDEST_INT cost)
234 struct allocno_hard_regs temp;
235 allocno_hard_regs_t hv;
237 gcc_assert (! hard_reg_set_empty_p (set));
238 COPY_HARD_REG_SET (temp.set, set);
239 if ((hv = find_hard_regs (&temp)) != NULL)
240 hv->cost += cost;
241 else
243 hv = ((struct allocno_hard_regs *)
244 ira_allocate (sizeof (struct allocno_hard_regs)));
245 COPY_HARD_REG_SET (hv->set, set);
246 hv->cost = cost;
247 VEC_safe_push (allocno_hard_regs_t, heap, allocno_hard_regs_vec, hv);
248 insert_hard_regs (hv);
250 return hv;
253 /* Finalize data concerning allocno hard registers. */
254 static void
255 finish_allocno_hard_regs (void)
257 int i;
258 allocno_hard_regs_t hv;
260 for (i = 0;
261 VEC_iterate (allocno_hard_regs_t, allocno_hard_regs_vec, i, hv);
262 i++)
263 ira_free (hv);
264 htab_delete (allocno_hard_regs_htab);
265 VEC_free (allocno_hard_regs_t, heap, allocno_hard_regs_vec);
268 /* Sort hard regs according to their frequency of usage. */
269 static int
270 allocno_hard_regs_compare (const void *v1p, const void *v2p)
272 allocno_hard_regs_t hv1 = *(const allocno_hard_regs_t *) v1p;
273 allocno_hard_regs_t hv2 = *(const allocno_hard_regs_t *) v2p;
275 if (hv2->cost > hv1->cost)
276 return 1;
277 else if (hv2->cost < hv1->cost)
278 return -1;
279 else
280 return 0;
285 /* Used for finding a common ancestor of two allocno hard registers
286 nodes in the forest. We use the current value of
287 'node_check_tick' to mark all nodes from one node to the top and
288 then walking up from another node until we find a marked node.
290 It is also used to figure out allocno colorability as a mark that
291 we already reset value of member 'conflict_size' for the forest
292 node corresponding to the processed allocno. */
293 static int node_check_tick;
295 /* Roots of the forest containing hard register sets can be assigned
296 to allocnos. */
297 static allocno_hard_regs_node_t hard_regs_roots;
299 /* Definition of vector of allocno hard register nodes. */
300 DEF_VEC_P(allocno_hard_regs_node_t);
301 DEF_VEC_ALLOC_P(allocno_hard_regs_node_t, heap);
303 /* Vector used to create the forest. */
304 static VEC(allocno_hard_regs_node_t, heap) *hard_regs_node_vec;
306 /* Create and return allocno hard registers node containing allocno
307 hard registers HV. */
308 static allocno_hard_regs_node_t
309 create_new_allocno_hard_regs_node (allocno_hard_regs_t hv)
311 allocno_hard_regs_node_t new_node;
313 new_node = ((struct allocno_hard_regs_node *)
314 ira_allocate (sizeof (struct allocno_hard_regs_node)));
315 new_node->check = 0;
316 new_node->hard_regs = hv;
317 new_node->hard_regs_num = hard_reg_set_size (hv->set);
318 new_node->first = NULL;
319 new_node->used_p = false;
320 return new_node;
323 /* Add allocno hard registers node NEW_NODE to the forest on its level
324 given by ROOTS. */
325 static void
326 add_new_allocno_hard_regs_node_to_forest (allocno_hard_regs_node_t *roots,
327 allocno_hard_regs_node_t new_node)
329 new_node->next = *roots;
330 if (new_node->next != NULL)
331 new_node->next->prev = new_node;
332 new_node->prev = NULL;
333 *roots = new_node;
336 /* Add allocno hard registers HV (or its best approximation if it is
337 not possible) to the forest on its level given by ROOTS. */
338 static void
339 add_allocno_hard_regs_to_forest (allocno_hard_regs_node_t *roots,
340 allocno_hard_regs_t hv)
342 unsigned int i, start;
343 allocno_hard_regs_node_t node, prev, new_node;
344 HARD_REG_SET temp_set;
345 allocno_hard_regs_t hv2;
347 start = VEC_length (allocno_hard_regs_node_t, hard_regs_node_vec);
348 for (node = *roots; node != NULL; node = node->next)
350 if (hard_reg_set_equal_p (hv->set, node->hard_regs->set))
351 return;
352 if (hard_reg_set_subset_p (hv->set, node->hard_regs->set))
354 add_allocno_hard_regs_to_forest (&node->first, hv);
355 return;
357 if (hard_reg_set_subset_p (node->hard_regs->set, hv->set))
358 VEC_safe_push (allocno_hard_regs_node_t, heap,
359 hard_regs_node_vec, node);
360 else if (hard_reg_set_intersect_p (hv->set, node->hard_regs->set))
362 COPY_HARD_REG_SET (temp_set, hv->set);
363 AND_HARD_REG_SET (temp_set, node->hard_regs->set);
364 hv2 = add_allocno_hard_regs (temp_set, hv->cost);
365 add_allocno_hard_regs_to_forest (&node->first, hv2);
368 if (VEC_length (allocno_hard_regs_node_t, hard_regs_node_vec)
369 > start + 1)
371 /* Create a new node which contains nodes in hard_regs_node_vec. */
372 CLEAR_HARD_REG_SET (temp_set);
373 for (i = start;
374 i < VEC_length (allocno_hard_regs_node_t, hard_regs_node_vec);
375 i++)
377 node = VEC_index (allocno_hard_regs_node_t, hard_regs_node_vec, i);
378 IOR_HARD_REG_SET (temp_set, node->hard_regs->set);
380 hv = add_allocno_hard_regs (temp_set, hv->cost);
381 new_node = create_new_allocno_hard_regs_node (hv);
382 prev = NULL;
383 for (i = start;
384 i < VEC_length (allocno_hard_regs_node_t, hard_regs_node_vec);
385 i++)
387 node = VEC_index (allocno_hard_regs_node_t, hard_regs_node_vec, i);
388 if (node->prev == NULL)
389 *roots = node->next;
390 else
391 node->prev->next = node->next;
392 if (node->next != NULL)
393 node->next->prev = node->prev;
394 if (prev == NULL)
395 new_node->first = node;
396 else
397 prev->next = node;
398 node->prev = prev;
399 node->next = NULL;
400 prev = node;
402 add_new_allocno_hard_regs_node_to_forest (roots, new_node);
404 VEC_truncate (allocno_hard_regs_node_t, hard_regs_node_vec, start);
407 /* Add allocno hard registers nodes starting with the forest level
408 given by FIRST which contains biggest set inside SET. */
409 static void
410 collect_allocno_hard_regs_cover (allocno_hard_regs_node_t first,
411 HARD_REG_SET set)
413 allocno_hard_regs_node_t node;
415 ira_assert (first != NULL);
416 for (node = first; node != NULL; node = node->next)
417 if (hard_reg_set_subset_p (node->hard_regs->set, set))
418 VEC_safe_push (allocno_hard_regs_node_t, heap, hard_regs_node_vec,
419 node);
420 else if (hard_reg_set_intersect_p (set, node->hard_regs->set))
421 collect_allocno_hard_regs_cover (node->first, set);
424 /* Set up field parent as PARENT in all allocno hard registers nodes
425 in forest given by FIRST. */
426 static void
427 setup_allocno_hard_regs_nodes_parent (allocno_hard_regs_node_t first,
428 allocno_hard_regs_node_t parent)
430 allocno_hard_regs_node_t node;
432 for (node = first; node != NULL; node = node->next)
434 node->parent = parent;
435 setup_allocno_hard_regs_nodes_parent (node->first, node);
439 /* Return allocno hard registers node which is a first common ancestor
440 node of FIRST and SECOND in the forest. */
441 static allocno_hard_regs_node_t
442 first_common_ancestor_node (allocno_hard_regs_node_t first,
443 allocno_hard_regs_node_t second)
445 allocno_hard_regs_node_t node;
447 node_check_tick++;
448 for (node = first; node != NULL; node = node->parent)
449 node->check = node_check_tick;
450 for (node = second; node != NULL; node = node->parent)
451 if (node->check == node_check_tick)
452 return node;
453 return first_common_ancestor_node (second, first);
456 /* Print hard reg set SET to F. */
457 static void
458 print_hard_reg_set (FILE *f, HARD_REG_SET set, bool new_line_p)
460 int i, start;
462 for (start = -1, i = 0; i < FIRST_PSEUDO_REGISTER; i++)
464 if (TEST_HARD_REG_BIT (set, i))
466 if (i == 0 || ! TEST_HARD_REG_BIT (set, i - 1))
467 start = i;
469 if (start >= 0
470 && (i == FIRST_PSEUDO_REGISTER - 1 || ! TEST_HARD_REG_BIT (set, i)))
472 if (start == i - 1)
473 fprintf (f, " %d", start);
474 else if (start == i - 2)
475 fprintf (f, " %d %d", start, start + 1);
476 else
477 fprintf (f, " %d-%d", start, i - 1);
478 start = -1;
481 if (new_line_p)
482 fprintf (f, "\n");
485 /* Print allocno hard register subforest given by ROOTS and its LEVEL
486 to F. */
487 static void
488 print_hard_regs_subforest (FILE *f, allocno_hard_regs_node_t roots,
489 int level)
491 int i;
492 allocno_hard_regs_node_t node;
494 for (node = roots; node != NULL; node = node->next)
496 fprintf (f, " ");
497 for (i = 0; i < level * 2; i++)
498 fprintf (f, " ");
499 fprintf (f, "%d:(", node->preorder_num);
500 print_hard_reg_set (f, node->hard_regs->set, false);
501 fprintf (f, ")@" HOST_WIDEST_INT_PRINT_DEC "\n", node->hard_regs->cost);
502 print_hard_regs_subforest (f, node->first, level + 1);
506 /* Print the allocno hard register forest to F. */
507 static void
508 print_hard_regs_forest (FILE *f)
510 fprintf (f, " Hard reg set forest:\n");
511 print_hard_regs_subforest (f, hard_regs_roots, 1);
514 /* Print the allocno hard register forest to stderr. */
515 void
516 ira_debug_hard_regs_forest (void)
518 print_hard_regs_forest (stderr);
521 /* Remove unused allocno hard registers nodes from forest given by its
522 *ROOTS. */
523 static void
524 remove_unused_allocno_hard_regs_nodes (allocno_hard_regs_node_t *roots)
526 allocno_hard_regs_node_t node, prev, next, last;
528 for (prev = NULL, node = *roots; node != NULL; node = next)
530 next = node->next;
531 if (node->used_p)
533 remove_unused_allocno_hard_regs_nodes (&node->first);
534 prev = node;
536 else
538 for (last = node->first;
539 last != NULL && last->next != NULL;
540 last = last->next)
542 if (last != NULL)
544 if (prev == NULL)
545 *roots = node->first;
546 else
547 prev->next = node->first;
548 if (next != NULL)
549 next->prev = last;
550 last->next = next;
551 next = node->first;
553 else
555 if (prev == NULL)
556 *roots = next;
557 else
558 prev->next = next;
559 if (next != NULL)
560 next->prev = prev;
562 ira_free (node);
567 /* Set up fields preorder_num starting with START_NUM in all allocno
568 hard registers nodes in forest given by FIRST. Return biggest set
569 PREORDER_NUM increased by 1. */
570 static int
571 enumerate_allocno_hard_regs_nodes (allocno_hard_regs_node_t first,
572 allocno_hard_regs_node_t parent,
573 int start_num)
575 allocno_hard_regs_node_t node;
577 for (node = first; node != NULL; node = node->next)
579 node->preorder_num = start_num++;
580 node->parent = parent;
581 start_num = enumerate_allocno_hard_regs_nodes (node->first, node,
582 start_num);
584 return start_num;
587 /* Number of allocno hard registers nodes in the forest. */
588 static int allocno_hard_regs_nodes_num;
590 /* Table preorder number of allocno hard registers node in the forest
591 -> the allocno hard registers node. */
592 static allocno_hard_regs_node_t *allocno_hard_regs_nodes;
594 /* See below. */
595 typedef struct allocno_hard_regs_subnode *allocno_hard_regs_subnode_t;
597 /* The structure is used to describes all subnodes (not only immediate
598 ones) in the mentioned above tree for given allocno hard register
599 node. The usage of such data accelerates calculation of
600 colorability of given allocno. */
601 struct allocno_hard_regs_subnode
603 /* The conflict size of conflicting allocnos whose hard register
604 sets are equal sets (plus supersets if given node is given
605 allocno hard registers node) of one in the given node. */
606 int left_conflict_size;
607 /* The summary conflict size of conflicting allocnos whose hard
608 register sets are strict subsets of one in the given node.
609 Overall conflict size is
610 left_conflict_subnodes_size
611 + MIN (max_node_impact - left_conflict_subnodes_size,
612 left_conflict_size)
614 short left_conflict_subnodes_size;
615 short max_node_impact;
618 /* Container for hard regs subnodes of all allocnos. */
619 static allocno_hard_regs_subnode_t allocno_hard_regs_subnodes;
621 /* Table (preorder number of allocno hard registers node in the
622 forest, preorder number of allocno hard registers subnode) -> index
623 of the subnode relative to the node. -1 if it is not a
624 subnode. */
625 static int *allocno_hard_regs_subnode_index;
627 /* Setup arrays ALLOCNO_HARD_REGS_NODES and
628 ALLOCNO_HARD_REGS_SUBNODE_INDEX. */
629 static void
630 setup_allocno_hard_regs_subnode_index (allocno_hard_regs_node_t first)
632 allocno_hard_regs_node_t node, parent;
633 int index;
635 for (node = first; node != NULL; node = node->next)
637 allocno_hard_regs_nodes[node->preorder_num] = node;
638 for (parent = node; parent != NULL; parent = parent->parent)
640 index = parent->preorder_num * allocno_hard_regs_nodes_num;
641 allocno_hard_regs_subnode_index[index + node->preorder_num]
642 = node->preorder_num - parent->preorder_num;
644 setup_allocno_hard_regs_subnode_index (node->first);
648 /* Count all allocno hard registers nodes in tree ROOT. */
649 static int
650 get_allocno_hard_regs_subnodes_num (allocno_hard_regs_node_t root)
652 int len = 1;
654 for (root = root->first; root != NULL; root = root->next)
655 len += get_allocno_hard_regs_subnodes_num (root);
656 return len;
659 /* Build the forest of allocno hard registers nodes and assign each
660 allocno a node from the forest. */
661 static void
662 form_allocno_hard_regs_nodes_forest (void)
664 unsigned int i, j, size, len;
665 int start;
666 ira_allocno_t a;
667 allocno_hard_regs_t hv;
668 bitmap_iterator bi;
669 HARD_REG_SET temp;
670 allocno_hard_regs_node_t node, allocno_hard_regs_node;
671 allocno_color_data_t allocno_data;
673 node_check_tick = 0;
674 init_allocno_hard_regs ();
675 hard_regs_roots = NULL;
676 hard_regs_node_vec = VEC_alloc (allocno_hard_regs_node_t, heap, 100);
677 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
678 if (! TEST_HARD_REG_BIT (ira_no_alloc_regs, i))
680 CLEAR_HARD_REG_SET (temp);
681 SET_HARD_REG_BIT (temp, i);
682 hv = add_allocno_hard_regs (temp, 0);
683 node = create_new_allocno_hard_regs_node (hv);
684 add_new_allocno_hard_regs_node_to_forest (&hard_regs_roots, node);
686 start = VEC_length (allocno_hard_regs_t, allocno_hard_regs_vec);
687 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
689 a = ira_allocnos[i];
690 allocno_data = ALLOCNO_COLOR_DATA (a);
692 if (hard_reg_set_empty_p (allocno_data->profitable_hard_regs))
693 continue;
694 hv = (add_allocno_hard_regs
695 (allocno_data->profitable_hard_regs,
696 ALLOCNO_MEMORY_COST (a) - ALLOCNO_CLASS_COST (a)));
698 SET_HARD_REG_SET (temp);
699 AND_COMPL_HARD_REG_SET (temp, ira_no_alloc_regs);
700 add_allocno_hard_regs (temp, 0);
701 qsort (VEC_address (allocno_hard_regs_t, allocno_hard_regs_vec) + start,
702 VEC_length (allocno_hard_regs_t, allocno_hard_regs_vec) - start,
703 sizeof (allocno_hard_regs_t), allocno_hard_regs_compare);
704 for (i = start;
705 VEC_iterate (allocno_hard_regs_t, allocno_hard_regs_vec, i, hv);
706 i++)
708 add_allocno_hard_regs_to_forest (&hard_regs_roots, hv);
709 ira_assert (VEC_length (allocno_hard_regs_node_t,
710 hard_regs_node_vec) == 0);
712 /* We need to set up parent fields for right work of
713 first_common_ancestor_node. */
714 setup_allocno_hard_regs_nodes_parent (hard_regs_roots, NULL);
715 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
717 a = ira_allocnos[i];
718 allocno_data = ALLOCNO_COLOR_DATA (a);
719 if (hard_reg_set_empty_p (allocno_data->profitable_hard_regs))
720 continue;
721 VEC_truncate (allocno_hard_regs_node_t, hard_regs_node_vec, 0);
722 collect_allocno_hard_regs_cover (hard_regs_roots,
723 allocno_data->profitable_hard_regs);
724 allocno_hard_regs_node = NULL;
725 for (j = 0;
726 VEC_iterate (allocno_hard_regs_node_t, hard_regs_node_vec,
727 j, node);
728 j++)
729 allocno_hard_regs_node
730 = (j == 0
731 ? node
732 : first_common_ancestor_node (node, allocno_hard_regs_node));
733 /* That is a temporary storage. */
734 allocno_hard_regs_node->used_p = true;
735 allocno_data->hard_regs_node = allocno_hard_regs_node;
737 ira_assert (hard_regs_roots->next == NULL);
738 hard_regs_roots->used_p = true;
739 remove_unused_allocno_hard_regs_nodes (&hard_regs_roots);
740 allocno_hard_regs_nodes_num
741 = enumerate_allocno_hard_regs_nodes (hard_regs_roots, NULL, 0);
742 allocno_hard_regs_nodes
743 = ((allocno_hard_regs_node_t *)
744 ira_allocate (allocno_hard_regs_nodes_num
745 * sizeof (allocno_hard_regs_node_t)));
746 size = allocno_hard_regs_nodes_num * allocno_hard_regs_nodes_num;
747 allocno_hard_regs_subnode_index
748 = (int *) ira_allocate (size * sizeof (int));
749 for (i = 0; i < size; i++)
750 allocno_hard_regs_subnode_index[i] = -1;
751 setup_allocno_hard_regs_subnode_index (hard_regs_roots);
752 start = 0;
753 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
755 a = ira_allocnos[i];
756 allocno_data = ALLOCNO_COLOR_DATA (a);
757 if (hard_reg_set_empty_p (allocno_data->profitable_hard_regs))
758 continue;
759 len = get_allocno_hard_regs_subnodes_num (allocno_data->hard_regs_node);
760 allocno_data->hard_regs_subnodes_start = start;
761 allocno_data->hard_regs_subnodes_num = len;
762 start += len;
764 allocno_hard_regs_subnodes
765 = ((allocno_hard_regs_subnode_t)
766 ira_allocate (sizeof (struct allocno_hard_regs_subnode) * start));
767 VEC_free (allocno_hard_regs_node_t, heap, hard_regs_node_vec);
770 /* Free tree of allocno hard registers nodes given by its ROOT. */
771 static void
772 finish_allocno_hard_regs_nodes_tree (allocno_hard_regs_node_t root)
774 allocno_hard_regs_node_t child, next;
776 for (child = root->first; child != NULL; child = next)
778 next = child->next;
779 finish_allocno_hard_regs_nodes_tree (child);
781 ira_free (root);
784 /* Finish work with the forest of allocno hard registers nodes. */
785 static void
786 finish_allocno_hard_regs_nodes_forest (void)
788 allocno_hard_regs_node_t node, next;
790 ira_free (allocno_hard_regs_subnodes);
791 for (node = hard_regs_roots; node != NULL; node = next)
793 next = node->next;
794 finish_allocno_hard_regs_nodes_tree (node);
796 ira_free (allocno_hard_regs_nodes);
797 ira_free (allocno_hard_regs_subnode_index);
798 finish_allocno_hard_regs ();
801 /* Set up left conflict sizes and left conflict subnodes sizes of hard
802 registers subnodes of allocno A. Return TRUE if allocno A is
803 trivially colorable. */
804 static bool
805 setup_left_conflict_sizes_p (ira_allocno_t a)
807 int i, k, nobj, start;
808 int conflict_size, left_conflict_subnodes_size, node_preorder_num;
809 allocno_color_data_t data;
810 HARD_REG_SET profitable_hard_regs;
811 allocno_hard_regs_subnode_t subnodes;
812 allocno_hard_regs_node_t node;
813 HARD_REG_SET node_set;
815 nobj = ALLOCNO_NUM_OBJECTS (a);
816 conflict_size = 0;
817 data = ALLOCNO_COLOR_DATA (a);
818 subnodes = allocno_hard_regs_subnodes + data->hard_regs_subnodes_start;
819 COPY_HARD_REG_SET (profitable_hard_regs, data->profitable_hard_regs);
820 node = data->hard_regs_node;
821 node_preorder_num = node->preorder_num;
822 COPY_HARD_REG_SET (node_set, node->hard_regs->set);
823 node_check_tick++;
824 for (k = 0; k < nobj; k++)
826 ira_object_t obj = ALLOCNO_OBJECT (a, k);
827 ira_object_t conflict_obj;
828 ira_object_conflict_iterator oci;
830 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
832 int size;
833 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
834 allocno_hard_regs_node_t conflict_node, temp_node;
835 HARD_REG_SET conflict_node_set;
836 allocno_color_data_t conflict_data;
838 conflict_data = ALLOCNO_COLOR_DATA (conflict_a);
839 if (! ALLOCNO_COLOR_DATA (conflict_a)->in_graph_p
840 || ! hard_reg_set_intersect_p (profitable_hard_regs,
841 conflict_data
842 ->profitable_hard_regs))
843 continue;
844 conflict_node = conflict_data->hard_regs_node;
845 COPY_HARD_REG_SET (conflict_node_set, conflict_node->hard_regs->set);
846 if (hard_reg_set_subset_p (node_set, conflict_node_set))
847 temp_node = node;
848 else
850 ira_assert (hard_reg_set_subset_p (conflict_node_set, node_set));
851 temp_node = conflict_node;
853 if (temp_node->check != node_check_tick)
855 temp_node->check = node_check_tick;
856 temp_node->conflict_size = 0;
858 size = (ira_reg_class_max_nregs
859 [ALLOCNO_CLASS (conflict_a)][ALLOCNO_MODE (conflict_a)]);
860 if (ALLOCNO_NUM_OBJECTS (conflict_a) > 1)
861 /* We will deal with the subwords individually. */
862 size = 1;
863 temp_node->conflict_size += size;
866 for (i = 0; i < data->hard_regs_subnodes_num; i++)
868 allocno_hard_regs_node_t temp_node;
870 temp_node = allocno_hard_regs_nodes[i + node_preorder_num];
871 ira_assert (temp_node->preorder_num == i + node_preorder_num);
872 subnodes[i].left_conflict_size = (temp_node->check != node_check_tick
873 ? 0 : temp_node->conflict_size);
874 if (hard_reg_set_subset_p (temp_node->hard_regs->set,
875 profitable_hard_regs))
876 subnodes[i].max_node_impact = temp_node->hard_regs_num;
877 else
879 HARD_REG_SET temp_set;
880 int j, n, hard_regno;
881 enum reg_class aclass;
883 COPY_HARD_REG_SET (temp_set, temp_node->hard_regs->set);
884 AND_HARD_REG_SET (temp_set, profitable_hard_regs);
885 aclass = ALLOCNO_CLASS (a);
886 for (n = 0, j = ira_class_hard_regs_num[aclass] - 1; j >= 0; j--)
888 hard_regno = ira_class_hard_regs[aclass][j];
889 if (TEST_HARD_REG_BIT (temp_set, hard_regno))
890 n++;
892 subnodes[i].max_node_impact = n;
894 subnodes[i].left_conflict_subnodes_size = 0;
896 start = node_preorder_num * allocno_hard_regs_nodes_num;
897 for (i = data->hard_regs_subnodes_num - 1; i >= 0; i--)
899 int size, parent_i;
900 allocno_hard_regs_node_t parent;
902 size = (subnodes[i].left_conflict_subnodes_size
903 + MIN (subnodes[i].max_node_impact
904 - subnodes[i].left_conflict_subnodes_size,
905 subnodes[i].left_conflict_size));
906 parent = allocno_hard_regs_nodes[i + node_preorder_num]->parent;
907 if (parent == NULL)
908 continue;
909 parent_i
910 = allocno_hard_regs_subnode_index[start + parent->preorder_num];
911 if (parent_i < 0)
912 continue;
913 subnodes[parent_i].left_conflict_subnodes_size += size;
915 left_conflict_subnodes_size = subnodes[0].left_conflict_subnodes_size;
916 conflict_size
917 += (left_conflict_subnodes_size
918 + MIN (subnodes[0].max_node_impact - left_conflict_subnodes_size,
919 subnodes[0].left_conflict_size));
920 conflict_size += ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)];
921 data->colorable_p = conflict_size <= data->available_regs_num;
922 return data->colorable_p;
925 /* Update left conflict sizes of hard registers subnodes of allocno A
926 after removing allocno REMOVED_A with SIZE from the conflict graph.
927 Return TRUE if A is trivially colorable. */
928 static bool
929 update_left_conflict_sizes_p (ira_allocno_t a,
930 ira_allocno_t removed_a, int size)
932 int i, conflict_size, before_conflict_size, diff, start;
933 int node_preorder_num, parent_i;
934 allocno_hard_regs_node_t node, removed_node, parent;
935 allocno_hard_regs_subnode_t subnodes;
936 allocno_color_data_t data = ALLOCNO_COLOR_DATA (a);
938 ira_assert (! data->colorable_p);
939 node = data->hard_regs_node;
940 node_preorder_num = node->preorder_num;
941 removed_node = ALLOCNO_COLOR_DATA (removed_a)->hard_regs_node;
942 ira_assert (hard_reg_set_subset_p (removed_node->hard_regs->set,
943 node->hard_regs->set)
944 || hard_reg_set_subset_p (node->hard_regs->set,
945 removed_node->hard_regs->set));
946 start = node_preorder_num * allocno_hard_regs_nodes_num;
947 i = allocno_hard_regs_subnode_index[start + removed_node->preorder_num];
948 if (i < 0)
949 i = 0;
950 subnodes = allocno_hard_regs_subnodes + data->hard_regs_subnodes_start;
951 before_conflict_size
952 = (subnodes[i].left_conflict_subnodes_size
953 + MIN (subnodes[i].max_node_impact
954 - subnodes[i].left_conflict_subnodes_size,
955 subnodes[i].left_conflict_size));
956 subnodes[i].left_conflict_size -= size;
957 for (;;)
959 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 if ((diff = before_conflict_size - conflict_size) == 0)
965 break;
966 ira_assert (conflict_size < before_conflict_size);
967 parent = allocno_hard_regs_nodes[i + node_preorder_num]->parent;
968 if (parent == NULL)
969 break;
970 parent_i
971 = allocno_hard_regs_subnode_index[start + parent->preorder_num];
972 if (parent_i < 0)
973 break;
974 i = parent_i;
975 before_conflict_size
976 = (subnodes[i].left_conflict_subnodes_size
977 + MIN (subnodes[i].max_node_impact
978 - subnodes[i].left_conflict_subnodes_size,
979 subnodes[i].left_conflict_size));
980 subnodes[i].left_conflict_subnodes_size -= diff;
982 if (i != 0
983 || (conflict_size
984 + ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]
985 > data->available_regs_num))
986 return false;
987 data->colorable_p = true;
988 return true;
991 /* Return true if allocno A has empty profitable hard regs. */
992 static bool
993 empty_profitable_hard_regs (ira_allocno_t a)
995 allocno_color_data_t data = ALLOCNO_COLOR_DATA (a);
997 return hard_reg_set_empty_p (data->profitable_hard_regs);
1000 /* Set up profitable hard registers for each allocno being
1001 colored. */
1002 static void
1003 setup_profitable_hard_regs (void)
1005 unsigned int i;
1006 int j, k, nobj, hard_regno, nregs, class_size;
1007 ira_allocno_t a;
1008 bitmap_iterator bi;
1009 enum reg_class aclass;
1010 enum machine_mode mode;
1011 allocno_color_data_t data;
1013 /* Initial set up from allocno classes and explicitly conflicting
1014 hard regs. */
1015 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
1017 a = ira_allocnos[i];
1018 if ((aclass = ALLOCNO_CLASS (a)) == NO_REGS)
1019 continue;
1020 data = ALLOCNO_COLOR_DATA (a);
1021 if (ALLOCNO_UPDATED_HARD_REG_COSTS (a) == NULL
1022 && ALLOCNO_CLASS_COST (a) > ALLOCNO_MEMORY_COST (a))
1023 CLEAR_HARD_REG_SET (data->profitable_hard_regs);
1024 else
1026 mode = ALLOCNO_MODE (a);
1027 COPY_HARD_REG_SET (data->profitable_hard_regs,
1028 ira_useful_class_mode_regs[aclass][mode]);
1029 nobj = ALLOCNO_NUM_OBJECTS (a);
1030 for (k = 0; k < nobj; k++)
1032 ira_object_t obj = ALLOCNO_OBJECT (a, k);
1034 AND_COMPL_HARD_REG_SET (data->profitable_hard_regs,
1035 OBJECT_TOTAL_CONFLICT_HARD_REGS (obj));
1039 /* Exclude hard regs already assigned for conflicting objects. */
1040 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, i, bi)
1042 a = ira_allocnos[i];
1043 if ((aclass = ALLOCNO_CLASS (a)) == NO_REGS
1044 || ! ALLOCNO_ASSIGNED_P (a)
1045 || (hard_regno = ALLOCNO_HARD_REGNO (a)) < 0)
1046 continue;
1047 mode = ALLOCNO_MODE (a);
1048 nregs = hard_regno_nregs[hard_regno][mode];
1049 nobj = ALLOCNO_NUM_OBJECTS (a);
1050 for (k = 0; k < nobj; k++)
1052 ira_object_t obj = ALLOCNO_OBJECT (a, k);
1053 ira_object_t conflict_obj;
1054 ira_object_conflict_iterator oci;
1056 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
1058 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
1060 /* We can process the conflict allocno repeatedly with
1061 the same result. */
1062 if (nregs == nobj && nregs > 1)
1064 int num = OBJECT_SUBWORD (conflict_obj);
1066 if (REG_WORDS_BIG_ENDIAN)
1067 CLEAR_HARD_REG_BIT
1068 (ALLOCNO_COLOR_DATA (conflict_a)->profitable_hard_regs,
1069 hard_regno + nobj - num - 1);
1070 else
1071 CLEAR_HARD_REG_BIT
1072 (ALLOCNO_COLOR_DATA (conflict_a)->profitable_hard_regs,
1073 hard_regno + num);
1075 else
1076 AND_COMPL_HARD_REG_SET
1077 (ALLOCNO_COLOR_DATA (conflict_a)->profitable_hard_regs,
1078 ira_reg_mode_hard_regset[hard_regno][mode]);
1082 /* Exclude too costly hard regs. */
1083 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
1085 int min_cost = INT_MAX;
1086 int *costs;
1088 a = ira_allocnos[i];
1089 if ((aclass = ALLOCNO_CLASS (a)) == NO_REGS
1090 || empty_profitable_hard_regs (a))
1091 continue;
1092 data = ALLOCNO_COLOR_DATA (a);
1093 mode = ALLOCNO_MODE (a);
1094 if ((costs = ALLOCNO_UPDATED_HARD_REG_COSTS (a)) != NULL
1095 || (costs = ALLOCNO_HARD_REG_COSTS (a)) != NULL)
1097 class_size = ira_class_hard_regs_num[aclass];
1098 for (j = 0; j < class_size; j++)
1100 hard_regno = ira_class_hard_regs[aclass][j];
1101 if (! TEST_HARD_REG_BIT (data->profitable_hard_regs,
1102 hard_regno))
1103 continue;
1104 if (ALLOCNO_UPDATED_MEMORY_COST (a) < costs[j])
1105 CLEAR_HARD_REG_BIT (data->profitable_hard_regs,
1106 hard_regno);
1107 else if (min_cost > costs[j])
1108 min_cost = costs[j];
1111 else if (ALLOCNO_UPDATED_MEMORY_COST (a)
1112 < ALLOCNO_UPDATED_CLASS_COST (a))
1113 CLEAR_HARD_REG_SET (data->profitable_hard_regs);
1114 if (ALLOCNO_UPDATED_CLASS_COST (a) > min_cost)
1115 ALLOCNO_UPDATED_CLASS_COST (a) = min_cost;
1121 /* This page contains functions used to choose hard registers for
1122 allocnos. */
1124 /* Array whose element value is TRUE if the corresponding hard
1125 register was already allocated for an allocno. */
1126 static bool allocated_hardreg_p[FIRST_PSEUDO_REGISTER];
1128 /* Describes one element in a queue of allocnos whose costs need to be
1129 updated. Each allocno in the queue is known to have an allocno
1130 class. */
1131 struct update_cost_queue_elem
1133 /* This element is in the queue iff CHECK == update_cost_check. */
1134 int check;
1136 /* COST_HOP_DIVISOR**N, where N is the length of the shortest path
1137 connecting this allocno to the one being allocated. */
1138 int divisor;
1140 /* The next allocno in the queue, or null if this is the last element. */
1141 ira_allocno_t next;
1144 /* The first element in a queue of allocnos whose copy costs need to be
1145 updated. Null if the queue is empty. */
1146 static ira_allocno_t update_cost_queue;
1148 /* The last element in the queue described by update_cost_queue.
1149 Not valid if update_cost_queue is null. */
1150 static struct update_cost_queue_elem *update_cost_queue_tail;
1152 /* A pool of elements in the queue described by update_cost_queue.
1153 Elements are indexed by ALLOCNO_NUM. */
1154 static struct update_cost_queue_elem *update_cost_queue_elems;
1156 /* The current value of update_copy_cost call count. */
1157 static int update_cost_check;
1159 /* Allocate and initialize data necessary for function
1160 update_copy_costs. */
1161 static void
1162 initiate_cost_update (void)
1164 size_t size;
1166 size = ira_allocnos_num * sizeof (struct update_cost_queue_elem);
1167 update_cost_queue_elems
1168 = (struct update_cost_queue_elem *) ira_allocate (size);
1169 memset (update_cost_queue_elems, 0, size);
1170 update_cost_check = 0;
1173 /* Deallocate data used by function update_copy_costs. */
1174 static void
1175 finish_cost_update (void)
1177 ira_free (update_cost_queue_elems);
1180 /* When we traverse allocnos to update hard register costs, the cost
1181 divisor will be multiplied by the following macro value for each
1182 hop from given allocno to directly connected allocnos. */
1183 #define COST_HOP_DIVISOR 4
1185 /* Start a new cost-updating pass. */
1186 static void
1187 start_update_cost (void)
1189 update_cost_check++;
1190 update_cost_queue = NULL;
1193 /* Add (ALLOCNO, DIVISOR) to the end of update_cost_queue, unless
1194 ALLOCNO is already in the queue, or has NO_REGS class. */
1195 static inline void
1196 queue_update_cost (ira_allocno_t allocno, int divisor)
1198 struct update_cost_queue_elem *elem;
1200 elem = &update_cost_queue_elems[ALLOCNO_NUM (allocno)];
1201 if (elem->check != update_cost_check
1202 && ALLOCNO_CLASS (allocno) != NO_REGS)
1204 elem->check = update_cost_check;
1205 elem->divisor = divisor;
1206 elem->next = NULL;
1207 if (update_cost_queue == NULL)
1208 update_cost_queue = allocno;
1209 else
1210 update_cost_queue_tail->next = allocno;
1211 update_cost_queue_tail = elem;
1215 /* Try to remove the first element from update_cost_queue. Return false
1216 if the queue was empty, otherwise make (*ALLOCNO, *DIVISOR) describe
1217 the removed element. */
1218 static inline bool
1219 get_next_update_cost (ira_allocno_t *allocno, int *divisor)
1221 struct update_cost_queue_elem *elem;
1223 if (update_cost_queue == NULL)
1224 return false;
1226 *allocno = update_cost_queue;
1227 elem = &update_cost_queue_elems[ALLOCNO_NUM (*allocno)];
1228 *divisor = elem->divisor;
1229 update_cost_queue = elem->next;
1230 return true;
1233 /* Update the cost of allocnos to increase chances to remove some
1234 copies as the result of subsequent assignment. */
1235 static void
1236 update_copy_costs (ira_allocno_t allocno, bool decr_p)
1238 int i, cost, update_cost, hard_regno, divisor;
1239 enum machine_mode mode;
1240 enum reg_class rclass, aclass;
1241 ira_allocno_t another_allocno;
1242 ira_copy_t cp, next_cp;
1244 hard_regno = ALLOCNO_HARD_REGNO (allocno);
1245 ira_assert (hard_regno >= 0);
1247 aclass = ALLOCNO_CLASS (allocno);
1248 if (aclass == NO_REGS)
1249 return;
1250 i = ira_class_hard_reg_index[aclass][hard_regno];
1251 ira_assert (i >= 0);
1252 rclass = REGNO_REG_CLASS (hard_regno);
1254 start_update_cost ();
1255 divisor = 1;
1258 mode = ALLOCNO_MODE (allocno);
1259 ira_init_register_move_cost_if_necessary (mode);
1260 for (cp = ALLOCNO_COPIES (allocno); cp != NULL; cp = next_cp)
1262 if (cp->first == allocno)
1264 next_cp = cp->next_first_allocno_copy;
1265 another_allocno = cp->second;
1267 else if (cp->second == allocno)
1269 next_cp = cp->next_second_allocno_copy;
1270 another_allocno = cp->first;
1272 else
1273 gcc_unreachable ();
1275 aclass = ALLOCNO_CLASS (another_allocno);
1276 if (! TEST_HARD_REG_BIT (reg_class_contents[aclass],
1277 hard_regno)
1278 || ALLOCNO_ASSIGNED_P (another_allocno))
1279 continue;
1281 cost = (cp->second == allocno
1282 ? ira_register_move_cost[mode][rclass][aclass]
1283 : ira_register_move_cost[mode][aclass][rclass]);
1284 if (decr_p)
1285 cost = -cost;
1287 update_cost = cp->freq * cost / divisor;
1288 if (update_cost == 0)
1289 continue;
1291 ira_allocate_and_set_or_copy_costs
1292 (&ALLOCNO_UPDATED_HARD_REG_COSTS (another_allocno), aclass,
1293 ALLOCNO_UPDATED_CLASS_COST (another_allocno),
1294 ALLOCNO_HARD_REG_COSTS (another_allocno));
1295 ira_allocate_and_set_or_copy_costs
1296 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (another_allocno),
1297 aclass, 0, ALLOCNO_CONFLICT_HARD_REG_COSTS (another_allocno));
1298 i = ira_class_hard_reg_index[aclass][hard_regno];
1299 if (i < 0)
1300 continue;
1301 ALLOCNO_UPDATED_HARD_REG_COSTS (another_allocno)[i] += update_cost;
1302 ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (another_allocno)[i]
1303 += update_cost;
1305 queue_update_cost (another_allocno, divisor * COST_HOP_DIVISOR);
1308 while (get_next_update_cost (&allocno, &divisor));
1311 /* This function updates COSTS (decrease if DECR_P) for hard_registers
1312 of ACLASS by conflict costs of the unassigned allocnos
1313 connected by copies with allocnos in update_cost_queue. This
1314 update increases chances to remove some copies. */
1315 static void
1316 update_conflict_hard_regno_costs (int *costs, enum reg_class aclass,
1317 bool decr_p)
1319 int i, cost, class_size, freq, mult, div, divisor;
1320 int index, hard_regno;
1321 int *conflict_costs;
1322 bool cont_p;
1323 enum reg_class another_aclass;
1324 ira_allocno_t allocno, another_allocno;
1325 ira_copy_t cp, next_cp;
1327 while (get_next_update_cost (&allocno, &divisor))
1328 for (cp = ALLOCNO_COPIES (allocno); cp != NULL; cp = next_cp)
1330 if (cp->first == allocno)
1332 next_cp = cp->next_first_allocno_copy;
1333 another_allocno = cp->second;
1335 else if (cp->second == allocno)
1337 next_cp = cp->next_second_allocno_copy;
1338 another_allocno = cp->first;
1340 else
1341 gcc_unreachable ();
1342 another_aclass = ALLOCNO_CLASS (another_allocno);
1343 if (! ira_reg_classes_intersect_p[aclass][another_aclass]
1344 || ALLOCNO_ASSIGNED_P (another_allocno)
1345 || ALLOCNO_COLOR_DATA (another_allocno)->may_be_spilled_p)
1346 continue;
1347 class_size = ira_class_hard_regs_num[another_aclass];
1348 ira_allocate_and_copy_costs
1349 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (another_allocno),
1350 another_aclass, ALLOCNO_CONFLICT_HARD_REG_COSTS (another_allocno));
1351 conflict_costs
1352 = ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (another_allocno);
1353 if (conflict_costs == NULL)
1354 cont_p = true;
1355 else
1357 mult = cp->freq;
1358 freq = ALLOCNO_FREQ (another_allocno);
1359 if (freq == 0)
1360 freq = 1;
1361 div = freq * divisor;
1362 cont_p = false;
1363 for (i = class_size - 1; i >= 0; i--)
1365 hard_regno = ira_class_hard_regs[another_aclass][i];
1366 ira_assert (hard_regno >= 0);
1367 index = ira_class_hard_reg_index[aclass][hard_regno];
1368 if (index < 0)
1369 continue;
1370 cost = conflict_costs [i] * mult / div;
1371 if (cost == 0)
1372 continue;
1373 cont_p = true;
1374 if (decr_p)
1375 cost = -cost;
1376 costs[index] += cost;
1379 /* Probably 5 hops will be enough. */
1380 if (cont_p
1381 && divisor <= (COST_HOP_DIVISOR
1382 * COST_HOP_DIVISOR
1383 * COST_HOP_DIVISOR
1384 * COST_HOP_DIVISOR))
1385 queue_update_cost (another_allocno, divisor * COST_HOP_DIVISOR);
1389 /* Set up conflicting (through CONFLICT_REGS) for each object of
1390 allocno A and the start allocno profitable regs (through
1391 START_PROFITABLE_REGS). Remember that the start profitable regs
1392 exclude hard regs which can not hold value of mode of allocno A.
1393 This covers mostly cases when multi-register value should be
1394 aligned. */
1395 static inline void
1396 get_conflict_and_start_profitable_regs (ira_allocno_t a, bool retry_p,
1397 HARD_REG_SET *conflict_regs,
1398 HARD_REG_SET *start_profitable_regs)
1400 int i, nwords;
1401 ira_object_t obj;
1403 nwords = ALLOCNO_NUM_OBJECTS (a);
1404 for (i = 0; i < nwords; i++)
1406 obj = ALLOCNO_OBJECT (a, i);
1407 COPY_HARD_REG_SET (conflict_regs[i],
1408 OBJECT_TOTAL_CONFLICT_HARD_REGS (obj));
1410 if (retry_p)
1412 COPY_HARD_REG_SET (*start_profitable_regs,
1413 reg_class_contents[ALLOCNO_CLASS (a)]);
1414 AND_COMPL_HARD_REG_SET (*start_profitable_regs,
1415 ira_prohibited_class_mode_regs
1416 [ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]);
1418 else
1419 COPY_HARD_REG_SET (*start_profitable_regs,
1420 ALLOCNO_COLOR_DATA (a)->profitable_hard_regs);
1423 /* Return true if HARD_REGNO is ok for assigning to allocno A with
1424 PROFITABLE_REGS and whose objects have CONFLICT_REGS. */
1425 static inline bool
1426 check_hard_reg_p (ira_allocno_t a, int hard_regno,
1427 HARD_REG_SET *conflict_regs, HARD_REG_SET profitable_regs)
1429 int j, nwords, nregs;
1430 enum reg_class aclass;
1431 enum machine_mode mode;
1433 aclass = ALLOCNO_CLASS (a);
1434 mode = ALLOCNO_MODE (a);
1435 if (TEST_HARD_REG_BIT (ira_prohibited_class_mode_regs[aclass][mode],
1436 hard_regno))
1437 return false;
1438 /* Checking only profitable hard regs. */
1439 if (! TEST_HARD_REG_BIT (profitable_regs, hard_regno))
1440 return false;
1441 nregs = hard_regno_nregs[hard_regno][mode];
1442 nwords = ALLOCNO_NUM_OBJECTS (a);
1443 for (j = 0; j < nregs; j++)
1445 int k;
1446 int set_to_test_start = 0, set_to_test_end = nwords;
1448 if (nregs == nwords)
1450 if (REG_WORDS_BIG_ENDIAN)
1451 set_to_test_start = nwords - j - 1;
1452 else
1453 set_to_test_start = j;
1454 set_to_test_end = set_to_test_start + 1;
1456 for (k = set_to_test_start; k < set_to_test_end; k++)
1457 if (TEST_HARD_REG_BIT (conflict_regs[k], hard_regno + j))
1458 break;
1459 if (k != set_to_test_end)
1460 break;
1462 return j == nregs;
1464 #ifndef HONOR_REG_ALLOC_ORDER
1466 /* Return number of registers needed to be saved and restored at
1467 function prologue/epilogue if we allocate HARD_REGNO to hold value
1468 of MODE. */
1469 static int
1470 calculate_saved_nregs (int hard_regno, enum machine_mode mode)
1472 int i;
1473 int nregs = 0;
1475 ira_assert (hard_regno >= 0);
1476 for (i = hard_regno_nregs[hard_regno][mode] - 1; i >= 0; i--)
1477 if (!allocated_hardreg_p[hard_regno + i]
1478 && !TEST_HARD_REG_BIT (call_used_reg_set, hard_regno + i)
1479 && !LOCAL_REGNO (hard_regno + i))
1480 nregs++;
1481 return nregs;
1483 #endif
1485 /* Choose a hard register for allocno A. If RETRY_P is TRUE, it means
1486 that the function called from function
1487 `ira_reassign_conflict_allocnos' and `allocno_reload_assign'. In
1488 this case some allocno data are not defined or updated and we
1489 should not touch these data. The function returns true if we
1490 managed to assign a hard register to the allocno.
1492 To assign a hard register, first of all we calculate all conflict
1493 hard registers which can come from conflicting allocnos with
1494 already assigned hard registers. After that we find first free
1495 hard register with the minimal cost. During hard register cost
1496 calculation we take conflict hard register costs into account to
1497 give a chance for conflicting allocnos to get a better hard
1498 register in the future.
1500 If the best hard register cost is bigger than cost of memory usage
1501 for the allocno, we don't assign a hard register to given allocno
1502 at all.
1504 If we assign a hard register to the allocno, we update costs of the
1505 hard register for allocnos connected by copies to improve a chance
1506 to coalesce insns represented by the copies when we assign hard
1507 registers to the allocnos connected by the copies. */
1508 static bool
1509 assign_hard_reg (ira_allocno_t a, bool retry_p)
1511 HARD_REG_SET conflicting_regs[2], profitable_hard_regs;
1512 int i, j, hard_regno, best_hard_regno, class_size;
1513 int cost, mem_cost, min_cost, full_cost, min_full_cost, nwords, word;
1514 int *a_costs;
1515 enum reg_class aclass;
1516 enum machine_mode mode;
1517 static int costs[FIRST_PSEUDO_REGISTER], full_costs[FIRST_PSEUDO_REGISTER];
1518 #ifndef HONOR_REG_ALLOC_ORDER
1519 int saved_nregs;
1520 enum reg_class rclass;
1521 int add_cost;
1522 #endif
1523 #ifdef STACK_REGS
1524 bool no_stack_reg_p;
1525 #endif
1527 ira_assert (! ALLOCNO_ASSIGNED_P (a));
1528 get_conflict_and_start_profitable_regs (a, retry_p,
1529 conflicting_regs,
1530 &profitable_hard_regs);
1531 aclass = ALLOCNO_CLASS (a);
1532 class_size = ira_class_hard_regs_num[aclass];
1533 best_hard_regno = -1;
1534 memset (full_costs, 0, sizeof (int) * class_size);
1535 mem_cost = 0;
1536 memset (costs, 0, sizeof (int) * class_size);
1537 memset (full_costs, 0, sizeof (int) * class_size);
1538 #ifdef STACK_REGS
1539 no_stack_reg_p = false;
1540 #endif
1541 if (! retry_p)
1542 start_update_cost ();
1543 mem_cost += ALLOCNO_UPDATED_MEMORY_COST (a);
1545 ira_allocate_and_copy_costs (&ALLOCNO_UPDATED_HARD_REG_COSTS (a),
1546 aclass, ALLOCNO_HARD_REG_COSTS (a));
1547 a_costs = ALLOCNO_UPDATED_HARD_REG_COSTS (a);
1548 #ifdef STACK_REGS
1549 no_stack_reg_p = no_stack_reg_p || ALLOCNO_TOTAL_NO_STACK_REG_P (a);
1550 #endif
1551 cost = ALLOCNO_UPDATED_CLASS_COST (a);
1552 for (i = 0; i < class_size; i++)
1553 if (a_costs != NULL)
1555 costs[i] += a_costs[i];
1556 full_costs[i] += a_costs[i];
1558 else
1560 costs[i] += cost;
1561 full_costs[i] += cost;
1563 nwords = ALLOCNO_NUM_OBJECTS (a);
1564 curr_allocno_process++;
1565 for (word = 0; word < nwords; word++)
1567 ira_object_t conflict_obj;
1568 ira_object_t obj = ALLOCNO_OBJECT (a, word);
1569 ira_object_conflict_iterator oci;
1571 /* Take preferences of conflicting allocnos into account. */
1572 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
1574 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
1575 enum reg_class conflict_aclass;
1577 /* Reload can give another class so we need to check all
1578 allocnos. */
1579 if (!retry_p
1580 && (!bitmap_bit_p (consideration_allocno_bitmap,
1581 ALLOCNO_NUM (conflict_a))
1582 || ((!ALLOCNO_ASSIGNED_P (conflict_a)
1583 || ALLOCNO_HARD_REGNO (conflict_a) < 0)
1584 && !(hard_reg_set_intersect_p
1585 (profitable_hard_regs,
1586 ALLOCNO_COLOR_DATA
1587 (conflict_a)->profitable_hard_regs)))))
1588 continue;
1589 conflict_aclass = ALLOCNO_CLASS (conflict_a);
1590 ira_assert (ira_reg_classes_intersect_p
1591 [aclass][conflict_aclass]);
1592 if (ALLOCNO_ASSIGNED_P (conflict_a))
1594 hard_regno = ALLOCNO_HARD_REGNO (conflict_a);
1595 if (hard_regno >= 0
1596 && (ira_hard_reg_set_intersection_p
1597 (hard_regno, ALLOCNO_MODE (conflict_a),
1598 reg_class_contents[aclass])))
1600 int n_objects = ALLOCNO_NUM_OBJECTS (conflict_a);
1601 int conflict_nregs;
1603 mode = ALLOCNO_MODE (conflict_a);
1604 conflict_nregs = hard_regno_nregs[hard_regno][mode];
1605 if (conflict_nregs == n_objects && conflict_nregs > 1)
1607 int num = OBJECT_SUBWORD (conflict_obj);
1609 if (REG_WORDS_BIG_ENDIAN)
1610 SET_HARD_REG_BIT (conflicting_regs[word],
1611 hard_regno + n_objects - num - 1);
1612 else
1613 SET_HARD_REG_BIT (conflicting_regs[word],
1614 hard_regno + num);
1616 else
1617 IOR_HARD_REG_SET
1618 (conflicting_regs[word],
1619 ira_reg_mode_hard_regset[hard_regno][mode]);
1620 if (hard_reg_set_subset_p (profitable_hard_regs,
1621 conflicting_regs[word]))
1622 goto fail;
1625 else if (! retry_p
1626 && ! ALLOCNO_COLOR_DATA (conflict_a)->may_be_spilled_p
1627 /* Don't process the conflict allocno twice. */
1628 && (ALLOCNO_COLOR_DATA (conflict_a)->last_process
1629 != curr_allocno_process))
1631 int k, *conflict_costs;
1633 ALLOCNO_COLOR_DATA (conflict_a)->last_process
1634 = curr_allocno_process;
1635 ira_allocate_and_copy_costs
1636 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (conflict_a),
1637 conflict_aclass,
1638 ALLOCNO_CONFLICT_HARD_REG_COSTS (conflict_a));
1639 conflict_costs
1640 = ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (conflict_a);
1641 if (conflict_costs != NULL)
1642 for (j = class_size - 1; j >= 0; j--)
1644 hard_regno = ira_class_hard_regs[aclass][j];
1645 ira_assert (hard_regno >= 0);
1646 k = ira_class_hard_reg_index[conflict_aclass][hard_regno];
1647 if (k < 0)
1648 continue;
1649 full_costs[j] -= conflict_costs[k];
1651 queue_update_cost (conflict_a, COST_HOP_DIVISOR);
1655 if (! retry_p)
1656 /* Take into account preferences of allocnos connected by copies to
1657 the conflict allocnos. */
1658 update_conflict_hard_regno_costs (full_costs, aclass, true);
1660 /* Take preferences of allocnos connected by copies into
1661 account. */
1662 if (! retry_p)
1664 start_update_cost ();
1665 queue_update_cost (a, COST_HOP_DIVISOR);
1666 update_conflict_hard_regno_costs (full_costs, aclass, false);
1668 min_cost = min_full_cost = INT_MAX;
1669 /* We don't care about giving callee saved registers to allocnos no
1670 living through calls because call clobbered registers are
1671 allocated first (it is usual practice to put them first in
1672 REG_ALLOC_ORDER). */
1673 mode = ALLOCNO_MODE (a);
1674 for (i = 0; i < class_size; i++)
1676 hard_regno = ira_class_hard_regs[aclass][i];
1677 #ifdef STACK_REGS
1678 if (no_stack_reg_p
1679 && FIRST_STACK_REG <= hard_regno && hard_regno <= LAST_STACK_REG)
1680 continue;
1681 #endif
1682 if (! check_hard_reg_p (a, hard_regno,
1683 conflicting_regs, profitable_hard_regs))
1684 continue;
1685 cost = costs[i];
1686 full_cost = full_costs[i];
1687 #ifndef HONOR_REG_ALLOC_ORDER
1688 if ((saved_nregs = calculate_saved_nregs (hard_regno, mode)) != 0)
1689 /* We need to save/restore the hard register in
1690 epilogue/prologue. Therefore we increase the cost. */
1692 rclass = REGNO_REG_CLASS (hard_regno);
1693 add_cost = ((ira_memory_move_cost[mode][rclass][0]
1694 + ira_memory_move_cost[mode][rclass][1])
1695 * saved_nregs / hard_regno_nregs[hard_regno][mode] - 1);
1696 cost += add_cost;
1697 full_cost += add_cost;
1699 #endif
1700 if (min_cost > cost)
1701 min_cost = cost;
1702 if (min_full_cost > full_cost)
1704 min_full_cost = full_cost;
1705 best_hard_regno = hard_regno;
1706 ira_assert (hard_regno >= 0);
1709 if (min_full_cost > mem_cost)
1711 if (! retry_p && internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
1712 fprintf (ira_dump_file, "(memory is more profitable %d vs %d) ",
1713 mem_cost, min_full_cost);
1714 best_hard_regno = -1;
1716 fail:
1717 if (best_hard_regno >= 0)
1719 for (i = hard_regno_nregs[best_hard_regno][mode] - 1; i >= 0; i--)
1720 allocated_hardreg_p[best_hard_regno + i] = true;
1722 ALLOCNO_HARD_REGNO (a) = best_hard_regno;
1723 ALLOCNO_ASSIGNED_P (a) = true;
1724 if (best_hard_regno >= 0)
1725 update_copy_costs (a, true);
1726 ira_assert (ALLOCNO_CLASS (a) == aclass);
1727 /* We don't need updated costs anymore: */
1728 ira_free_allocno_updated_costs (a);
1729 return best_hard_regno >= 0;
1734 /* This page contains the allocator based on the Chaitin-Briggs algorithm. */
1736 /* Bucket of allocnos that can colored currently without spilling. */
1737 static ira_allocno_t colorable_allocno_bucket;
1739 /* Bucket of allocnos that might be not colored currently without
1740 spilling. */
1741 static ira_allocno_t uncolorable_allocno_bucket;
1743 /* The current number of allocnos in the uncolorable_bucket. */
1744 static int uncolorable_allocnos_num;
1746 /* Return the current spill priority of allocno A. The less the
1747 number, the more preferable the allocno for spilling. */
1748 static inline int
1749 allocno_spill_priority (ira_allocno_t a)
1751 allocno_color_data_t data = ALLOCNO_COLOR_DATA (a);
1753 return (data->temp
1754 / (ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a)
1755 * ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]
1756 + 1));
1759 /* Add allocno A to bucket *BUCKET_PTR. A should be not in a bucket
1760 before the call. */
1761 static void
1762 add_allocno_to_bucket (ira_allocno_t a, ira_allocno_t *bucket_ptr)
1764 ira_allocno_t first_a;
1765 allocno_color_data_t data;
1767 if (bucket_ptr == &uncolorable_allocno_bucket
1768 && ALLOCNO_CLASS (a) != NO_REGS)
1770 uncolorable_allocnos_num++;
1771 ira_assert (uncolorable_allocnos_num > 0);
1773 first_a = *bucket_ptr;
1774 data = ALLOCNO_COLOR_DATA (a);
1775 data->next_bucket_allocno = first_a;
1776 data->prev_bucket_allocno = NULL;
1777 if (first_a != NULL)
1778 ALLOCNO_COLOR_DATA (first_a)->prev_bucket_allocno = a;
1779 *bucket_ptr = a;
1782 /* Compare two allocnos to define which allocno should be pushed first
1783 into the coloring stack. If the return is a negative number, the
1784 allocno given by the first parameter will be pushed first. In this
1785 case such allocno has less priority than the second one and the
1786 hard register will be assigned to it after assignment to the second
1787 one. As the result of such assignment order, the second allocno
1788 has a better chance to get the best hard register. */
1789 static int
1790 bucket_allocno_compare_func (const void *v1p, const void *v2p)
1792 ira_allocno_t a1 = *(const ira_allocno_t *) v1p;
1793 ira_allocno_t a2 = *(const ira_allocno_t *) v2p;
1794 int diff, a1_freq, a2_freq, a1_num, a2_num;
1795 int cl1 = ALLOCNO_CLASS (a1), cl2 = ALLOCNO_CLASS (a2);
1797 /* Push pseudos requiring less hard registers first. It means that
1798 we will assign pseudos requiring more hard registers first
1799 avoiding creation small holes in free hard register file into
1800 which the pseudos requiring more hard registers can not fit. */
1801 if ((diff = (ira_reg_class_max_nregs[cl1][ALLOCNO_MODE (a1)]
1802 - ira_reg_class_max_nregs[cl2][ALLOCNO_MODE (a2)])) != 0)
1803 return diff;
1804 a1_freq = ALLOCNO_FREQ (a1);
1805 a2_freq = ALLOCNO_FREQ (a2);
1806 if ((diff = a1_freq - a2_freq) != 0)
1807 return diff;
1808 a1_num = ALLOCNO_COLOR_DATA (a1)->available_regs_num;
1809 a2_num = ALLOCNO_COLOR_DATA (a2)->available_regs_num;
1810 if ((diff = a2_num - a1_num) != 0)
1811 return diff;
1812 return ALLOCNO_NUM (a2) - ALLOCNO_NUM (a1);
1815 /* Sort bucket *BUCKET_PTR and return the result through
1816 BUCKET_PTR. */
1817 static void
1818 sort_bucket (ira_allocno_t *bucket_ptr,
1819 int (*compare_func) (const void *, const void *))
1821 ira_allocno_t a, head;
1822 int n;
1824 for (n = 0, a = *bucket_ptr;
1825 a != NULL;
1826 a = ALLOCNO_COLOR_DATA (a)->next_bucket_allocno)
1827 sorted_allocnos[n++] = a;
1828 if (n <= 1)
1829 return;
1830 qsort (sorted_allocnos, n, sizeof (ira_allocno_t), compare_func);
1831 head = NULL;
1832 for (n--; n >= 0; n--)
1834 a = sorted_allocnos[n];
1835 ALLOCNO_COLOR_DATA (a)->next_bucket_allocno = head;
1836 ALLOCNO_COLOR_DATA (a)->prev_bucket_allocno = NULL;
1837 if (head != NULL)
1838 ALLOCNO_COLOR_DATA (head)->prev_bucket_allocno = a;
1839 head = a;
1841 *bucket_ptr = head;
1844 /* Add ALLOCNO to bucket *BUCKET_PTR maintaining the order according
1845 their priority. ALLOCNO should be not in a bucket before the
1846 call. */
1847 static void
1848 add_allocno_to_ordered_bucket (ira_allocno_t allocno,
1849 ira_allocno_t *bucket_ptr)
1851 ira_allocno_t before, after;
1853 if (bucket_ptr == &uncolorable_allocno_bucket
1854 && ALLOCNO_CLASS (allocno) != NO_REGS)
1856 uncolorable_allocnos_num++;
1857 ira_assert (uncolorable_allocnos_num > 0);
1859 for (before = *bucket_ptr, after = NULL;
1860 before != NULL;
1861 after = before,
1862 before = ALLOCNO_COLOR_DATA (before)->next_bucket_allocno)
1863 if (bucket_allocno_compare_func (&allocno, &before) < 0)
1864 break;
1865 ALLOCNO_COLOR_DATA (allocno)->next_bucket_allocno = before;
1866 ALLOCNO_COLOR_DATA (allocno)->prev_bucket_allocno = after;
1867 if (after == NULL)
1868 *bucket_ptr = allocno;
1869 else
1870 ALLOCNO_COLOR_DATA (after)->next_bucket_allocno = allocno;
1871 if (before != NULL)
1872 ALLOCNO_COLOR_DATA (before)->prev_bucket_allocno = allocno;
1875 /* Delete ALLOCNO from bucket *BUCKET_PTR. It should be there before
1876 the call. */
1877 static void
1878 delete_allocno_from_bucket (ira_allocno_t allocno, ira_allocno_t *bucket_ptr)
1880 ira_allocno_t prev_allocno, next_allocno;
1882 if (bucket_ptr == &uncolorable_allocno_bucket
1883 && ALLOCNO_CLASS (allocno) != NO_REGS)
1885 uncolorable_allocnos_num--;
1886 ira_assert (uncolorable_allocnos_num >= 0);
1888 prev_allocno = ALLOCNO_COLOR_DATA (allocno)->prev_bucket_allocno;
1889 next_allocno = ALLOCNO_COLOR_DATA (allocno)->next_bucket_allocno;
1890 if (prev_allocno != NULL)
1891 ALLOCNO_COLOR_DATA (prev_allocno)->next_bucket_allocno = next_allocno;
1892 else
1894 ira_assert (*bucket_ptr == allocno);
1895 *bucket_ptr = next_allocno;
1897 if (next_allocno != NULL)
1898 ALLOCNO_COLOR_DATA (next_allocno)->prev_bucket_allocno = prev_allocno;
1901 /* Put allocno A onto the coloring stack without removing it from its
1902 bucket. Pushing allocno to the coloring stack can result in moving
1903 conflicting allocnos from the uncolorable bucket to the colorable
1904 one. */
1905 static void
1906 push_allocno_to_stack (ira_allocno_t a)
1908 enum reg_class aclass;
1909 allocno_color_data_t data, conflict_data;
1910 int size, i, n = ALLOCNO_NUM_OBJECTS (a);
1912 data = ALLOCNO_COLOR_DATA (a);
1913 data->in_graph_p = false;
1914 VEC_safe_push (ira_allocno_t, heap, allocno_stack_vec, a);
1915 aclass = ALLOCNO_CLASS (a);
1916 if (aclass == NO_REGS)
1917 return;
1918 size = ira_reg_class_max_nregs[aclass][ALLOCNO_MODE (a)];
1919 if (n > 1)
1921 /* We will deal with the subwords individually. */
1922 gcc_assert (size == ALLOCNO_NUM_OBJECTS (a));
1923 size = 1;
1925 for (i = 0; i < n; i++)
1927 ira_object_t obj = ALLOCNO_OBJECT (a, i);
1928 ira_object_t conflict_obj;
1929 ira_object_conflict_iterator oci;
1931 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
1933 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
1935 conflict_data = ALLOCNO_COLOR_DATA (conflict_a);
1936 if (conflict_data->colorable_p
1937 || ! conflict_data->in_graph_p
1938 || ALLOCNO_ASSIGNED_P (conflict_a)
1939 || !(hard_reg_set_intersect_p
1940 (ALLOCNO_COLOR_DATA (a)->profitable_hard_regs,
1941 conflict_data->profitable_hard_regs)))
1942 continue;
1943 ira_assert (bitmap_bit_p (coloring_allocno_bitmap,
1944 ALLOCNO_NUM (conflict_a)));
1945 if (update_left_conflict_sizes_p (conflict_a, a, size))
1947 delete_allocno_from_bucket
1948 (conflict_a, &uncolorable_allocno_bucket);
1949 add_allocno_to_ordered_bucket
1950 (conflict_a, &colorable_allocno_bucket);
1951 if (internal_flag_ira_verbose > 4 && ira_dump_file != NULL)
1953 fprintf (ira_dump_file, " Making");
1954 ira_print_expanded_allocno (conflict_a);
1955 fprintf (ira_dump_file, " colorable\n");
1963 /* Put ALLOCNO onto the coloring stack and remove it from its bucket.
1964 The allocno is in the colorable bucket if COLORABLE_P is TRUE. */
1965 static void
1966 remove_allocno_from_bucket_and_push (ira_allocno_t allocno, bool colorable_p)
1968 if (colorable_p)
1969 delete_allocno_from_bucket (allocno, &colorable_allocno_bucket);
1970 else
1971 delete_allocno_from_bucket (allocno, &uncolorable_allocno_bucket);
1972 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
1974 fprintf (ira_dump_file, " Pushing");
1975 ira_print_expanded_allocno (allocno);
1976 if (colorable_p)
1977 fprintf (ira_dump_file, "(cost %d)\n",
1978 ALLOCNO_COLOR_DATA (allocno)->temp);
1979 else
1980 fprintf (ira_dump_file, "(potential spill: %spri=%d, cost=%d)\n",
1981 ALLOCNO_BAD_SPILL_P (allocno) ? "bad spill, " : "",
1982 allocno_spill_priority (allocno),
1983 ALLOCNO_COLOR_DATA (allocno)->temp);
1985 if (! colorable_p)
1986 ALLOCNO_COLOR_DATA (allocno)->may_be_spilled_p = true;
1987 push_allocno_to_stack (allocno);
1990 /* Put all allocnos from colorable bucket onto the coloring stack. */
1991 static void
1992 push_only_colorable (void)
1994 sort_bucket (&colorable_allocno_bucket, bucket_allocno_compare_func);
1995 for (;colorable_allocno_bucket != NULL;)
1996 remove_allocno_from_bucket_and_push (colorable_allocno_bucket, true);
1999 /* Return the frequency of exit edges (if EXIT_P) or entry from/to the
2000 loop given by its LOOP_NODE. */
2002 ira_loop_edge_freq (ira_loop_tree_node_t loop_node, int regno, bool exit_p)
2004 int freq, i;
2005 edge_iterator ei;
2006 edge e;
2007 VEC (edge, heap) *edges;
2009 ira_assert (current_loops != NULL && loop_node->loop != NULL
2010 && (regno < 0 || regno >= FIRST_PSEUDO_REGISTER));
2011 freq = 0;
2012 if (! exit_p)
2014 FOR_EACH_EDGE (e, ei, loop_node->loop->header->preds)
2015 if (e->src != loop_node->loop->latch
2016 && (regno < 0
2017 || (bitmap_bit_p (df_get_live_out (e->src), regno)
2018 && bitmap_bit_p (df_get_live_in (e->dest), regno))))
2019 freq += EDGE_FREQUENCY (e);
2021 else
2023 edges = get_loop_exit_edges (loop_node->loop);
2024 FOR_EACH_VEC_ELT (edge, edges, i, e)
2025 if (regno < 0
2026 || (bitmap_bit_p (df_get_live_out (e->src), regno)
2027 && bitmap_bit_p (df_get_live_in (e->dest), regno)))
2028 freq += EDGE_FREQUENCY (e);
2029 VEC_free (edge, heap, edges);
2032 return REG_FREQ_FROM_EDGE_FREQ (freq);
2035 /* Calculate and return the cost of putting allocno A into memory. */
2036 static int
2037 calculate_allocno_spill_cost (ira_allocno_t a)
2039 int regno, cost;
2040 enum machine_mode mode;
2041 enum reg_class rclass;
2042 ira_allocno_t parent_allocno;
2043 ira_loop_tree_node_t parent_node, loop_node;
2045 regno = ALLOCNO_REGNO (a);
2046 cost = ALLOCNO_UPDATED_MEMORY_COST (a) - ALLOCNO_UPDATED_CLASS_COST (a);
2047 if (ALLOCNO_CAP (a) != NULL)
2048 return cost;
2049 loop_node = ALLOCNO_LOOP_TREE_NODE (a);
2050 if ((parent_node = loop_node->parent) == NULL)
2051 return cost;
2052 if ((parent_allocno = parent_node->regno_allocno_map[regno]) == NULL)
2053 return cost;
2054 mode = ALLOCNO_MODE (a);
2055 rclass = ALLOCNO_CLASS (a);
2056 if (ALLOCNO_HARD_REGNO (parent_allocno) < 0)
2057 cost -= (ira_memory_move_cost[mode][rclass][0]
2058 * ira_loop_edge_freq (loop_node, regno, true)
2059 + ira_memory_move_cost[mode][rclass][1]
2060 * ira_loop_edge_freq (loop_node, regno, false));
2061 else
2063 ira_init_register_move_cost_if_necessary (mode);
2064 cost += ((ira_memory_move_cost[mode][rclass][1]
2065 * ira_loop_edge_freq (loop_node, regno, true)
2066 + ira_memory_move_cost[mode][rclass][0]
2067 * ira_loop_edge_freq (loop_node, regno, false))
2068 - (ira_register_move_cost[mode][rclass][rclass]
2069 * (ira_loop_edge_freq (loop_node, regno, false)
2070 + ira_loop_edge_freq (loop_node, regno, true))));
2072 return cost;
2075 /* Used for sorting allocnos for spilling. */
2076 static inline int
2077 allocno_spill_priority_compare (ira_allocno_t a1, ira_allocno_t a2)
2079 int pri1, pri2, diff;
2081 if (ALLOCNO_BAD_SPILL_P (a1) && ! ALLOCNO_BAD_SPILL_P (a2))
2082 return 1;
2083 if (ALLOCNO_BAD_SPILL_P (a2) && ! ALLOCNO_BAD_SPILL_P (a1))
2084 return -1;
2085 pri1 = allocno_spill_priority (a1);
2086 pri2 = allocno_spill_priority (a2);
2087 if ((diff = pri1 - pri2) != 0)
2088 return diff;
2089 if ((diff
2090 = ALLOCNO_COLOR_DATA (a1)->temp - ALLOCNO_COLOR_DATA (a2)->temp) != 0)
2091 return diff;
2092 return ALLOCNO_NUM (a1) - ALLOCNO_NUM (a2);
2095 /* Used for sorting allocnos for spilling. */
2096 static int
2097 allocno_spill_sort_compare (const void *v1p, const void *v2p)
2099 ira_allocno_t p1 = *(const ira_allocno_t *) v1p;
2100 ira_allocno_t p2 = *(const ira_allocno_t *) v2p;
2102 return allocno_spill_priority_compare (p1, p2);
2105 /* Push allocnos to the coloring stack. The order of allocnos in the
2106 stack defines the order for the subsequent coloring. */
2107 static void
2108 push_allocnos_to_stack (void)
2110 ira_allocno_t a;
2111 int cost;
2113 /* Calculate uncolorable allocno spill costs. */
2114 for (a = uncolorable_allocno_bucket;
2115 a != NULL;
2116 a = ALLOCNO_COLOR_DATA (a)->next_bucket_allocno)
2117 if (ALLOCNO_CLASS (a) != NO_REGS)
2119 cost = calculate_allocno_spill_cost (a);
2120 /* ??? Remove cost of copies between the coalesced
2121 allocnos. */
2122 ALLOCNO_COLOR_DATA (a)->temp = cost;
2124 sort_bucket (&uncolorable_allocno_bucket, allocno_spill_sort_compare);
2125 for (;;)
2127 push_only_colorable ();
2128 a = uncolorable_allocno_bucket;
2129 if (a == NULL)
2130 break;
2131 remove_allocno_from_bucket_and_push (a, false);
2133 ira_assert (colorable_allocno_bucket == NULL
2134 && uncolorable_allocno_bucket == NULL);
2135 ira_assert (uncolorable_allocnos_num == 0);
2138 /* Pop the coloring stack and assign hard registers to the popped
2139 allocnos. */
2140 static void
2141 pop_allocnos_from_stack (void)
2143 ira_allocno_t allocno;
2144 enum reg_class aclass;
2146 for (;VEC_length (ira_allocno_t, allocno_stack_vec) != 0;)
2148 allocno = VEC_pop (ira_allocno_t, allocno_stack_vec);
2149 aclass = ALLOCNO_CLASS (allocno);
2150 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2152 fprintf (ira_dump_file, " Popping");
2153 ira_print_expanded_allocno (allocno);
2154 fprintf (ira_dump_file, " -- ");
2156 if (aclass == NO_REGS)
2158 ALLOCNO_HARD_REGNO (allocno) = -1;
2159 ALLOCNO_ASSIGNED_P (allocno) = true;
2160 ira_assert (ALLOCNO_UPDATED_HARD_REG_COSTS (allocno) == NULL);
2161 ira_assert
2162 (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (allocno) == NULL);
2163 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2164 fprintf (ira_dump_file, "assign memory\n");
2166 else if (assign_hard_reg (allocno, false))
2168 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2169 fprintf (ira_dump_file, "assign reg %d\n",
2170 ALLOCNO_HARD_REGNO (allocno));
2172 else if (ALLOCNO_ASSIGNED_P (allocno))
2174 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2175 fprintf (ira_dump_file, "spill\n");
2177 ALLOCNO_COLOR_DATA (allocno)->in_graph_p = true;
2181 /* Set up number of available hard registers for allocno A. */
2182 static void
2183 setup_allocno_available_regs_num (ira_allocno_t a)
2185 int i, n, hard_regno, hard_regs_num, nwords;
2186 enum reg_class aclass;
2187 allocno_color_data_t data;
2189 aclass = ALLOCNO_CLASS (a);
2190 data = ALLOCNO_COLOR_DATA (a);
2191 data->available_regs_num = 0;
2192 if (aclass == NO_REGS)
2193 return;
2194 hard_regs_num = ira_class_hard_regs_num[aclass];
2195 nwords = ALLOCNO_NUM_OBJECTS (a);
2196 for (n = 0, i = hard_regs_num - 1; i >= 0; i--)
2198 hard_regno = ira_class_hard_regs[aclass][i];
2199 /* Checking only profitable hard regs. */
2200 if (TEST_HARD_REG_BIT (data->profitable_hard_regs, hard_regno))
2201 n++;
2203 data->available_regs_num = n;
2204 if (internal_flag_ira_verbose <= 2 || ira_dump_file == NULL)
2205 return;
2206 fprintf
2207 (ira_dump_file,
2208 " Allocno a%dr%d of %s(%d) has %d avail. regs ",
2209 ALLOCNO_NUM (a), ALLOCNO_REGNO (a),
2210 reg_class_names[aclass], ira_class_hard_regs_num[aclass], n);
2211 print_hard_reg_set (ira_dump_file, data->profitable_hard_regs, false);
2212 fprintf (ira_dump_file, ", %snode: ",
2213 hard_reg_set_equal_p (data->profitable_hard_regs,
2214 data->hard_regs_node->hard_regs->set)
2215 ? "" : "^");
2216 print_hard_reg_set (ira_dump_file,
2217 data->hard_regs_node->hard_regs->set, false);
2218 for (i = 0; i < nwords; i++)
2220 ira_object_t obj = ALLOCNO_OBJECT (a, i);
2222 if (nwords != 1)
2224 if (i != 0)
2225 fprintf (ira_dump_file, ", ");
2226 fprintf (ira_dump_file, " obj %d", i);
2228 fprintf (ira_dump_file, " (confl regs = ");
2229 print_hard_reg_set (ira_dump_file, OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
2230 false);
2231 fprintf (ira_dump_file, ")");
2233 fprintf (ira_dump_file, "\n");
2236 /* Put ALLOCNO in a bucket corresponding to its number and size of its
2237 conflicting allocnos and hard registers. */
2238 static void
2239 put_allocno_into_bucket (ira_allocno_t allocno)
2241 ALLOCNO_COLOR_DATA (allocno)->in_graph_p = true;
2242 setup_allocno_available_regs_num (allocno);
2243 if (setup_left_conflict_sizes_p (allocno))
2244 add_allocno_to_bucket (allocno, &colorable_allocno_bucket);
2245 else
2246 add_allocno_to_bucket (allocno, &uncolorable_allocno_bucket);
2249 /* Map: allocno number -> allocno priority. */
2250 static int *allocno_priorities;
2252 /* Set up priorities for N allocnos in array
2253 CONSIDERATION_ALLOCNOS. */
2254 static void
2255 setup_allocno_priorities (ira_allocno_t *consideration_allocnos, int n)
2257 int i, length, nrefs, priority, max_priority, mult;
2258 ira_allocno_t a;
2260 max_priority = 0;
2261 for (i = 0; i < n; i++)
2263 a = consideration_allocnos[i];
2264 nrefs = ALLOCNO_NREFS (a);
2265 ira_assert (nrefs >= 0);
2266 mult = floor_log2 (ALLOCNO_NREFS (a)) + 1;
2267 ira_assert (mult >= 0);
2268 allocno_priorities[ALLOCNO_NUM (a)]
2269 = priority
2270 = (mult
2271 * (ALLOCNO_MEMORY_COST (a) - ALLOCNO_CLASS_COST (a))
2272 * ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]);
2273 if (priority < 0)
2274 priority = -priority;
2275 if (max_priority < priority)
2276 max_priority = priority;
2278 mult = max_priority == 0 ? 1 : INT_MAX / max_priority;
2279 for (i = 0; i < n; i++)
2281 a = consideration_allocnos[i];
2282 length = ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a);
2283 if (ALLOCNO_NUM_OBJECTS (a) > 1)
2284 length /= ALLOCNO_NUM_OBJECTS (a);
2285 if (length <= 0)
2286 length = 1;
2287 allocno_priorities[ALLOCNO_NUM (a)]
2288 = allocno_priorities[ALLOCNO_NUM (a)] * mult / length;
2292 /* Sort allocnos according to the profit of usage of a hard register
2293 instead of memory for them. */
2294 static int
2295 allocno_cost_compare_func (const void *v1p, const void *v2p)
2297 ira_allocno_t p1 = *(const ira_allocno_t *) v1p;
2298 ira_allocno_t p2 = *(const ira_allocno_t *) v2p;
2299 int c1, c2;
2301 c1 = ALLOCNO_UPDATED_MEMORY_COST (p1) - ALLOCNO_UPDATED_CLASS_COST (p1);
2302 c2 = ALLOCNO_UPDATED_MEMORY_COST (p2) - ALLOCNO_UPDATED_CLASS_COST (p2);
2303 if (c1 - c2)
2304 return c1 - c2;
2306 /* If regs are equally good, sort by allocno numbers, so that the
2307 results of qsort leave nothing to chance. */
2308 return ALLOCNO_NUM (p1) - ALLOCNO_NUM (p2);
2311 /* We used Chaitin-Briggs coloring to assign as many pseudos as
2312 possible to hard registers. Let us try to improve allocation with
2313 cost point of view. This function improves the allocation by
2314 spilling some allocnos and assigning the freed hard registers to
2315 other allocnos if it decreases the overall allocation cost. */
2316 static void
2317 improve_allocation (void)
2319 unsigned int i;
2320 int j, k, n, hregno, conflict_hregno, base_cost, class_size, word, nwords;
2321 int check, spill_cost, min_cost, nregs, conflict_nregs, r, best;
2322 bool try_p;
2323 enum reg_class aclass;
2324 enum machine_mode mode;
2325 int *allocno_costs;
2326 int costs[FIRST_PSEUDO_REGISTER];
2327 HARD_REG_SET conflicting_regs[2], profitable_hard_regs;
2328 ira_allocno_t a;
2329 bitmap_iterator bi;
2331 /* Clear counts used to process conflicting allocnos only once for
2332 each allocno. */
2333 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
2334 ALLOCNO_COLOR_DATA (ira_allocnos[i])->temp = 0;
2335 check = n = 0;
2336 /* Process each allocno and try to assign a hard register to it by
2337 spilling some its conflicting allocnos. */
2338 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
2340 a = ira_allocnos[i];
2341 ALLOCNO_COLOR_DATA (a)->temp = 0;
2342 if (empty_profitable_hard_regs (a))
2343 continue;
2344 check++;
2345 aclass = ALLOCNO_CLASS (a);
2346 allocno_costs = ALLOCNO_UPDATED_HARD_REG_COSTS (a);
2347 if (allocno_costs == NULL)
2348 allocno_costs = ALLOCNO_HARD_REG_COSTS (a);
2349 if ((hregno = ALLOCNO_HARD_REGNO (a)) < 0)
2350 base_cost = ALLOCNO_UPDATED_MEMORY_COST (a);
2351 else if (allocno_costs == NULL)
2352 /* It means that assigning a hard register is not profitable
2353 (we don't waste memory for hard register costs in this
2354 case). */
2355 continue;
2356 else
2357 base_cost = allocno_costs[ira_class_hard_reg_index[aclass][hregno]];
2358 try_p = false;
2359 get_conflict_and_start_profitable_regs (a, false,
2360 conflicting_regs,
2361 &profitable_hard_regs);
2362 class_size = ira_class_hard_regs_num[aclass];
2363 /* Set up cost improvement for usage of each profitable hard
2364 register for allocno A. */
2365 for (j = 0; j < class_size; j++)
2367 hregno = ira_class_hard_regs[aclass][j];
2368 if (! check_hard_reg_p (a, hregno,
2369 conflicting_regs, profitable_hard_regs))
2370 continue;
2371 ira_assert (ira_class_hard_reg_index[aclass][hregno] == j);
2372 k = allocno_costs == NULL ? 0 : j;
2373 costs[hregno] = (allocno_costs == NULL
2374 ? ALLOCNO_UPDATED_CLASS_COST (a) : allocno_costs[k]);
2375 costs[hregno] -= base_cost;
2376 if (costs[hregno] < 0)
2377 try_p = true;
2379 if (! try_p)
2380 /* There is no chance to improve the allocation cost by
2381 assigning hard register to allocno A even without spilling
2382 conflicting allocnos. */
2383 continue;
2384 mode = ALLOCNO_MODE (a);
2385 nwords = ALLOCNO_NUM_OBJECTS (a);
2386 /* Process each allocno conflicting with A and update the cost
2387 improvement for profitable hard registers of A. To use a
2388 hard register for A we need to spill some conflicting
2389 allocnos and that creates penalty for the cost
2390 improvement. */
2391 for (word = 0; word < nwords; word++)
2393 ira_object_t conflict_obj;
2394 ira_object_t obj = ALLOCNO_OBJECT (a, word);
2395 ira_object_conflict_iterator oci;
2397 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
2399 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
2401 if (ALLOCNO_COLOR_DATA (conflict_a)->temp == check)
2402 /* We already processed this conflicting allocno
2403 because we processed earlier another object of the
2404 conflicting allocno. */
2405 continue;
2406 ALLOCNO_COLOR_DATA (conflict_a)->temp = check;
2407 if ((conflict_hregno = ALLOCNO_HARD_REGNO (conflict_a)) < 0)
2408 continue;
2409 spill_cost = ALLOCNO_UPDATED_MEMORY_COST (conflict_a);
2410 k = (ira_class_hard_reg_index
2411 [ALLOCNO_CLASS (conflict_a)][conflict_hregno]);
2412 ira_assert (k >= 0);
2413 if ((allocno_costs = ALLOCNO_UPDATED_HARD_REG_COSTS (conflict_a))
2414 != NULL)
2415 spill_cost -= allocno_costs[k];
2416 else if ((allocno_costs = ALLOCNO_HARD_REG_COSTS (conflict_a))
2417 != NULL)
2418 spill_cost -= allocno_costs[k];
2419 else
2420 spill_cost -= ALLOCNO_UPDATED_CLASS_COST (conflict_a);
2421 conflict_nregs
2422 = hard_regno_nregs[conflict_hregno][ALLOCNO_MODE (conflict_a)];
2423 for (r = conflict_hregno;
2424 r >= 0 && r + hard_regno_nregs[r][mode] > conflict_hregno;
2425 r--)
2426 if (check_hard_reg_p (a, r,
2427 conflicting_regs, profitable_hard_regs))
2428 costs[r] += spill_cost;
2429 for (r = conflict_hregno + 1;
2430 r < conflict_hregno + conflict_nregs;
2431 r++)
2432 if (check_hard_reg_p (a, r,
2433 conflicting_regs, profitable_hard_regs))
2434 costs[r] += spill_cost;
2437 min_cost = INT_MAX;
2438 best = -1;
2439 /* Now we choose hard register for A which results in highest
2440 allocation cost improvement. */
2441 for (j = 0; j < class_size; j++)
2443 hregno = ira_class_hard_regs[aclass][j];
2444 if (check_hard_reg_p (a, hregno,
2445 conflicting_regs, profitable_hard_regs)
2446 && min_cost > costs[hregno])
2448 best = hregno;
2449 min_cost = costs[hregno];
2452 if (min_cost >= 0)
2453 /* We are in a situation when assigning any hard register to A
2454 by spilling some conflicting allocnos does not improve the
2455 allocation cost. */
2456 continue;
2457 nregs = hard_regno_nregs[best][mode];
2458 /* Now spill conflicting allocnos which contain a hard register
2459 of A when we assign the best chosen hard register to it. */
2460 for (word = 0; word < nwords; word++)
2462 ira_object_t conflict_obj;
2463 ira_object_t obj = ALLOCNO_OBJECT (a, word);
2464 ira_object_conflict_iterator oci;
2466 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
2468 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
2470 if ((conflict_hregno = ALLOCNO_HARD_REGNO (conflict_a)) < 0)
2471 continue;
2472 conflict_nregs
2473 = hard_regno_nregs[conflict_hregno][ALLOCNO_MODE (conflict_a)];
2474 if (best + nregs <= conflict_hregno
2475 || conflict_hregno + conflict_nregs <= best)
2476 /* No intersection. */
2477 continue;
2478 ALLOCNO_HARD_REGNO (conflict_a) = -1;
2479 sorted_allocnos[n++] = conflict_a;
2480 if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
2481 fprintf (ira_dump_file, "Spilling a%dr%d for a%dr%d\n",
2482 ALLOCNO_NUM (conflict_a), ALLOCNO_REGNO (conflict_a),
2483 ALLOCNO_NUM (a), ALLOCNO_REGNO (a));
2486 /* Assign the best chosen hard register to A. */
2487 ALLOCNO_HARD_REGNO (a) = best;
2488 if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
2489 fprintf (ira_dump_file, "Assigning %d to a%dr%d\n",
2490 best, ALLOCNO_NUM (a), ALLOCNO_REGNO (a));
2492 if (n == 0)
2493 return;
2494 /* We spilled some allocnos to assign their hard registers to other
2495 allocnos. The spilled allocnos are now in array
2496 'sorted_allocnos'. There is still a possibility that some of the
2497 spilled allocnos can get hard registers. So let us try assign
2498 them hard registers again (just a reminder -- function
2499 'assign_hard_reg' assigns hard registers only if it is possible
2500 and profitable). We process the spilled allocnos with biggest
2501 benefit to get hard register first -- see function
2502 'allocno_cost_compare_func'. */
2503 qsort (sorted_allocnos, n, sizeof (ira_allocno_t),
2504 allocno_cost_compare_func);
2505 for (j = 0; j < n; j++)
2507 a = sorted_allocnos[j];
2508 ALLOCNO_ASSIGNED_P (a) = false;
2509 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2511 fprintf (ira_dump_file, " ");
2512 ira_print_expanded_allocno (a);
2513 fprintf (ira_dump_file, " -- ");
2515 if (assign_hard_reg (a, false))
2517 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2518 fprintf (ira_dump_file, "assign hard reg %d\n",
2519 ALLOCNO_HARD_REGNO (a));
2521 else
2523 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2524 fprintf (ira_dump_file, "assign memory\n");
2529 /* Sort allocnos according to their priorities which are calculated
2530 analogous to ones in file `global.c'. */
2531 static int
2532 allocno_priority_compare_func (const void *v1p, const void *v2p)
2534 ira_allocno_t a1 = *(const ira_allocno_t *) v1p;
2535 ira_allocno_t a2 = *(const ira_allocno_t *) v2p;
2536 int pri1, pri2;
2538 pri1 = allocno_priorities[ALLOCNO_NUM (a1)];
2539 pri2 = allocno_priorities[ALLOCNO_NUM (a2)];
2540 if (pri2 != pri1)
2541 return SORTGT (pri2, pri1);
2543 /* If regs are equally good, sort by allocnos, so that the results of
2544 qsort leave nothing to chance. */
2545 return ALLOCNO_NUM (a1) - ALLOCNO_NUM (a2);
2548 /* Chaitin-Briggs coloring for allocnos in COLORING_ALLOCNO_BITMAP
2549 taking into account allocnos in CONSIDERATION_ALLOCNO_BITMAP. */
2550 static void
2551 color_allocnos (void)
2553 unsigned int i, n;
2554 bitmap_iterator bi;
2555 ira_allocno_t a;
2557 setup_profitable_hard_regs ();
2558 if (flag_ira_algorithm == IRA_ALGORITHM_PRIORITY)
2560 n = 0;
2561 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
2563 a = ira_allocnos[i];
2564 if (ALLOCNO_CLASS (a) == NO_REGS)
2566 ALLOCNO_HARD_REGNO (a) = -1;
2567 ALLOCNO_ASSIGNED_P (a) = true;
2568 ira_assert (ALLOCNO_UPDATED_HARD_REG_COSTS (a) == NULL);
2569 ira_assert (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a) == NULL);
2570 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2572 fprintf (ira_dump_file, " Spill");
2573 ira_print_expanded_allocno (a);
2574 fprintf (ira_dump_file, "\n");
2576 continue;
2578 sorted_allocnos[n++] = a;
2580 if (n != 0)
2582 setup_allocno_priorities (sorted_allocnos, n);
2583 qsort (sorted_allocnos, n, sizeof (ira_allocno_t),
2584 allocno_priority_compare_func);
2585 for (i = 0; i < n; i++)
2587 a = sorted_allocnos[i];
2588 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2590 fprintf (ira_dump_file, " ");
2591 ira_print_expanded_allocno (a);
2592 fprintf (ira_dump_file, " -- ");
2594 if (assign_hard_reg (a, false))
2596 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2597 fprintf (ira_dump_file, "assign hard reg %d\n",
2598 ALLOCNO_HARD_REGNO (a));
2600 else
2602 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2603 fprintf (ira_dump_file, "assign memory\n");
2608 else
2610 form_allocno_hard_regs_nodes_forest ();
2611 if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
2612 print_hard_regs_forest (ira_dump_file);
2613 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
2615 a = ira_allocnos[i];
2616 if (ALLOCNO_CLASS (a) != NO_REGS && ! empty_profitable_hard_regs (a))
2617 ALLOCNO_COLOR_DATA (a)->in_graph_p = true;
2618 else
2620 ALLOCNO_HARD_REGNO (a) = -1;
2621 ALLOCNO_ASSIGNED_P (a) = true;
2622 /* We don't need updated costs anymore. */
2623 ira_free_allocno_updated_costs (a);
2624 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2626 fprintf (ira_dump_file, " Spill");
2627 ira_print_expanded_allocno (a);
2628 fprintf (ira_dump_file, "\n");
2632 /* Put the allocnos into the corresponding buckets. */
2633 colorable_allocno_bucket = NULL;
2634 uncolorable_allocno_bucket = NULL;
2635 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
2637 a = ira_allocnos[i];
2638 if (ALLOCNO_COLOR_DATA (a)->in_graph_p)
2639 put_allocno_into_bucket (a);
2641 push_allocnos_to_stack ();
2642 pop_allocnos_from_stack ();
2643 finish_allocno_hard_regs_nodes_forest ();
2645 improve_allocation ();
2650 /* Output information about the loop given by its LOOP_TREE_NODE. */
2651 static void
2652 print_loop_title (ira_loop_tree_node_t loop_tree_node)
2654 unsigned int j;
2655 bitmap_iterator bi;
2656 ira_loop_tree_node_t subloop_node, dest_loop_node;
2657 edge e;
2658 edge_iterator ei;
2660 if (loop_tree_node->parent == NULL)
2661 fprintf (ira_dump_file,
2662 "\n Loop 0 (parent -1, header bb%d, depth 0)\n bbs:",
2663 NUM_FIXED_BLOCKS);
2664 else
2666 ira_assert (current_loops != NULL && loop_tree_node->loop != NULL);
2667 fprintf (ira_dump_file,
2668 "\n Loop %d (parent %d, header bb%d, depth %d)\n bbs:",
2669 loop_tree_node->loop_num, loop_tree_node->parent->loop_num,
2670 loop_tree_node->loop->header->index,
2671 loop_depth (loop_tree_node->loop));
2673 for (subloop_node = loop_tree_node->children;
2674 subloop_node != NULL;
2675 subloop_node = subloop_node->next)
2676 if (subloop_node->bb != NULL)
2678 fprintf (ira_dump_file, " %d", subloop_node->bb->index);
2679 FOR_EACH_EDGE (e, ei, subloop_node->bb->succs)
2680 if (e->dest != EXIT_BLOCK_PTR
2681 && ((dest_loop_node = IRA_BB_NODE (e->dest)->parent)
2682 != loop_tree_node))
2683 fprintf (ira_dump_file, "(->%d:l%d)",
2684 e->dest->index, dest_loop_node->loop_num);
2686 fprintf (ira_dump_file, "\n all:");
2687 EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->all_allocnos, 0, j, bi)
2688 fprintf (ira_dump_file, " %dr%d", j, ALLOCNO_REGNO (ira_allocnos[j]));
2689 fprintf (ira_dump_file, "\n modified regnos:");
2690 EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->modified_regnos, 0, j, bi)
2691 fprintf (ira_dump_file, " %d", j);
2692 fprintf (ira_dump_file, "\n border:");
2693 EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->border_allocnos, 0, j, bi)
2694 fprintf (ira_dump_file, " %dr%d", j, ALLOCNO_REGNO (ira_allocnos[j]));
2695 fprintf (ira_dump_file, "\n Pressure:");
2696 for (j = 0; (int) j < ira_pressure_classes_num; j++)
2698 enum reg_class pclass;
2700 pclass = ira_pressure_classes[j];
2701 if (loop_tree_node->reg_pressure[pclass] == 0)
2702 continue;
2703 fprintf (ira_dump_file, " %s=%d", reg_class_names[pclass],
2704 loop_tree_node->reg_pressure[pclass]);
2706 fprintf (ira_dump_file, "\n");
2709 /* Color the allocnos inside loop (in the extreme case it can be all
2710 of the function) given the corresponding LOOP_TREE_NODE. The
2711 function is called for each loop during top-down traverse of the
2712 loop tree. */
2713 static void
2714 color_pass (ira_loop_tree_node_t loop_tree_node)
2716 int regno, hard_regno, index = -1, n;
2717 int cost, exit_freq, enter_freq;
2718 unsigned int j;
2719 bitmap_iterator bi;
2720 enum machine_mode mode;
2721 enum reg_class rclass, aclass, pclass;
2722 ira_allocno_t a, subloop_allocno;
2723 ira_loop_tree_node_t subloop_node;
2725 ira_assert (loop_tree_node->bb == NULL);
2726 if (internal_flag_ira_verbose > 1 && ira_dump_file != NULL)
2727 print_loop_title (loop_tree_node);
2729 bitmap_copy (coloring_allocno_bitmap, loop_tree_node->all_allocnos);
2730 bitmap_copy (consideration_allocno_bitmap, coloring_allocno_bitmap);
2731 n = 0;
2732 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
2734 a = ira_allocnos[j];
2735 n++;
2736 if (! ALLOCNO_ASSIGNED_P (a))
2737 continue;
2738 bitmap_clear_bit (coloring_allocno_bitmap, ALLOCNO_NUM (a));
2740 allocno_color_data
2741 = (allocno_color_data_t) ira_allocate (sizeof (struct allocno_color_data)
2742 * n);
2743 memset (allocno_color_data, 0, sizeof (struct allocno_color_data) * n);
2744 curr_allocno_process = 0;
2745 n = 0;
2746 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
2748 a = ira_allocnos[j];
2749 ALLOCNO_ADD_DATA (a) = allocno_color_data + n;
2750 n++;
2752 /* Color all mentioned allocnos including transparent ones. */
2753 color_allocnos ();
2754 /* Process caps. They are processed just once. */
2755 if (flag_ira_region == IRA_REGION_MIXED
2756 || flag_ira_region == IRA_REGION_ALL)
2757 EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->all_allocnos, 0, j, bi)
2759 a = ira_allocnos[j];
2760 if (ALLOCNO_CAP_MEMBER (a) == NULL)
2761 continue;
2762 /* Remove from processing in the next loop. */
2763 bitmap_clear_bit (consideration_allocno_bitmap, j);
2764 rclass = ALLOCNO_CLASS (a);
2765 pclass = ira_pressure_class_translate[rclass];
2766 if (flag_ira_region == IRA_REGION_MIXED
2767 && (loop_tree_node->reg_pressure[pclass]
2768 <= ira_class_hard_regs_num[pclass]))
2770 mode = ALLOCNO_MODE (a);
2771 hard_regno = ALLOCNO_HARD_REGNO (a);
2772 if (hard_regno >= 0)
2774 index = ira_class_hard_reg_index[rclass][hard_regno];
2775 ira_assert (index >= 0);
2777 regno = ALLOCNO_REGNO (a);
2778 subloop_allocno = ALLOCNO_CAP_MEMBER (a);
2779 subloop_node = ALLOCNO_LOOP_TREE_NODE (subloop_allocno);
2780 ira_assert (!ALLOCNO_ASSIGNED_P (subloop_allocno));
2781 ALLOCNO_HARD_REGNO (subloop_allocno) = hard_regno;
2782 ALLOCNO_ASSIGNED_P (subloop_allocno) = true;
2783 if (hard_regno >= 0)
2784 update_copy_costs (subloop_allocno, true);
2785 /* We don't need updated costs anymore: */
2786 ira_free_allocno_updated_costs (subloop_allocno);
2789 /* Update costs of the corresponding allocnos (not caps) in the
2790 subloops. */
2791 for (subloop_node = loop_tree_node->subloops;
2792 subloop_node != NULL;
2793 subloop_node = subloop_node->subloop_next)
2795 ira_assert (subloop_node->bb == NULL);
2796 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
2798 a = ira_allocnos[j];
2799 ira_assert (ALLOCNO_CAP_MEMBER (a) == NULL);
2800 mode = ALLOCNO_MODE (a);
2801 rclass = ALLOCNO_CLASS (a);
2802 pclass = ira_pressure_class_translate[rclass];
2803 hard_regno = ALLOCNO_HARD_REGNO (a);
2804 /* Use hard register class here. ??? */
2805 if (hard_regno >= 0)
2807 index = ira_class_hard_reg_index[rclass][hard_regno];
2808 ira_assert (index >= 0);
2810 regno = ALLOCNO_REGNO (a);
2811 /* ??? conflict costs */
2812 subloop_allocno = subloop_node->regno_allocno_map[regno];
2813 if (subloop_allocno == NULL
2814 || ALLOCNO_CAP (subloop_allocno) != NULL)
2815 continue;
2816 ira_assert (ALLOCNO_CLASS (subloop_allocno) == rclass);
2817 ira_assert (bitmap_bit_p (subloop_node->all_allocnos,
2818 ALLOCNO_NUM (subloop_allocno)));
2819 if ((flag_ira_region == IRA_REGION_MIXED)
2820 && (loop_tree_node->reg_pressure[pclass]
2821 <= ira_class_hard_regs_num[pclass]))
2823 if (! ALLOCNO_ASSIGNED_P (subloop_allocno))
2825 ALLOCNO_HARD_REGNO (subloop_allocno) = hard_regno;
2826 ALLOCNO_ASSIGNED_P (subloop_allocno) = true;
2827 if (hard_regno >= 0)
2828 update_copy_costs (subloop_allocno, true);
2829 /* We don't need updated costs anymore: */
2830 ira_free_allocno_updated_costs (subloop_allocno);
2832 continue;
2834 exit_freq = ira_loop_edge_freq (subloop_node, regno, true);
2835 enter_freq = ira_loop_edge_freq (subloop_node, regno, false);
2836 ira_assert (regno < ira_reg_equiv_len);
2837 if (ira_equiv_no_lvalue_p (regno))
2839 if (! ALLOCNO_ASSIGNED_P (subloop_allocno))
2841 ALLOCNO_HARD_REGNO (subloop_allocno) = hard_regno;
2842 ALLOCNO_ASSIGNED_P (subloop_allocno) = true;
2843 if (hard_regno >= 0)
2844 update_copy_costs (subloop_allocno, true);
2845 /* We don't need updated costs anymore: */
2846 ira_free_allocno_updated_costs (subloop_allocno);
2849 else if (hard_regno < 0)
2851 ALLOCNO_UPDATED_MEMORY_COST (subloop_allocno)
2852 -= ((ira_memory_move_cost[mode][rclass][1] * enter_freq)
2853 + (ira_memory_move_cost[mode][rclass][0] * exit_freq));
2855 else
2857 aclass = ALLOCNO_CLASS (subloop_allocno);
2858 ira_init_register_move_cost_if_necessary (mode);
2859 cost = (ira_register_move_cost[mode][rclass][rclass]
2860 * (exit_freq + enter_freq));
2861 ira_allocate_and_set_or_copy_costs
2862 (&ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno), aclass,
2863 ALLOCNO_UPDATED_CLASS_COST (subloop_allocno),
2864 ALLOCNO_HARD_REG_COSTS (subloop_allocno));
2865 ira_allocate_and_set_or_copy_costs
2866 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (subloop_allocno),
2867 aclass, 0, ALLOCNO_CONFLICT_HARD_REG_COSTS (subloop_allocno));
2868 ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno)[index] -= cost;
2869 ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (subloop_allocno)[index]
2870 -= cost;
2871 if (ALLOCNO_UPDATED_CLASS_COST (subloop_allocno)
2872 > ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno)[index])
2873 ALLOCNO_UPDATED_CLASS_COST (subloop_allocno)
2874 = ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno)[index];
2875 ALLOCNO_UPDATED_MEMORY_COST (subloop_allocno)
2876 += (ira_memory_move_cost[mode][rclass][0] * enter_freq
2877 + ira_memory_move_cost[mode][rclass][1] * exit_freq);
2881 ira_free (allocno_color_data);
2882 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, j, bi)
2884 a = ira_allocnos[j];
2885 ALLOCNO_ADD_DATA (a) = NULL;
2889 /* Initialize the common data for coloring and calls functions to do
2890 Chaitin-Briggs and regional coloring. */
2891 static void
2892 do_coloring (void)
2894 coloring_allocno_bitmap = ira_allocate_bitmap ();
2895 if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
2896 fprintf (ira_dump_file, "\n**** Allocnos coloring:\n\n");
2898 ira_traverse_loop_tree (false, ira_loop_tree_root, color_pass, NULL);
2900 if (internal_flag_ira_verbose > 1 && ira_dump_file != NULL)
2901 ira_print_disposition (ira_dump_file);
2903 ira_free_bitmap (coloring_allocno_bitmap);
2908 /* Move spill/restore code, which are to be generated in ira-emit.c,
2909 to less frequent points (if it is profitable) by reassigning some
2910 allocnos (in loop with subloops containing in another loop) to
2911 memory which results in longer live-range where the corresponding
2912 pseudo-registers will be in memory. */
2913 static void
2914 move_spill_restore (void)
2916 int cost, regno, hard_regno, hard_regno2, index;
2917 bool changed_p;
2918 int enter_freq, exit_freq;
2919 enum machine_mode mode;
2920 enum reg_class rclass;
2921 ira_allocno_t a, parent_allocno, subloop_allocno;
2922 ira_loop_tree_node_t parent, loop_node, subloop_node;
2923 ira_allocno_iterator ai;
2925 for (;;)
2927 changed_p = false;
2928 if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
2929 fprintf (ira_dump_file, "New iteration of spill/restore move\n");
2930 FOR_EACH_ALLOCNO (a, ai)
2932 regno = ALLOCNO_REGNO (a);
2933 loop_node = ALLOCNO_LOOP_TREE_NODE (a);
2934 if (ALLOCNO_CAP_MEMBER (a) != NULL
2935 || ALLOCNO_CAP (a) != NULL
2936 || (hard_regno = ALLOCNO_HARD_REGNO (a)) < 0
2937 || loop_node->children == NULL
2938 /* don't do the optimization because it can create
2939 copies and the reload pass can spill the allocno set
2940 by copy although the allocno will not get memory
2941 slot. */
2942 || ira_equiv_no_lvalue_p (regno)
2943 || !bitmap_bit_p (loop_node->border_allocnos, ALLOCNO_NUM (a)))
2944 continue;
2945 mode = ALLOCNO_MODE (a);
2946 rclass = ALLOCNO_CLASS (a);
2947 index = ira_class_hard_reg_index[rclass][hard_regno];
2948 ira_assert (index >= 0);
2949 cost = (ALLOCNO_MEMORY_COST (a)
2950 - (ALLOCNO_HARD_REG_COSTS (a) == NULL
2951 ? ALLOCNO_CLASS_COST (a)
2952 : ALLOCNO_HARD_REG_COSTS (a)[index]));
2953 ira_init_register_move_cost_if_necessary (mode);
2954 for (subloop_node = loop_node->subloops;
2955 subloop_node != NULL;
2956 subloop_node = subloop_node->subloop_next)
2958 ira_assert (subloop_node->bb == NULL);
2959 subloop_allocno = subloop_node->regno_allocno_map[regno];
2960 if (subloop_allocno == NULL)
2961 continue;
2962 ira_assert (rclass == ALLOCNO_CLASS (subloop_allocno));
2963 /* We have accumulated cost. To get the real cost of
2964 allocno usage in the loop we should subtract costs of
2965 the subloop allocnos. */
2966 cost -= (ALLOCNO_MEMORY_COST (subloop_allocno)
2967 - (ALLOCNO_HARD_REG_COSTS (subloop_allocno) == NULL
2968 ? ALLOCNO_CLASS_COST (subloop_allocno)
2969 : ALLOCNO_HARD_REG_COSTS (subloop_allocno)[index]));
2970 exit_freq = ira_loop_edge_freq (subloop_node, regno, true);
2971 enter_freq = ira_loop_edge_freq (subloop_node, regno, false);
2972 if ((hard_regno2 = ALLOCNO_HARD_REGNO (subloop_allocno)) < 0)
2973 cost -= (ira_memory_move_cost[mode][rclass][0] * exit_freq
2974 + ira_memory_move_cost[mode][rclass][1] * enter_freq);
2975 else
2977 cost
2978 += (ira_memory_move_cost[mode][rclass][0] * exit_freq
2979 + ira_memory_move_cost[mode][rclass][1] * enter_freq);
2980 if (hard_regno2 != hard_regno)
2981 cost -= (ira_register_move_cost[mode][rclass][rclass]
2982 * (exit_freq + enter_freq));
2985 if ((parent = loop_node->parent) != NULL
2986 && (parent_allocno = parent->regno_allocno_map[regno]) != NULL)
2988 ira_assert (rclass == ALLOCNO_CLASS (parent_allocno));
2989 exit_freq = ira_loop_edge_freq (loop_node, regno, true);
2990 enter_freq = ira_loop_edge_freq (loop_node, regno, false);
2991 if ((hard_regno2 = ALLOCNO_HARD_REGNO (parent_allocno)) < 0)
2992 cost -= (ira_memory_move_cost[mode][rclass][0] * exit_freq
2993 + ira_memory_move_cost[mode][rclass][1] * enter_freq);
2994 else
2996 cost
2997 += (ira_memory_move_cost[mode][rclass][1] * exit_freq
2998 + ira_memory_move_cost[mode][rclass][0] * enter_freq);
2999 if (hard_regno2 != hard_regno)
3000 cost -= (ira_register_move_cost[mode][rclass][rclass]
3001 * (exit_freq + enter_freq));
3004 if (cost < 0)
3006 ALLOCNO_HARD_REGNO (a) = -1;
3007 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3009 fprintf
3010 (ira_dump_file,
3011 " Moving spill/restore for a%dr%d up from loop %d",
3012 ALLOCNO_NUM (a), regno, loop_node->loop_num);
3013 fprintf (ira_dump_file, " - profit %d\n", -cost);
3015 changed_p = true;
3018 if (! changed_p)
3019 break;
3025 /* Update current hard reg costs and current conflict hard reg costs
3026 for allocno A. It is done by processing its copies containing
3027 other allocnos already assigned. */
3028 static void
3029 update_curr_costs (ira_allocno_t a)
3031 int i, hard_regno, cost;
3032 enum machine_mode mode;
3033 enum reg_class aclass, rclass;
3034 ira_allocno_t another_a;
3035 ira_copy_t cp, next_cp;
3037 ira_free_allocno_updated_costs (a);
3038 ira_assert (! ALLOCNO_ASSIGNED_P (a));
3039 aclass = ALLOCNO_CLASS (a);
3040 if (aclass == NO_REGS)
3041 return;
3042 mode = ALLOCNO_MODE (a);
3043 ira_init_register_move_cost_if_necessary (mode);
3044 for (cp = ALLOCNO_COPIES (a); cp != NULL; cp = next_cp)
3046 if (cp->first == a)
3048 next_cp = cp->next_first_allocno_copy;
3049 another_a = cp->second;
3051 else if (cp->second == a)
3053 next_cp = cp->next_second_allocno_copy;
3054 another_a = cp->first;
3056 else
3057 gcc_unreachable ();
3058 if (! ira_reg_classes_intersect_p[aclass][ALLOCNO_CLASS (another_a)]
3059 || ! ALLOCNO_ASSIGNED_P (another_a)
3060 || (hard_regno = ALLOCNO_HARD_REGNO (another_a)) < 0)
3061 continue;
3062 rclass = REGNO_REG_CLASS (hard_regno);
3063 i = ira_class_hard_reg_index[aclass][hard_regno];
3064 if (i < 0)
3065 continue;
3066 cost = (cp->first == a
3067 ? ira_register_move_cost[mode][rclass][aclass]
3068 : ira_register_move_cost[mode][aclass][rclass]);
3069 ira_allocate_and_set_or_copy_costs
3070 (&ALLOCNO_UPDATED_HARD_REG_COSTS (a), aclass, ALLOCNO_CLASS_COST (a),
3071 ALLOCNO_HARD_REG_COSTS (a));
3072 ira_allocate_and_set_or_copy_costs
3073 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a),
3074 aclass, 0, ALLOCNO_CONFLICT_HARD_REG_COSTS (a));
3075 ALLOCNO_UPDATED_HARD_REG_COSTS (a)[i] -= cp->freq * cost;
3076 ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a)[i] -= cp->freq * cost;
3080 /* Try to assign hard registers to the unassigned allocnos and
3081 allocnos conflicting with them or conflicting with allocnos whose
3082 regno >= START_REGNO. The function is called after ira_flattening,
3083 so more allocnos (including ones created in ira-emit.c) will have a
3084 chance to get a hard register. We use simple assignment algorithm
3085 based on priorities. */
3086 void
3087 ira_reassign_conflict_allocnos (int start_regno)
3089 int i, allocnos_to_color_num;
3090 ira_allocno_t a;
3091 enum reg_class aclass;
3092 bitmap allocnos_to_color;
3093 ira_allocno_iterator ai;
3095 allocnos_to_color = ira_allocate_bitmap ();
3096 allocnos_to_color_num = 0;
3097 FOR_EACH_ALLOCNO (a, ai)
3099 int n = ALLOCNO_NUM_OBJECTS (a);
3101 if (! ALLOCNO_ASSIGNED_P (a)
3102 && ! bitmap_bit_p (allocnos_to_color, ALLOCNO_NUM (a)))
3104 if (ALLOCNO_CLASS (a) != NO_REGS)
3105 sorted_allocnos[allocnos_to_color_num++] = a;
3106 else
3108 ALLOCNO_ASSIGNED_P (a) = true;
3109 ALLOCNO_HARD_REGNO (a) = -1;
3110 ira_assert (ALLOCNO_UPDATED_HARD_REG_COSTS (a) == NULL);
3111 ira_assert (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a) == NULL);
3113 bitmap_set_bit (allocnos_to_color, ALLOCNO_NUM (a));
3115 if (ALLOCNO_REGNO (a) < start_regno
3116 || (aclass = ALLOCNO_CLASS (a)) == NO_REGS)
3117 continue;
3118 for (i = 0; i < n; i++)
3120 ira_object_t obj = ALLOCNO_OBJECT (a, i);
3121 ira_object_t conflict_obj;
3122 ira_object_conflict_iterator oci;
3124 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
3126 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
3128 ira_assert (ira_reg_classes_intersect_p
3129 [aclass][ALLOCNO_CLASS (conflict_a)]);
3130 if (!bitmap_set_bit (allocnos_to_color, ALLOCNO_NUM (conflict_a)))
3131 continue;
3132 sorted_allocnos[allocnos_to_color_num++] = conflict_a;
3136 ira_free_bitmap (allocnos_to_color);
3137 if (allocnos_to_color_num > 1)
3139 setup_allocno_priorities (sorted_allocnos, allocnos_to_color_num);
3140 qsort (sorted_allocnos, allocnos_to_color_num, sizeof (ira_allocno_t),
3141 allocno_priority_compare_func);
3143 for (i = 0; i < allocnos_to_color_num; i++)
3145 a = sorted_allocnos[i];
3146 ALLOCNO_ASSIGNED_P (a) = false;
3147 update_curr_costs (a);
3149 for (i = 0; i < allocnos_to_color_num; i++)
3151 a = sorted_allocnos[i];
3152 if (assign_hard_reg (a, true))
3154 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3155 fprintf
3156 (ira_dump_file,
3157 " Secondary allocation: assign hard reg %d to reg %d\n",
3158 ALLOCNO_HARD_REGNO (a), ALLOCNO_REGNO (a));
3165 /* This page contains functions used to find conflicts using allocno
3166 live ranges. */
3168 /* Return TRUE if live ranges of allocnos A1 and A2 intersect. It is
3169 used to find a conflict for new allocnos or allocnos with the
3170 different allocno classes. */
3171 static bool
3172 allocnos_conflict_by_live_ranges_p (ira_allocno_t a1, ira_allocno_t a2)
3174 rtx reg1, reg2;
3175 int i, j;
3176 int n1 = ALLOCNO_NUM_OBJECTS (a1);
3177 int n2 = ALLOCNO_NUM_OBJECTS (a2);
3179 if (a1 == a2)
3180 return false;
3181 reg1 = regno_reg_rtx[ALLOCNO_REGNO (a1)];
3182 reg2 = regno_reg_rtx[ALLOCNO_REGNO (a2)];
3183 if (reg1 != NULL && reg2 != NULL
3184 && ORIGINAL_REGNO (reg1) == ORIGINAL_REGNO (reg2))
3185 return false;
3187 for (i = 0; i < n1; i++)
3189 ira_object_t c1 = ALLOCNO_OBJECT (a1, i);
3191 for (j = 0; j < n2; j++)
3193 ira_object_t c2 = ALLOCNO_OBJECT (a2, j);
3195 if (ira_live_ranges_intersect_p (OBJECT_LIVE_RANGES (c1),
3196 OBJECT_LIVE_RANGES (c2)))
3197 return true;
3200 return false;
3203 #ifdef ENABLE_IRA_CHECKING
3205 /* Return TRUE if live ranges of pseudo-registers REGNO1 and REGNO2
3206 intersect. This should be used when there is only one region.
3207 Currently this is used during reload. */
3208 static bool
3209 conflict_by_live_ranges_p (int regno1, int regno2)
3211 ira_allocno_t a1, a2;
3213 ira_assert (regno1 >= FIRST_PSEUDO_REGISTER
3214 && regno2 >= FIRST_PSEUDO_REGISTER);
3215 /* Reg info caclulated by dataflow infrastructure can be different
3216 from one calculated by regclass. */
3217 if ((a1 = ira_loop_tree_root->regno_allocno_map[regno1]) == NULL
3218 || (a2 = ira_loop_tree_root->regno_allocno_map[regno2]) == NULL)
3219 return false;
3220 return allocnos_conflict_by_live_ranges_p (a1, a2);
3223 #endif
3227 /* This page contains code to coalesce memory stack slots used by
3228 spilled allocnos. This results in smaller stack frame, better data
3229 locality, and in smaller code for some architectures like
3230 x86/x86_64 where insn size depends on address displacement value.
3231 On the other hand, it can worsen insn scheduling after the RA but
3232 in practice it is less important than smaller stack frames. */
3234 /* TRUE if we coalesced some allocnos. In other words, if we got
3235 loops formed by members first_coalesced_allocno and
3236 next_coalesced_allocno containing more one allocno. */
3237 static bool allocno_coalesced_p;
3239 /* Bitmap used to prevent a repeated allocno processing because of
3240 coalescing. */
3241 static bitmap processed_coalesced_allocno_bitmap;
3243 /* See below. */
3244 typedef struct coalesce_data *coalesce_data_t;
3246 /* To decrease footprint of ira_allocno structure we store all data
3247 needed only for coalescing in the following structure. */
3248 struct coalesce_data
3250 /* Coalesced allocnos form a cyclic list. One allocno given by
3251 FIRST represents all coalesced allocnos. The
3252 list is chained by NEXT. */
3253 ira_allocno_t first;
3254 ira_allocno_t next;
3255 int temp;
3258 /* Container for storing allocno data concerning coalescing. */
3259 static coalesce_data_t allocno_coalesce_data;
3261 /* Macro to access the data concerning coalescing. */
3262 #define ALLOCNO_COALESCE_DATA(a) ((coalesce_data_t) ALLOCNO_ADD_DATA (a))
3264 /* The function is used to sort allocnos according to their execution
3265 frequencies. */
3266 static int
3267 copy_freq_compare_func (const void *v1p, const void *v2p)
3269 ira_copy_t cp1 = *(const ira_copy_t *) v1p, cp2 = *(const ira_copy_t *) v2p;
3270 int pri1, pri2;
3272 pri1 = cp1->freq;
3273 pri2 = cp2->freq;
3274 if (pri2 - pri1)
3275 return pri2 - pri1;
3277 /* If freqencies are equal, sort by copies, so that the results of
3278 qsort leave nothing to chance. */
3279 return cp1->num - cp2->num;
3282 /* Merge two sets of coalesced allocnos given correspondingly by
3283 allocnos A1 and A2 (more accurately merging A2 set into A1
3284 set). */
3285 static void
3286 merge_allocnos (ira_allocno_t a1, ira_allocno_t a2)
3288 ira_allocno_t a, first, last, next;
3290 first = ALLOCNO_COALESCE_DATA (a1)->first;
3291 a = ALLOCNO_COALESCE_DATA (a2)->first;
3292 if (first == a)
3293 return;
3294 for (last = a2, a = ALLOCNO_COALESCE_DATA (a2)->next;;
3295 a = ALLOCNO_COALESCE_DATA (a)->next)
3297 ALLOCNO_COALESCE_DATA (a)->first = first;
3298 if (a == a2)
3299 break;
3300 last = a;
3302 next = allocno_coalesce_data[ALLOCNO_NUM (first)].next;
3303 allocno_coalesce_data[ALLOCNO_NUM (first)].next = a2;
3304 allocno_coalesce_data[ALLOCNO_NUM (last)].next = next;
3307 /* Return TRUE if there are conflicting allocnos from two sets of
3308 coalesced allocnos given correspondingly by allocnos A1 and A2. We
3309 use live ranges to find conflicts because conflicts are represented
3310 only for allocnos of the same allocno class and during the reload
3311 pass we coalesce allocnos for sharing stack memory slots. */
3312 static bool
3313 coalesced_allocno_conflict_p (ira_allocno_t a1, ira_allocno_t a2)
3315 ira_allocno_t a, conflict_a;
3317 if (allocno_coalesced_p)
3319 bitmap_clear (processed_coalesced_allocno_bitmap);
3320 for (a = ALLOCNO_COALESCE_DATA (a1)->next;;
3321 a = ALLOCNO_COALESCE_DATA (a)->next)
3323 bitmap_set_bit (processed_coalesced_allocno_bitmap, ALLOCNO_NUM (a));
3324 if (a == a1)
3325 break;
3328 for (a = ALLOCNO_COALESCE_DATA (a2)->next;;
3329 a = ALLOCNO_COALESCE_DATA (a)->next)
3331 for (conflict_a = ALLOCNO_COALESCE_DATA (a1)->next;;
3332 conflict_a = ALLOCNO_COALESCE_DATA (conflict_a)->next)
3334 if (allocnos_conflict_by_live_ranges_p (a, conflict_a))
3335 return true;
3336 if (conflict_a == a1)
3337 break;
3339 if (a == a2)
3340 break;
3342 return false;
3345 /* The major function for aggressive allocno coalescing. We coalesce
3346 only spilled allocnos. If some allocnos have been coalesced, we
3347 set up flag allocno_coalesced_p. */
3348 static void
3349 coalesce_allocnos (void)
3351 ira_allocno_t a;
3352 ira_copy_t cp, next_cp, *sorted_copies;
3353 unsigned int j;
3354 int i, n, cp_num, regno;
3355 bitmap_iterator bi;
3357 sorted_copies = (ira_copy_t *) ira_allocate (ira_copies_num
3358 * sizeof (ira_copy_t));
3359 cp_num = 0;
3360 /* Collect copies. */
3361 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, j, bi)
3363 a = ira_allocnos[j];
3364 regno = ALLOCNO_REGNO (a);
3365 if (! ALLOCNO_ASSIGNED_P (a) || ALLOCNO_HARD_REGNO (a) >= 0
3366 || ira_equiv_no_lvalue_p (regno))
3367 continue;
3368 for (cp = ALLOCNO_COPIES (a); cp != NULL; cp = next_cp)
3370 if (cp->first == a)
3372 next_cp = cp->next_first_allocno_copy;
3373 regno = ALLOCNO_REGNO (cp->second);
3374 /* For priority coloring we coalesce allocnos only with
3375 the same allocno class not with intersected allocno
3376 classes as it were possible. It is done for
3377 simplicity. */
3378 if ((cp->insn != NULL || cp->constraint_p)
3379 && ALLOCNO_ASSIGNED_P (cp->second)
3380 && ALLOCNO_HARD_REGNO (cp->second) < 0
3381 && ! ira_equiv_no_lvalue_p (regno))
3382 sorted_copies[cp_num++] = cp;
3384 else if (cp->second == a)
3385 next_cp = cp->next_second_allocno_copy;
3386 else
3387 gcc_unreachable ();
3390 qsort (sorted_copies, cp_num, sizeof (ira_copy_t), copy_freq_compare_func);
3391 /* Coalesced copies, most frequently executed first. */
3392 for (; cp_num != 0;)
3394 for (i = 0; i < cp_num; i++)
3396 cp = sorted_copies[i];
3397 if (! coalesced_allocno_conflict_p (cp->first, cp->second))
3399 allocno_coalesced_p = true;
3400 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3401 fprintf
3402 (ira_dump_file,
3403 " Coalescing copy %d:a%dr%d-a%dr%d (freq=%d)\n",
3404 cp->num, ALLOCNO_NUM (cp->first), ALLOCNO_REGNO (cp->first),
3405 ALLOCNO_NUM (cp->second), ALLOCNO_REGNO (cp->second),
3406 cp->freq);
3407 merge_allocnos (cp->first, cp->second);
3408 i++;
3409 break;
3412 /* Collect the rest of copies. */
3413 for (n = 0; i < cp_num; i++)
3415 cp = sorted_copies[i];
3416 if (allocno_coalesce_data[ALLOCNO_NUM (cp->first)].first
3417 != allocno_coalesce_data[ALLOCNO_NUM (cp->second)].first)
3418 sorted_copies[n++] = cp;
3420 cp_num = n;
3422 ira_free (sorted_copies);
3425 /* Usage cost and order number of coalesced allocno set to which
3426 given pseudo register belongs to. */
3427 static int *regno_coalesced_allocno_cost;
3428 static int *regno_coalesced_allocno_num;
3430 /* Sort pseudos according frequencies of coalesced allocno sets they
3431 belong to (putting most frequently ones first), and according to
3432 coalesced allocno set order numbers. */
3433 static int
3434 coalesced_pseudo_reg_freq_compare (const void *v1p, const void *v2p)
3436 const int regno1 = *(const int *) v1p;
3437 const int regno2 = *(const int *) v2p;
3438 int diff;
3440 if ((diff = (regno_coalesced_allocno_cost[regno2]
3441 - regno_coalesced_allocno_cost[regno1])) != 0)
3442 return diff;
3443 if ((diff = (regno_coalesced_allocno_num[regno1]
3444 - regno_coalesced_allocno_num[regno2])) != 0)
3445 return diff;
3446 return regno1 - regno2;
3449 /* Widest width in which each pseudo reg is referred to (via subreg).
3450 It is used for sorting pseudo registers. */
3451 static unsigned int *regno_max_ref_width;
3453 /* Redefine STACK_GROWS_DOWNWARD in terms of 0 or 1. */
3454 #ifdef STACK_GROWS_DOWNWARD
3455 # undef STACK_GROWS_DOWNWARD
3456 # define STACK_GROWS_DOWNWARD 1
3457 #else
3458 # define STACK_GROWS_DOWNWARD 0
3459 #endif
3461 /* Sort pseudos according their slot numbers (putting ones with
3462 smaller numbers first, or last when the frame pointer is not
3463 needed). */
3464 static int
3465 coalesced_pseudo_reg_slot_compare (const void *v1p, const void *v2p)
3467 const int regno1 = *(const int *) v1p;
3468 const int regno2 = *(const int *) v2p;
3469 ira_allocno_t a1 = ira_regno_allocno_map[regno1];
3470 ira_allocno_t a2 = ira_regno_allocno_map[regno2];
3471 int diff, slot_num1, slot_num2;
3472 int total_size1, total_size2;
3474 if (a1 == NULL || ALLOCNO_HARD_REGNO (a1) >= 0)
3476 if (a2 == NULL || ALLOCNO_HARD_REGNO (a2) >= 0)
3477 return regno1 - regno2;
3478 return 1;
3480 else if (a2 == NULL || ALLOCNO_HARD_REGNO (a2) >= 0)
3481 return -1;
3482 slot_num1 = -ALLOCNO_HARD_REGNO (a1);
3483 slot_num2 = -ALLOCNO_HARD_REGNO (a2);
3484 if ((diff = slot_num1 - slot_num2) != 0)
3485 return (frame_pointer_needed
3486 || !FRAME_GROWS_DOWNWARD == STACK_GROWS_DOWNWARD ? diff : -diff);
3487 total_size1 = MAX (PSEUDO_REGNO_BYTES (regno1),
3488 regno_max_ref_width[regno1]);
3489 total_size2 = MAX (PSEUDO_REGNO_BYTES (regno2),
3490 regno_max_ref_width[regno2]);
3491 if ((diff = total_size2 - total_size1) != 0)
3492 return diff;
3493 return regno1 - regno2;
3496 /* Setup REGNO_COALESCED_ALLOCNO_COST and REGNO_COALESCED_ALLOCNO_NUM
3497 for coalesced allocno sets containing allocnos with their regnos
3498 given in array PSEUDO_REGNOS of length N. */
3499 static void
3500 setup_coalesced_allocno_costs_and_nums (int *pseudo_regnos, int n)
3502 int i, num, regno, cost;
3503 ira_allocno_t allocno, a;
3505 for (num = i = 0; i < n; i++)
3507 regno = pseudo_regnos[i];
3508 allocno = ira_regno_allocno_map[regno];
3509 if (allocno == NULL)
3511 regno_coalesced_allocno_cost[regno] = 0;
3512 regno_coalesced_allocno_num[regno] = ++num;
3513 continue;
3515 if (ALLOCNO_COALESCE_DATA (allocno)->first != allocno)
3516 continue;
3517 num++;
3518 for (cost = 0, a = ALLOCNO_COALESCE_DATA (allocno)->next;;
3519 a = ALLOCNO_COALESCE_DATA (a)->next)
3521 cost += ALLOCNO_FREQ (a);
3522 if (a == allocno)
3523 break;
3525 for (a = ALLOCNO_COALESCE_DATA (allocno)->next;;
3526 a = ALLOCNO_COALESCE_DATA (a)->next)
3528 regno_coalesced_allocno_num[ALLOCNO_REGNO (a)] = num;
3529 regno_coalesced_allocno_cost[ALLOCNO_REGNO (a)] = cost;
3530 if (a == allocno)
3531 break;
3536 /* Collect spilled allocnos representing coalesced allocno sets (the
3537 first coalesced allocno). The collected allocnos are returned
3538 through array SPILLED_COALESCED_ALLOCNOS. The function returns the
3539 number of the collected allocnos. The allocnos are given by their
3540 regnos in array PSEUDO_REGNOS of length N. */
3541 static int
3542 collect_spilled_coalesced_allocnos (int *pseudo_regnos, int n,
3543 ira_allocno_t *spilled_coalesced_allocnos)
3545 int i, num, regno;
3546 ira_allocno_t allocno;
3548 for (num = i = 0; i < n; i++)
3550 regno = pseudo_regnos[i];
3551 allocno = ira_regno_allocno_map[regno];
3552 if (allocno == NULL || ALLOCNO_HARD_REGNO (allocno) >= 0
3553 || ALLOCNO_COALESCE_DATA (allocno)->first != allocno)
3554 continue;
3555 spilled_coalesced_allocnos[num++] = allocno;
3557 return num;
3560 /* Array of live ranges of size IRA_ALLOCNOS_NUM. Live range for
3561 given slot contains live ranges of coalesced allocnos assigned to
3562 given slot. */
3563 static live_range_t *slot_coalesced_allocnos_live_ranges;
3565 /* Return TRUE if coalesced allocnos represented by ALLOCNO has live
3566 ranges intersected with live ranges of coalesced allocnos assigned
3567 to slot with number N. */
3568 static bool
3569 slot_coalesced_allocno_live_ranges_intersect_p (ira_allocno_t allocno, int n)
3571 ira_allocno_t a;
3573 for (a = ALLOCNO_COALESCE_DATA (allocno)->next;;
3574 a = ALLOCNO_COALESCE_DATA (a)->next)
3576 int i;
3577 int nr = ALLOCNO_NUM_OBJECTS (a);
3579 for (i = 0; i < nr; i++)
3581 ira_object_t obj = ALLOCNO_OBJECT (a, i);
3583 if (ira_live_ranges_intersect_p
3584 (slot_coalesced_allocnos_live_ranges[n],
3585 OBJECT_LIVE_RANGES (obj)))
3586 return true;
3588 if (a == allocno)
3589 break;
3591 return false;
3594 /* Update live ranges of slot to which coalesced allocnos represented
3595 by ALLOCNO were assigned. */
3596 static void
3597 setup_slot_coalesced_allocno_live_ranges (ira_allocno_t allocno)
3599 int i, n;
3600 ira_allocno_t a;
3601 live_range_t r;
3603 n = ALLOCNO_COALESCE_DATA (allocno)->temp;
3604 for (a = ALLOCNO_COALESCE_DATA (allocno)->next;;
3605 a = ALLOCNO_COALESCE_DATA (a)->next)
3607 int nr = ALLOCNO_NUM_OBJECTS (a);
3608 for (i = 0; i < nr; i++)
3610 ira_object_t obj = ALLOCNO_OBJECT (a, i);
3612 r = ira_copy_live_range_list (OBJECT_LIVE_RANGES (obj));
3613 slot_coalesced_allocnos_live_ranges[n]
3614 = ira_merge_live_ranges
3615 (slot_coalesced_allocnos_live_ranges[n], r);
3617 if (a == allocno)
3618 break;
3622 /* We have coalesced allocnos involving in copies. Coalesce allocnos
3623 further in order to share the same memory stack slot. Allocnos
3624 representing sets of allocnos coalesced before the call are given
3625 in array SPILLED_COALESCED_ALLOCNOS of length NUM. Return TRUE if
3626 some allocnos were coalesced in the function. */
3627 static bool
3628 coalesce_spill_slots (ira_allocno_t *spilled_coalesced_allocnos, int num)
3630 int i, j, n, last_coalesced_allocno_num;
3631 ira_allocno_t allocno, a;
3632 bool merged_p = false;
3633 bitmap set_jump_crosses = regstat_get_setjmp_crosses ();
3635 slot_coalesced_allocnos_live_ranges
3636 = (live_range_t *) ira_allocate (sizeof (live_range_t) * ira_allocnos_num);
3637 memset (slot_coalesced_allocnos_live_ranges, 0,
3638 sizeof (live_range_t) * ira_allocnos_num);
3639 last_coalesced_allocno_num = 0;
3640 /* Coalesce non-conflicting spilled allocnos preferring most
3641 frequently used. */
3642 for (i = 0; i < num; i++)
3644 allocno = spilled_coalesced_allocnos[i];
3645 if (ALLOCNO_COALESCE_DATA (allocno)->first != allocno
3646 || bitmap_bit_p (set_jump_crosses, ALLOCNO_REGNO (allocno))
3647 || ira_equiv_no_lvalue_p (ALLOCNO_REGNO (allocno)))
3648 continue;
3649 for (j = 0; j < i; j++)
3651 a = spilled_coalesced_allocnos[j];
3652 n = ALLOCNO_COALESCE_DATA (a)->temp;
3653 if (ALLOCNO_COALESCE_DATA (a)->first == a
3654 && ! bitmap_bit_p (set_jump_crosses, ALLOCNO_REGNO (a))
3655 && ! ira_equiv_no_lvalue_p (ALLOCNO_REGNO (a))
3656 && ! slot_coalesced_allocno_live_ranges_intersect_p (allocno, n))
3657 break;
3659 if (j >= i)
3661 /* No coalescing: set up number for coalesced allocnos
3662 represented by ALLOCNO. */
3663 ALLOCNO_COALESCE_DATA (allocno)->temp = last_coalesced_allocno_num++;
3664 setup_slot_coalesced_allocno_live_ranges (allocno);
3666 else
3668 allocno_coalesced_p = true;
3669 merged_p = true;
3670 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3671 fprintf (ira_dump_file,
3672 " Coalescing spilled allocnos a%dr%d->a%dr%d\n",
3673 ALLOCNO_NUM (allocno), ALLOCNO_REGNO (allocno),
3674 ALLOCNO_NUM (a), ALLOCNO_REGNO (a));
3675 ALLOCNO_COALESCE_DATA (allocno)->temp
3676 = ALLOCNO_COALESCE_DATA (a)->temp;
3677 setup_slot_coalesced_allocno_live_ranges (allocno);
3678 merge_allocnos (a, allocno);
3679 ira_assert (ALLOCNO_COALESCE_DATA (a)->first == a);
3682 for (i = 0; i < ira_allocnos_num; i++)
3683 ira_finish_live_range_list (slot_coalesced_allocnos_live_ranges[i]);
3684 ira_free (slot_coalesced_allocnos_live_ranges);
3685 return merged_p;
3688 /* Sort pseudo-register numbers in array PSEUDO_REGNOS of length N for
3689 subsequent assigning stack slots to them in the reload pass. To do
3690 this we coalesce spilled allocnos first to decrease the number of
3691 memory-memory move insns. This function is called by the
3692 reload. */
3693 void
3694 ira_sort_regnos_for_alter_reg (int *pseudo_regnos, int n,
3695 unsigned int *reg_max_ref_width)
3697 int max_regno = max_reg_num ();
3698 int i, regno, num, slot_num;
3699 ira_allocno_t allocno, a;
3700 ira_allocno_iterator ai;
3701 ira_allocno_t *spilled_coalesced_allocnos;
3703 /* Set up allocnos can be coalesced. */
3704 coloring_allocno_bitmap = ira_allocate_bitmap ();
3705 for (i = 0; i < n; i++)
3707 regno = pseudo_regnos[i];
3708 allocno = ira_regno_allocno_map[regno];
3709 if (allocno != NULL)
3710 bitmap_set_bit (coloring_allocno_bitmap, ALLOCNO_NUM (allocno));
3712 allocno_coalesced_p = false;
3713 processed_coalesced_allocno_bitmap = ira_allocate_bitmap ();
3714 allocno_coalesce_data
3715 = (coalesce_data_t) ira_allocate (sizeof (struct coalesce_data)
3716 * ira_allocnos_num);
3717 /* Initialize coalesce data for allocnos. */
3718 FOR_EACH_ALLOCNO (a, ai)
3720 ALLOCNO_ADD_DATA (a) = allocno_coalesce_data + ALLOCNO_NUM (a);
3721 ALLOCNO_COALESCE_DATA (a)->first = a;
3722 ALLOCNO_COALESCE_DATA (a)->next = a;
3724 coalesce_allocnos ();
3725 ira_free_bitmap (coloring_allocno_bitmap);
3726 regno_coalesced_allocno_cost
3727 = (int *) ira_allocate (max_regno * sizeof (int));
3728 regno_coalesced_allocno_num
3729 = (int *) ira_allocate (max_regno * sizeof (int));
3730 memset (regno_coalesced_allocno_num, 0, max_regno * sizeof (int));
3731 setup_coalesced_allocno_costs_and_nums (pseudo_regnos, n);
3732 /* Sort regnos according frequencies of the corresponding coalesced
3733 allocno sets. */
3734 qsort (pseudo_regnos, n, sizeof (int), coalesced_pseudo_reg_freq_compare);
3735 spilled_coalesced_allocnos
3736 = (ira_allocno_t *) ira_allocate (ira_allocnos_num
3737 * sizeof (ira_allocno_t));
3738 /* Collect allocnos representing the spilled coalesced allocno
3739 sets. */
3740 num = collect_spilled_coalesced_allocnos (pseudo_regnos, n,
3741 spilled_coalesced_allocnos);
3742 if (flag_ira_share_spill_slots
3743 && coalesce_spill_slots (spilled_coalesced_allocnos, num))
3745 setup_coalesced_allocno_costs_and_nums (pseudo_regnos, n);
3746 qsort (pseudo_regnos, n, sizeof (int),
3747 coalesced_pseudo_reg_freq_compare);
3748 num = collect_spilled_coalesced_allocnos (pseudo_regnos, n,
3749 spilled_coalesced_allocnos);
3751 ira_free_bitmap (processed_coalesced_allocno_bitmap);
3752 allocno_coalesced_p = false;
3753 /* Assign stack slot numbers to spilled allocno sets, use smaller
3754 numbers for most frequently used coalesced allocnos. -1 is
3755 reserved for dynamic search of stack slots for pseudos spilled by
3756 the reload. */
3757 slot_num = 1;
3758 for (i = 0; i < num; i++)
3760 allocno = spilled_coalesced_allocnos[i];
3761 if (ALLOCNO_COALESCE_DATA (allocno)->first != allocno
3762 || ALLOCNO_HARD_REGNO (allocno) >= 0
3763 || ira_equiv_no_lvalue_p (ALLOCNO_REGNO (allocno)))
3764 continue;
3765 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3766 fprintf (ira_dump_file, " Slot %d (freq,size):", slot_num);
3767 slot_num++;
3768 for (a = ALLOCNO_COALESCE_DATA (allocno)->next;;
3769 a = ALLOCNO_COALESCE_DATA (a)->next)
3771 ira_assert (ALLOCNO_HARD_REGNO (a) < 0);
3772 ALLOCNO_HARD_REGNO (a) = -slot_num;
3773 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3774 fprintf (ira_dump_file, " a%dr%d(%d,%d)",
3775 ALLOCNO_NUM (a), ALLOCNO_REGNO (a), ALLOCNO_FREQ (a),
3776 MAX (PSEUDO_REGNO_BYTES (ALLOCNO_REGNO (a)),
3777 reg_max_ref_width[ALLOCNO_REGNO (a)]));
3779 if (a == allocno)
3780 break;
3782 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3783 fprintf (ira_dump_file, "\n");
3785 ira_spilled_reg_stack_slots_num = slot_num - 1;
3786 ira_free (spilled_coalesced_allocnos);
3787 /* Sort regnos according the slot numbers. */
3788 regno_max_ref_width = reg_max_ref_width;
3789 qsort (pseudo_regnos, n, sizeof (int), coalesced_pseudo_reg_slot_compare);
3790 FOR_EACH_ALLOCNO (a, ai)
3791 ALLOCNO_ADD_DATA (a) = NULL;
3792 ira_free (allocno_coalesce_data);
3793 ira_free (regno_coalesced_allocno_num);
3794 ira_free (regno_coalesced_allocno_cost);
3799 /* This page contains code used by the reload pass to improve the
3800 final code. */
3802 /* The function is called from reload to mark changes in the
3803 allocation of REGNO made by the reload. Remember that reg_renumber
3804 reflects the change result. */
3805 void
3806 ira_mark_allocation_change (int regno)
3808 ira_allocno_t a = ira_regno_allocno_map[regno];
3809 int old_hard_regno, hard_regno, cost;
3810 enum reg_class aclass = ALLOCNO_CLASS (a);
3812 ira_assert (a != NULL);
3813 hard_regno = reg_renumber[regno];
3814 if ((old_hard_regno = ALLOCNO_HARD_REGNO (a)) == hard_regno)
3815 return;
3816 if (old_hard_regno < 0)
3817 cost = -ALLOCNO_MEMORY_COST (a);
3818 else
3820 ira_assert (ira_class_hard_reg_index[aclass][old_hard_regno] >= 0);
3821 cost = -(ALLOCNO_HARD_REG_COSTS (a) == NULL
3822 ? ALLOCNO_CLASS_COST (a)
3823 : ALLOCNO_HARD_REG_COSTS (a)
3824 [ira_class_hard_reg_index[aclass][old_hard_regno]]);
3825 update_copy_costs (a, false);
3827 ira_overall_cost -= cost;
3828 ALLOCNO_HARD_REGNO (a) = hard_regno;
3829 if (hard_regno < 0)
3831 ALLOCNO_HARD_REGNO (a) = -1;
3832 cost += ALLOCNO_MEMORY_COST (a);
3834 else if (ira_class_hard_reg_index[aclass][hard_regno] >= 0)
3836 cost += (ALLOCNO_HARD_REG_COSTS (a) == NULL
3837 ? ALLOCNO_CLASS_COST (a)
3838 : ALLOCNO_HARD_REG_COSTS (a)
3839 [ira_class_hard_reg_index[aclass][hard_regno]]);
3840 update_copy_costs (a, true);
3842 else
3843 /* Reload changed class of the allocno. */
3844 cost = 0;
3845 ira_overall_cost += cost;
3848 /* This function is called when reload deletes memory-memory move. In
3849 this case we marks that the allocation of the corresponding
3850 allocnos should be not changed in future. Otherwise we risk to get
3851 a wrong code. */
3852 void
3853 ira_mark_memory_move_deletion (int dst_regno, int src_regno)
3855 ira_allocno_t dst = ira_regno_allocno_map[dst_regno];
3856 ira_allocno_t src = ira_regno_allocno_map[src_regno];
3858 ira_assert (dst != NULL && src != NULL
3859 && ALLOCNO_HARD_REGNO (dst) < 0
3860 && ALLOCNO_HARD_REGNO (src) < 0);
3861 ALLOCNO_DONT_REASSIGN_P (dst) = true;
3862 ALLOCNO_DONT_REASSIGN_P (src) = true;
3865 /* Try to assign a hard register (except for FORBIDDEN_REGS) to
3866 allocno A and return TRUE in the case of success. */
3867 static bool
3868 allocno_reload_assign (ira_allocno_t a, HARD_REG_SET forbidden_regs)
3870 int hard_regno;
3871 enum reg_class aclass;
3872 int regno = ALLOCNO_REGNO (a);
3873 HARD_REG_SET saved[2];
3874 int i, n;
3876 n = ALLOCNO_NUM_OBJECTS (a);
3877 for (i = 0; i < n; i++)
3879 ira_object_t obj = ALLOCNO_OBJECT (a, i);
3880 COPY_HARD_REG_SET (saved[i], OBJECT_TOTAL_CONFLICT_HARD_REGS (obj));
3881 IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), forbidden_regs);
3882 if (! flag_caller_saves && ALLOCNO_CALLS_CROSSED_NUM (a) != 0)
3883 IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
3884 call_used_reg_set);
3886 ALLOCNO_ASSIGNED_P (a) = false;
3887 aclass = ALLOCNO_CLASS (a);
3888 update_curr_costs (a);
3889 assign_hard_reg (a, true);
3890 hard_regno = ALLOCNO_HARD_REGNO (a);
3891 reg_renumber[regno] = hard_regno;
3892 if (hard_regno < 0)
3893 ALLOCNO_HARD_REGNO (a) = -1;
3894 else
3896 ira_assert (ira_class_hard_reg_index[aclass][hard_regno] >= 0);
3897 ira_overall_cost
3898 -= (ALLOCNO_MEMORY_COST (a)
3899 - (ALLOCNO_HARD_REG_COSTS (a) == NULL
3900 ? ALLOCNO_CLASS_COST (a)
3901 : ALLOCNO_HARD_REG_COSTS (a)[ira_class_hard_reg_index
3902 [aclass][hard_regno]]));
3903 if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0
3904 && ira_hard_reg_set_intersection_p (hard_regno, ALLOCNO_MODE (a),
3905 call_used_reg_set))
3907 ira_assert (flag_caller_saves);
3908 caller_save_needed = 1;
3912 /* If we found a hard register, modify the RTL for the pseudo
3913 register to show the hard register, and mark the pseudo register
3914 live. */
3915 if (reg_renumber[regno] >= 0)
3917 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3918 fprintf (ira_dump_file, ": reassign to %d\n", reg_renumber[regno]);
3919 SET_REGNO (regno_reg_rtx[regno], reg_renumber[regno]);
3920 mark_home_live (regno);
3922 else if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3923 fprintf (ira_dump_file, "\n");
3924 for (i = 0; i < n; i++)
3926 ira_object_t obj = ALLOCNO_OBJECT (a, i);
3927 COPY_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), saved[i]);
3929 return reg_renumber[regno] >= 0;
3932 /* Sort pseudos according their usage frequencies (putting most
3933 frequently ones first). */
3934 static int
3935 pseudo_reg_compare (const void *v1p, const void *v2p)
3937 int regno1 = *(const int *) v1p;
3938 int regno2 = *(const int *) v2p;
3939 int diff;
3941 if ((diff = REG_FREQ (regno2) - REG_FREQ (regno1)) != 0)
3942 return diff;
3943 return regno1 - regno2;
3946 /* Try to allocate hard registers to SPILLED_PSEUDO_REGS (there are
3947 NUM of them) or spilled pseudos conflicting with pseudos in
3948 SPILLED_PSEUDO_REGS. Return TRUE and update SPILLED, if the
3949 allocation has been changed. The function doesn't use
3950 BAD_SPILL_REGS and hard registers in PSEUDO_FORBIDDEN_REGS and
3951 PSEUDO_PREVIOUS_REGS for the corresponding pseudos. The function
3952 is called by the reload pass at the end of each reload
3953 iteration. */
3954 bool
3955 ira_reassign_pseudos (int *spilled_pseudo_regs, int num,
3956 HARD_REG_SET bad_spill_regs,
3957 HARD_REG_SET *pseudo_forbidden_regs,
3958 HARD_REG_SET *pseudo_previous_regs,
3959 bitmap spilled)
3961 int i, n, regno;
3962 bool changed_p;
3963 ira_allocno_t a;
3964 HARD_REG_SET forbidden_regs;
3965 bitmap temp = BITMAP_ALLOC (NULL);
3967 /* Add pseudos which conflict with pseudos already in
3968 SPILLED_PSEUDO_REGS to SPILLED_PSEUDO_REGS. This is preferable
3969 to allocating in two steps as some of the conflicts might have
3970 a higher priority than the pseudos passed in SPILLED_PSEUDO_REGS. */
3971 for (i = 0; i < num; i++)
3972 bitmap_set_bit (temp, spilled_pseudo_regs[i]);
3974 for (i = 0, n = num; i < n; i++)
3976 int nr, j;
3977 int regno = spilled_pseudo_regs[i];
3978 bitmap_set_bit (temp, regno);
3980 a = ira_regno_allocno_map[regno];
3981 nr = ALLOCNO_NUM_OBJECTS (a);
3982 for (j = 0; j < nr; j++)
3984 ira_object_t conflict_obj;
3985 ira_object_t obj = ALLOCNO_OBJECT (a, j);
3986 ira_object_conflict_iterator oci;
3988 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
3990 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
3991 if (ALLOCNO_HARD_REGNO (conflict_a) < 0
3992 && ! ALLOCNO_DONT_REASSIGN_P (conflict_a)
3993 && bitmap_set_bit (temp, ALLOCNO_REGNO (conflict_a)))
3995 spilled_pseudo_regs[num++] = ALLOCNO_REGNO (conflict_a);
3996 /* ?!? This seems wrong. */
3997 bitmap_set_bit (consideration_allocno_bitmap,
3998 ALLOCNO_NUM (conflict_a));
4004 if (num > 1)
4005 qsort (spilled_pseudo_regs, num, sizeof (int), pseudo_reg_compare);
4006 changed_p = false;
4007 /* Try to assign hard registers to pseudos from
4008 SPILLED_PSEUDO_REGS. */
4009 for (i = 0; i < num; i++)
4011 regno = spilled_pseudo_regs[i];
4012 COPY_HARD_REG_SET (forbidden_regs, bad_spill_regs);
4013 IOR_HARD_REG_SET (forbidden_regs, pseudo_forbidden_regs[regno]);
4014 IOR_HARD_REG_SET (forbidden_regs, pseudo_previous_regs[regno]);
4015 gcc_assert (reg_renumber[regno] < 0);
4016 a = ira_regno_allocno_map[regno];
4017 ira_mark_allocation_change (regno);
4018 ira_assert (reg_renumber[regno] < 0);
4019 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4020 fprintf (ira_dump_file,
4021 " Try Assign %d(a%d), cost=%d", regno, ALLOCNO_NUM (a),
4022 ALLOCNO_MEMORY_COST (a)
4023 - ALLOCNO_CLASS_COST (a));
4024 allocno_reload_assign (a, forbidden_regs);
4025 if (reg_renumber[regno] >= 0)
4027 CLEAR_REGNO_REG_SET (spilled, regno);
4028 changed_p = true;
4031 BITMAP_FREE (temp);
4032 return changed_p;
4035 /* The function is called by reload and returns already allocated
4036 stack slot (if any) for REGNO with given INHERENT_SIZE and
4037 TOTAL_SIZE. In the case of failure to find a slot which can be
4038 used for REGNO, the function returns NULL. */
4040 ira_reuse_stack_slot (int regno, unsigned int inherent_size,
4041 unsigned int total_size)
4043 unsigned int i;
4044 int slot_num, best_slot_num;
4045 int cost, best_cost;
4046 ira_copy_t cp, next_cp;
4047 ira_allocno_t another_allocno, allocno = ira_regno_allocno_map[regno];
4048 rtx x;
4049 bitmap_iterator bi;
4050 struct ira_spilled_reg_stack_slot *slot = NULL;
4052 ira_assert (inherent_size == PSEUDO_REGNO_BYTES (regno)
4053 && inherent_size <= total_size
4054 && ALLOCNO_HARD_REGNO (allocno) < 0);
4055 if (! flag_ira_share_spill_slots)
4056 return NULL_RTX;
4057 slot_num = -ALLOCNO_HARD_REGNO (allocno) - 2;
4058 if (slot_num != -1)
4060 slot = &ira_spilled_reg_stack_slots[slot_num];
4061 x = slot->mem;
4063 else
4065 best_cost = best_slot_num = -1;
4066 x = NULL_RTX;
4067 /* It means that the pseudo was spilled in the reload pass, try
4068 to reuse a slot. */
4069 for (slot_num = 0;
4070 slot_num < ira_spilled_reg_stack_slots_num;
4071 slot_num++)
4073 slot = &ira_spilled_reg_stack_slots[slot_num];
4074 if (slot->mem == NULL_RTX)
4075 continue;
4076 if (slot->width < total_size
4077 || GET_MODE_SIZE (GET_MODE (slot->mem)) < inherent_size)
4078 continue;
4080 EXECUTE_IF_SET_IN_BITMAP (&slot->spilled_regs,
4081 FIRST_PSEUDO_REGISTER, i, bi)
4083 another_allocno = ira_regno_allocno_map[i];
4084 if (allocnos_conflict_by_live_ranges_p (allocno,
4085 another_allocno))
4086 goto cont;
4088 for (cost = 0, cp = ALLOCNO_COPIES (allocno);
4089 cp != NULL;
4090 cp = next_cp)
4092 if (cp->first == allocno)
4094 next_cp = cp->next_first_allocno_copy;
4095 another_allocno = cp->second;
4097 else if (cp->second == allocno)
4099 next_cp = cp->next_second_allocno_copy;
4100 another_allocno = cp->first;
4102 else
4103 gcc_unreachable ();
4104 if (cp->insn == NULL_RTX)
4105 continue;
4106 if (bitmap_bit_p (&slot->spilled_regs,
4107 ALLOCNO_REGNO (another_allocno)))
4108 cost += cp->freq;
4110 if (cost > best_cost)
4112 best_cost = cost;
4113 best_slot_num = slot_num;
4115 cont:
4118 if (best_cost >= 0)
4120 slot_num = best_slot_num;
4121 slot = &ira_spilled_reg_stack_slots[slot_num];
4122 SET_REGNO_REG_SET (&slot->spilled_regs, regno);
4123 x = slot->mem;
4124 ALLOCNO_HARD_REGNO (allocno) = -slot_num - 2;
4127 if (x != NULL_RTX)
4129 ira_assert (slot->width >= total_size);
4130 #ifdef ENABLE_IRA_CHECKING
4131 EXECUTE_IF_SET_IN_BITMAP (&slot->spilled_regs,
4132 FIRST_PSEUDO_REGISTER, i, bi)
4134 ira_assert (! conflict_by_live_ranges_p (regno, i));
4136 #endif
4137 SET_REGNO_REG_SET (&slot->spilled_regs, regno);
4138 if (internal_flag_ira_verbose > 3 && ira_dump_file)
4140 fprintf (ira_dump_file, " Assigning %d(freq=%d) slot %d of",
4141 regno, REG_FREQ (regno), slot_num);
4142 EXECUTE_IF_SET_IN_BITMAP (&slot->spilled_regs,
4143 FIRST_PSEUDO_REGISTER, i, bi)
4145 if ((unsigned) regno != i)
4146 fprintf (ira_dump_file, " %d", i);
4148 fprintf (ira_dump_file, "\n");
4151 return x;
4154 /* This is called by reload every time a new stack slot X with
4155 TOTAL_SIZE was allocated for REGNO. We store this info for
4156 subsequent ira_reuse_stack_slot calls. */
4157 void
4158 ira_mark_new_stack_slot (rtx x, int regno, unsigned int total_size)
4160 struct ira_spilled_reg_stack_slot *slot;
4161 int slot_num;
4162 ira_allocno_t allocno;
4164 ira_assert (PSEUDO_REGNO_BYTES (regno) <= total_size);
4165 allocno = ira_regno_allocno_map[regno];
4166 slot_num = -ALLOCNO_HARD_REGNO (allocno) - 2;
4167 if (slot_num == -1)
4169 slot_num = ira_spilled_reg_stack_slots_num++;
4170 ALLOCNO_HARD_REGNO (allocno) = -slot_num - 2;
4172 slot = &ira_spilled_reg_stack_slots[slot_num];
4173 INIT_REG_SET (&slot->spilled_regs);
4174 SET_REGNO_REG_SET (&slot->spilled_regs, regno);
4175 slot->mem = x;
4176 slot->width = total_size;
4177 if (internal_flag_ira_verbose > 3 && ira_dump_file)
4178 fprintf (ira_dump_file, " Assigning %d(freq=%d) a new slot %d\n",
4179 regno, REG_FREQ (regno), slot_num);
4183 /* Return spill cost for pseudo-registers whose numbers are in array
4184 REGNOS (with a negative number as an end marker) for reload with
4185 given IN and OUT for INSN. Return also number points (through
4186 EXCESS_PRESSURE_LIVE_LENGTH) where the pseudo-register lives and
4187 the register pressure is high, number of references of the
4188 pseudo-registers (through NREFS), number of callee-clobbered
4189 hard-registers occupied by the pseudo-registers (through
4190 CALL_USED_COUNT), and the first hard regno occupied by the
4191 pseudo-registers (through FIRST_HARD_REGNO). */
4192 static int
4193 calculate_spill_cost (int *regnos, rtx in, rtx out, rtx insn,
4194 int *excess_pressure_live_length,
4195 int *nrefs, int *call_used_count, int *first_hard_regno)
4197 int i, cost, regno, hard_regno, j, count, saved_cost, nregs;
4198 bool in_p, out_p;
4199 int length;
4200 ira_allocno_t a;
4202 *nrefs = 0;
4203 for (length = count = cost = i = 0;; i++)
4205 regno = regnos[i];
4206 if (regno < 0)
4207 break;
4208 *nrefs += REG_N_REFS (regno);
4209 hard_regno = reg_renumber[regno];
4210 ira_assert (hard_regno >= 0);
4211 a = ira_regno_allocno_map[regno];
4212 length += ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a) / ALLOCNO_NUM_OBJECTS (a);
4213 cost += ALLOCNO_MEMORY_COST (a) - ALLOCNO_CLASS_COST (a);
4214 nregs = hard_regno_nregs[hard_regno][ALLOCNO_MODE (a)];
4215 for (j = 0; j < nregs; j++)
4216 if (! TEST_HARD_REG_BIT (call_used_reg_set, hard_regno + j))
4217 break;
4218 if (j == nregs)
4219 count++;
4220 in_p = in && REG_P (in) && (int) REGNO (in) == hard_regno;
4221 out_p = out && REG_P (out) && (int) REGNO (out) == hard_regno;
4222 if ((in_p || out_p)
4223 && find_regno_note (insn, REG_DEAD, hard_regno) != NULL_RTX)
4225 saved_cost = 0;
4226 if (in_p)
4227 saved_cost += ira_memory_move_cost
4228 [ALLOCNO_MODE (a)][ALLOCNO_CLASS (a)][1];
4229 if (out_p)
4230 saved_cost
4231 += ira_memory_move_cost
4232 [ALLOCNO_MODE (a)][ALLOCNO_CLASS (a)][0];
4233 cost -= REG_FREQ_FROM_BB (BLOCK_FOR_INSN (insn)) * saved_cost;
4236 *excess_pressure_live_length = length;
4237 *call_used_count = count;
4238 hard_regno = -1;
4239 if (regnos[0] >= 0)
4241 hard_regno = reg_renumber[regnos[0]];
4243 *first_hard_regno = hard_regno;
4244 return cost;
4247 /* Return TRUE if spilling pseudo-registers whose numbers are in array
4248 REGNOS is better than spilling pseudo-registers with numbers in
4249 OTHER_REGNOS for reload with given IN and OUT for INSN. The
4250 function used by the reload pass to make better register spilling
4251 decisions. */
4252 bool
4253 ira_better_spill_reload_regno_p (int *regnos, int *other_regnos,
4254 rtx in, rtx out, rtx insn)
4256 int cost, other_cost;
4257 int length, other_length;
4258 int nrefs, other_nrefs;
4259 int call_used_count, other_call_used_count;
4260 int hard_regno, other_hard_regno;
4262 cost = calculate_spill_cost (regnos, in, out, insn,
4263 &length, &nrefs, &call_used_count, &hard_regno);
4264 other_cost = calculate_spill_cost (other_regnos, in, out, insn,
4265 &other_length, &other_nrefs,
4266 &other_call_used_count,
4267 &other_hard_regno);
4268 if (nrefs == 0 && other_nrefs != 0)
4269 return true;
4270 if (nrefs != 0 && other_nrefs == 0)
4271 return false;
4272 if (cost != other_cost)
4273 return cost < other_cost;
4274 if (length != other_length)
4275 return length > other_length;
4276 #ifdef REG_ALLOC_ORDER
4277 if (hard_regno >= 0 && other_hard_regno >= 0)
4278 return (inv_reg_alloc_order[hard_regno]
4279 < inv_reg_alloc_order[other_hard_regno]);
4280 #else
4281 if (call_used_count != other_call_used_count)
4282 return call_used_count > other_call_used_count;
4283 #endif
4284 return false;
4289 /* Allocate and initialize data necessary for assign_hard_reg. */
4290 void
4291 ira_initiate_assign (void)
4293 sorted_allocnos
4294 = (ira_allocno_t *) ira_allocate (sizeof (ira_allocno_t)
4295 * ira_allocnos_num);
4296 consideration_allocno_bitmap = ira_allocate_bitmap ();
4297 initiate_cost_update ();
4298 allocno_priorities = (int *) ira_allocate (sizeof (int) * ira_allocnos_num);
4301 /* Deallocate data used by assign_hard_reg. */
4302 void
4303 ira_finish_assign (void)
4305 ira_free (sorted_allocnos);
4306 ira_free_bitmap (consideration_allocno_bitmap);
4307 finish_cost_update ();
4308 ira_free (allocno_priorities);
4313 /* Entry function doing color-based register allocation. */
4314 static void
4315 color (void)
4317 allocno_stack_vec = VEC_alloc (ira_allocno_t, heap, ira_allocnos_num);
4318 memset (allocated_hardreg_p, 0, sizeof (allocated_hardreg_p));
4319 ira_initiate_assign ();
4320 do_coloring ();
4321 ira_finish_assign ();
4322 VEC_free (ira_allocno_t, heap, allocno_stack_vec);
4323 move_spill_restore ();
4328 /* This page contains a simple register allocator without usage of
4329 allocno conflicts. This is used for fast allocation for -O0. */
4331 /* Do register allocation by not using allocno conflicts. It uses
4332 only allocno live ranges. The algorithm is close to Chow's
4333 priority coloring. */
4334 static void
4335 fast_allocation (void)
4337 int i, j, k, num, class_size, hard_regno;
4338 #ifdef STACK_REGS
4339 bool no_stack_reg_p;
4340 #endif
4341 enum reg_class aclass;
4342 enum machine_mode mode;
4343 ira_allocno_t a;
4344 ira_allocno_iterator ai;
4345 live_range_t r;
4346 HARD_REG_SET conflict_hard_regs, *used_hard_regs;
4348 sorted_allocnos = (ira_allocno_t *) ira_allocate (sizeof (ira_allocno_t)
4349 * ira_allocnos_num);
4350 num = 0;
4351 FOR_EACH_ALLOCNO (a, ai)
4352 sorted_allocnos[num++] = a;
4353 allocno_priorities = (int *) ira_allocate (sizeof (int) * ira_allocnos_num);
4354 setup_allocno_priorities (sorted_allocnos, num);
4355 used_hard_regs = (HARD_REG_SET *) ira_allocate (sizeof (HARD_REG_SET)
4356 * ira_max_point);
4357 for (i = 0; i < ira_max_point; i++)
4358 CLEAR_HARD_REG_SET (used_hard_regs[i]);
4359 qsort (sorted_allocnos, num, sizeof (ira_allocno_t),
4360 allocno_priority_compare_func);
4361 for (i = 0; i < num; i++)
4363 int nr, l;
4365 a = sorted_allocnos[i];
4366 nr = ALLOCNO_NUM_OBJECTS (a);
4367 CLEAR_HARD_REG_SET (conflict_hard_regs);
4368 for (l = 0; l < nr; l++)
4370 ira_object_t obj = ALLOCNO_OBJECT (a, l);
4371 IOR_HARD_REG_SET (conflict_hard_regs,
4372 OBJECT_CONFLICT_HARD_REGS (obj));
4373 for (r = OBJECT_LIVE_RANGES (obj); r != NULL; r = r->next)
4374 for (j = r->start; j <= r->finish; j++)
4375 IOR_HARD_REG_SET (conflict_hard_regs, used_hard_regs[j]);
4377 aclass = ALLOCNO_CLASS (a);
4378 ALLOCNO_ASSIGNED_P (a) = true;
4379 ALLOCNO_HARD_REGNO (a) = -1;
4380 if (hard_reg_set_subset_p (reg_class_contents[aclass],
4381 conflict_hard_regs))
4382 continue;
4383 mode = ALLOCNO_MODE (a);
4384 #ifdef STACK_REGS
4385 no_stack_reg_p = ALLOCNO_NO_STACK_REG_P (a);
4386 #endif
4387 class_size = ira_class_hard_regs_num[aclass];
4388 for (j = 0; j < class_size; j++)
4390 hard_regno = ira_class_hard_regs[aclass][j];
4391 #ifdef STACK_REGS
4392 if (no_stack_reg_p && FIRST_STACK_REG <= hard_regno
4393 && hard_regno <= LAST_STACK_REG)
4394 continue;
4395 #endif
4396 if (ira_hard_reg_set_intersection_p (hard_regno, mode, conflict_hard_regs)
4397 || (TEST_HARD_REG_BIT
4398 (ira_prohibited_class_mode_regs[aclass][mode], hard_regno)))
4399 continue;
4400 ALLOCNO_HARD_REGNO (a) = hard_regno;
4401 for (l = 0; l < nr; l++)
4403 ira_object_t obj = ALLOCNO_OBJECT (a, l);
4404 for (r = OBJECT_LIVE_RANGES (obj); r != NULL; r = r->next)
4405 for (k = r->start; k <= r->finish; k++)
4406 IOR_HARD_REG_SET (used_hard_regs[k],
4407 ira_reg_mode_hard_regset[hard_regno][mode]);
4409 break;
4412 ira_free (sorted_allocnos);
4413 ira_free (used_hard_regs);
4414 ira_free (allocno_priorities);
4415 if (internal_flag_ira_verbose > 1 && ira_dump_file != NULL)
4416 ira_print_disposition (ira_dump_file);
4421 /* Entry function doing coloring. */
4422 void
4423 ira_color (void)
4425 ira_allocno_t a;
4426 ira_allocno_iterator ai;
4428 /* Setup updated costs. */
4429 FOR_EACH_ALLOCNO (a, ai)
4431 ALLOCNO_UPDATED_MEMORY_COST (a) = ALLOCNO_MEMORY_COST (a);
4432 ALLOCNO_UPDATED_CLASS_COST (a) = ALLOCNO_CLASS_COST (a);
4434 if (ira_conflicts_p)
4435 color ();
4436 else
4437 fast_allocation ();