Fortran] Use proper type for hidden is-present argument
[gcc.git] / gcc / ira-color.c
1 /* IRA allocation based on graph coloring.
2 Copyright (C) 2006-2019 Free Software Foundation, Inc.
3 Contributed by Vladimir Makarov <vmakarov@redhat.com>.
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
11
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
20
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "backend.h"
25 #include "target.h"
26 #include "rtl.h"
27 #include "tree.h"
28 #include "predict.h"
29 #include "df.h"
30 #include "memmodel.h"
31 #include "tm_p.h"
32 #include "insn-config.h"
33 #include "regs.h"
34 #include "ira.h"
35 #include "ira-int.h"
36 #include "reload.h"
37 #include "cfgloop.h"
38
39 typedef struct allocno_hard_regs *allocno_hard_regs_t;
40
41 /* The structure contains information about hard registers can be
42 assigned to allocnos. Usually it is allocno profitable hard
43 registers but in some cases this set can be a bit different. Major
44 reason of the difference is a requirement to use hard register sets
45 that form a tree or a forest (set of trees), i.e. hard register set
46 of a node should contain hard register sets of its subnodes. */
47 struct allocno_hard_regs
48 {
49 /* Hard registers can be assigned to an allocno. */
50 HARD_REG_SET set;
51 /* Overall (spilling) cost of all allocnos with given register
52 set. */
53 int64_t cost;
54 };
55
56 typedef struct allocno_hard_regs_node *allocno_hard_regs_node_t;
57
58 /* A node representing allocno hard registers. Such nodes form a
59 forest (set of trees). Each subnode of given node in the forest
60 refers for hard register set (usually allocno profitable hard
61 register set) which is a subset of one referred from given
62 node. */
63 struct allocno_hard_regs_node
64 {
65 /* Set up number of the node in preorder traversing of the forest. */
66 int preorder_num;
67 /* Used for different calculation like finding conflict size of an
68 allocno. */
69 int check;
70 /* Used for calculation of conflict size of an allocno. The
71 conflict size of the allocno is maximal number of given allocno
72 hard registers needed for allocation of the conflicting allocnos.
73 Given allocno is trivially colored if this number plus the number
74 of hard registers needed for given allocno is not greater than
75 the number of given allocno hard register set. */
76 int conflict_size;
77 /* The number of hard registers given by member hard_regs. */
78 int hard_regs_num;
79 /* The following member is used to form the final forest. */
80 bool used_p;
81 /* Pointer to the corresponding profitable hard registers. */
82 allocno_hard_regs_t hard_regs;
83 /* Parent, first subnode, previous and next node with the same
84 parent in the forest. */
85 allocno_hard_regs_node_t parent, first, prev, next;
86 };
87
88 /* Info about changing hard reg costs of an allocno. */
89 struct update_cost_record
90 {
91 /* Hard regno for which we changed the cost. */
92 int hard_regno;
93 /* Divisor used when we changed the cost of HARD_REGNO. */
94 int divisor;
95 /* Next record for given allocno. */
96 struct update_cost_record *next;
97 };
98
99 /* To decrease footprint of ira_allocno structure we store all data
100 needed only for coloring in the following structure. */
101 struct allocno_color_data
102 {
103 /* TRUE value means that the allocno was not removed yet from the
104 conflicting graph during coloring. */
105 unsigned int in_graph_p : 1;
106 /* TRUE if it is put on the stack to make other allocnos
107 colorable. */
108 unsigned int may_be_spilled_p : 1;
109 /* TRUE if the allocno is trivially colorable. */
110 unsigned int colorable_p : 1;
111 /* Number of hard registers of the allocno class really
112 available for the allocno allocation. It is number of the
113 profitable hard regs. */
114 int available_regs_num;
115 /* Sum of frequencies of hard register preferences of all
116 conflicting allocnos which are not the coloring stack yet. */
117 int conflict_allocno_hard_prefs;
118 /* Allocnos in a bucket (used in coloring) chained by the following
119 two members. */
120 ira_allocno_t next_bucket_allocno;
121 ira_allocno_t prev_bucket_allocno;
122 /* Used for temporary purposes. */
123 int temp;
124 /* Used to exclude repeated processing. */
125 int last_process;
126 /* Profitable hard regs available for this pseudo allocation. It
127 means that the set excludes unavailable hard regs and hard regs
128 conflicting with given pseudo. They should be of the allocno
129 class. */
130 HARD_REG_SET profitable_hard_regs;
131 /* The allocno hard registers node. */
132 allocno_hard_regs_node_t hard_regs_node;
133 /* Array of structures allocno_hard_regs_subnode representing
134 given allocno hard registers node (the 1st element in the array)
135 and all its subnodes in the tree (forest) of allocno hard
136 register nodes (see comments above). */
137 int hard_regs_subnodes_start;
138 /* The length of the previous array. */
139 int hard_regs_subnodes_num;
140 /* Records about updating allocno hard reg costs from copies. If
141 the allocno did not get expected hard register, these records are
142 used to restore original hard reg costs of allocnos connected to
143 this allocno by copies. */
144 struct update_cost_record *update_cost_records;
145 /* Threads. We collect allocnos connected by copies into threads
146 and try to assign hard regs to allocnos by threads. */
147 /* Allocno representing all thread. */
148 ira_allocno_t first_thread_allocno;
149 /* Allocnos in thread forms a cycle list through the following
150 member. */
151 ira_allocno_t next_thread_allocno;
152 /* All thread frequency. Defined only for first thread allocno. */
153 int thread_freq;
154 };
155
156 /* See above. */
157 typedef struct allocno_color_data *allocno_color_data_t;
158
159 /* Container for storing allocno data concerning coloring. */
160 static allocno_color_data_t allocno_color_data;
161
162 /* Macro to access the data concerning coloring. */
163 #define ALLOCNO_COLOR_DATA(a) ((allocno_color_data_t) ALLOCNO_ADD_DATA (a))
164
165 /* Used for finding allocno colorability to exclude repeated allocno
166 processing and for updating preferencing to exclude repeated
167 allocno processing during assignment. */
168 static int curr_allocno_process;
169
170 /* This file contains code for regional graph coloring, spill/restore
171 code placement optimization, and code helping the reload pass to do
172 a better job. */
173
174 /* Bitmap of allocnos which should be colored. */
175 static bitmap coloring_allocno_bitmap;
176
177 /* Bitmap of allocnos which should be taken into account during
178 coloring. In general case it contains allocnos from
179 coloring_allocno_bitmap plus other already colored conflicting
180 allocnos. */
181 static bitmap consideration_allocno_bitmap;
182
183 /* All allocnos sorted according their priorities. */
184 static ira_allocno_t *sorted_allocnos;
185
186 /* Vec representing the stack of allocnos used during coloring. */
187 static vec<ira_allocno_t> allocno_stack_vec;
188
189 /* Helper for qsort comparison callbacks - return a positive integer if
190 X > Y, or a negative value otherwise. Use a conditional expression
191 instead of a difference computation to insulate from possible overflow
192 issues, e.g. X - Y < 0 for some X > 0 and Y < 0. */
193 #define SORTGT(x,y) (((x) > (y)) ? 1 : -1)
194
195 \f
196
197 /* Definition of vector of allocno hard registers. */
198
199 /* Vector of unique allocno hard registers. */
200 static vec<allocno_hard_regs_t> allocno_hard_regs_vec;
201
202 struct allocno_hard_regs_hasher : nofree_ptr_hash <allocno_hard_regs>
203 {
204 static inline hashval_t hash (const allocno_hard_regs *);
205 static inline bool equal (const allocno_hard_regs *,
206 const allocno_hard_regs *);
207 };
208
209 /* Returns hash value for allocno hard registers V. */
210 inline hashval_t
211 allocno_hard_regs_hasher::hash (const allocno_hard_regs *hv)
212 {
213 return iterative_hash (&hv->set, sizeof (HARD_REG_SET), 0);
214 }
215
216 /* Compares allocno hard registers V1 and V2. */
217 inline bool
218 allocno_hard_regs_hasher::equal (const allocno_hard_regs *hv1,
219 const allocno_hard_regs *hv2)
220 {
221 return hv1->set == hv2->set;
222 }
223
224 /* Hash table of unique allocno hard registers. */
225 static hash_table<allocno_hard_regs_hasher> *allocno_hard_regs_htab;
226
227 /* Return allocno hard registers in the hash table equal to HV. */
228 static allocno_hard_regs_t
229 find_hard_regs (allocno_hard_regs_t hv)
230 {
231 return allocno_hard_regs_htab->find (hv);
232 }
233
234 /* Insert allocno hard registers HV in the hash table (if it is not
235 there yet) and return the value which in the table. */
236 static allocno_hard_regs_t
237 insert_hard_regs (allocno_hard_regs_t hv)
238 {
239 allocno_hard_regs **slot = allocno_hard_regs_htab->find_slot (hv, INSERT);
240
241 if (*slot == NULL)
242 *slot = hv;
243 return *slot;
244 }
245
246 /* Initialize data concerning allocno hard registers. */
247 static void
248 init_allocno_hard_regs (void)
249 {
250 allocno_hard_regs_vec.create (200);
251 allocno_hard_regs_htab
252 = new hash_table<allocno_hard_regs_hasher> (200);
253 }
254
255 /* Add (or update info about) allocno hard registers with SET and
256 COST. */
257 static allocno_hard_regs_t
258 add_allocno_hard_regs (HARD_REG_SET set, int64_t cost)
259 {
260 struct allocno_hard_regs temp;
261 allocno_hard_regs_t hv;
262
263 gcc_assert (! hard_reg_set_empty_p (set));
264 temp.set = set;
265 if ((hv = find_hard_regs (&temp)) != NULL)
266 hv->cost += cost;
267 else
268 {
269 hv = ((struct allocno_hard_regs *)
270 ira_allocate (sizeof (struct allocno_hard_regs)));
271 hv->set = set;
272 hv->cost = cost;
273 allocno_hard_regs_vec.safe_push (hv);
274 insert_hard_regs (hv);
275 }
276 return hv;
277 }
278
279 /* Finalize data concerning allocno hard registers. */
280 static void
281 finish_allocno_hard_regs (void)
282 {
283 int i;
284 allocno_hard_regs_t hv;
285
286 for (i = 0;
287 allocno_hard_regs_vec.iterate (i, &hv);
288 i++)
289 ira_free (hv);
290 delete allocno_hard_regs_htab;
291 allocno_hard_regs_htab = NULL;
292 allocno_hard_regs_vec.release ();
293 }
294
295 /* Sort hard regs according to their frequency of usage. */
296 static int
297 allocno_hard_regs_compare (const void *v1p, const void *v2p)
298 {
299 allocno_hard_regs_t hv1 = *(const allocno_hard_regs_t *) v1p;
300 allocno_hard_regs_t hv2 = *(const allocno_hard_regs_t *) v2p;
301
302 if (hv2->cost > hv1->cost)
303 return 1;
304 else if (hv2->cost < hv1->cost)
305 return -1;
306 return SORTGT (allocno_hard_regs_hasher::hash(hv2), allocno_hard_regs_hasher::hash(hv1));
307 }
308
309 \f
310
311 /* Used for finding a common ancestor of two allocno hard registers
312 nodes in the forest. We use the current value of
313 'node_check_tick' to mark all nodes from one node to the top and
314 then walking up from another node until we find a marked node.
315
316 It is also used to figure out allocno colorability as a mark that
317 we already reset value of member 'conflict_size' for the forest
318 node corresponding to the processed allocno. */
319 static int node_check_tick;
320
321 /* Roots of the forest containing hard register sets can be assigned
322 to allocnos. */
323 static allocno_hard_regs_node_t hard_regs_roots;
324
325 /* Definition of vector of allocno hard register nodes. */
326
327 /* Vector used to create the forest. */
328 static vec<allocno_hard_regs_node_t> hard_regs_node_vec;
329
330 /* Create and return allocno hard registers node containing allocno
331 hard registers HV. */
332 static allocno_hard_regs_node_t
333 create_new_allocno_hard_regs_node (allocno_hard_regs_t hv)
334 {
335 allocno_hard_regs_node_t new_node;
336
337 new_node = ((struct allocno_hard_regs_node *)
338 ira_allocate (sizeof (struct allocno_hard_regs_node)));
339 new_node->check = 0;
340 new_node->hard_regs = hv;
341 new_node->hard_regs_num = hard_reg_set_size (hv->set);
342 new_node->first = NULL;
343 new_node->used_p = false;
344 return new_node;
345 }
346
347 /* Add allocno hard registers node NEW_NODE to the forest on its level
348 given by ROOTS. */
349 static void
350 add_new_allocno_hard_regs_node_to_forest (allocno_hard_regs_node_t *roots,
351 allocno_hard_regs_node_t new_node)
352 {
353 new_node->next = *roots;
354 if (new_node->next != NULL)
355 new_node->next->prev = new_node;
356 new_node->prev = NULL;
357 *roots = new_node;
358 }
359
360 /* Add allocno hard registers HV (or its best approximation if it is
361 not possible) to the forest on its level given by ROOTS. */
362 static void
363 add_allocno_hard_regs_to_forest (allocno_hard_regs_node_t *roots,
364 allocno_hard_regs_t hv)
365 {
366 unsigned int i, start;
367 allocno_hard_regs_node_t node, prev, new_node;
368 HARD_REG_SET temp_set;
369 allocno_hard_regs_t hv2;
370
371 start = hard_regs_node_vec.length ();
372 for (node = *roots; node != NULL; node = node->next)
373 {
374 if (hv->set == node->hard_regs->set)
375 return;
376 if (hard_reg_set_subset_p (hv->set, node->hard_regs->set))
377 {
378 add_allocno_hard_regs_to_forest (&node->first, hv);
379 return;
380 }
381 if (hard_reg_set_subset_p (node->hard_regs->set, hv->set))
382 hard_regs_node_vec.safe_push (node);
383 else if (hard_reg_set_intersect_p (hv->set, node->hard_regs->set))
384 {
385 temp_set = hv->set & node->hard_regs->set;
386 hv2 = add_allocno_hard_regs (temp_set, hv->cost);
387 add_allocno_hard_regs_to_forest (&node->first, hv2);
388 }
389 }
390 if (hard_regs_node_vec.length ()
391 > start + 1)
392 {
393 /* Create a new node which contains nodes in hard_regs_node_vec. */
394 CLEAR_HARD_REG_SET (temp_set);
395 for (i = start;
396 i < hard_regs_node_vec.length ();
397 i++)
398 {
399 node = hard_regs_node_vec[i];
400 temp_set |= node->hard_regs->set;
401 }
402 hv = add_allocno_hard_regs (temp_set, hv->cost);
403 new_node = create_new_allocno_hard_regs_node (hv);
404 prev = NULL;
405 for (i = start;
406 i < hard_regs_node_vec.length ();
407 i++)
408 {
409 node = hard_regs_node_vec[i];
410 if (node->prev == NULL)
411 *roots = node->next;
412 else
413 node->prev->next = node->next;
414 if (node->next != NULL)
415 node->next->prev = node->prev;
416 if (prev == NULL)
417 new_node->first = node;
418 else
419 prev->next = node;
420 node->prev = prev;
421 node->next = NULL;
422 prev = node;
423 }
424 add_new_allocno_hard_regs_node_to_forest (roots, new_node);
425 }
426 hard_regs_node_vec.truncate (start);
427 }
428
429 /* Add allocno hard registers nodes starting with the forest level
430 given by FIRST which contains biggest set inside SET. */
431 static void
432 collect_allocno_hard_regs_cover (allocno_hard_regs_node_t first,
433 HARD_REG_SET set)
434 {
435 allocno_hard_regs_node_t node;
436
437 ira_assert (first != NULL);
438 for (node = first; node != NULL; node = node->next)
439 if (hard_reg_set_subset_p (node->hard_regs->set, set))
440 hard_regs_node_vec.safe_push (node);
441 else if (hard_reg_set_intersect_p (set, node->hard_regs->set))
442 collect_allocno_hard_regs_cover (node->first, set);
443 }
444
445 /* Set up field parent as PARENT in all allocno hard registers nodes
446 in forest given by FIRST. */
447 static void
448 setup_allocno_hard_regs_nodes_parent (allocno_hard_regs_node_t first,
449 allocno_hard_regs_node_t parent)
450 {
451 allocno_hard_regs_node_t node;
452
453 for (node = first; node != NULL; node = node->next)
454 {
455 node->parent = parent;
456 setup_allocno_hard_regs_nodes_parent (node->first, node);
457 }
458 }
459
460 /* Return allocno hard registers node which is a first common ancestor
461 node of FIRST and SECOND in the forest. */
462 static allocno_hard_regs_node_t
463 first_common_ancestor_node (allocno_hard_regs_node_t first,
464 allocno_hard_regs_node_t second)
465 {
466 allocno_hard_regs_node_t node;
467
468 node_check_tick++;
469 for (node = first; node != NULL; node = node->parent)
470 node->check = node_check_tick;
471 for (node = second; node != NULL; node = node->parent)
472 if (node->check == node_check_tick)
473 return node;
474 return first_common_ancestor_node (second, first);
475 }
476
477 /* Print hard reg set SET to F. */
478 static void
479 print_hard_reg_set (FILE *f, HARD_REG_SET set, bool new_line_p)
480 {
481 int i, start;
482
483 for (start = -1, i = 0; i < FIRST_PSEUDO_REGISTER; i++)
484 {
485 if (TEST_HARD_REG_BIT (set, i))
486 {
487 if (i == 0 || ! TEST_HARD_REG_BIT (set, i - 1))
488 start = i;
489 }
490 if (start >= 0
491 && (i == FIRST_PSEUDO_REGISTER - 1 || ! TEST_HARD_REG_BIT (set, i)))
492 {
493 if (start == i - 1)
494 fprintf (f, " %d", start);
495 else if (start == i - 2)
496 fprintf (f, " %d %d", start, start + 1);
497 else
498 fprintf (f, " %d-%d", start, i - 1);
499 start = -1;
500 }
501 }
502 if (new_line_p)
503 fprintf (f, "\n");
504 }
505
506 /* Print allocno hard register subforest given by ROOTS and its LEVEL
507 to F. */
508 static void
509 print_hard_regs_subforest (FILE *f, allocno_hard_regs_node_t roots,
510 int level)
511 {
512 int i;
513 allocno_hard_regs_node_t node;
514
515 for (node = roots; node != NULL; node = node->next)
516 {
517 fprintf (f, " ");
518 for (i = 0; i < level * 2; i++)
519 fprintf (f, " ");
520 fprintf (f, "%d:(", node->preorder_num);
521 print_hard_reg_set (f, node->hard_regs->set, false);
522 fprintf (f, ")@%" PRId64"\n", node->hard_regs->cost);
523 print_hard_regs_subforest (f, node->first, level + 1);
524 }
525 }
526
527 /* Print the allocno hard register forest to F. */
528 static void
529 print_hard_regs_forest (FILE *f)
530 {
531 fprintf (f, " Hard reg set forest:\n");
532 print_hard_regs_subforest (f, hard_regs_roots, 1);
533 }
534
535 /* Print the allocno hard register forest to stderr. */
536 void
537 ira_debug_hard_regs_forest (void)
538 {
539 print_hard_regs_forest (stderr);
540 }
541
542 /* Remove unused allocno hard registers nodes from forest given by its
543 *ROOTS. */
544 static void
545 remove_unused_allocno_hard_regs_nodes (allocno_hard_regs_node_t *roots)
546 {
547 allocno_hard_regs_node_t node, prev, next, last;
548
549 for (prev = NULL, node = *roots; node != NULL; node = next)
550 {
551 next = node->next;
552 if (node->used_p)
553 {
554 remove_unused_allocno_hard_regs_nodes (&node->first);
555 prev = node;
556 }
557 else
558 {
559 for (last = node->first;
560 last != NULL && last->next != NULL;
561 last = last->next)
562 ;
563 if (last != NULL)
564 {
565 if (prev == NULL)
566 *roots = node->first;
567 else
568 prev->next = node->first;
569 if (next != NULL)
570 next->prev = last;
571 last->next = next;
572 next = node->first;
573 }
574 else
575 {
576 if (prev == NULL)
577 *roots = next;
578 else
579 prev->next = next;
580 if (next != NULL)
581 next->prev = prev;
582 }
583 ira_free (node);
584 }
585 }
586 }
587
588 /* Set up fields preorder_num starting with START_NUM in all allocno
589 hard registers nodes in forest given by FIRST. Return biggest set
590 PREORDER_NUM increased by 1. */
591 static int
592 enumerate_allocno_hard_regs_nodes (allocno_hard_regs_node_t first,
593 allocno_hard_regs_node_t parent,
594 int start_num)
595 {
596 allocno_hard_regs_node_t node;
597
598 for (node = first; node != NULL; node = node->next)
599 {
600 node->preorder_num = start_num++;
601 node->parent = parent;
602 start_num = enumerate_allocno_hard_regs_nodes (node->first, node,
603 start_num);
604 }
605 return start_num;
606 }
607
608 /* Number of allocno hard registers nodes in the forest. */
609 static int allocno_hard_regs_nodes_num;
610
611 /* Table preorder number of allocno hard registers node in the forest
612 -> the allocno hard registers node. */
613 static allocno_hard_regs_node_t *allocno_hard_regs_nodes;
614
615 /* See below. */
616 typedef struct allocno_hard_regs_subnode *allocno_hard_regs_subnode_t;
617
618 /* The structure is used to describes all subnodes (not only immediate
619 ones) in the mentioned above tree for given allocno hard register
620 node. The usage of such data accelerates calculation of
621 colorability of given allocno. */
622 struct allocno_hard_regs_subnode
623 {
624 /* The conflict size of conflicting allocnos whose hard register
625 sets are equal sets (plus supersets if given node is given
626 allocno hard registers node) of one in the given node. */
627 int left_conflict_size;
628 /* The summary conflict size of conflicting allocnos whose hard
629 register sets are strict subsets of one in the given node.
630 Overall conflict size is
631 left_conflict_subnodes_size
632 + MIN (max_node_impact - left_conflict_subnodes_size,
633 left_conflict_size)
634 */
635 short left_conflict_subnodes_size;
636 short max_node_impact;
637 };
638
639 /* Container for hard regs subnodes of all allocnos. */
640 static allocno_hard_regs_subnode_t allocno_hard_regs_subnodes;
641
642 /* Table (preorder number of allocno hard registers node in the
643 forest, preorder number of allocno hard registers subnode) -> index
644 of the subnode relative to the node. -1 if it is not a
645 subnode. */
646 static int *allocno_hard_regs_subnode_index;
647
648 /* Setup arrays ALLOCNO_HARD_REGS_NODES and
649 ALLOCNO_HARD_REGS_SUBNODE_INDEX. */
650 static void
651 setup_allocno_hard_regs_subnode_index (allocno_hard_regs_node_t first)
652 {
653 allocno_hard_regs_node_t node, parent;
654 int index;
655
656 for (node = first; node != NULL; node = node->next)
657 {
658 allocno_hard_regs_nodes[node->preorder_num] = node;
659 for (parent = node; parent != NULL; parent = parent->parent)
660 {
661 index = parent->preorder_num * allocno_hard_regs_nodes_num;
662 allocno_hard_regs_subnode_index[index + node->preorder_num]
663 = node->preorder_num - parent->preorder_num;
664 }
665 setup_allocno_hard_regs_subnode_index (node->first);
666 }
667 }
668
669 /* Count all allocno hard registers nodes in tree ROOT. */
670 static int
671 get_allocno_hard_regs_subnodes_num (allocno_hard_regs_node_t root)
672 {
673 int len = 1;
674
675 for (root = root->first; root != NULL; root = root->next)
676 len += get_allocno_hard_regs_subnodes_num (root);
677 return len;
678 }
679
680 /* Build the forest of allocno hard registers nodes and assign each
681 allocno a node from the forest. */
682 static void
683 form_allocno_hard_regs_nodes_forest (void)
684 {
685 unsigned int i, j, size, len;
686 int start;
687 ira_allocno_t a;
688 allocno_hard_regs_t hv;
689 bitmap_iterator bi;
690 HARD_REG_SET temp;
691 allocno_hard_regs_node_t node, allocno_hard_regs_node;
692 allocno_color_data_t allocno_data;
693
694 node_check_tick = 0;
695 init_allocno_hard_regs ();
696 hard_regs_roots = NULL;
697 hard_regs_node_vec.create (100);
698 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
699 if (! TEST_HARD_REG_BIT (ira_no_alloc_regs, i))
700 {
701 CLEAR_HARD_REG_SET (temp);
702 SET_HARD_REG_BIT (temp, i);
703 hv = add_allocno_hard_regs (temp, 0);
704 node = create_new_allocno_hard_regs_node (hv);
705 add_new_allocno_hard_regs_node_to_forest (&hard_regs_roots, node);
706 }
707 start = allocno_hard_regs_vec.length ();
708 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
709 {
710 a = ira_allocnos[i];
711 allocno_data = ALLOCNO_COLOR_DATA (a);
712
713 if (hard_reg_set_empty_p (allocno_data->profitable_hard_regs))
714 continue;
715 hv = (add_allocno_hard_regs
716 (allocno_data->profitable_hard_regs,
717 ALLOCNO_MEMORY_COST (a) - ALLOCNO_CLASS_COST (a)));
718 }
719 temp = ~ira_no_alloc_regs;
720 add_allocno_hard_regs (temp, 0);
721 qsort (allocno_hard_regs_vec.address () + start,
722 allocno_hard_regs_vec.length () - start,
723 sizeof (allocno_hard_regs_t), allocno_hard_regs_compare);
724 for (i = start;
725 allocno_hard_regs_vec.iterate (i, &hv);
726 i++)
727 {
728 add_allocno_hard_regs_to_forest (&hard_regs_roots, hv);
729 ira_assert (hard_regs_node_vec.length () == 0);
730 }
731 /* We need to set up parent fields for right work of
732 first_common_ancestor_node. */
733 setup_allocno_hard_regs_nodes_parent (hard_regs_roots, NULL);
734 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
735 {
736 a = ira_allocnos[i];
737 allocno_data = ALLOCNO_COLOR_DATA (a);
738 if (hard_reg_set_empty_p (allocno_data->profitable_hard_regs))
739 continue;
740 hard_regs_node_vec.truncate (0);
741 collect_allocno_hard_regs_cover (hard_regs_roots,
742 allocno_data->profitable_hard_regs);
743 allocno_hard_regs_node = NULL;
744 for (j = 0; hard_regs_node_vec.iterate (j, &node); j++)
745 allocno_hard_regs_node
746 = (j == 0
747 ? node
748 : first_common_ancestor_node (node, allocno_hard_regs_node));
749 /* That is a temporary storage. */
750 allocno_hard_regs_node->used_p = true;
751 allocno_data->hard_regs_node = allocno_hard_regs_node;
752 }
753 ira_assert (hard_regs_roots->next == NULL);
754 hard_regs_roots->used_p = true;
755 remove_unused_allocno_hard_regs_nodes (&hard_regs_roots);
756 allocno_hard_regs_nodes_num
757 = enumerate_allocno_hard_regs_nodes (hard_regs_roots, NULL, 0);
758 allocno_hard_regs_nodes
759 = ((allocno_hard_regs_node_t *)
760 ira_allocate (allocno_hard_regs_nodes_num
761 * sizeof (allocno_hard_regs_node_t)));
762 size = allocno_hard_regs_nodes_num * allocno_hard_regs_nodes_num;
763 allocno_hard_regs_subnode_index
764 = (int *) ira_allocate (size * sizeof (int));
765 for (i = 0; i < size; i++)
766 allocno_hard_regs_subnode_index[i] = -1;
767 setup_allocno_hard_regs_subnode_index (hard_regs_roots);
768 start = 0;
769 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
770 {
771 a = ira_allocnos[i];
772 allocno_data = ALLOCNO_COLOR_DATA (a);
773 if (hard_reg_set_empty_p (allocno_data->profitable_hard_regs))
774 continue;
775 len = get_allocno_hard_regs_subnodes_num (allocno_data->hard_regs_node);
776 allocno_data->hard_regs_subnodes_start = start;
777 allocno_data->hard_regs_subnodes_num = len;
778 start += len;
779 }
780 allocno_hard_regs_subnodes
781 = ((allocno_hard_regs_subnode_t)
782 ira_allocate (sizeof (struct allocno_hard_regs_subnode) * start));
783 hard_regs_node_vec.release ();
784 }
785
786 /* Free tree of allocno hard registers nodes given by its ROOT. */
787 static void
788 finish_allocno_hard_regs_nodes_tree (allocno_hard_regs_node_t root)
789 {
790 allocno_hard_regs_node_t child, next;
791
792 for (child = root->first; child != NULL; child = next)
793 {
794 next = child->next;
795 finish_allocno_hard_regs_nodes_tree (child);
796 }
797 ira_free (root);
798 }
799
800 /* Finish work with the forest of allocno hard registers nodes. */
801 static void
802 finish_allocno_hard_regs_nodes_forest (void)
803 {
804 allocno_hard_regs_node_t node, next;
805
806 ira_free (allocno_hard_regs_subnodes);
807 for (node = hard_regs_roots; node != NULL; node = next)
808 {
809 next = node->next;
810 finish_allocno_hard_regs_nodes_tree (node);
811 }
812 ira_free (allocno_hard_regs_nodes);
813 ira_free (allocno_hard_regs_subnode_index);
814 finish_allocno_hard_regs ();
815 }
816
817 /* Set up left conflict sizes and left conflict subnodes sizes of hard
818 registers subnodes of allocno A. Return TRUE if allocno A is
819 trivially colorable. */
820 static bool
821 setup_left_conflict_sizes_p (ira_allocno_t a)
822 {
823 int i, k, nobj, start;
824 int conflict_size, left_conflict_subnodes_size, node_preorder_num;
825 allocno_color_data_t data;
826 HARD_REG_SET profitable_hard_regs;
827 allocno_hard_regs_subnode_t subnodes;
828 allocno_hard_regs_node_t node;
829 HARD_REG_SET node_set;
830
831 nobj = ALLOCNO_NUM_OBJECTS (a);
832 data = ALLOCNO_COLOR_DATA (a);
833 subnodes = allocno_hard_regs_subnodes + data->hard_regs_subnodes_start;
834 profitable_hard_regs = data->profitable_hard_regs;
835 node = data->hard_regs_node;
836 node_preorder_num = node->preorder_num;
837 node_set = node->hard_regs->set;
838 node_check_tick++;
839 for (k = 0; k < nobj; k++)
840 {
841 ira_object_t obj = ALLOCNO_OBJECT (a, k);
842 ira_object_t conflict_obj;
843 ira_object_conflict_iterator oci;
844
845 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
846 {
847 int size;
848 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
849 allocno_hard_regs_node_t conflict_node, temp_node;
850 HARD_REG_SET conflict_node_set;
851 allocno_color_data_t conflict_data;
852
853 conflict_data = ALLOCNO_COLOR_DATA (conflict_a);
854 if (! ALLOCNO_COLOR_DATA (conflict_a)->in_graph_p
855 || ! hard_reg_set_intersect_p (profitable_hard_regs,
856 conflict_data
857 ->profitable_hard_regs))
858 continue;
859 conflict_node = conflict_data->hard_regs_node;
860 conflict_node_set = conflict_node->hard_regs->set;
861 if (hard_reg_set_subset_p (node_set, conflict_node_set))
862 temp_node = node;
863 else
864 {
865 ira_assert (hard_reg_set_subset_p (conflict_node_set, node_set));
866 temp_node = conflict_node;
867 }
868 if (temp_node->check != node_check_tick)
869 {
870 temp_node->check = node_check_tick;
871 temp_node->conflict_size = 0;
872 }
873 size = (ira_reg_class_max_nregs
874 [ALLOCNO_CLASS (conflict_a)][ALLOCNO_MODE (conflict_a)]);
875 if (ALLOCNO_NUM_OBJECTS (conflict_a) > 1)
876 /* We will deal with the subwords individually. */
877 size = 1;
878 temp_node->conflict_size += size;
879 }
880 }
881 for (i = 0; i < data->hard_regs_subnodes_num; i++)
882 {
883 allocno_hard_regs_node_t temp_node;
884
885 temp_node = allocno_hard_regs_nodes[i + node_preorder_num];
886 ira_assert (temp_node->preorder_num == i + node_preorder_num);
887 subnodes[i].left_conflict_size = (temp_node->check != node_check_tick
888 ? 0 : temp_node->conflict_size);
889 if (hard_reg_set_subset_p (temp_node->hard_regs->set,
890 profitable_hard_regs))
891 subnodes[i].max_node_impact = temp_node->hard_regs_num;
892 else
893 {
894 HARD_REG_SET temp_set;
895 int j, n, hard_regno;
896 enum reg_class aclass;
897
898 temp_set = temp_node->hard_regs->set & profitable_hard_regs;
899 aclass = ALLOCNO_CLASS (a);
900 for (n = 0, j = ira_class_hard_regs_num[aclass] - 1; j >= 0; j--)
901 {
902 hard_regno = ira_class_hard_regs[aclass][j];
903 if (TEST_HARD_REG_BIT (temp_set, hard_regno))
904 n++;
905 }
906 subnodes[i].max_node_impact = n;
907 }
908 subnodes[i].left_conflict_subnodes_size = 0;
909 }
910 start = node_preorder_num * allocno_hard_regs_nodes_num;
911 for (i = data->hard_regs_subnodes_num - 1; i > 0; i--)
912 {
913 int size, parent_i;
914 allocno_hard_regs_node_t parent;
915
916 size = (subnodes[i].left_conflict_subnodes_size
917 + MIN (subnodes[i].max_node_impact
918 - subnodes[i].left_conflict_subnodes_size,
919 subnodes[i].left_conflict_size));
920 parent = allocno_hard_regs_nodes[i + node_preorder_num]->parent;
921 gcc_checking_assert(parent);
922 parent_i
923 = allocno_hard_regs_subnode_index[start + parent->preorder_num];
924 gcc_checking_assert(parent_i >= 0);
925 subnodes[parent_i].left_conflict_subnodes_size += size;
926 }
927 left_conflict_subnodes_size = subnodes[0].left_conflict_subnodes_size;
928 conflict_size
929 = (left_conflict_subnodes_size
930 + MIN (subnodes[0].max_node_impact - left_conflict_subnodes_size,
931 subnodes[0].left_conflict_size));
932 conflict_size += ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)];
933 data->colorable_p = conflict_size <= data->available_regs_num;
934 return data->colorable_p;
935 }
936
937 /* Update left conflict sizes of hard registers subnodes of allocno A
938 after removing allocno REMOVED_A with SIZE from the conflict graph.
939 Return TRUE if A is trivially colorable. */
940 static bool
941 update_left_conflict_sizes_p (ira_allocno_t a,
942 ira_allocno_t removed_a, int size)
943 {
944 int i, conflict_size, before_conflict_size, diff, start;
945 int node_preorder_num, parent_i;
946 allocno_hard_regs_node_t node, removed_node, parent;
947 allocno_hard_regs_subnode_t subnodes;
948 allocno_color_data_t data = ALLOCNO_COLOR_DATA (a);
949
950 ira_assert (! data->colorable_p);
951 node = data->hard_regs_node;
952 node_preorder_num = node->preorder_num;
953 removed_node = ALLOCNO_COLOR_DATA (removed_a)->hard_regs_node;
954 ira_assert (hard_reg_set_subset_p (removed_node->hard_regs->set,
955 node->hard_regs->set)
956 || hard_reg_set_subset_p (node->hard_regs->set,
957 removed_node->hard_regs->set));
958 start = node_preorder_num * allocno_hard_regs_nodes_num;
959 i = allocno_hard_regs_subnode_index[start + removed_node->preorder_num];
960 if (i < 0)
961 i = 0;
962 subnodes = allocno_hard_regs_subnodes + data->hard_regs_subnodes_start;
963 before_conflict_size
964 = (subnodes[i].left_conflict_subnodes_size
965 + MIN (subnodes[i].max_node_impact
966 - subnodes[i].left_conflict_subnodes_size,
967 subnodes[i].left_conflict_size));
968 subnodes[i].left_conflict_size -= size;
969 for (;;)
970 {
971 conflict_size
972 = (subnodes[i].left_conflict_subnodes_size
973 + MIN (subnodes[i].max_node_impact
974 - subnodes[i].left_conflict_subnodes_size,
975 subnodes[i].left_conflict_size));
976 if ((diff = before_conflict_size - conflict_size) == 0)
977 break;
978 ira_assert (conflict_size < before_conflict_size);
979 parent = allocno_hard_regs_nodes[i + node_preorder_num]->parent;
980 if (parent == NULL)
981 break;
982 parent_i
983 = allocno_hard_regs_subnode_index[start + parent->preorder_num];
984 if (parent_i < 0)
985 break;
986 i = parent_i;
987 before_conflict_size
988 = (subnodes[i].left_conflict_subnodes_size
989 + MIN (subnodes[i].max_node_impact
990 - subnodes[i].left_conflict_subnodes_size,
991 subnodes[i].left_conflict_size));
992 subnodes[i].left_conflict_subnodes_size -= diff;
993 }
994 if (i != 0
995 || (conflict_size
996 + ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]
997 > data->available_regs_num))
998 return false;
999 data->colorable_p = true;
1000 return true;
1001 }
1002
1003 /* Return true if allocno A has empty profitable hard regs. */
1004 static bool
1005 empty_profitable_hard_regs (ira_allocno_t a)
1006 {
1007 allocno_color_data_t data = ALLOCNO_COLOR_DATA (a);
1008
1009 return hard_reg_set_empty_p (data->profitable_hard_regs);
1010 }
1011
1012 /* Set up profitable hard registers for each allocno being
1013 colored. */
1014 static void
1015 setup_profitable_hard_regs (void)
1016 {
1017 unsigned int i;
1018 int j, k, nobj, hard_regno, nregs, class_size;
1019 ira_allocno_t a;
1020 bitmap_iterator bi;
1021 enum reg_class aclass;
1022 machine_mode mode;
1023 allocno_color_data_t data;
1024
1025 /* Initial set up from allocno classes and explicitly conflicting
1026 hard regs. */
1027 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
1028 {
1029 a = ira_allocnos[i];
1030 if ((aclass = ALLOCNO_CLASS (a)) == NO_REGS)
1031 continue;
1032 data = ALLOCNO_COLOR_DATA (a);
1033 if (ALLOCNO_UPDATED_HARD_REG_COSTS (a) == NULL
1034 && ALLOCNO_CLASS_COST (a) > ALLOCNO_MEMORY_COST (a)
1035 /* Do not empty profitable regs for static chain pointer
1036 pseudo when non-local goto is used. */
1037 && ! non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a)))
1038 CLEAR_HARD_REG_SET (data->profitable_hard_regs);
1039 else
1040 {
1041 mode = ALLOCNO_MODE (a);
1042 data->profitable_hard_regs
1043 = ira_useful_class_mode_regs[aclass][mode];
1044 nobj = ALLOCNO_NUM_OBJECTS (a);
1045 for (k = 0; k < nobj; k++)
1046 {
1047 ira_object_t obj = ALLOCNO_OBJECT (a, k);
1048
1049 data->profitable_hard_regs
1050 &= ~OBJECT_TOTAL_CONFLICT_HARD_REGS (obj);
1051 }
1052 }
1053 }
1054 /* Exclude hard regs already assigned for conflicting objects. */
1055 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, i, bi)
1056 {
1057 a = ira_allocnos[i];
1058 if ((aclass = ALLOCNO_CLASS (a)) == NO_REGS
1059 || ! ALLOCNO_ASSIGNED_P (a)
1060 || (hard_regno = ALLOCNO_HARD_REGNO (a)) < 0)
1061 continue;
1062 mode = ALLOCNO_MODE (a);
1063 nregs = hard_regno_nregs (hard_regno, mode);
1064 nobj = ALLOCNO_NUM_OBJECTS (a);
1065 for (k = 0; k < nobj; k++)
1066 {
1067 ira_object_t obj = ALLOCNO_OBJECT (a, k);
1068 ira_object_t conflict_obj;
1069 ira_object_conflict_iterator oci;
1070
1071 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
1072 {
1073 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
1074
1075 /* We can process the conflict allocno repeatedly with
1076 the same result. */
1077 if (nregs == nobj && nregs > 1)
1078 {
1079 int num = OBJECT_SUBWORD (conflict_obj);
1080
1081 if (REG_WORDS_BIG_ENDIAN)
1082 CLEAR_HARD_REG_BIT
1083 (ALLOCNO_COLOR_DATA (conflict_a)->profitable_hard_regs,
1084 hard_regno + nobj - num - 1);
1085 else
1086 CLEAR_HARD_REG_BIT
1087 (ALLOCNO_COLOR_DATA (conflict_a)->profitable_hard_regs,
1088 hard_regno + num);
1089 }
1090 else
1091 ALLOCNO_COLOR_DATA (conflict_a)->profitable_hard_regs
1092 &= ~ira_reg_mode_hard_regset[hard_regno][mode];
1093 }
1094 }
1095 }
1096 /* Exclude too costly hard regs. */
1097 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
1098 {
1099 int min_cost = INT_MAX;
1100 int *costs;
1101
1102 a = ira_allocnos[i];
1103 if ((aclass = ALLOCNO_CLASS (a)) == NO_REGS
1104 || empty_profitable_hard_regs (a))
1105 continue;
1106 data = ALLOCNO_COLOR_DATA (a);
1107 if ((costs = ALLOCNO_UPDATED_HARD_REG_COSTS (a)) != NULL
1108 || (costs = ALLOCNO_HARD_REG_COSTS (a)) != NULL)
1109 {
1110 class_size = ira_class_hard_regs_num[aclass];
1111 for (j = 0; j < class_size; j++)
1112 {
1113 hard_regno = ira_class_hard_regs[aclass][j];
1114 if (! TEST_HARD_REG_BIT (data->profitable_hard_regs,
1115 hard_regno))
1116 continue;
1117 if (ALLOCNO_UPDATED_MEMORY_COST (a) < costs[j]
1118 /* Do not remove HARD_REGNO for static chain pointer
1119 pseudo when non-local goto is used. */
1120 && ! non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a)))
1121 CLEAR_HARD_REG_BIT (data->profitable_hard_regs,
1122 hard_regno);
1123 else if (min_cost > costs[j])
1124 min_cost = costs[j];
1125 }
1126 }
1127 else if (ALLOCNO_UPDATED_MEMORY_COST (a)
1128 < ALLOCNO_UPDATED_CLASS_COST (a)
1129 /* Do not empty profitable regs for static chain
1130 pointer pseudo when non-local goto is used. */
1131 && ! non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a)))
1132 CLEAR_HARD_REG_SET (data->profitable_hard_regs);
1133 if (ALLOCNO_UPDATED_CLASS_COST (a) > min_cost)
1134 ALLOCNO_UPDATED_CLASS_COST (a) = min_cost;
1135 }
1136 }
1137
1138 \f
1139
1140 /* This page contains functions used to choose hard registers for
1141 allocnos. */
1142
1143 /* Pool for update cost records. */
1144 static object_allocator<update_cost_record> update_cost_record_pool
1145 ("update cost records");
1146
1147 /* Return new update cost record with given params. */
1148 static struct update_cost_record *
1149 get_update_cost_record (int hard_regno, int divisor,
1150 struct update_cost_record *next)
1151 {
1152 struct update_cost_record *record;
1153
1154 record = update_cost_record_pool.allocate ();
1155 record->hard_regno = hard_regno;
1156 record->divisor = divisor;
1157 record->next = next;
1158 return record;
1159 }
1160
1161 /* Free memory for all records in LIST. */
1162 static void
1163 free_update_cost_record_list (struct update_cost_record *list)
1164 {
1165 struct update_cost_record *next;
1166
1167 while (list != NULL)
1168 {
1169 next = list->next;
1170 update_cost_record_pool.remove (list);
1171 list = next;
1172 }
1173 }
1174
1175 /* Free memory allocated for all update cost records. */
1176 static void
1177 finish_update_cost_records (void)
1178 {
1179 update_cost_record_pool.release ();
1180 }
1181
1182 /* Array whose element value is TRUE if the corresponding hard
1183 register was already allocated for an allocno. */
1184 static bool allocated_hardreg_p[FIRST_PSEUDO_REGISTER];
1185
1186 /* Describes one element in a queue of allocnos whose costs need to be
1187 updated. Each allocno in the queue is known to have an allocno
1188 class. */
1189 struct update_cost_queue_elem
1190 {
1191 /* This element is in the queue iff CHECK == update_cost_check. */
1192 int check;
1193
1194 /* COST_HOP_DIVISOR**N, where N is the length of the shortest path
1195 connecting this allocno to the one being allocated. */
1196 int divisor;
1197
1198 /* Allocno from which we are chaining costs of connected allocnos.
1199 It is used not go back in graph of allocnos connected by
1200 copies. */
1201 ira_allocno_t from;
1202
1203 /* The next allocno in the queue, or null if this is the last element. */
1204 ira_allocno_t next;
1205 };
1206
1207 /* The first element in a queue of allocnos whose copy costs need to be
1208 updated. Null if the queue is empty. */
1209 static ira_allocno_t update_cost_queue;
1210
1211 /* The last element in the queue described by update_cost_queue.
1212 Not valid if update_cost_queue is null. */
1213 static struct update_cost_queue_elem *update_cost_queue_tail;
1214
1215 /* A pool of elements in the queue described by update_cost_queue.
1216 Elements are indexed by ALLOCNO_NUM. */
1217 static struct update_cost_queue_elem *update_cost_queue_elems;
1218
1219 /* The current value of update_costs_from_copies call count. */
1220 static int update_cost_check;
1221
1222 /* Allocate and initialize data necessary for function
1223 update_costs_from_copies. */
1224 static void
1225 initiate_cost_update (void)
1226 {
1227 size_t size;
1228
1229 size = ira_allocnos_num * sizeof (struct update_cost_queue_elem);
1230 update_cost_queue_elems
1231 = (struct update_cost_queue_elem *) ira_allocate (size);
1232 memset (update_cost_queue_elems, 0, size);
1233 update_cost_check = 0;
1234 }
1235
1236 /* Deallocate data used by function update_costs_from_copies. */
1237 static void
1238 finish_cost_update (void)
1239 {
1240 ira_free (update_cost_queue_elems);
1241 finish_update_cost_records ();
1242 }
1243
1244 /* When we traverse allocnos to update hard register costs, the cost
1245 divisor will be multiplied by the following macro value for each
1246 hop from given allocno to directly connected allocnos. */
1247 #define COST_HOP_DIVISOR 4
1248
1249 /* Start a new cost-updating pass. */
1250 static void
1251 start_update_cost (void)
1252 {
1253 update_cost_check++;
1254 update_cost_queue = NULL;
1255 }
1256
1257 /* Add (ALLOCNO, FROM, DIVISOR) to the end of update_cost_queue, unless
1258 ALLOCNO is already in the queue, or has NO_REGS class. */
1259 static inline void
1260 queue_update_cost (ira_allocno_t allocno, ira_allocno_t from, int divisor)
1261 {
1262 struct update_cost_queue_elem *elem;
1263
1264 elem = &update_cost_queue_elems[ALLOCNO_NUM (allocno)];
1265 if (elem->check != update_cost_check
1266 && ALLOCNO_CLASS (allocno) != NO_REGS)
1267 {
1268 elem->check = update_cost_check;
1269 elem->from = from;
1270 elem->divisor = divisor;
1271 elem->next = NULL;
1272 if (update_cost_queue == NULL)
1273 update_cost_queue = allocno;
1274 else
1275 update_cost_queue_tail->next = allocno;
1276 update_cost_queue_tail = elem;
1277 }
1278 }
1279
1280 /* Try to remove the first element from update_cost_queue. Return
1281 false if the queue was empty, otherwise make (*ALLOCNO, *FROM,
1282 *DIVISOR) describe the removed element. */
1283 static inline bool
1284 get_next_update_cost (ira_allocno_t *allocno, ira_allocno_t *from, int *divisor)
1285 {
1286 struct update_cost_queue_elem *elem;
1287
1288 if (update_cost_queue == NULL)
1289 return false;
1290
1291 *allocno = update_cost_queue;
1292 elem = &update_cost_queue_elems[ALLOCNO_NUM (*allocno)];
1293 *from = elem->from;
1294 *divisor = elem->divisor;
1295 update_cost_queue = elem->next;
1296 return true;
1297 }
1298
1299 /* Increase costs of HARD_REGNO by UPDATE_COST and conflict cost by
1300 UPDATE_CONFLICT_COST for ALLOCNO. Return true if we really
1301 modified the cost. */
1302 static bool
1303 update_allocno_cost (ira_allocno_t allocno, int hard_regno,
1304 int update_cost, int update_conflict_cost)
1305 {
1306 int i;
1307 enum reg_class aclass = ALLOCNO_CLASS (allocno);
1308
1309 i = ira_class_hard_reg_index[aclass][hard_regno];
1310 if (i < 0)
1311 return false;
1312 ira_allocate_and_set_or_copy_costs
1313 (&ALLOCNO_UPDATED_HARD_REG_COSTS (allocno), aclass,
1314 ALLOCNO_UPDATED_CLASS_COST (allocno),
1315 ALLOCNO_HARD_REG_COSTS (allocno));
1316 ira_allocate_and_set_or_copy_costs
1317 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (allocno),
1318 aclass, 0, ALLOCNO_CONFLICT_HARD_REG_COSTS (allocno));
1319 ALLOCNO_UPDATED_HARD_REG_COSTS (allocno)[i] += update_cost;
1320 ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (allocno)[i] += update_conflict_cost;
1321 return true;
1322 }
1323
1324 /* Update (decrease if DECR_P) HARD_REGNO cost of allocnos connected
1325 by copies to ALLOCNO to increase chances to remove some copies as
1326 the result of subsequent assignment. Record cost updates if
1327 RECORD_P is true. */
1328 static void
1329 update_costs_from_allocno (ira_allocno_t allocno, int hard_regno,
1330 int divisor, bool decr_p, bool record_p)
1331 {
1332 int cost, update_cost, update_conflict_cost;
1333 machine_mode mode;
1334 enum reg_class rclass, aclass;
1335 ira_allocno_t another_allocno, from = NULL;
1336 ira_copy_t cp, next_cp;
1337
1338 rclass = REGNO_REG_CLASS (hard_regno);
1339 do
1340 {
1341 mode = ALLOCNO_MODE (allocno);
1342 ira_init_register_move_cost_if_necessary (mode);
1343 for (cp = ALLOCNO_COPIES (allocno); cp != NULL; cp = next_cp)
1344 {
1345 if (cp->first == allocno)
1346 {
1347 next_cp = cp->next_first_allocno_copy;
1348 another_allocno = cp->second;
1349 }
1350 else if (cp->second == allocno)
1351 {
1352 next_cp = cp->next_second_allocno_copy;
1353 another_allocno = cp->first;
1354 }
1355 else
1356 gcc_unreachable ();
1357
1358 if (another_allocno == from)
1359 continue;
1360
1361 aclass = ALLOCNO_CLASS (another_allocno);
1362 if (! TEST_HARD_REG_BIT (reg_class_contents[aclass],
1363 hard_regno)
1364 || ALLOCNO_ASSIGNED_P (another_allocno))
1365 continue;
1366
1367 /* If we have different modes use the smallest one. It is
1368 a sub-register move. It is hard to predict what LRA
1369 will reload (the pseudo or its sub-register) but LRA
1370 will try to minimize the data movement. Also for some
1371 register classes bigger modes might be invalid,
1372 e.g. DImode for AREG on x86. For such cases the
1373 register move cost will be maximal. */
1374 mode = narrower_subreg_mode (mode, ALLOCNO_MODE (cp->second));
1375 ira_init_register_move_cost_if_necessary (mode);
1376
1377 cost = (cp->second == allocno
1378 ? ira_register_move_cost[mode][rclass][aclass]
1379 : ira_register_move_cost[mode][aclass][rclass]);
1380 if (decr_p)
1381 cost = -cost;
1382
1383 update_conflict_cost = update_cost = cp->freq * cost / divisor;
1384
1385 if (ALLOCNO_COLOR_DATA (another_allocno) != NULL
1386 && (ALLOCNO_COLOR_DATA (allocno)->first_thread_allocno
1387 != ALLOCNO_COLOR_DATA (another_allocno)->first_thread_allocno))
1388 /* Decrease conflict cost of ANOTHER_ALLOCNO if it is not
1389 in the same allocation thread. */
1390 update_conflict_cost /= COST_HOP_DIVISOR;
1391
1392 if (update_cost == 0)
1393 continue;
1394
1395 if (! update_allocno_cost (another_allocno, hard_regno,
1396 update_cost, update_conflict_cost))
1397 continue;
1398 queue_update_cost (another_allocno, allocno, divisor * COST_HOP_DIVISOR);
1399 if (record_p && ALLOCNO_COLOR_DATA (another_allocno) != NULL)
1400 ALLOCNO_COLOR_DATA (another_allocno)->update_cost_records
1401 = get_update_cost_record (hard_regno, divisor,
1402 ALLOCNO_COLOR_DATA (another_allocno)
1403 ->update_cost_records);
1404 }
1405 }
1406 while (get_next_update_cost (&allocno, &from, &divisor));
1407 }
1408
1409 /* Decrease preferred ALLOCNO hard register costs and costs of
1410 allocnos connected to ALLOCNO through copy. */
1411 static void
1412 update_costs_from_prefs (ira_allocno_t allocno)
1413 {
1414 ira_pref_t pref;
1415
1416 start_update_cost ();
1417 for (pref = ALLOCNO_PREFS (allocno); pref != NULL; pref = pref->next_pref)
1418 update_costs_from_allocno (allocno, pref->hard_regno,
1419 COST_HOP_DIVISOR, true, true);
1420 }
1421
1422 /* Update (decrease if DECR_P) the cost of allocnos connected to
1423 ALLOCNO through copies to increase chances to remove some copies as
1424 the result of subsequent assignment. ALLOCNO was just assigned to
1425 a hard register. Record cost updates if RECORD_P is true. */
1426 static void
1427 update_costs_from_copies (ira_allocno_t allocno, bool decr_p, bool record_p)
1428 {
1429 int hard_regno;
1430
1431 hard_regno = ALLOCNO_HARD_REGNO (allocno);
1432 ira_assert (hard_regno >= 0 && ALLOCNO_CLASS (allocno) != NO_REGS);
1433 start_update_cost ();
1434 update_costs_from_allocno (allocno, hard_regno, 1, decr_p, record_p);
1435 }
1436
1437 /* Update conflict_allocno_hard_prefs of allocnos conflicting with
1438 ALLOCNO. */
1439 static void
1440 update_conflict_allocno_hard_prefs (ira_allocno_t allocno)
1441 {
1442 int l, nr = ALLOCNO_NUM_OBJECTS (allocno);
1443
1444 for (l = 0; l < nr; l++)
1445 {
1446 ira_object_t conflict_obj, obj = ALLOCNO_OBJECT (allocno, l);
1447 ira_object_conflict_iterator oci;
1448
1449 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
1450 {
1451 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
1452 allocno_color_data_t conflict_data = ALLOCNO_COLOR_DATA (conflict_a);
1453 ira_pref_t pref;
1454
1455 if (!(hard_reg_set_intersect_p
1456 (ALLOCNO_COLOR_DATA (allocno)->profitable_hard_regs,
1457 conflict_data->profitable_hard_regs)))
1458 continue;
1459 for (pref = ALLOCNO_PREFS (allocno);
1460 pref != NULL;
1461 pref = pref->next_pref)
1462 conflict_data->conflict_allocno_hard_prefs += pref->freq;
1463 }
1464 }
1465 }
1466
1467 /* Restore costs of allocnos connected to ALLOCNO by copies as it was
1468 before updating costs of these allocnos from given allocno. This
1469 is a wise thing to do as if given allocno did not get an expected
1470 hard reg, using smaller cost of the hard reg for allocnos connected
1471 by copies to given allocno becomes actually misleading. Free all
1472 update cost records for ALLOCNO as we don't need them anymore. */
1473 static void
1474 restore_costs_from_copies (ira_allocno_t allocno)
1475 {
1476 struct update_cost_record *records, *curr;
1477
1478 if (ALLOCNO_COLOR_DATA (allocno) == NULL)
1479 return;
1480 records = ALLOCNO_COLOR_DATA (allocno)->update_cost_records;
1481 start_update_cost ();
1482 for (curr = records; curr != NULL; curr = curr->next)
1483 update_costs_from_allocno (allocno, curr->hard_regno,
1484 curr->divisor, true, false);
1485 free_update_cost_record_list (records);
1486 ALLOCNO_COLOR_DATA (allocno)->update_cost_records = NULL;
1487 }
1488
1489 /* This function updates COSTS (decrease if DECR_P) for hard_registers
1490 of ACLASS by conflict costs of the unassigned allocnos
1491 connected by copies with allocnos in update_cost_queue. This
1492 update increases chances to remove some copies. */
1493 static void
1494 update_conflict_hard_regno_costs (int *costs, enum reg_class aclass,
1495 bool decr_p)
1496 {
1497 int i, cost, class_size, freq, mult, div, divisor;
1498 int index, hard_regno;
1499 int *conflict_costs;
1500 bool cont_p;
1501 enum reg_class another_aclass;
1502 ira_allocno_t allocno, another_allocno, from;
1503 ira_copy_t cp, next_cp;
1504
1505 while (get_next_update_cost (&allocno, &from, &divisor))
1506 for (cp = ALLOCNO_COPIES (allocno); cp != NULL; cp = next_cp)
1507 {
1508 if (cp->first == allocno)
1509 {
1510 next_cp = cp->next_first_allocno_copy;
1511 another_allocno = cp->second;
1512 }
1513 else if (cp->second == allocno)
1514 {
1515 next_cp = cp->next_second_allocno_copy;
1516 another_allocno = cp->first;
1517 }
1518 else
1519 gcc_unreachable ();
1520
1521 if (another_allocno == from)
1522 continue;
1523
1524 another_aclass = ALLOCNO_CLASS (another_allocno);
1525 if (! ira_reg_classes_intersect_p[aclass][another_aclass]
1526 || ALLOCNO_ASSIGNED_P (another_allocno)
1527 || ALLOCNO_COLOR_DATA (another_allocno)->may_be_spilled_p)
1528 continue;
1529 class_size = ira_class_hard_regs_num[another_aclass];
1530 ira_allocate_and_copy_costs
1531 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (another_allocno),
1532 another_aclass, ALLOCNO_CONFLICT_HARD_REG_COSTS (another_allocno));
1533 conflict_costs
1534 = ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (another_allocno);
1535 if (conflict_costs == NULL)
1536 cont_p = true;
1537 else
1538 {
1539 mult = cp->freq;
1540 freq = ALLOCNO_FREQ (another_allocno);
1541 if (freq == 0)
1542 freq = 1;
1543 div = freq * divisor;
1544 cont_p = false;
1545 for (i = class_size - 1; i >= 0; i--)
1546 {
1547 hard_regno = ira_class_hard_regs[another_aclass][i];
1548 ira_assert (hard_regno >= 0);
1549 index = ira_class_hard_reg_index[aclass][hard_regno];
1550 if (index < 0)
1551 continue;
1552 cost = (int) (((int64_t) conflict_costs [i] * mult) / div);
1553 if (cost == 0)
1554 continue;
1555 cont_p = true;
1556 if (decr_p)
1557 cost = -cost;
1558 costs[index] += cost;
1559 }
1560 }
1561 /* Probably 5 hops will be enough. */
1562 if (cont_p
1563 && divisor <= (COST_HOP_DIVISOR
1564 * COST_HOP_DIVISOR
1565 * COST_HOP_DIVISOR
1566 * COST_HOP_DIVISOR))
1567 queue_update_cost (another_allocno, allocno, divisor * COST_HOP_DIVISOR);
1568 }
1569 }
1570
1571 /* Set up conflicting (through CONFLICT_REGS) for each object of
1572 allocno A and the start allocno profitable regs (through
1573 START_PROFITABLE_REGS). Remember that the start profitable regs
1574 exclude hard regs which cannot hold value of mode of allocno A.
1575 This covers mostly cases when multi-register value should be
1576 aligned. */
1577 static inline void
1578 get_conflict_and_start_profitable_regs (ira_allocno_t a, bool retry_p,
1579 HARD_REG_SET *conflict_regs,
1580 HARD_REG_SET *start_profitable_regs)
1581 {
1582 int i, nwords;
1583 ira_object_t obj;
1584
1585 nwords = ALLOCNO_NUM_OBJECTS (a);
1586 for (i = 0; i < nwords; i++)
1587 {
1588 obj = ALLOCNO_OBJECT (a, i);
1589 conflict_regs[i] = OBJECT_TOTAL_CONFLICT_HARD_REGS (obj);
1590 }
1591 if (retry_p)
1592 *start_profitable_regs
1593 = (reg_class_contents[ALLOCNO_CLASS (a)]
1594 &~ (ira_prohibited_class_mode_regs
1595 [ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]));
1596 else
1597 *start_profitable_regs = ALLOCNO_COLOR_DATA (a)->profitable_hard_regs;
1598 }
1599
1600 /* Return true if HARD_REGNO is ok for assigning to allocno A with
1601 PROFITABLE_REGS and whose objects have CONFLICT_REGS. */
1602 static inline bool
1603 check_hard_reg_p (ira_allocno_t a, int hard_regno,
1604 HARD_REG_SET *conflict_regs, HARD_REG_SET profitable_regs)
1605 {
1606 int j, nwords, nregs;
1607 enum reg_class aclass;
1608 machine_mode mode;
1609
1610 aclass = ALLOCNO_CLASS (a);
1611 mode = ALLOCNO_MODE (a);
1612 if (TEST_HARD_REG_BIT (ira_prohibited_class_mode_regs[aclass][mode],
1613 hard_regno))
1614 return false;
1615 /* Checking only profitable hard regs. */
1616 if (! TEST_HARD_REG_BIT (profitable_regs, hard_regno))
1617 return false;
1618 nregs = hard_regno_nregs (hard_regno, mode);
1619 nwords = ALLOCNO_NUM_OBJECTS (a);
1620 for (j = 0; j < nregs; j++)
1621 {
1622 int k;
1623 int set_to_test_start = 0, set_to_test_end = nwords;
1624
1625 if (nregs == nwords)
1626 {
1627 if (REG_WORDS_BIG_ENDIAN)
1628 set_to_test_start = nwords - j - 1;
1629 else
1630 set_to_test_start = j;
1631 set_to_test_end = set_to_test_start + 1;
1632 }
1633 for (k = set_to_test_start; k < set_to_test_end; k++)
1634 if (TEST_HARD_REG_BIT (conflict_regs[k], hard_regno + j))
1635 break;
1636 if (k != set_to_test_end)
1637 break;
1638 }
1639 return j == nregs;
1640 }
1641
1642 /* Return number of registers needed to be saved and restored at
1643 function prologue/epilogue if we allocate HARD_REGNO to hold value
1644 of MODE. */
1645 static int
1646 calculate_saved_nregs (int hard_regno, machine_mode mode)
1647 {
1648 int i;
1649 int nregs = 0;
1650
1651 ira_assert (hard_regno >= 0);
1652 for (i = hard_regno_nregs (hard_regno, mode) - 1; i >= 0; i--)
1653 if (!allocated_hardreg_p[hard_regno + i]
1654 && !crtl->abi->clobbers_full_reg_p (hard_regno + i)
1655 && !LOCAL_REGNO (hard_regno + i))
1656 nregs++;
1657 return nregs;
1658 }
1659
1660 /* Choose a hard register for allocno A. If RETRY_P is TRUE, it means
1661 that the function called from function
1662 `ira_reassign_conflict_allocnos' and `allocno_reload_assign'. In
1663 this case some allocno data are not defined or updated and we
1664 should not touch these data. The function returns true if we
1665 managed to assign a hard register to the allocno.
1666
1667 To assign a hard register, first of all we calculate all conflict
1668 hard registers which can come from conflicting allocnos with
1669 already assigned hard registers. After that we find first free
1670 hard register with the minimal cost. During hard register cost
1671 calculation we take conflict hard register costs into account to
1672 give a chance for conflicting allocnos to get a better hard
1673 register in the future.
1674
1675 If the best hard register cost is bigger than cost of memory usage
1676 for the allocno, we don't assign a hard register to given allocno
1677 at all.
1678
1679 If we assign a hard register to the allocno, we update costs of the
1680 hard register for allocnos connected by copies to improve a chance
1681 to coalesce insns represented by the copies when we assign hard
1682 registers to the allocnos connected by the copies. */
1683 static bool
1684 assign_hard_reg (ira_allocno_t a, bool retry_p)
1685 {
1686 HARD_REG_SET conflicting_regs[2], profitable_hard_regs;
1687 int i, j, hard_regno, best_hard_regno, class_size;
1688 int cost, mem_cost, min_cost, full_cost, min_full_cost, nwords, word;
1689 int *a_costs;
1690 enum reg_class aclass;
1691 machine_mode mode;
1692 static int costs[FIRST_PSEUDO_REGISTER], full_costs[FIRST_PSEUDO_REGISTER];
1693 int saved_nregs;
1694 enum reg_class rclass;
1695 int add_cost;
1696 #ifdef STACK_REGS
1697 bool no_stack_reg_p;
1698 #endif
1699
1700 ira_assert (! ALLOCNO_ASSIGNED_P (a));
1701 get_conflict_and_start_profitable_regs (a, retry_p,
1702 conflicting_regs,
1703 &profitable_hard_regs);
1704 aclass = ALLOCNO_CLASS (a);
1705 class_size = ira_class_hard_regs_num[aclass];
1706 best_hard_regno = -1;
1707 memset (full_costs, 0, sizeof (int) * class_size);
1708 mem_cost = 0;
1709 memset (costs, 0, sizeof (int) * class_size);
1710 memset (full_costs, 0, sizeof (int) * class_size);
1711 #ifdef STACK_REGS
1712 no_stack_reg_p = false;
1713 #endif
1714 if (! retry_p)
1715 start_update_cost ();
1716 mem_cost += ALLOCNO_UPDATED_MEMORY_COST (a);
1717
1718 ira_allocate_and_copy_costs (&ALLOCNO_UPDATED_HARD_REG_COSTS (a),
1719 aclass, ALLOCNO_HARD_REG_COSTS (a));
1720 a_costs = ALLOCNO_UPDATED_HARD_REG_COSTS (a);
1721 #ifdef STACK_REGS
1722 no_stack_reg_p = no_stack_reg_p || ALLOCNO_TOTAL_NO_STACK_REG_P (a);
1723 #endif
1724 cost = ALLOCNO_UPDATED_CLASS_COST (a);
1725 for (i = 0; i < class_size; i++)
1726 if (a_costs != NULL)
1727 {
1728 costs[i] += a_costs[i];
1729 full_costs[i] += a_costs[i];
1730 }
1731 else
1732 {
1733 costs[i] += cost;
1734 full_costs[i] += cost;
1735 }
1736 nwords = ALLOCNO_NUM_OBJECTS (a);
1737 curr_allocno_process++;
1738 for (word = 0; word < nwords; word++)
1739 {
1740 ira_object_t conflict_obj;
1741 ira_object_t obj = ALLOCNO_OBJECT (a, word);
1742 ira_object_conflict_iterator oci;
1743
1744 /* Take preferences of conflicting allocnos into account. */
1745 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
1746 {
1747 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
1748 enum reg_class conflict_aclass;
1749 allocno_color_data_t data = ALLOCNO_COLOR_DATA (conflict_a);
1750
1751 /* Reload can give another class so we need to check all
1752 allocnos. */
1753 if (!retry_p
1754 && ((!ALLOCNO_ASSIGNED_P (conflict_a)
1755 || ALLOCNO_HARD_REGNO (conflict_a) < 0)
1756 && !(hard_reg_set_intersect_p
1757 (profitable_hard_regs,
1758 ALLOCNO_COLOR_DATA
1759 (conflict_a)->profitable_hard_regs))))
1760 {
1761 /* All conflict allocnos are in consideration bitmap
1762 when retry_p is false. It might change in future and
1763 if it happens the assert will be broken. It means
1764 the code should be modified for the new
1765 assumptions. */
1766 ira_assert (bitmap_bit_p (consideration_allocno_bitmap,
1767 ALLOCNO_NUM (conflict_a)));
1768 continue;
1769 }
1770 conflict_aclass = ALLOCNO_CLASS (conflict_a);
1771 ira_assert (ira_reg_classes_intersect_p
1772 [aclass][conflict_aclass]);
1773 if (ALLOCNO_ASSIGNED_P (conflict_a))
1774 {
1775 hard_regno = ALLOCNO_HARD_REGNO (conflict_a);
1776 if (hard_regno >= 0
1777 && (ira_hard_reg_set_intersection_p
1778 (hard_regno, ALLOCNO_MODE (conflict_a),
1779 reg_class_contents[aclass])))
1780 {
1781 int n_objects = ALLOCNO_NUM_OBJECTS (conflict_a);
1782 int conflict_nregs;
1783
1784 mode = ALLOCNO_MODE (conflict_a);
1785 conflict_nregs = hard_regno_nregs (hard_regno, mode);
1786 if (conflict_nregs == n_objects && conflict_nregs > 1)
1787 {
1788 int num = OBJECT_SUBWORD (conflict_obj);
1789
1790 if (REG_WORDS_BIG_ENDIAN)
1791 SET_HARD_REG_BIT (conflicting_regs[word],
1792 hard_regno + n_objects - num - 1);
1793 else
1794 SET_HARD_REG_BIT (conflicting_regs[word],
1795 hard_regno + num);
1796 }
1797 else
1798 conflicting_regs[word]
1799 |= ira_reg_mode_hard_regset[hard_regno][mode];
1800 if (hard_reg_set_subset_p (profitable_hard_regs,
1801 conflicting_regs[word]))
1802 goto fail;
1803 }
1804 }
1805 else if (! retry_p
1806 && ! ALLOCNO_COLOR_DATA (conflict_a)->may_be_spilled_p
1807 /* Don't process the conflict allocno twice. */
1808 && (ALLOCNO_COLOR_DATA (conflict_a)->last_process
1809 != curr_allocno_process))
1810 {
1811 int k, *conflict_costs;
1812
1813 ALLOCNO_COLOR_DATA (conflict_a)->last_process
1814 = curr_allocno_process;
1815 ira_allocate_and_copy_costs
1816 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (conflict_a),
1817 conflict_aclass,
1818 ALLOCNO_CONFLICT_HARD_REG_COSTS (conflict_a));
1819 conflict_costs
1820 = ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (conflict_a);
1821 if (conflict_costs != NULL)
1822 for (j = class_size - 1; j >= 0; j--)
1823 {
1824 hard_regno = ira_class_hard_regs[aclass][j];
1825 ira_assert (hard_regno >= 0);
1826 k = ira_class_hard_reg_index[conflict_aclass][hard_regno];
1827 if (k < 0
1828 /* If HARD_REGNO is not available for CONFLICT_A,
1829 the conflict would be ignored, since HARD_REGNO
1830 will never be assigned to CONFLICT_A. */
1831 || !TEST_HARD_REG_BIT (data->profitable_hard_regs,
1832 hard_regno))
1833 continue;
1834 full_costs[j] -= conflict_costs[k];
1835 }
1836 queue_update_cost (conflict_a, NULL, COST_HOP_DIVISOR);
1837
1838 }
1839 }
1840 }
1841 if (! retry_p)
1842 /* Take into account preferences of allocnos connected by copies to
1843 the conflict allocnos. */
1844 update_conflict_hard_regno_costs (full_costs, aclass, true);
1845
1846 /* Take preferences of allocnos connected by copies into
1847 account. */
1848 if (! retry_p)
1849 {
1850 start_update_cost ();
1851 queue_update_cost (a, NULL, COST_HOP_DIVISOR);
1852 update_conflict_hard_regno_costs (full_costs, aclass, false);
1853 }
1854 min_cost = min_full_cost = INT_MAX;
1855 /* We don't care about giving callee saved registers to allocnos no
1856 living through calls because call clobbered registers are
1857 allocated first (it is usual practice to put them first in
1858 REG_ALLOC_ORDER). */
1859 mode = ALLOCNO_MODE (a);
1860 for (i = 0; i < class_size; i++)
1861 {
1862 hard_regno = ira_class_hard_regs[aclass][i];
1863 #ifdef STACK_REGS
1864 if (no_stack_reg_p
1865 && FIRST_STACK_REG <= hard_regno && hard_regno <= LAST_STACK_REG)
1866 continue;
1867 #endif
1868 if (! check_hard_reg_p (a, hard_regno,
1869 conflicting_regs, profitable_hard_regs))
1870 continue;
1871 cost = costs[i];
1872 full_cost = full_costs[i];
1873 if (!HONOR_REG_ALLOC_ORDER)
1874 {
1875 if ((saved_nregs = calculate_saved_nregs (hard_regno, mode)) != 0)
1876 /* We need to save/restore the hard register in
1877 epilogue/prologue. Therefore we increase the cost. */
1878 {
1879 rclass = REGNO_REG_CLASS (hard_regno);
1880 add_cost = ((ira_memory_move_cost[mode][rclass][0]
1881 + ira_memory_move_cost[mode][rclass][1])
1882 * saved_nregs / hard_regno_nregs (hard_regno,
1883 mode) - 1);
1884 cost += add_cost;
1885 full_cost += add_cost;
1886 }
1887 }
1888 if (min_cost > cost)
1889 min_cost = cost;
1890 if (min_full_cost > full_cost)
1891 {
1892 min_full_cost = full_cost;
1893 best_hard_regno = hard_regno;
1894 ira_assert (hard_regno >= 0);
1895 }
1896 }
1897 if (min_full_cost > mem_cost
1898 /* Do not spill static chain pointer pseudo when non-local goto
1899 is used. */
1900 && ! non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a)))
1901 {
1902 if (! retry_p && internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
1903 fprintf (ira_dump_file, "(memory is more profitable %d vs %d) ",
1904 mem_cost, min_full_cost);
1905 best_hard_regno = -1;
1906 }
1907 fail:
1908 if (best_hard_regno >= 0)
1909 {
1910 for (i = hard_regno_nregs (best_hard_regno, mode) - 1; i >= 0; i--)
1911 allocated_hardreg_p[best_hard_regno + i] = true;
1912 }
1913 if (! retry_p)
1914 restore_costs_from_copies (a);
1915 ALLOCNO_HARD_REGNO (a) = best_hard_regno;
1916 ALLOCNO_ASSIGNED_P (a) = true;
1917 if (best_hard_regno >= 0)
1918 update_costs_from_copies (a, true, ! retry_p);
1919 ira_assert (ALLOCNO_CLASS (a) == aclass);
1920 /* We don't need updated costs anymore. */
1921 ira_free_allocno_updated_costs (a);
1922 return best_hard_regno >= 0;
1923 }
1924
1925 \f
1926
1927 /* An array used to sort copies. */
1928 static ira_copy_t *sorted_copies;
1929
1930 /* If allocno A is a cap, return non-cap allocno from which A is
1931 created. Otherwise, return A. */
1932 static ira_allocno_t
1933 get_cap_member (ira_allocno_t a)
1934 {
1935 ira_allocno_t member;
1936
1937 while ((member = ALLOCNO_CAP_MEMBER (a)) != NULL)
1938 a = member;
1939 return a;
1940 }
1941
1942 /* Return TRUE if live ranges of allocnos A1 and A2 intersect. It is
1943 used to find a conflict for new allocnos or allocnos with the
1944 different allocno classes. */
1945 static bool
1946 allocnos_conflict_by_live_ranges_p (ira_allocno_t a1, ira_allocno_t a2)
1947 {
1948 rtx reg1, reg2;
1949 int i, j;
1950 int n1 = ALLOCNO_NUM_OBJECTS (a1);
1951 int n2 = ALLOCNO_NUM_OBJECTS (a2);
1952
1953 if (a1 == a2)
1954 return false;
1955 reg1 = regno_reg_rtx[ALLOCNO_REGNO (a1)];
1956 reg2 = regno_reg_rtx[ALLOCNO_REGNO (a2)];
1957 if (reg1 != NULL && reg2 != NULL
1958 && ORIGINAL_REGNO (reg1) == ORIGINAL_REGNO (reg2))
1959 return false;
1960
1961 /* We don't keep live ranges for caps because they can be quite big.
1962 Use ranges of non-cap allocno from which caps are created. */
1963 a1 = get_cap_member (a1);
1964 a2 = get_cap_member (a2);
1965 for (i = 0; i < n1; i++)
1966 {
1967 ira_object_t c1 = ALLOCNO_OBJECT (a1, i);
1968
1969 for (j = 0; j < n2; j++)
1970 {
1971 ira_object_t c2 = ALLOCNO_OBJECT (a2, j);
1972
1973 if (ira_live_ranges_intersect_p (OBJECT_LIVE_RANGES (c1),
1974 OBJECT_LIVE_RANGES (c2)))
1975 return true;
1976 }
1977 }
1978 return false;
1979 }
1980
1981 /* The function is used to sort copies according to their execution
1982 frequencies. */
1983 static int
1984 copy_freq_compare_func (const void *v1p, const void *v2p)
1985 {
1986 ira_copy_t cp1 = *(const ira_copy_t *) v1p, cp2 = *(const ira_copy_t *) v2p;
1987 int pri1, pri2;
1988
1989 pri1 = cp1->freq;
1990 pri2 = cp2->freq;
1991 if (pri2 - pri1)
1992 return pri2 - pri1;
1993
1994 /* If frequencies are equal, sort by copies, so that the results of
1995 qsort leave nothing to chance. */
1996 return cp1->num - cp2->num;
1997 }
1998
1999 \f
2000
2001 /* Return true if any allocno from thread of A1 conflicts with any
2002 allocno from thread A2. */
2003 static bool
2004 allocno_thread_conflict_p (ira_allocno_t a1, ira_allocno_t a2)
2005 {
2006 ira_allocno_t a, conflict_a;
2007
2008 for (a = ALLOCNO_COLOR_DATA (a2)->next_thread_allocno;;
2009 a = ALLOCNO_COLOR_DATA (a)->next_thread_allocno)
2010 {
2011 for (conflict_a = ALLOCNO_COLOR_DATA (a1)->next_thread_allocno;;
2012 conflict_a = ALLOCNO_COLOR_DATA (conflict_a)->next_thread_allocno)
2013 {
2014 if (allocnos_conflict_by_live_ranges_p (a, conflict_a))
2015 return true;
2016 if (conflict_a == a1)
2017 break;
2018 }
2019 if (a == a2)
2020 break;
2021 }
2022 return false;
2023 }
2024
2025 /* Merge two threads given correspondingly by their first allocnos T1
2026 and T2 (more accurately merging T2 into T1). */
2027 static void
2028 merge_threads (ira_allocno_t t1, ira_allocno_t t2)
2029 {
2030 ira_allocno_t a, next, last;
2031
2032 gcc_assert (t1 != t2
2033 && ALLOCNO_COLOR_DATA (t1)->first_thread_allocno == t1
2034 && ALLOCNO_COLOR_DATA (t2)->first_thread_allocno == t2);
2035 for (last = t2, a = ALLOCNO_COLOR_DATA (t2)->next_thread_allocno;;
2036 a = ALLOCNO_COLOR_DATA (a)->next_thread_allocno)
2037 {
2038 ALLOCNO_COLOR_DATA (a)->first_thread_allocno = t1;
2039 if (a == t2)
2040 break;
2041 last = a;
2042 }
2043 next = ALLOCNO_COLOR_DATA (t1)->next_thread_allocno;
2044 ALLOCNO_COLOR_DATA (t1)->next_thread_allocno = t2;
2045 ALLOCNO_COLOR_DATA (last)->next_thread_allocno = next;
2046 ALLOCNO_COLOR_DATA (t1)->thread_freq += ALLOCNO_COLOR_DATA (t2)->thread_freq;
2047 }
2048
2049 /* Create threads by processing CP_NUM copies from sorted copies. We
2050 process the most expensive copies first. */
2051 static void
2052 form_threads_from_copies (int cp_num)
2053 {
2054 ira_allocno_t a, thread1, thread2;
2055 ira_copy_t cp;
2056 int i, n;
2057
2058 qsort (sorted_copies, cp_num, sizeof (ira_copy_t), copy_freq_compare_func);
2059 /* Form threads processing copies, most frequently executed
2060 first. */
2061 for (; cp_num != 0;)
2062 {
2063 for (i = 0; i < cp_num; i++)
2064 {
2065 cp = sorted_copies[i];
2066 thread1 = ALLOCNO_COLOR_DATA (cp->first)->first_thread_allocno;
2067 thread2 = ALLOCNO_COLOR_DATA (cp->second)->first_thread_allocno;
2068 if (thread1 == thread2)
2069 continue;
2070 if (! allocno_thread_conflict_p (thread1, thread2))
2071 {
2072 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2073 fprintf
2074 (ira_dump_file,
2075 " Forming thread by copy %d:a%dr%d-a%dr%d (freq=%d):\n",
2076 cp->num, ALLOCNO_NUM (cp->first), ALLOCNO_REGNO (cp->first),
2077 ALLOCNO_NUM (cp->second), ALLOCNO_REGNO (cp->second),
2078 cp->freq);
2079 merge_threads (thread1, thread2);
2080 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2081 {
2082 thread1 = ALLOCNO_COLOR_DATA (thread1)->first_thread_allocno;
2083 fprintf (ira_dump_file, " Result (freq=%d): a%dr%d(%d)",
2084 ALLOCNO_COLOR_DATA (thread1)->thread_freq,
2085 ALLOCNO_NUM (thread1), ALLOCNO_REGNO (thread1),
2086 ALLOCNO_FREQ (thread1));
2087 for (a = ALLOCNO_COLOR_DATA (thread1)->next_thread_allocno;
2088 a != thread1;
2089 a = ALLOCNO_COLOR_DATA (a)->next_thread_allocno)
2090 fprintf (ira_dump_file, " a%dr%d(%d)",
2091 ALLOCNO_NUM (a), ALLOCNO_REGNO (a),
2092 ALLOCNO_FREQ (a));
2093 fprintf (ira_dump_file, "\n");
2094 }
2095 i++;
2096 break;
2097 }
2098 }
2099 /* Collect the rest of copies. */
2100 for (n = 0; i < cp_num; i++)
2101 {
2102 cp = sorted_copies[i];
2103 if (ALLOCNO_COLOR_DATA (cp->first)->first_thread_allocno
2104 != ALLOCNO_COLOR_DATA (cp->second)->first_thread_allocno)
2105 sorted_copies[n++] = cp;
2106 }
2107 cp_num = n;
2108 }
2109 }
2110
2111 /* Create threads by processing copies of all alocnos from BUCKET. We
2112 process the most expensive copies first. */
2113 static void
2114 form_threads_from_bucket (ira_allocno_t bucket)
2115 {
2116 ira_allocno_t a;
2117 ira_copy_t cp, next_cp;
2118 int cp_num = 0;
2119
2120 for (a = bucket; a != NULL; a = ALLOCNO_COLOR_DATA (a)->next_bucket_allocno)
2121 {
2122 for (cp = ALLOCNO_COPIES (a); cp != NULL; cp = next_cp)
2123 {
2124 if (cp->first == a)
2125 {
2126 next_cp = cp->next_first_allocno_copy;
2127 sorted_copies[cp_num++] = cp;
2128 }
2129 else if (cp->second == a)
2130 next_cp = cp->next_second_allocno_copy;
2131 else
2132 gcc_unreachable ();
2133 }
2134 }
2135 form_threads_from_copies (cp_num);
2136 }
2137
2138 /* Create threads by processing copies of colorable allocno A. We
2139 process most expensive copies first. */
2140 static void
2141 form_threads_from_colorable_allocno (ira_allocno_t a)
2142 {
2143 ira_allocno_t another_a;
2144 ira_copy_t cp, next_cp;
2145 int cp_num = 0;
2146
2147 for (cp = ALLOCNO_COPIES (a); cp != NULL; cp = next_cp)
2148 {
2149 if (cp->first == a)
2150 {
2151 next_cp = cp->next_first_allocno_copy;
2152 another_a = cp->second;
2153 }
2154 else if (cp->second == a)
2155 {
2156 next_cp = cp->next_second_allocno_copy;
2157 another_a = cp->first;
2158 }
2159 else
2160 gcc_unreachable ();
2161 if ((! ALLOCNO_COLOR_DATA (another_a)->in_graph_p
2162 && !ALLOCNO_COLOR_DATA (another_a)->may_be_spilled_p)
2163 || ALLOCNO_COLOR_DATA (another_a)->colorable_p)
2164 sorted_copies[cp_num++] = cp;
2165 }
2166 form_threads_from_copies (cp_num);
2167 }
2168
2169 /* Form initial threads which contain only one allocno. */
2170 static void
2171 init_allocno_threads (void)
2172 {
2173 ira_allocno_t a;
2174 unsigned int j;
2175 bitmap_iterator bi;
2176
2177 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
2178 {
2179 a = ira_allocnos[j];
2180 /* Set up initial thread data: */
2181 ALLOCNO_COLOR_DATA (a)->first_thread_allocno
2182 = ALLOCNO_COLOR_DATA (a)->next_thread_allocno = a;
2183 ALLOCNO_COLOR_DATA (a)->thread_freq = ALLOCNO_FREQ (a);
2184 }
2185 }
2186
2187 \f
2188
2189 /* This page contains the allocator based on the Chaitin-Briggs algorithm. */
2190
2191 /* Bucket of allocnos that can colored currently without spilling. */
2192 static ira_allocno_t colorable_allocno_bucket;
2193
2194 /* Bucket of allocnos that might be not colored currently without
2195 spilling. */
2196 static ira_allocno_t uncolorable_allocno_bucket;
2197
2198 /* The current number of allocnos in the uncolorable_bucket. */
2199 static int uncolorable_allocnos_num;
2200
2201 /* Return the current spill priority of allocno A. The less the
2202 number, the more preferable the allocno for spilling. */
2203 static inline int
2204 allocno_spill_priority (ira_allocno_t a)
2205 {
2206 allocno_color_data_t data = ALLOCNO_COLOR_DATA (a);
2207
2208 return (data->temp
2209 / (ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a)
2210 * ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]
2211 + 1));
2212 }
2213
2214 /* Add allocno A to bucket *BUCKET_PTR. A should be not in a bucket
2215 before the call. */
2216 static void
2217 add_allocno_to_bucket (ira_allocno_t a, ira_allocno_t *bucket_ptr)
2218 {
2219 ira_allocno_t first_a;
2220 allocno_color_data_t data;
2221
2222 if (bucket_ptr == &uncolorable_allocno_bucket
2223 && ALLOCNO_CLASS (a) != NO_REGS)
2224 {
2225 uncolorable_allocnos_num++;
2226 ira_assert (uncolorable_allocnos_num > 0);
2227 }
2228 first_a = *bucket_ptr;
2229 data = ALLOCNO_COLOR_DATA (a);
2230 data->next_bucket_allocno = first_a;
2231 data->prev_bucket_allocno = NULL;
2232 if (first_a != NULL)
2233 ALLOCNO_COLOR_DATA (first_a)->prev_bucket_allocno = a;
2234 *bucket_ptr = a;
2235 }
2236
2237 /* Compare two allocnos to define which allocno should be pushed first
2238 into the coloring stack. If the return is a negative number, the
2239 allocno given by the first parameter will be pushed first. In this
2240 case such allocno has less priority than the second one and the
2241 hard register will be assigned to it after assignment to the second
2242 one. As the result of such assignment order, the second allocno
2243 has a better chance to get the best hard register. */
2244 static int
2245 bucket_allocno_compare_func (const void *v1p, const void *v2p)
2246 {
2247 ira_allocno_t a1 = *(const ira_allocno_t *) v1p;
2248 ira_allocno_t a2 = *(const ira_allocno_t *) v2p;
2249 int diff, freq1, freq2, a1_num, a2_num, pref1, pref2;
2250 ira_allocno_t t1 = ALLOCNO_COLOR_DATA (a1)->first_thread_allocno;
2251 ira_allocno_t t2 = ALLOCNO_COLOR_DATA (a2)->first_thread_allocno;
2252 int cl1 = ALLOCNO_CLASS (a1), cl2 = ALLOCNO_CLASS (a2);
2253
2254 freq1 = ALLOCNO_COLOR_DATA (t1)->thread_freq;
2255 freq2 = ALLOCNO_COLOR_DATA (t2)->thread_freq;
2256 if ((diff = freq1 - freq2) != 0)
2257 return diff;
2258
2259 if ((diff = ALLOCNO_NUM (t2) - ALLOCNO_NUM (t1)) != 0)
2260 return diff;
2261
2262 /* Push pseudos requiring less hard registers first. It means that
2263 we will assign pseudos requiring more hard registers first
2264 avoiding creation small holes in free hard register file into
2265 which the pseudos requiring more hard registers cannot fit. */
2266 if ((diff = (ira_reg_class_max_nregs[cl1][ALLOCNO_MODE (a1)]
2267 - ira_reg_class_max_nregs[cl2][ALLOCNO_MODE (a2)])) != 0)
2268 return diff;
2269
2270 freq1 = ALLOCNO_FREQ (a1);
2271 freq2 = ALLOCNO_FREQ (a2);
2272 if ((diff = freq1 - freq2) != 0)
2273 return diff;
2274
2275 a1_num = ALLOCNO_COLOR_DATA (a1)->available_regs_num;
2276 a2_num = ALLOCNO_COLOR_DATA (a2)->available_regs_num;
2277 if ((diff = a2_num - a1_num) != 0)
2278 return diff;
2279 /* Push allocnos with minimal conflict_allocno_hard_prefs first. */
2280 pref1 = ALLOCNO_COLOR_DATA (a1)->conflict_allocno_hard_prefs;
2281 pref2 = ALLOCNO_COLOR_DATA (a2)->conflict_allocno_hard_prefs;
2282 if ((diff = pref1 - pref2) != 0)
2283 return diff;
2284 return ALLOCNO_NUM (a2) - ALLOCNO_NUM (a1);
2285 }
2286
2287 /* Sort bucket *BUCKET_PTR and return the result through
2288 BUCKET_PTR. */
2289 static void
2290 sort_bucket (ira_allocno_t *bucket_ptr,
2291 int (*compare_func) (const void *, const void *))
2292 {
2293 ira_allocno_t a, head;
2294 int n;
2295
2296 for (n = 0, a = *bucket_ptr;
2297 a != NULL;
2298 a = ALLOCNO_COLOR_DATA (a)->next_bucket_allocno)
2299 sorted_allocnos[n++] = a;
2300 if (n <= 1)
2301 return;
2302 qsort (sorted_allocnos, n, sizeof (ira_allocno_t), compare_func);
2303 head = NULL;
2304 for (n--; n >= 0; n--)
2305 {
2306 a = sorted_allocnos[n];
2307 ALLOCNO_COLOR_DATA (a)->next_bucket_allocno = head;
2308 ALLOCNO_COLOR_DATA (a)->prev_bucket_allocno = NULL;
2309 if (head != NULL)
2310 ALLOCNO_COLOR_DATA (head)->prev_bucket_allocno = a;
2311 head = a;
2312 }
2313 *bucket_ptr = head;
2314 }
2315
2316 /* Add ALLOCNO to colorable bucket maintaining the order according
2317 their priority. ALLOCNO should be not in a bucket before the
2318 call. */
2319 static void
2320 add_allocno_to_ordered_colorable_bucket (ira_allocno_t allocno)
2321 {
2322 ira_allocno_t before, after;
2323
2324 form_threads_from_colorable_allocno (allocno);
2325 for (before = colorable_allocno_bucket, after = NULL;
2326 before != NULL;
2327 after = before,
2328 before = ALLOCNO_COLOR_DATA (before)->next_bucket_allocno)
2329 if (bucket_allocno_compare_func (&allocno, &before) < 0)
2330 break;
2331 ALLOCNO_COLOR_DATA (allocno)->next_bucket_allocno = before;
2332 ALLOCNO_COLOR_DATA (allocno)->prev_bucket_allocno = after;
2333 if (after == NULL)
2334 colorable_allocno_bucket = allocno;
2335 else
2336 ALLOCNO_COLOR_DATA (after)->next_bucket_allocno = allocno;
2337 if (before != NULL)
2338 ALLOCNO_COLOR_DATA (before)->prev_bucket_allocno = allocno;
2339 }
2340
2341 /* Delete ALLOCNO from bucket *BUCKET_PTR. It should be there before
2342 the call. */
2343 static void
2344 delete_allocno_from_bucket (ira_allocno_t allocno, ira_allocno_t *bucket_ptr)
2345 {
2346 ira_allocno_t prev_allocno, next_allocno;
2347
2348 if (bucket_ptr == &uncolorable_allocno_bucket
2349 && ALLOCNO_CLASS (allocno) != NO_REGS)
2350 {
2351 uncolorable_allocnos_num--;
2352 ira_assert (uncolorable_allocnos_num >= 0);
2353 }
2354 prev_allocno = ALLOCNO_COLOR_DATA (allocno)->prev_bucket_allocno;
2355 next_allocno = ALLOCNO_COLOR_DATA (allocno)->next_bucket_allocno;
2356 if (prev_allocno != NULL)
2357 ALLOCNO_COLOR_DATA (prev_allocno)->next_bucket_allocno = next_allocno;
2358 else
2359 {
2360 ira_assert (*bucket_ptr == allocno);
2361 *bucket_ptr = next_allocno;
2362 }
2363 if (next_allocno != NULL)
2364 ALLOCNO_COLOR_DATA (next_allocno)->prev_bucket_allocno = prev_allocno;
2365 }
2366
2367 /* Put allocno A onto the coloring stack without removing it from its
2368 bucket. Pushing allocno to the coloring stack can result in moving
2369 conflicting allocnos from the uncolorable bucket to the colorable
2370 one. Update conflict_allocno_hard_prefs of the conflicting
2371 allocnos which are not on stack yet. */
2372 static void
2373 push_allocno_to_stack (ira_allocno_t a)
2374 {
2375 enum reg_class aclass;
2376 allocno_color_data_t data, conflict_data;
2377 int size, i, n = ALLOCNO_NUM_OBJECTS (a);
2378
2379 data = ALLOCNO_COLOR_DATA (a);
2380 data->in_graph_p = false;
2381 allocno_stack_vec.safe_push (a);
2382 aclass = ALLOCNO_CLASS (a);
2383 if (aclass == NO_REGS)
2384 return;
2385 size = ira_reg_class_max_nregs[aclass][ALLOCNO_MODE (a)];
2386 if (n > 1)
2387 {
2388 /* We will deal with the subwords individually. */
2389 gcc_assert (size == ALLOCNO_NUM_OBJECTS (a));
2390 size = 1;
2391 }
2392 for (i = 0; i < n; i++)
2393 {
2394 ira_object_t obj = ALLOCNO_OBJECT (a, i);
2395 ira_object_t conflict_obj;
2396 ira_object_conflict_iterator oci;
2397
2398 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
2399 {
2400 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
2401 ira_pref_t pref;
2402
2403 conflict_data = ALLOCNO_COLOR_DATA (conflict_a);
2404 if (! conflict_data->in_graph_p
2405 || ALLOCNO_ASSIGNED_P (conflict_a)
2406 || !(hard_reg_set_intersect_p
2407 (ALLOCNO_COLOR_DATA (a)->profitable_hard_regs,
2408 conflict_data->profitable_hard_regs)))
2409 continue;
2410 for (pref = ALLOCNO_PREFS (a); pref != NULL; pref = pref->next_pref)
2411 conflict_data->conflict_allocno_hard_prefs -= pref->freq;
2412 if (conflict_data->colorable_p)
2413 continue;
2414 ira_assert (bitmap_bit_p (coloring_allocno_bitmap,
2415 ALLOCNO_NUM (conflict_a)));
2416 if (update_left_conflict_sizes_p (conflict_a, a, size))
2417 {
2418 delete_allocno_from_bucket
2419 (conflict_a, &uncolorable_allocno_bucket);
2420 add_allocno_to_ordered_colorable_bucket (conflict_a);
2421 if (internal_flag_ira_verbose > 4 && ira_dump_file != NULL)
2422 {
2423 fprintf (ira_dump_file, " Making");
2424 ira_print_expanded_allocno (conflict_a);
2425 fprintf (ira_dump_file, " colorable\n");
2426 }
2427 }
2428
2429 }
2430 }
2431 }
2432
2433 /* Put ALLOCNO onto the coloring stack and remove it from its bucket.
2434 The allocno is in the colorable bucket if COLORABLE_P is TRUE. */
2435 static void
2436 remove_allocno_from_bucket_and_push (ira_allocno_t allocno, bool colorable_p)
2437 {
2438 if (colorable_p)
2439 delete_allocno_from_bucket (allocno, &colorable_allocno_bucket);
2440 else
2441 delete_allocno_from_bucket (allocno, &uncolorable_allocno_bucket);
2442 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2443 {
2444 fprintf (ira_dump_file, " Pushing");
2445 ira_print_expanded_allocno (allocno);
2446 if (colorable_p)
2447 fprintf (ira_dump_file, "(cost %d)\n",
2448 ALLOCNO_COLOR_DATA (allocno)->temp);
2449 else
2450 fprintf (ira_dump_file, "(potential spill: %spri=%d, cost=%d)\n",
2451 ALLOCNO_BAD_SPILL_P (allocno) ? "bad spill, " : "",
2452 allocno_spill_priority (allocno),
2453 ALLOCNO_COLOR_DATA (allocno)->temp);
2454 }
2455 if (! colorable_p)
2456 ALLOCNO_COLOR_DATA (allocno)->may_be_spilled_p = true;
2457 push_allocno_to_stack (allocno);
2458 }
2459
2460 /* Put all allocnos from colorable bucket onto the coloring stack. */
2461 static void
2462 push_only_colorable (void)
2463 {
2464 form_threads_from_bucket (colorable_allocno_bucket);
2465 sort_bucket (&colorable_allocno_bucket, bucket_allocno_compare_func);
2466 for (;colorable_allocno_bucket != NULL;)
2467 remove_allocno_from_bucket_and_push (colorable_allocno_bucket, true);
2468 }
2469
2470 /* Return the frequency of exit edges (if EXIT_P) or entry from/to the
2471 loop given by its LOOP_NODE. */
2472 int
2473 ira_loop_edge_freq (ira_loop_tree_node_t loop_node, int regno, bool exit_p)
2474 {
2475 int freq, i;
2476 edge_iterator ei;
2477 edge e;
2478 vec<edge> edges;
2479
2480 ira_assert (current_loops != NULL && loop_node->loop != NULL
2481 && (regno < 0 || regno >= FIRST_PSEUDO_REGISTER));
2482 freq = 0;
2483 if (! exit_p)
2484 {
2485 FOR_EACH_EDGE (e, ei, loop_node->loop->header->preds)
2486 if (e->src != loop_node->loop->latch
2487 && (regno < 0
2488 || (bitmap_bit_p (df_get_live_out (e->src), regno)
2489 && bitmap_bit_p (df_get_live_in (e->dest), regno))))
2490 freq += EDGE_FREQUENCY (e);
2491 }
2492 else
2493 {
2494 edges = get_loop_exit_edges (loop_node->loop);
2495 FOR_EACH_VEC_ELT (edges, i, e)
2496 if (regno < 0
2497 || (bitmap_bit_p (df_get_live_out (e->src), regno)
2498 && bitmap_bit_p (df_get_live_in (e->dest), regno)))
2499 freq += EDGE_FREQUENCY (e);
2500 edges.release ();
2501 }
2502
2503 return REG_FREQ_FROM_EDGE_FREQ (freq);
2504 }
2505
2506 /* Calculate and return the cost of putting allocno A into memory. */
2507 static int
2508 calculate_allocno_spill_cost (ira_allocno_t a)
2509 {
2510 int regno, cost;
2511 machine_mode mode;
2512 enum reg_class rclass;
2513 ira_allocno_t parent_allocno;
2514 ira_loop_tree_node_t parent_node, loop_node;
2515
2516 regno = ALLOCNO_REGNO (a);
2517 cost = ALLOCNO_UPDATED_MEMORY_COST (a) - ALLOCNO_UPDATED_CLASS_COST (a);
2518 if (ALLOCNO_CAP (a) != NULL)
2519 return cost;
2520 loop_node = ALLOCNO_LOOP_TREE_NODE (a);
2521 if ((parent_node = loop_node->parent) == NULL)
2522 return cost;
2523 if ((parent_allocno = parent_node->regno_allocno_map[regno]) == NULL)
2524 return cost;
2525 mode = ALLOCNO_MODE (a);
2526 rclass = ALLOCNO_CLASS (a);
2527 if (ALLOCNO_HARD_REGNO (parent_allocno) < 0)
2528 cost -= (ira_memory_move_cost[mode][rclass][0]
2529 * ira_loop_edge_freq (loop_node, regno, true)
2530 + ira_memory_move_cost[mode][rclass][1]
2531 * ira_loop_edge_freq (loop_node, regno, false));
2532 else
2533 {
2534 ira_init_register_move_cost_if_necessary (mode);
2535 cost += ((ira_memory_move_cost[mode][rclass][1]
2536 * ira_loop_edge_freq (loop_node, regno, true)
2537 + ira_memory_move_cost[mode][rclass][0]
2538 * ira_loop_edge_freq (loop_node, regno, false))
2539 - (ira_register_move_cost[mode][rclass][rclass]
2540 * (ira_loop_edge_freq (loop_node, regno, false)
2541 + ira_loop_edge_freq (loop_node, regno, true))));
2542 }
2543 return cost;
2544 }
2545
2546 /* Used for sorting allocnos for spilling. */
2547 static inline int
2548 allocno_spill_priority_compare (ira_allocno_t a1, ira_allocno_t a2)
2549 {
2550 int pri1, pri2, diff;
2551
2552 /* Avoid spilling static chain pointer pseudo when non-local goto is
2553 used. */
2554 if (non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a1)))
2555 return 1;
2556 else if (non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a2)))
2557 return -1;
2558 if (ALLOCNO_BAD_SPILL_P (a1) && ! ALLOCNO_BAD_SPILL_P (a2))
2559 return 1;
2560 if (ALLOCNO_BAD_SPILL_P (a2) && ! ALLOCNO_BAD_SPILL_P (a1))
2561 return -1;
2562 pri1 = allocno_spill_priority (a1);
2563 pri2 = allocno_spill_priority (a2);
2564 if ((diff = pri1 - pri2) != 0)
2565 return diff;
2566 if ((diff
2567 = ALLOCNO_COLOR_DATA (a1)->temp - ALLOCNO_COLOR_DATA (a2)->temp) != 0)
2568 return diff;
2569 return ALLOCNO_NUM (a1) - ALLOCNO_NUM (a2);
2570 }
2571
2572 /* Used for sorting allocnos for spilling. */
2573 static int
2574 allocno_spill_sort_compare (const void *v1p, const void *v2p)
2575 {
2576 ira_allocno_t p1 = *(const ira_allocno_t *) v1p;
2577 ira_allocno_t p2 = *(const ira_allocno_t *) v2p;
2578
2579 return allocno_spill_priority_compare (p1, p2);
2580 }
2581
2582 /* Push allocnos to the coloring stack. The order of allocnos in the
2583 stack defines the order for the subsequent coloring. */
2584 static void
2585 push_allocnos_to_stack (void)
2586 {
2587 ira_allocno_t a;
2588 int cost;
2589
2590 /* Calculate uncolorable allocno spill costs. */
2591 for (a = uncolorable_allocno_bucket;
2592 a != NULL;
2593 a = ALLOCNO_COLOR_DATA (a)->next_bucket_allocno)
2594 if (ALLOCNO_CLASS (a) != NO_REGS)
2595 {
2596 cost = calculate_allocno_spill_cost (a);
2597 /* ??? Remove cost of copies between the coalesced
2598 allocnos. */
2599 ALLOCNO_COLOR_DATA (a)->temp = cost;
2600 }
2601 sort_bucket (&uncolorable_allocno_bucket, allocno_spill_sort_compare);
2602 for (;;)
2603 {
2604 push_only_colorable ();
2605 a = uncolorable_allocno_bucket;
2606 if (a == NULL)
2607 break;
2608 remove_allocno_from_bucket_and_push (a, false);
2609 }
2610 ira_assert (colorable_allocno_bucket == NULL
2611 && uncolorable_allocno_bucket == NULL);
2612 ira_assert (uncolorable_allocnos_num == 0);
2613 }
2614
2615 /* Pop the coloring stack and assign hard registers to the popped
2616 allocnos. */
2617 static void
2618 pop_allocnos_from_stack (void)
2619 {
2620 ira_allocno_t allocno;
2621 enum reg_class aclass;
2622
2623 for (;allocno_stack_vec.length () != 0;)
2624 {
2625 allocno = allocno_stack_vec.pop ();
2626 aclass = ALLOCNO_CLASS (allocno);
2627 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2628 {
2629 fprintf (ira_dump_file, " Popping");
2630 ira_print_expanded_allocno (allocno);
2631 fprintf (ira_dump_file, " -- ");
2632 }
2633 if (aclass == NO_REGS)
2634 {
2635 ALLOCNO_HARD_REGNO (allocno) = -1;
2636 ALLOCNO_ASSIGNED_P (allocno) = true;
2637 ira_assert (ALLOCNO_UPDATED_HARD_REG_COSTS (allocno) == NULL);
2638 ira_assert
2639 (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (allocno) == NULL);
2640 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2641 fprintf (ira_dump_file, "assign memory\n");
2642 }
2643 else if (assign_hard_reg (allocno, false))
2644 {
2645 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2646 fprintf (ira_dump_file, "assign reg %d\n",
2647 ALLOCNO_HARD_REGNO (allocno));
2648 }
2649 else if (ALLOCNO_ASSIGNED_P (allocno))
2650 {
2651 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2652 fprintf (ira_dump_file, "spill%s\n",
2653 ALLOCNO_COLOR_DATA (allocno)->may_be_spilled_p
2654 ? "" : "!");
2655 }
2656 ALLOCNO_COLOR_DATA (allocno)->in_graph_p = true;
2657 }
2658 }
2659
2660 /* Set up number of available hard registers for allocno A. */
2661 static void
2662 setup_allocno_available_regs_num (ira_allocno_t a)
2663 {
2664 int i, n, hard_regno, hard_regs_num, nwords;
2665 enum reg_class aclass;
2666 allocno_color_data_t data;
2667
2668 aclass = ALLOCNO_CLASS (a);
2669 data = ALLOCNO_COLOR_DATA (a);
2670 data->available_regs_num = 0;
2671 if (aclass == NO_REGS)
2672 return;
2673 hard_regs_num = ira_class_hard_regs_num[aclass];
2674 nwords = ALLOCNO_NUM_OBJECTS (a);
2675 for (n = 0, i = hard_regs_num - 1; i >= 0; i--)
2676 {
2677 hard_regno = ira_class_hard_regs[aclass][i];
2678 /* Checking only profitable hard regs. */
2679 if (TEST_HARD_REG_BIT (data->profitable_hard_regs, hard_regno))
2680 n++;
2681 }
2682 data->available_regs_num = n;
2683 if (internal_flag_ira_verbose <= 2 || ira_dump_file == NULL)
2684 return;
2685 fprintf
2686 (ira_dump_file,
2687 " Allocno a%dr%d of %s(%d) has %d avail. regs ",
2688 ALLOCNO_NUM (a), ALLOCNO_REGNO (a),
2689 reg_class_names[aclass], ira_class_hard_regs_num[aclass], n);
2690 print_hard_reg_set (ira_dump_file, data->profitable_hard_regs, false);
2691 fprintf (ira_dump_file, ", %snode: ",
2692 data->profitable_hard_regs == data->hard_regs_node->hard_regs->set
2693 ? "" : "^");
2694 print_hard_reg_set (ira_dump_file,
2695 data->hard_regs_node->hard_regs->set, false);
2696 for (i = 0; i < nwords; i++)
2697 {
2698 ira_object_t obj = ALLOCNO_OBJECT (a, i);
2699
2700 if (nwords != 1)
2701 {
2702 if (i != 0)
2703 fprintf (ira_dump_file, ", ");
2704 fprintf (ira_dump_file, " obj %d", i);
2705 }
2706 fprintf (ira_dump_file, " (confl regs = ");
2707 print_hard_reg_set (ira_dump_file, OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
2708 false);
2709 fprintf (ira_dump_file, ")");
2710 }
2711 fprintf (ira_dump_file, "\n");
2712 }
2713
2714 /* Put ALLOCNO in a bucket corresponding to its number and size of its
2715 conflicting allocnos and hard registers. */
2716 static void
2717 put_allocno_into_bucket (ira_allocno_t allocno)
2718 {
2719 ALLOCNO_COLOR_DATA (allocno)->in_graph_p = true;
2720 setup_allocno_available_regs_num (allocno);
2721 if (setup_left_conflict_sizes_p (allocno))
2722 add_allocno_to_bucket (allocno, &colorable_allocno_bucket);
2723 else
2724 add_allocno_to_bucket (allocno, &uncolorable_allocno_bucket);
2725 }
2726
2727 /* Map: allocno number -> allocno priority. */
2728 static int *allocno_priorities;
2729
2730 /* Set up priorities for N allocnos in array
2731 CONSIDERATION_ALLOCNOS. */
2732 static void
2733 setup_allocno_priorities (ira_allocno_t *consideration_allocnos, int n)
2734 {
2735 int i, length, nrefs, priority, max_priority, mult;
2736 ira_allocno_t a;
2737
2738 max_priority = 0;
2739 for (i = 0; i < n; i++)
2740 {
2741 a = consideration_allocnos[i];
2742 nrefs = ALLOCNO_NREFS (a);
2743 ira_assert (nrefs >= 0);
2744 mult = floor_log2 (ALLOCNO_NREFS (a)) + 1;
2745 ira_assert (mult >= 0);
2746 allocno_priorities[ALLOCNO_NUM (a)]
2747 = priority
2748 = (mult
2749 * (ALLOCNO_MEMORY_COST (a) - ALLOCNO_CLASS_COST (a))
2750 * ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]);
2751 if (priority < 0)
2752 priority = -priority;
2753 if (max_priority < priority)
2754 max_priority = priority;
2755 }
2756 mult = max_priority == 0 ? 1 : INT_MAX / max_priority;
2757 for (i = 0; i < n; i++)
2758 {
2759 a = consideration_allocnos[i];
2760 length = ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a);
2761 if (ALLOCNO_NUM_OBJECTS (a) > 1)
2762 length /= ALLOCNO_NUM_OBJECTS (a);
2763 if (length <= 0)
2764 length = 1;
2765 allocno_priorities[ALLOCNO_NUM (a)]
2766 = allocno_priorities[ALLOCNO_NUM (a)] * mult / length;
2767 }
2768 }
2769
2770 /* Sort allocnos according to the profit of usage of a hard register
2771 instead of memory for them. */
2772 static int
2773 allocno_cost_compare_func (const void *v1p, const void *v2p)
2774 {
2775 ira_allocno_t p1 = *(const ira_allocno_t *) v1p;
2776 ira_allocno_t p2 = *(const ira_allocno_t *) v2p;
2777 int c1, c2;
2778
2779 c1 = ALLOCNO_UPDATED_MEMORY_COST (p1) - ALLOCNO_UPDATED_CLASS_COST (p1);
2780 c2 = ALLOCNO_UPDATED_MEMORY_COST (p2) - ALLOCNO_UPDATED_CLASS_COST (p2);
2781 if (c1 - c2)
2782 return c1 - c2;
2783
2784 /* If regs are equally good, sort by allocno numbers, so that the
2785 results of qsort leave nothing to chance. */
2786 return ALLOCNO_NUM (p1) - ALLOCNO_NUM (p2);
2787 }
2788
2789 /* Return savings on removed copies when ALLOCNO is assigned to
2790 HARD_REGNO. */
2791 static int
2792 allocno_copy_cost_saving (ira_allocno_t allocno, int hard_regno)
2793 {
2794 int cost = 0;
2795 machine_mode allocno_mode = ALLOCNO_MODE (allocno);
2796 enum reg_class rclass;
2797 ira_copy_t cp, next_cp;
2798
2799 rclass = REGNO_REG_CLASS (hard_regno);
2800 if (ira_reg_class_max_nregs[rclass][allocno_mode]
2801 > ira_class_hard_regs_num[rclass])
2802 /* For the above condition the cost can be wrong. Use the allocno
2803 class in this case. */
2804 rclass = ALLOCNO_CLASS (allocno);
2805 for (cp = ALLOCNO_COPIES (allocno); cp != NULL; cp = next_cp)
2806 {
2807 if (cp->first == allocno)
2808 {
2809 next_cp = cp->next_first_allocno_copy;
2810 if (ALLOCNO_HARD_REGNO (cp->second) != hard_regno)
2811 continue;
2812 }
2813 else if (cp->second == allocno)
2814 {
2815 next_cp = cp->next_second_allocno_copy;
2816 if (ALLOCNO_HARD_REGNO (cp->first) != hard_regno)
2817 continue;
2818 }
2819 else
2820 gcc_unreachable ();
2821 ira_init_register_move_cost_if_necessary (allocno_mode);
2822 cost += cp->freq * ira_register_move_cost[allocno_mode][rclass][rclass];
2823 }
2824 return cost;
2825 }
2826
2827 /* We used Chaitin-Briggs coloring to assign as many pseudos as
2828 possible to hard registers. Let us try to improve allocation with
2829 cost point of view. This function improves the allocation by
2830 spilling some allocnos and assigning the freed hard registers to
2831 other allocnos if it decreases the overall allocation cost. */
2832 static void
2833 improve_allocation (void)
2834 {
2835 unsigned int i;
2836 int j, k, n, hregno, conflict_hregno, base_cost, class_size, word, nwords;
2837 int check, spill_cost, min_cost, nregs, conflict_nregs, r, best;
2838 bool try_p;
2839 enum reg_class aclass;
2840 machine_mode mode;
2841 int *allocno_costs;
2842 int costs[FIRST_PSEUDO_REGISTER];
2843 HARD_REG_SET conflicting_regs[2], profitable_hard_regs;
2844 ira_allocno_t a;
2845 bitmap_iterator bi;
2846
2847 /* Don't bother to optimize the code with static chain pointer and
2848 non-local goto in order not to spill the chain pointer
2849 pseudo. */
2850 if (cfun->static_chain_decl && crtl->has_nonlocal_goto)
2851 return;
2852 /* Clear counts used to process conflicting allocnos only once for
2853 each allocno. */
2854 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
2855 ALLOCNO_COLOR_DATA (ira_allocnos[i])->temp = 0;
2856 check = n = 0;
2857 /* Process each allocno and try to assign a hard register to it by
2858 spilling some its conflicting allocnos. */
2859 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
2860 {
2861 a = ira_allocnos[i];
2862 ALLOCNO_COLOR_DATA (a)->temp = 0;
2863 if (empty_profitable_hard_regs (a))
2864 continue;
2865 check++;
2866 aclass = ALLOCNO_CLASS (a);
2867 allocno_costs = ALLOCNO_HARD_REG_COSTS (a);
2868 if ((hregno = ALLOCNO_HARD_REGNO (a)) < 0)
2869 base_cost = ALLOCNO_UPDATED_MEMORY_COST (a);
2870 else if (allocno_costs == NULL)
2871 /* It means that assigning a hard register is not profitable
2872 (we don't waste memory for hard register costs in this
2873 case). */
2874 continue;
2875 else
2876 base_cost = (allocno_costs[ira_class_hard_reg_index[aclass][hregno]]
2877 - allocno_copy_cost_saving (a, hregno));
2878 try_p = false;
2879 get_conflict_and_start_profitable_regs (a, false,
2880 conflicting_regs,
2881 &profitable_hard_regs);
2882 class_size = ira_class_hard_regs_num[aclass];
2883 /* Set up cost improvement for usage of each profitable hard
2884 register for allocno A. */
2885 for (j = 0; j < class_size; j++)
2886 {
2887 hregno = ira_class_hard_regs[aclass][j];
2888 if (! check_hard_reg_p (a, hregno,
2889 conflicting_regs, profitable_hard_regs))
2890 continue;
2891 ira_assert (ira_class_hard_reg_index[aclass][hregno] == j);
2892 k = allocno_costs == NULL ? 0 : j;
2893 costs[hregno] = (allocno_costs == NULL
2894 ? ALLOCNO_UPDATED_CLASS_COST (a) : allocno_costs[k]);
2895 costs[hregno] -= allocno_copy_cost_saving (a, hregno);
2896 costs[hregno] -= base_cost;
2897 if (costs[hregno] < 0)
2898 try_p = true;
2899 }
2900 if (! try_p)
2901 /* There is no chance to improve the allocation cost by
2902 assigning hard register to allocno A even without spilling
2903 conflicting allocnos. */
2904 continue;
2905 mode = ALLOCNO_MODE (a);
2906 nwords = ALLOCNO_NUM_OBJECTS (a);
2907 /* Process each allocno conflicting with A and update the cost
2908 improvement for profitable hard registers of A. To use a
2909 hard register for A we need to spill some conflicting
2910 allocnos and that creates penalty for the cost
2911 improvement. */
2912 for (word = 0; word < nwords; word++)
2913 {
2914 ira_object_t conflict_obj;
2915 ira_object_t obj = ALLOCNO_OBJECT (a, word);
2916 ira_object_conflict_iterator oci;
2917
2918 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
2919 {
2920 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
2921
2922 if (ALLOCNO_COLOR_DATA (conflict_a)->temp == check)
2923 /* We already processed this conflicting allocno
2924 because we processed earlier another object of the
2925 conflicting allocno. */
2926 continue;
2927 ALLOCNO_COLOR_DATA (conflict_a)->temp = check;
2928 if ((conflict_hregno = ALLOCNO_HARD_REGNO (conflict_a)) < 0)
2929 continue;
2930 spill_cost = ALLOCNO_UPDATED_MEMORY_COST (conflict_a);
2931 k = (ira_class_hard_reg_index
2932 [ALLOCNO_CLASS (conflict_a)][conflict_hregno]);
2933 ira_assert (k >= 0);
2934 if ((allocno_costs = ALLOCNO_HARD_REG_COSTS (conflict_a))
2935 != NULL)
2936 spill_cost -= allocno_costs[k];
2937 else
2938 spill_cost -= ALLOCNO_UPDATED_CLASS_COST (conflict_a);
2939 spill_cost
2940 += allocno_copy_cost_saving (conflict_a, conflict_hregno);
2941 conflict_nregs = hard_regno_nregs (conflict_hregno,
2942 ALLOCNO_MODE (conflict_a));
2943 for (r = conflict_hregno;
2944 r >= 0 && (int) end_hard_regno (mode, r) > conflict_hregno;
2945 r--)
2946 if (check_hard_reg_p (a, r,
2947 conflicting_regs, profitable_hard_regs))
2948 costs[r] += spill_cost;
2949 for (r = conflict_hregno + 1;
2950 r < conflict_hregno + conflict_nregs;
2951 r++)
2952 if (check_hard_reg_p (a, r,
2953 conflicting_regs, profitable_hard_regs))
2954 costs[r] += spill_cost;
2955 }
2956 }
2957 min_cost = INT_MAX;
2958 best = -1;
2959 /* Now we choose hard register for A which results in highest
2960 allocation cost improvement. */
2961 for (j = 0; j < class_size; j++)
2962 {
2963 hregno = ira_class_hard_regs[aclass][j];
2964 if (check_hard_reg_p (a, hregno,
2965 conflicting_regs, profitable_hard_regs)
2966 && min_cost > costs[hregno])
2967 {
2968 best = hregno;
2969 min_cost = costs[hregno];
2970 }
2971 }
2972 if (min_cost >= 0)
2973 /* We are in a situation when assigning any hard register to A
2974 by spilling some conflicting allocnos does not improve the
2975 allocation cost. */
2976 continue;
2977 nregs = hard_regno_nregs (best, mode);
2978 /* Now spill conflicting allocnos which contain a hard register
2979 of A when we assign the best chosen hard register to it. */
2980 for (word = 0; word < nwords; word++)
2981 {
2982 ira_object_t conflict_obj;
2983 ira_object_t obj = ALLOCNO_OBJECT (a, word);
2984 ira_object_conflict_iterator oci;
2985
2986 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
2987 {
2988 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
2989
2990 if ((conflict_hregno = ALLOCNO_HARD_REGNO (conflict_a)) < 0)
2991 continue;
2992 conflict_nregs = hard_regno_nregs (conflict_hregno,
2993 ALLOCNO_MODE (conflict_a));
2994 if (best + nregs <= conflict_hregno
2995 || conflict_hregno + conflict_nregs <= best)
2996 /* No intersection. */
2997 continue;
2998 ALLOCNO_HARD_REGNO (conflict_a) = -1;
2999 sorted_allocnos[n++] = conflict_a;
3000 if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
3001 fprintf (ira_dump_file, "Spilling a%dr%d for a%dr%d\n",
3002 ALLOCNO_NUM (conflict_a), ALLOCNO_REGNO (conflict_a),
3003 ALLOCNO_NUM (a), ALLOCNO_REGNO (a));
3004 }
3005 }
3006 /* Assign the best chosen hard register to A. */
3007 ALLOCNO_HARD_REGNO (a) = best;
3008 if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
3009 fprintf (ira_dump_file, "Assigning %d to a%dr%d\n",
3010 best, ALLOCNO_NUM (a), ALLOCNO_REGNO (a));
3011 }
3012 if (n == 0)
3013 return;
3014 /* We spilled some allocnos to assign their hard registers to other
3015 allocnos. The spilled allocnos are now in array
3016 'sorted_allocnos'. There is still a possibility that some of the
3017 spilled allocnos can get hard registers. So let us try assign
3018 them hard registers again (just a reminder -- function
3019 'assign_hard_reg' assigns hard registers only if it is possible
3020 and profitable). We process the spilled allocnos with biggest
3021 benefit to get hard register first -- see function
3022 'allocno_cost_compare_func'. */
3023 qsort (sorted_allocnos, n, sizeof (ira_allocno_t),
3024 allocno_cost_compare_func);
3025 for (j = 0; j < n; j++)
3026 {
3027 a = sorted_allocnos[j];
3028 ALLOCNO_ASSIGNED_P (a) = false;
3029 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3030 {
3031 fprintf (ira_dump_file, " ");
3032 ira_print_expanded_allocno (a);
3033 fprintf (ira_dump_file, " -- ");
3034 }
3035 if (assign_hard_reg (a, false))
3036 {
3037 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3038 fprintf (ira_dump_file, "assign hard reg %d\n",
3039 ALLOCNO_HARD_REGNO (a));
3040 }
3041 else
3042 {
3043 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3044 fprintf (ira_dump_file, "assign memory\n");
3045 }
3046 }
3047 }
3048
3049 /* Sort allocnos according to their priorities. */
3050 static int
3051 allocno_priority_compare_func (const void *v1p, const void *v2p)
3052 {
3053 ira_allocno_t a1 = *(const ira_allocno_t *) v1p;
3054 ira_allocno_t a2 = *(const ira_allocno_t *) v2p;
3055 int pri1, pri2, diff;
3056
3057 /* Assign hard reg to static chain pointer pseudo first when
3058 non-local goto is used. */
3059 if ((diff = (non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a2))
3060 - non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a1)))) != 0)
3061 return diff;
3062 pri1 = allocno_priorities[ALLOCNO_NUM (a1)];
3063 pri2 = allocno_priorities[ALLOCNO_NUM (a2)];
3064 if (pri2 != pri1)
3065 return SORTGT (pri2, pri1);
3066
3067 /* If regs are equally good, sort by allocnos, so that the results of
3068 qsort leave nothing to chance. */
3069 return ALLOCNO_NUM (a1) - ALLOCNO_NUM (a2);
3070 }
3071
3072 /* Chaitin-Briggs coloring for allocnos in COLORING_ALLOCNO_BITMAP
3073 taking into account allocnos in CONSIDERATION_ALLOCNO_BITMAP. */
3074 static void
3075 color_allocnos (void)
3076 {
3077 unsigned int i, n;
3078 bitmap_iterator bi;
3079 ira_allocno_t a;
3080
3081 setup_profitable_hard_regs ();
3082 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
3083 {
3084 allocno_color_data_t data;
3085 ira_pref_t pref, next_pref;
3086
3087 a = ira_allocnos[i];
3088 data = ALLOCNO_COLOR_DATA (a);
3089 data->conflict_allocno_hard_prefs = 0;
3090 for (pref = ALLOCNO_PREFS (a); pref != NULL; pref = next_pref)
3091 {
3092 next_pref = pref->next_pref;
3093 if (! ira_hard_reg_in_set_p (pref->hard_regno,
3094 ALLOCNO_MODE (a),
3095 data->profitable_hard_regs))
3096 ira_remove_pref (pref);
3097 }
3098 }
3099
3100 if (flag_ira_algorithm == IRA_ALGORITHM_PRIORITY)
3101 {
3102 n = 0;
3103 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
3104 {
3105 a = ira_allocnos[i];
3106 if (ALLOCNO_CLASS (a) == NO_REGS)
3107 {
3108 ALLOCNO_HARD_REGNO (a) = -1;
3109 ALLOCNO_ASSIGNED_P (a) = true;
3110 ira_assert (ALLOCNO_UPDATED_HARD_REG_COSTS (a) == NULL);
3111 ira_assert (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a) == NULL);
3112 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3113 {
3114 fprintf (ira_dump_file, " Spill");
3115 ira_print_expanded_allocno (a);
3116 fprintf (ira_dump_file, "\n");
3117 }
3118 continue;
3119 }
3120 sorted_allocnos[n++] = a;
3121 }
3122 if (n != 0)
3123 {
3124 setup_allocno_priorities (sorted_allocnos, n);
3125 qsort (sorted_allocnos, n, sizeof (ira_allocno_t),
3126 allocno_priority_compare_func);
3127 for (i = 0; i < n; i++)
3128 {
3129 a = sorted_allocnos[i];
3130 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3131 {
3132 fprintf (ira_dump_file, " ");
3133 ira_print_expanded_allocno (a);
3134 fprintf (ira_dump_file, " -- ");
3135 }
3136 if (assign_hard_reg (a, false))
3137 {
3138 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3139 fprintf (ira_dump_file, "assign hard reg %d\n",
3140 ALLOCNO_HARD_REGNO (a));
3141 }
3142 else
3143 {
3144 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3145 fprintf (ira_dump_file, "assign memory\n");
3146 }
3147 }
3148 }
3149 }
3150 else
3151 {
3152 form_allocno_hard_regs_nodes_forest ();
3153 if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
3154 print_hard_regs_forest (ira_dump_file);
3155 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
3156 {
3157 a = ira_allocnos[i];
3158 if (ALLOCNO_CLASS (a) != NO_REGS && ! empty_profitable_hard_regs (a))
3159 {
3160 ALLOCNO_COLOR_DATA (a)->in_graph_p = true;
3161 update_costs_from_prefs (a);
3162 update_conflict_allocno_hard_prefs (a);
3163 }
3164 else
3165 {
3166 ALLOCNO_HARD_REGNO (a) = -1;
3167 ALLOCNO_ASSIGNED_P (a) = true;
3168 /* We don't need updated costs anymore. */
3169 ira_free_allocno_updated_costs (a);
3170 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3171 {
3172 fprintf (ira_dump_file, " Spill");
3173 ira_print_expanded_allocno (a);
3174 fprintf (ira_dump_file, "\n");
3175 }
3176 }
3177 }
3178 /* Put the allocnos into the corresponding buckets. */
3179 colorable_allocno_bucket = NULL;
3180 uncolorable_allocno_bucket = NULL;
3181 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
3182 {
3183 a = ira_allocnos[i];
3184 if (ALLOCNO_COLOR_DATA (a)->in_graph_p)
3185 put_allocno_into_bucket (a);
3186 }
3187 push_allocnos_to_stack ();
3188 pop_allocnos_from_stack ();
3189 finish_allocno_hard_regs_nodes_forest ();
3190 }
3191 improve_allocation ();
3192 }
3193
3194 \f
3195
3196 /* Output information about the loop given by its LOOP_TREE_NODE. */
3197 static void
3198 print_loop_title (ira_loop_tree_node_t loop_tree_node)
3199 {
3200 unsigned int j;
3201 bitmap_iterator bi;
3202 ira_loop_tree_node_t subloop_node, dest_loop_node;
3203 edge e;
3204 edge_iterator ei;
3205
3206 if (loop_tree_node->parent == NULL)
3207 fprintf (ira_dump_file,
3208 "\n Loop 0 (parent -1, header bb%d, depth 0)\n bbs:",
3209 NUM_FIXED_BLOCKS);
3210 else
3211 {
3212 ira_assert (current_loops != NULL && loop_tree_node->loop != NULL);
3213 fprintf (ira_dump_file,
3214 "\n Loop %d (parent %d, header bb%d, depth %d)\n bbs:",
3215 loop_tree_node->loop_num, loop_tree_node->parent->loop_num,
3216 loop_tree_node->loop->header->index,
3217 loop_depth (loop_tree_node->loop));
3218 }
3219 for (subloop_node = loop_tree_node->children;
3220 subloop_node != NULL;
3221 subloop_node = subloop_node->next)
3222 if (subloop_node->bb != NULL)
3223 {
3224 fprintf (ira_dump_file, " %d", subloop_node->bb->index);
3225 FOR_EACH_EDGE (e, ei, subloop_node->bb->succs)
3226 if (e->dest != EXIT_BLOCK_PTR_FOR_FN (cfun)
3227 && ((dest_loop_node = IRA_BB_NODE (e->dest)->parent)
3228 != loop_tree_node))
3229 fprintf (ira_dump_file, "(->%d:l%d)",
3230 e->dest->index, dest_loop_node->loop_num);
3231 }
3232 fprintf (ira_dump_file, "\n all:");
3233 EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->all_allocnos, 0, j, bi)
3234 fprintf (ira_dump_file, " %dr%d", j, ALLOCNO_REGNO (ira_allocnos[j]));
3235 fprintf (ira_dump_file, "\n modified regnos:");
3236 EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->modified_regnos, 0, j, bi)
3237 fprintf (ira_dump_file, " %d", j);
3238 fprintf (ira_dump_file, "\n border:");
3239 EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->border_allocnos, 0, j, bi)
3240 fprintf (ira_dump_file, " %dr%d", j, ALLOCNO_REGNO (ira_allocnos[j]));
3241 fprintf (ira_dump_file, "\n Pressure:");
3242 for (j = 0; (int) j < ira_pressure_classes_num; j++)
3243 {
3244 enum reg_class pclass;
3245
3246 pclass = ira_pressure_classes[j];
3247 if (loop_tree_node->reg_pressure[pclass] == 0)
3248 continue;
3249 fprintf (ira_dump_file, " %s=%d", reg_class_names[pclass],
3250 loop_tree_node->reg_pressure[pclass]);
3251 }
3252 fprintf (ira_dump_file, "\n");
3253 }
3254
3255 /* Color the allocnos inside loop (in the extreme case it can be all
3256 of the function) given the corresponding LOOP_TREE_NODE. The
3257 function is called for each loop during top-down traverse of the
3258 loop tree. */
3259 static void
3260 color_pass (ira_loop_tree_node_t loop_tree_node)
3261 {
3262 int regno, hard_regno, index = -1, n;
3263 int cost, exit_freq, enter_freq;
3264 unsigned int j;
3265 bitmap_iterator bi;
3266 machine_mode mode;
3267 enum reg_class rclass, aclass, pclass;
3268 ira_allocno_t a, subloop_allocno;
3269 ira_loop_tree_node_t subloop_node;
3270
3271 ira_assert (loop_tree_node->bb == NULL);
3272 if (internal_flag_ira_verbose > 1 && ira_dump_file != NULL)
3273 print_loop_title (loop_tree_node);
3274
3275 bitmap_copy (coloring_allocno_bitmap, loop_tree_node->all_allocnos);
3276 bitmap_copy (consideration_allocno_bitmap, coloring_allocno_bitmap);
3277 n = 0;
3278 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
3279 {
3280 a = ira_allocnos[j];
3281 n++;
3282 if (! ALLOCNO_ASSIGNED_P (a))
3283 continue;
3284 bitmap_clear_bit (coloring_allocno_bitmap, ALLOCNO_NUM (a));
3285 }
3286 allocno_color_data
3287 = (allocno_color_data_t) ira_allocate (sizeof (struct allocno_color_data)
3288 * n);
3289 memset (allocno_color_data, 0, sizeof (struct allocno_color_data) * n);
3290 curr_allocno_process = 0;
3291 n = 0;
3292 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
3293 {
3294 a = ira_allocnos[j];
3295 ALLOCNO_ADD_DATA (a) = allocno_color_data + n;
3296 n++;
3297 }
3298 init_allocno_threads ();
3299 /* Color all mentioned allocnos including transparent ones. */
3300 color_allocnos ();
3301 /* Process caps. They are processed just once. */
3302 if (flag_ira_region == IRA_REGION_MIXED
3303 || flag_ira_region == IRA_REGION_ALL)
3304 EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->all_allocnos, 0, j, bi)
3305 {
3306 a = ira_allocnos[j];
3307 if (ALLOCNO_CAP_MEMBER (a) == NULL)
3308 continue;
3309 /* Remove from processing in the next loop. */
3310 bitmap_clear_bit (consideration_allocno_bitmap, j);
3311 rclass = ALLOCNO_CLASS (a);
3312 pclass = ira_pressure_class_translate[rclass];
3313 if (flag_ira_region == IRA_REGION_MIXED
3314 && (loop_tree_node->reg_pressure[pclass]
3315 <= ira_class_hard_regs_num[pclass]))
3316 {
3317 mode = ALLOCNO_MODE (a);
3318 hard_regno = ALLOCNO_HARD_REGNO (a);
3319 if (hard_regno >= 0)
3320 {
3321 index = ira_class_hard_reg_index[rclass][hard_regno];
3322 ira_assert (index >= 0);
3323 }
3324 regno = ALLOCNO_REGNO (a);
3325 subloop_allocno = ALLOCNO_CAP_MEMBER (a);
3326 subloop_node = ALLOCNO_LOOP_TREE_NODE (subloop_allocno);
3327 ira_assert (!ALLOCNO_ASSIGNED_P (subloop_allocno));
3328 ALLOCNO_HARD_REGNO (subloop_allocno) = hard_regno;
3329 ALLOCNO_ASSIGNED_P (subloop_allocno) = true;
3330 if (hard_regno >= 0)
3331 update_costs_from_copies (subloop_allocno, true, true);
3332 /* We don't need updated costs anymore. */
3333 ira_free_allocno_updated_costs (subloop_allocno);
3334 }
3335 }
3336 /* Update costs of the corresponding allocnos (not caps) in the
3337 subloops. */
3338 for (subloop_node = loop_tree_node->subloops;
3339 subloop_node != NULL;
3340 subloop_node = subloop_node->subloop_next)
3341 {
3342 ira_assert (subloop_node->bb == NULL);
3343 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
3344 {
3345 a = ira_allocnos[j];
3346 ira_assert (ALLOCNO_CAP_MEMBER (a) == NULL);
3347 mode = ALLOCNO_MODE (a);
3348 rclass = ALLOCNO_CLASS (a);
3349 pclass = ira_pressure_class_translate[rclass];
3350 hard_regno = ALLOCNO_HARD_REGNO (a);
3351 /* Use hard register class here. ??? */
3352 if (hard_regno >= 0)
3353 {
3354 index = ira_class_hard_reg_index[rclass][hard_regno];
3355 ira_assert (index >= 0);
3356 }
3357 regno = ALLOCNO_REGNO (a);
3358 /* ??? conflict costs */
3359 subloop_allocno = subloop_node->regno_allocno_map[regno];
3360 if (subloop_allocno == NULL
3361 || ALLOCNO_CAP (subloop_allocno) != NULL)
3362 continue;
3363 ira_assert (ALLOCNO_CLASS (subloop_allocno) == rclass);
3364 ira_assert (bitmap_bit_p (subloop_node->all_allocnos,
3365 ALLOCNO_NUM (subloop_allocno)));
3366 if ((flag_ira_region == IRA_REGION_MIXED
3367 && (loop_tree_node->reg_pressure[pclass]
3368 <= ira_class_hard_regs_num[pclass]))
3369 || (pic_offset_table_rtx != NULL
3370 && regno == (int) REGNO (pic_offset_table_rtx))
3371 /* Avoid overlapped multi-registers. Moves between them
3372 might result in wrong code generation. */
3373 || (hard_regno >= 0
3374 && ira_reg_class_max_nregs[pclass][mode] > 1))
3375 {
3376 if (! ALLOCNO_ASSIGNED_P (subloop_allocno))
3377 {
3378 ALLOCNO_HARD_REGNO (subloop_allocno) = hard_regno;
3379 ALLOCNO_ASSIGNED_P (subloop_allocno) = true;
3380 if (hard_regno >= 0)
3381 update_costs_from_copies (subloop_allocno, true, true);
3382 /* We don't need updated costs anymore. */
3383 ira_free_allocno_updated_costs (subloop_allocno);
3384 }
3385 continue;
3386 }
3387 exit_freq = ira_loop_edge_freq (subloop_node, regno, true);
3388 enter_freq = ira_loop_edge_freq (subloop_node, regno, false);
3389 ira_assert (regno < ira_reg_equiv_len);
3390 if (ira_equiv_no_lvalue_p (regno))
3391 {
3392 if (! ALLOCNO_ASSIGNED_P (subloop_allocno))
3393 {
3394 ALLOCNO_HARD_REGNO (subloop_allocno) = hard_regno;
3395 ALLOCNO_ASSIGNED_P (subloop_allocno) = true;
3396 if (hard_regno >= 0)
3397 update_costs_from_copies (subloop_allocno, true, true);
3398 /* We don't need updated costs anymore. */
3399 ira_free_allocno_updated_costs (subloop_allocno);
3400 }
3401 }
3402 else if (hard_regno < 0)
3403 {
3404 ALLOCNO_UPDATED_MEMORY_COST (subloop_allocno)
3405 -= ((ira_memory_move_cost[mode][rclass][1] * enter_freq)
3406 + (ira_memory_move_cost[mode][rclass][0] * exit_freq));
3407 }
3408 else
3409 {
3410 aclass = ALLOCNO_CLASS (subloop_allocno);
3411 ira_init_register_move_cost_if_necessary (mode);
3412 cost = (ira_register_move_cost[mode][rclass][rclass]
3413 * (exit_freq + enter_freq));
3414 ira_allocate_and_set_or_copy_costs
3415 (&ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno), aclass,
3416 ALLOCNO_UPDATED_CLASS_COST (subloop_allocno),
3417 ALLOCNO_HARD_REG_COSTS (subloop_allocno));
3418 ira_allocate_and_set_or_copy_costs
3419 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (subloop_allocno),
3420 aclass, 0, ALLOCNO_CONFLICT_HARD_REG_COSTS (subloop_allocno));
3421 ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno)[index] -= cost;
3422 ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (subloop_allocno)[index]
3423 -= cost;
3424 if (ALLOCNO_UPDATED_CLASS_COST (subloop_allocno)
3425 > ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno)[index])
3426 ALLOCNO_UPDATED_CLASS_COST (subloop_allocno)
3427 = ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno)[index];
3428 ALLOCNO_UPDATED_MEMORY_COST (subloop_allocno)
3429 += (ira_memory_move_cost[mode][rclass][0] * enter_freq
3430 + ira_memory_move_cost[mode][rclass][1] * exit_freq);
3431 }
3432 }
3433 }
3434 ira_free (allocno_color_data);
3435 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
3436 {
3437 a = ira_allocnos[j];
3438 ALLOCNO_ADD_DATA (a) = NULL;
3439 }
3440 }
3441
3442 /* Initialize the common data for coloring and calls functions to do
3443 Chaitin-Briggs and regional coloring. */
3444 static void
3445 do_coloring (void)
3446 {
3447 coloring_allocno_bitmap = ira_allocate_bitmap ();
3448 if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
3449 fprintf (ira_dump_file, "\n**** Allocnos coloring:\n\n");
3450
3451 ira_traverse_loop_tree (false, ira_loop_tree_root, color_pass, NULL);
3452
3453 if (internal_flag_ira_verbose > 1 && ira_dump_file != NULL)
3454 ira_print_disposition (ira_dump_file);
3455
3456 ira_free_bitmap (coloring_allocno_bitmap);
3457 }
3458
3459 \f
3460
3461 /* Move spill/restore code, which are to be generated in ira-emit.c,
3462 to less frequent points (if it is profitable) by reassigning some
3463 allocnos (in loop with subloops containing in another loop) to
3464 memory which results in longer live-range where the corresponding
3465 pseudo-registers will be in memory. */
3466 static void
3467 move_spill_restore (void)
3468 {
3469 int cost, regno, hard_regno, hard_regno2, index;
3470 bool changed_p;
3471 int enter_freq, exit_freq;
3472 machine_mode mode;
3473 enum reg_class rclass;
3474 ira_allocno_t a, parent_allocno, subloop_allocno;
3475 ira_loop_tree_node_t parent, loop_node, subloop_node;
3476 ira_allocno_iterator ai;
3477
3478 for (;;)
3479 {
3480 changed_p = false;
3481 if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
3482 fprintf (ira_dump_file, "New iteration of spill/restore move\n");
3483 FOR_EACH_ALLOCNO (a, ai)
3484 {
3485 regno = ALLOCNO_REGNO (a);
3486 loop_node = ALLOCNO_LOOP_TREE_NODE (a);
3487 if (ALLOCNO_CAP_MEMBER (a) != NULL
3488 || ALLOCNO_CAP (a) != NULL
3489 || (hard_regno = ALLOCNO_HARD_REGNO (a)) < 0
3490 || loop_node->children == NULL
3491 /* don't do the optimization because it can create
3492 copies and the reload pass can spill the allocno set
3493 by copy although the allocno will not get memory
3494 slot. */
3495 || ira_equiv_no_lvalue_p (regno)
3496 || !bitmap_bit_p (loop_node->border_allocnos, ALLOCNO_NUM (a))
3497 /* Do not spill static chain pointer pseudo when
3498 non-local goto is used. */
3499 || non_spilled_static_chain_regno_p (regno))
3500 continue;
3501 mode = ALLOCNO_MODE (a);
3502 rclass = ALLOCNO_CLASS (a);
3503 index = ira_class_hard_reg_index[rclass][hard_regno];
3504 ira_assert (index >= 0);
3505 cost = (ALLOCNO_MEMORY_COST (a)
3506 - (ALLOCNO_HARD_REG_COSTS (a) == NULL
3507 ? ALLOCNO_CLASS_COST (a)
3508 : ALLOCNO_HARD_REG_COSTS (a)[index]));
3509 ira_init_register_move_cost_if_necessary (mode);
3510 for (subloop_node = loop_node->subloops;
3511 subloop_node != NULL;
3512 subloop_node = subloop_node->subloop_next)
3513 {
3514 ira_assert (subloop_node->bb == NULL);
3515 subloop_allocno = subloop_node->regno_allocno_map[regno];
3516 if (subloop_allocno == NULL)
3517 continue;
3518 ira_assert (rclass == ALLOCNO_CLASS (subloop_allocno));
3519 /* We have accumulated cost. To get the real cost of
3520 allocno usage in the loop we should subtract costs of
3521 the subloop allocnos. */
3522 cost -= (ALLOCNO_MEMORY_COST (subloop_allocno)
3523 - (ALLOCNO_HARD_REG_COSTS (subloop_allocno) == NULL
3524 ? ALLOCNO_CLASS_COST (subloop_allocno)
3525 : ALLOCNO_HARD_REG_COSTS (subloop_allocno)[index]));
3526 exit_freq = ira_loop_edge_freq (subloop_node, regno, true);
3527 enter_freq = ira_loop_edge_freq (subloop_node, regno, false);
3528 if ((hard_regno2 = ALLOCNO_HARD_REGNO (subloop_allocno)) < 0)
3529 cost -= (ira_memory_move_cost[mode][rclass][0] * exit_freq
3530 + ira_memory_move_cost[mode][rclass][1] * enter_freq);
3531 else
3532 {
3533 cost
3534 += (ira_memory_move_cost[mode][rclass][0] * exit_freq
3535 + ira_memory_move_cost[mode][rclass][1] * enter_freq);
3536 if (hard_regno2 != hard_regno)
3537 cost -= (ira_register_move_cost[mode][rclass][rclass]
3538 * (exit_freq + enter_freq));
3539 }
3540 }
3541 if ((parent = loop_node->parent) != NULL
3542 && (parent_allocno = parent->regno_allocno_map[regno]) != NULL)
3543 {
3544 ira_assert (rclass == ALLOCNO_CLASS (parent_allocno));
3545 exit_freq = ira_loop_edge_freq (loop_node, regno, true);
3546 enter_freq = ira_loop_edge_freq (loop_node, regno, false);
3547 if ((hard_regno2 = ALLOCNO_HARD_REGNO (parent_allocno)) < 0)
3548 cost -= (ira_memory_move_cost[mode][rclass][0] * exit_freq
3549 + ira_memory_move_cost[mode][rclass][1] * enter_freq);
3550 else
3551 {
3552 cost
3553 += (ira_memory_move_cost[mode][rclass][1] * exit_freq
3554 + ira_memory_move_cost[mode][rclass][0] * enter_freq);
3555 if (hard_regno2 != hard_regno)
3556 cost -= (ira_register_move_cost[mode][rclass][rclass]
3557 * (exit_freq + enter_freq));
3558 }
3559 }
3560 if (cost < 0)
3561 {
3562 ALLOCNO_HARD_REGNO (a) = -1;
3563 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3564 {
3565 fprintf
3566 (ira_dump_file,
3567 " Moving spill/restore for a%dr%d up from loop %d",
3568 ALLOCNO_NUM (a), regno, loop_node->loop_num);
3569 fprintf (ira_dump_file, " - profit %d\n", -cost);
3570 }
3571 changed_p = true;
3572 }
3573 }
3574 if (! changed_p)
3575 break;
3576 }
3577 }
3578
3579 \f
3580
3581 /* Update current hard reg costs and current conflict hard reg costs
3582 for allocno A. It is done by processing its copies containing
3583 other allocnos already assigned. */
3584 static void
3585 update_curr_costs (ira_allocno_t a)
3586 {
3587 int i, hard_regno, cost;
3588 machine_mode mode;
3589 enum reg_class aclass, rclass;
3590 ira_allocno_t another_a;
3591 ira_copy_t cp, next_cp;
3592
3593 ira_free_allocno_updated_costs (a);
3594 ira_assert (! ALLOCNO_ASSIGNED_P (a));
3595 aclass = ALLOCNO_CLASS (a);
3596 if (aclass == NO_REGS)
3597 return;
3598 mode = ALLOCNO_MODE (a);
3599 ira_init_register_move_cost_if_necessary (mode);
3600 for (cp = ALLOCNO_COPIES (a); cp != NULL; cp = next_cp)
3601 {
3602 if (cp->first == a)
3603 {
3604 next_cp = cp->next_first_allocno_copy;
3605 another_a = cp->second;
3606 }
3607 else if (cp->second == a)
3608 {
3609 next_cp = cp->next_second_allocno_copy;
3610 another_a = cp->first;
3611 }
3612 else
3613 gcc_unreachable ();
3614 if (! ira_reg_classes_intersect_p[aclass][ALLOCNO_CLASS (another_a)]
3615 || ! ALLOCNO_ASSIGNED_P (another_a)
3616 || (hard_regno = ALLOCNO_HARD_REGNO (another_a)) < 0)
3617 continue;
3618 rclass = REGNO_REG_CLASS (hard_regno);
3619 i = ira_class_hard_reg_index[aclass][hard_regno];
3620 if (i < 0)
3621 continue;
3622 cost = (cp->first == a
3623 ? ira_register_move_cost[mode][rclass][aclass]
3624 : ira_register_move_cost[mode][aclass][rclass]);
3625 ira_allocate_and_set_or_copy_costs
3626 (&ALLOCNO_UPDATED_HARD_REG_COSTS (a), aclass, ALLOCNO_CLASS_COST (a),
3627 ALLOCNO_HARD_REG_COSTS (a));
3628 ira_allocate_and_set_or_copy_costs
3629 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a),
3630 aclass, 0, ALLOCNO_CONFLICT_HARD_REG_COSTS (a));
3631 ALLOCNO_UPDATED_HARD_REG_COSTS (a)[i] -= cp->freq * cost;
3632 ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a)[i] -= cp->freq * cost;
3633 }
3634 }
3635
3636 /* Try to assign hard registers to the unassigned allocnos and
3637 allocnos conflicting with them or conflicting with allocnos whose
3638 regno >= START_REGNO. The function is called after ira_flattening,
3639 so more allocnos (including ones created in ira-emit.c) will have a
3640 chance to get a hard register. We use simple assignment algorithm
3641 based on priorities. */
3642 void
3643 ira_reassign_conflict_allocnos (int start_regno)
3644 {
3645 int i, allocnos_to_color_num;
3646 ira_allocno_t a;
3647 enum reg_class aclass;
3648 bitmap allocnos_to_color;
3649 ira_allocno_iterator ai;
3650
3651 allocnos_to_color = ira_allocate_bitmap ();
3652 allocnos_to_color_num = 0;
3653 FOR_EACH_ALLOCNO (a, ai)
3654 {
3655 int n = ALLOCNO_NUM_OBJECTS (a);
3656
3657 if (! ALLOCNO_ASSIGNED_P (a)
3658 && ! bitmap_bit_p (allocnos_to_color, ALLOCNO_NUM (a)))
3659 {
3660 if (ALLOCNO_CLASS (a) != NO_REGS)
3661 sorted_allocnos[allocnos_to_color_num++] = a;
3662 else
3663 {
3664 ALLOCNO_ASSIGNED_P (a) = true;
3665 ALLOCNO_HARD_REGNO (a) = -1;
3666 ira_assert (ALLOCNO_UPDATED_HARD_REG_COSTS (a) == NULL);
3667 ira_assert (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a) == NULL);
3668 }
3669 bitmap_set_bit (allocnos_to_color, ALLOCNO_NUM (a));
3670 }
3671 if (ALLOCNO_REGNO (a) < start_regno
3672 || (aclass = ALLOCNO_CLASS (a)) == NO_REGS)
3673 continue;
3674 for (i = 0; i < n; i++)
3675 {
3676 ira_object_t obj = ALLOCNO_OBJECT (a, i);
3677 ira_object_t conflict_obj;
3678 ira_object_conflict_iterator oci;
3679
3680 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
3681 {
3682 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
3683
3684 ira_assert (ira_reg_classes_intersect_p
3685 [aclass][ALLOCNO_CLASS (conflict_a)]);
3686 if (!bitmap_set_bit (allocnos_to_color, ALLOCNO_NUM (conflict_a)))
3687 continue;
3688 sorted_allocnos[allocnos_to_color_num++] = conflict_a;
3689 }
3690 }
3691 }
3692 ira_free_bitmap (allocnos_to_color);
3693 if (allocnos_to_color_num > 1)
3694 {
3695 setup_allocno_priorities (sorted_allocnos, allocnos_to_color_num);
3696 qsort (sorted_allocnos, allocnos_to_color_num, sizeof (ira_allocno_t),
3697 allocno_priority_compare_func);
3698 }
3699 for (i = 0; i < allocnos_to_color_num; i++)
3700 {
3701 a = sorted_allocnos[i];
3702 ALLOCNO_ASSIGNED_P (a) = false;
3703 update_curr_costs (a);
3704 }
3705 for (i = 0; i < allocnos_to_color_num; i++)
3706 {
3707 a = sorted_allocnos[i];
3708 if (assign_hard_reg (a, true))
3709 {
3710 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3711 fprintf
3712 (ira_dump_file,
3713 " Secondary allocation: assign hard reg %d to reg %d\n",
3714 ALLOCNO_HARD_REGNO (a), ALLOCNO_REGNO (a));
3715 }
3716 }
3717 }
3718
3719 \f
3720
3721 /* This page contains functions used to find conflicts using allocno
3722 live ranges. */
3723
3724 #ifdef ENABLE_IRA_CHECKING
3725
3726 /* Return TRUE if live ranges of pseudo-registers REGNO1 and REGNO2
3727 intersect. This should be used when there is only one region.
3728 Currently this is used during reload. */
3729 static bool
3730 conflict_by_live_ranges_p (int regno1, int regno2)
3731 {
3732 ira_allocno_t a1, a2;
3733
3734 ira_assert (regno1 >= FIRST_PSEUDO_REGISTER
3735 && regno2 >= FIRST_PSEUDO_REGISTER);
3736 /* Reg info calculated by dataflow infrastructure can be different
3737 from one calculated by regclass. */
3738 if ((a1 = ira_loop_tree_root->regno_allocno_map[regno1]) == NULL
3739 || (a2 = ira_loop_tree_root->regno_allocno_map[regno2]) == NULL)
3740 return false;
3741 return allocnos_conflict_by_live_ranges_p (a1, a2);
3742 }
3743
3744 #endif
3745
3746 \f
3747
3748 /* This page contains code to coalesce memory stack slots used by
3749 spilled allocnos. This results in smaller stack frame, better data
3750 locality, and in smaller code for some architectures like
3751 x86/x86_64 where insn size depends on address displacement value.
3752 On the other hand, it can worsen insn scheduling after the RA but
3753 in practice it is less important than smaller stack frames. */
3754
3755 /* TRUE if we coalesced some allocnos. In other words, if we got
3756 loops formed by members first_coalesced_allocno and
3757 next_coalesced_allocno containing more one allocno. */
3758 static bool allocno_coalesced_p;
3759
3760 /* Bitmap used to prevent a repeated allocno processing because of
3761 coalescing. */
3762 static bitmap processed_coalesced_allocno_bitmap;
3763
3764 /* See below. */
3765 typedef struct coalesce_data *coalesce_data_t;
3766
3767 /* To decrease footprint of ira_allocno structure we store all data
3768 needed only for coalescing in the following structure. */
3769 struct coalesce_data
3770 {
3771 /* Coalesced allocnos form a cyclic list. One allocno given by
3772 FIRST represents all coalesced allocnos. The
3773 list is chained by NEXT. */
3774 ira_allocno_t first;
3775 ira_allocno_t next;
3776 int temp;
3777 };
3778
3779 /* Container for storing allocno data concerning coalescing. */
3780 static coalesce_data_t allocno_coalesce_data;
3781
3782 /* Macro to access the data concerning coalescing. */
3783 #define ALLOCNO_COALESCE_DATA(a) ((coalesce_data_t) ALLOCNO_ADD_DATA (a))
3784
3785 /* Merge two sets of coalesced allocnos given correspondingly by
3786 allocnos A1 and A2 (more accurately merging A2 set into A1
3787 set). */
3788 static void
3789 merge_allocnos (ira_allocno_t a1, ira_allocno_t a2)
3790 {
3791 ira_allocno_t a, first, last, next;
3792
3793 first = ALLOCNO_COALESCE_DATA (a1)->first;
3794 a = ALLOCNO_COALESCE_DATA (a2)->first;
3795 if (first == a)
3796 return;
3797 for (last = a2, a = ALLOCNO_COALESCE_DATA (a2)->next;;
3798 a = ALLOCNO_COALESCE_DATA (a)->next)
3799 {
3800 ALLOCNO_COALESCE_DATA (a)->first = first;
3801 if (a == a2)
3802 break;
3803 last = a;
3804 }
3805 next = allocno_coalesce_data[ALLOCNO_NUM (first)].next;
3806 allocno_coalesce_data[ALLOCNO_NUM (first)].next = a2;
3807 allocno_coalesce_data[ALLOCNO_NUM (last)].next = next;
3808 }
3809
3810 /* Return TRUE if there are conflicting allocnos from two sets of
3811 coalesced allocnos given correspondingly by allocnos A1 and A2. We
3812 use live ranges to find conflicts because conflicts are represented
3813 only for allocnos of the same allocno class and during the reload
3814 pass we coalesce allocnos for sharing stack memory slots. */
3815 static bool
3816 coalesced_allocno_conflict_p (ira_allocno_t a1, ira_allocno_t a2)
3817 {
3818 ira_allocno_t a, conflict_a;
3819
3820 if (allocno_coalesced_p)
3821 {
3822 bitmap_clear (processed_coalesced_allocno_bitmap);
3823 for (a = ALLOCNO_COALESCE_DATA (a1)->next;;
3824 a = ALLOCNO_COALESCE_DATA (a)->next)
3825 {
3826 bitmap_set_bit (processed_coalesced_allocno_bitmap, ALLOCNO_NUM (a));
3827 if (a == a1)
3828 break;
3829 }
3830 }
3831 for (a = ALLOCNO_COALESCE_DATA (a2)->next;;
3832 a = ALLOCNO_COALESCE_DATA (a)->next)
3833 {
3834 for (conflict_a = ALLOCNO_COALESCE_DATA (a1)->next;;
3835 conflict_a = ALLOCNO_COALESCE_DATA (conflict_a)->next)
3836 {
3837 if (allocnos_conflict_by_live_ranges_p (a, conflict_a))
3838 return true;
3839 if (conflict_a == a1)
3840 break;
3841 }
3842 if (a == a2)
3843 break;
3844 }
3845 return false;
3846 }
3847
3848 /* The major function for aggressive allocno coalescing. We coalesce
3849 only spilled allocnos. If some allocnos have been coalesced, we
3850 set up flag allocno_coalesced_p. */
3851 static void
3852 coalesce_allocnos (void)
3853 {
3854 ira_allocno_t a;
3855 ira_copy_t cp, next_cp;
3856 unsigned int j;
3857 int i, n, cp_num, regno;
3858 bitmap_iterator bi;
3859
3860 cp_num = 0;
3861 /* Collect copies. */
3862 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, j, bi)
3863 {
3864 a = ira_allocnos[j];
3865 regno = ALLOCNO_REGNO (a);
3866 if (! ALLOCNO_ASSIGNED_P (a) || ALLOCNO_HARD_REGNO (a) >= 0
3867 || ira_equiv_no_lvalue_p (regno))
3868 continue;
3869 for (cp = ALLOCNO_COPIES (a); cp != NULL; cp = next_cp)
3870 {
3871 if (cp->first == a)
3872 {
3873 next_cp = cp->next_first_allocno_copy;
3874 regno = ALLOCNO_REGNO (cp->second);
3875 /* For priority coloring we coalesce allocnos only with
3876 the same allocno class not with intersected allocno
3877 classes as it were possible. It is done for
3878 simplicity. */
3879 if ((cp->insn != NULL || cp->constraint_p)
3880 && ALLOCNO_ASSIGNED_P (cp->second)
3881 && ALLOCNO_HARD_REGNO (cp->second) < 0
3882 && ! ira_equiv_no_lvalue_p (regno))
3883 sorted_copies[cp_num++] = cp;
3884 }
3885 else if (cp->second == a)
3886 next_cp = cp->next_second_allocno_copy;
3887 else
3888 gcc_unreachable ();
3889 }
3890 }
3891 qsort (sorted_copies, cp_num, sizeof (ira_copy_t), copy_freq_compare_func);
3892 /* Coalesced copies, most frequently executed first. */
3893 for (; cp_num != 0;)
3894 {
3895 for (i = 0; i < cp_num; i++)
3896 {
3897 cp = sorted_copies[i];
3898 if (! coalesced_allocno_conflict_p (cp->first, cp->second))
3899 {
3900 allocno_coalesced_p = true;
3901 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3902 fprintf
3903 (ira_dump_file,
3904 " Coalescing copy %d:a%dr%d-a%dr%d (freq=%d)\n",
3905 cp->num, ALLOCNO_NUM (cp->first), ALLOCNO_REGNO (cp->first),
3906 ALLOCNO_NUM (cp->second), ALLOCNO_REGNO (cp->second),
3907 cp->freq);
3908 merge_allocnos (cp->first, cp->second);
3909 i++;
3910 break;
3911 }
3912 }
3913 /* Collect the rest of copies. */
3914 for (n = 0; i < cp_num; i++)
3915 {
3916 cp = sorted_copies[i];
3917 if (allocno_coalesce_data[ALLOCNO_NUM (cp->first)].first
3918 != allocno_coalesce_data[ALLOCNO_NUM (cp->second)].first)
3919 sorted_copies[n++] = cp;
3920 }
3921 cp_num = n;
3922 }
3923 }
3924
3925 /* Usage cost and order number of coalesced allocno set to which
3926 given pseudo register belongs to. */
3927 static int *regno_coalesced_allocno_cost;
3928 static int *regno_coalesced_allocno_num;
3929
3930 /* Sort pseudos according frequencies of coalesced allocno sets they
3931 belong to (putting most frequently ones first), and according to
3932 coalesced allocno set order numbers. */
3933 static int
3934 coalesced_pseudo_reg_freq_compare (const void *v1p, const void *v2p)
3935 {
3936 const int regno1 = *(const int *) v1p;
3937 const int regno2 = *(const int *) v2p;
3938 int diff;
3939
3940 if ((diff = (regno_coalesced_allocno_cost[regno2]
3941 - regno_coalesced_allocno_cost[regno1])) != 0)
3942 return diff;
3943 if ((diff = (regno_coalesced_allocno_num[regno1]
3944 - regno_coalesced_allocno_num[regno2])) != 0)
3945 return diff;
3946 return regno1 - regno2;
3947 }
3948
3949 /* Widest width in which each pseudo reg is referred to (via subreg).
3950 It is used for sorting pseudo registers. */
3951 static machine_mode *regno_max_ref_mode;
3952
3953 /* Sort pseudos according their slot numbers (putting ones with
3954 smaller numbers first, or last when the frame pointer is not
3955 needed). */
3956 static int
3957 coalesced_pseudo_reg_slot_compare (const void *v1p, const void *v2p)
3958 {
3959 const int regno1 = *(const int *) v1p;
3960 const int regno2 = *(const int *) v2p;
3961 ira_allocno_t a1 = ira_regno_allocno_map[regno1];
3962 ira_allocno_t a2 = ira_regno_allocno_map[regno2];
3963 int diff, slot_num1, slot_num2;
3964 machine_mode mode1, mode2;
3965
3966 if (a1 == NULL || ALLOCNO_HARD_REGNO (a1) >= 0)
3967 {
3968 if (a2 == NULL || ALLOCNO_HARD_REGNO (a2) >= 0)
3969 return regno1 - regno2;
3970 return 1;
3971 }
3972 else if (a2 == NULL || ALLOCNO_HARD_REGNO (a2) >= 0)
3973 return -1;
3974 slot_num1 = -ALLOCNO_HARD_REGNO (a1);
3975 slot_num2 = -ALLOCNO_HARD_REGNO (a2);
3976 if ((diff = slot_num1 - slot_num2) != 0)
3977 return (frame_pointer_needed
3978 || (!FRAME_GROWS_DOWNWARD) == STACK_GROWS_DOWNWARD ? diff : -diff);
3979 mode1 = wider_subreg_mode (PSEUDO_REGNO_MODE (regno1),
3980 regno_max_ref_mode[regno1]);
3981 mode2 = wider_subreg_mode (PSEUDO_REGNO_MODE (regno2),
3982 regno_max_ref_mode[regno2]);
3983 if ((diff = compare_sizes_for_sort (GET_MODE_SIZE (mode2),
3984 GET_MODE_SIZE (mode1))) != 0)
3985 return diff;
3986 return regno1 - regno2;
3987 }
3988
3989 /* Setup REGNO_COALESCED_ALLOCNO_COST and REGNO_COALESCED_ALLOCNO_NUM
3990 for coalesced allocno sets containing allocnos with their regnos
3991 given in array PSEUDO_REGNOS of length N. */
3992 static void
3993 setup_coalesced_allocno_costs_and_nums (int *pseudo_regnos, int n)
3994 {
3995 int i, num, regno, cost;
3996 ira_allocno_t allocno, a;
3997
3998 for (num = i = 0; i < n; i++)
3999 {
4000 regno = pseudo_regnos[i];
4001 allocno = ira_regno_allocno_map[regno];
4002 if (allocno == NULL)
4003 {
4004 regno_coalesced_allocno_cost[regno] = 0;
4005 regno_coalesced_allocno_num[regno] = ++num;
4006 continue;
4007 }
4008 if (ALLOCNO_COALESCE_DATA (allocno)->first != allocno)
4009 continue;
4010 num++;
4011 for (cost = 0, a = ALLOCNO_COALESCE_DATA (allocno)->next;;
4012 a = ALLOCNO_COALESCE_DATA (a)->next)
4013 {
4014 cost += ALLOCNO_FREQ (a);
4015 if (a == allocno)
4016 break;
4017 }
4018 for (a = ALLOCNO_COALESCE_DATA (allocno)->next;;
4019 a = ALLOCNO_COALESCE_DATA (a)->next)
4020 {
4021 regno_coalesced_allocno_num[ALLOCNO_REGNO (a)] = num;
4022 regno_coalesced_allocno_cost[ALLOCNO_REGNO (a)] = cost;
4023 if (a == allocno)
4024 break;
4025 }
4026 }
4027 }
4028
4029 /* Collect spilled allocnos representing coalesced allocno sets (the
4030 first coalesced allocno). The collected allocnos are returned
4031 through array SPILLED_COALESCED_ALLOCNOS. The function returns the
4032 number of the collected allocnos. The allocnos are given by their
4033 regnos in array PSEUDO_REGNOS of length N. */
4034 static int
4035 collect_spilled_coalesced_allocnos (int *pseudo_regnos, int n,
4036 ira_allocno_t *spilled_coalesced_allocnos)
4037 {
4038 int i, num, regno;
4039 ira_allocno_t allocno;
4040
4041 for (num = i = 0; i < n; i++)
4042 {
4043 regno = pseudo_regnos[i];
4044 allocno = ira_regno_allocno_map[regno];
4045 if (allocno == NULL || ALLOCNO_HARD_REGNO (allocno) >= 0
4046 || ALLOCNO_COALESCE_DATA (allocno)->first != allocno)
4047 continue;
4048 spilled_coalesced_allocnos[num++] = allocno;
4049 }
4050 return num;
4051 }
4052
4053 /* Array of live ranges of size IRA_ALLOCNOS_NUM. Live range for
4054 given slot contains live ranges of coalesced allocnos assigned to
4055 given slot. */
4056 static live_range_t *slot_coalesced_allocnos_live_ranges;
4057
4058 /* Return TRUE if coalesced allocnos represented by ALLOCNO has live
4059 ranges intersected with live ranges of coalesced allocnos assigned
4060 to slot with number N. */
4061 static bool
4062 slot_coalesced_allocno_live_ranges_intersect_p (ira_allocno_t allocno, int n)
4063 {
4064 ira_allocno_t a;
4065
4066 for (a = ALLOCNO_COALESCE_DATA (allocno)->next;;
4067 a = ALLOCNO_COALESCE_DATA (a)->next)
4068 {
4069 int i;
4070 int nr = ALLOCNO_NUM_OBJECTS (a);
4071 gcc_assert (ALLOCNO_CAP_MEMBER (a) == NULL);
4072 for (i = 0; i < nr; i++)
4073 {
4074 ira_object_t obj = ALLOCNO_OBJECT (a, i);
4075
4076 if (ira_live_ranges_intersect_p
4077 (slot_coalesced_allocnos_live_ranges[n],
4078 OBJECT_LIVE_RANGES (obj)))
4079 return true;
4080 }
4081 if (a == allocno)
4082 break;
4083 }
4084 return false;
4085 }
4086
4087 /* Update live ranges of slot to which coalesced allocnos represented
4088 by ALLOCNO were assigned. */
4089 static void
4090 setup_slot_coalesced_allocno_live_ranges (ira_allocno_t allocno)
4091 {
4092 int i, n;
4093 ira_allocno_t a;
4094 live_range_t r;
4095
4096 n = ALLOCNO_COALESCE_DATA (allocno)->temp;
4097 for (a = ALLOCNO_COALESCE_DATA (allocno)->next;;
4098 a = ALLOCNO_COALESCE_DATA (a)->next)
4099 {
4100 int nr = ALLOCNO_NUM_OBJECTS (a);
4101 gcc_assert (ALLOCNO_CAP_MEMBER (a) == NULL);
4102 for (i = 0; i < nr; i++)
4103 {
4104 ira_object_t obj = ALLOCNO_OBJECT (a, i);
4105
4106 r = ira_copy_live_range_list (OBJECT_LIVE_RANGES (obj));
4107 slot_coalesced_allocnos_live_ranges[n]
4108 = ira_merge_live_ranges
4109 (slot_coalesced_allocnos_live_ranges[n], r);
4110 }
4111 if (a == allocno)
4112 break;
4113 }
4114 }
4115
4116 /* We have coalesced allocnos involving in copies. Coalesce allocnos
4117 further in order to share the same memory stack slot. Allocnos
4118 representing sets of allocnos coalesced before the call are given
4119 in array SPILLED_COALESCED_ALLOCNOS of length NUM. Return TRUE if
4120 some allocnos were coalesced in the function. */
4121 static bool
4122 coalesce_spill_slots (ira_allocno_t *spilled_coalesced_allocnos, int num)
4123 {
4124 int i, j, n, last_coalesced_allocno_num;
4125 ira_allocno_t allocno, a;
4126 bool merged_p = false;
4127 bitmap set_jump_crosses = regstat_get_setjmp_crosses ();
4128
4129 slot_coalesced_allocnos_live_ranges
4130 = (live_range_t *) ira_allocate (sizeof (live_range_t) * ira_allocnos_num);
4131 memset (slot_coalesced_allocnos_live_ranges, 0,
4132 sizeof (live_range_t) * ira_allocnos_num);
4133 last_coalesced_allocno_num = 0;
4134 /* Coalesce non-conflicting spilled allocnos preferring most
4135 frequently used. */
4136 for (i = 0; i < num; i++)
4137 {
4138 allocno = spilled_coalesced_allocnos[i];
4139 if (ALLOCNO_COALESCE_DATA (allocno)->first != allocno
4140 || bitmap_bit_p (set_jump_crosses, ALLOCNO_REGNO (allocno))
4141 || ira_equiv_no_lvalue_p (ALLOCNO_REGNO (allocno)))
4142 continue;
4143 for (j = 0; j < i; j++)
4144 {
4145 a = spilled_coalesced_allocnos[j];
4146 n = ALLOCNO_COALESCE_DATA (a)->temp;
4147 if (ALLOCNO_COALESCE_DATA (a)->first == a
4148 && ! bitmap_bit_p (set_jump_crosses, ALLOCNO_REGNO (a))
4149 && ! ira_equiv_no_lvalue_p (ALLOCNO_REGNO (a))
4150 && ! slot_coalesced_allocno_live_ranges_intersect_p (allocno, n))
4151 break;
4152 }
4153 if (j >= i)
4154 {
4155 /* No coalescing: set up number for coalesced allocnos
4156 represented by ALLOCNO. */
4157 ALLOCNO_COALESCE_DATA (allocno)->temp = last_coalesced_allocno_num++;
4158 setup_slot_coalesced_allocno_live_ranges (allocno);
4159 }
4160 else
4161 {
4162 allocno_coalesced_p = true;
4163 merged_p = true;
4164 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4165 fprintf (ira_dump_file,
4166 " Coalescing spilled allocnos a%dr%d->a%dr%d\n",
4167 ALLOCNO_NUM (allocno), ALLOCNO_REGNO (allocno),
4168 ALLOCNO_NUM (a), ALLOCNO_REGNO (a));
4169 ALLOCNO_COALESCE_DATA (allocno)->temp
4170 = ALLOCNO_COALESCE_DATA (a)->temp;
4171 setup_slot_coalesced_allocno_live_ranges (allocno);
4172 merge_allocnos (a, allocno);
4173 ira_assert (ALLOCNO_COALESCE_DATA (a)->first == a);
4174 }
4175 }
4176 for (i = 0; i < ira_allocnos_num; i++)
4177 ira_finish_live_range_list (slot_coalesced_allocnos_live_ranges[i]);
4178 ira_free (slot_coalesced_allocnos_live_ranges);
4179 return merged_p;
4180 }
4181
4182 /* Sort pseudo-register numbers in array PSEUDO_REGNOS of length N for
4183 subsequent assigning stack slots to them in the reload pass. To do
4184 this we coalesce spilled allocnos first to decrease the number of
4185 memory-memory move insns. This function is called by the
4186 reload. */
4187 void
4188 ira_sort_regnos_for_alter_reg (int *pseudo_regnos, int n,
4189 machine_mode *reg_max_ref_mode)
4190 {
4191 int max_regno = max_reg_num ();
4192 int i, regno, num, slot_num;
4193 ira_allocno_t allocno, a;
4194 ira_allocno_iterator ai;
4195 ira_allocno_t *spilled_coalesced_allocnos;
4196
4197 ira_assert (! ira_use_lra_p);
4198
4199 /* Set up allocnos can be coalesced. */
4200 coloring_allocno_bitmap = ira_allocate_bitmap ();
4201 for (i = 0; i < n; i++)
4202 {
4203 regno = pseudo_regnos[i];
4204 allocno = ira_regno_allocno_map[regno];
4205 if (allocno != NULL)
4206 bitmap_set_bit (coloring_allocno_bitmap, ALLOCNO_NUM (allocno));
4207 }
4208 allocno_coalesced_p = false;
4209 processed_coalesced_allocno_bitmap = ira_allocate_bitmap ();
4210 allocno_coalesce_data
4211 = (coalesce_data_t) ira_allocate (sizeof (struct coalesce_data)
4212 * ira_allocnos_num);
4213 /* Initialize coalesce data for allocnos. */
4214 FOR_EACH_ALLOCNO (a, ai)
4215 {
4216 ALLOCNO_ADD_DATA (a) = allocno_coalesce_data + ALLOCNO_NUM (a);
4217 ALLOCNO_COALESCE_DATA (a)->first = a;
4218 ALLOCNO_COALESCE_DATA (a)->next = a;
4219 }
4220 coalesce_allocnos ();
4221 ira_free_bitmap (coloring_allocno_bitmap);
4222 regno_coalesced_allocno_cost
4223 = (int *) ira_allocate (max_regno * sizeof (int));
4224 regno_coalesced_allocno_num
4225 = (int *) ira_allocate (max_regno * sizeof (int));
4226 memset (regno_coalesced_allocno_num, 0, max_regno * sizeof (int));
4227 setup_coalesced_allocno_costs_and_nums (pseudo_regnos, n);
4228 /* Sort regnos according frequencies of the corresponding coalesced
4229 allocno sets. */
4230 qsort (pseudo_regnos, n, sizeof (int), coalesced_pseudo_reg_freq_compare);
4231 spilled_coalesced_allocnos
4232 = (ira_allocno_t *) ira_allocate (ira_allocnos_num
4233 * sizeof (ira_allocno_t));
4234 /* Collect allocnos representing the spilled coalesced allocno
4235 sets. */
4236 num = collect_spilled_coalesced_allocnos (pseudo_regnos, n,
4237 spilled_coalesced_allocnos);
4238 if (flag_ira_share_spill_slots
4239 && coalesce_spill_slots (spilled_coalesced_allocnos, num))
4240 {
4241 setup_coalesced_allocno_costs_and_nums (pseudo_regnos, n);
4242 qsort (pseudo_regnos, n, sizeof (int),
4243 coalesced_pseudo_reg_freq_compare);
4244 num = collect_spilled_coalesced_allocnos (pseudo_regnos, n,
4245 spilled_coalesced_allocnos);
4246 }
4247 ira_free_bitmap (processed_coalesced_allocno_bitmap);
4248 allocno_coalesced_p = false;
4249 /* Assign stack slot numbers to spilled allocno sets, use smaller
4250 numbers for most frequently used coalesced allocnos. -1 is
4251 reserved for dynamic search of stack slots for pseudos spilled by
4252 the reload. */
4253 slot_num = 1;
4254 for (i = 0; i < num; i++)
4255 {
4256 allocno = spilled_coalesced_allocnos[i];
4257 if (ALLOCNO_COALESCE_DATA (allocno)->first != allocno
4258 || ALLOCNO_HARD_REGNO (allocno) >= 0
4259 || ira_equiv_no_lvalue_p (ALLOCNO_REGNO (allocno)))
4260 continue;
4261 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4262 fprintf (ira_dump_file, " Slot %d (freq,size):", slot_num);
4263 slot_num++;
4264 for (a = ALLOCNO_COALESCE_DATA (allocno)->next;;
4265 a = ALLOCNO_COALESCE_DATA (a)->next)
4266 {
4267 ira_assert (ALLOCNO_HARD_REGNO (a) < 0);
4268 ALLOCNO_HARD_REGNO (a) = -slot_num;
4269 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4270 {
4271 machine_mode mode = wider_subreg_mode
4272 (PSEUDO_REGNO_MODE (ALLOCNO_REGNO (a)),
4273 reg_max_ref_mode[ALLOCNO_REGNO (a)]);
4274 fprintf (ira_dump_file, " a%dr%d(%d,",
4275 ALLOCNO_NUM (a), ALLOCNO_REGNO (a), ALLOCNO_FREQ (a));
4276 print_dec (GET_MODE_SIZE (mode), ira_dump_file, SIGNED);
4277 fprintf (ira_dump_file, ")\n");
4278 }
4279
4280 if (a == allocno)
4281 break;
4282 }
4283 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4284 fprintf (ira_dump_file, "\n");
4285 }
4286 ira_spilled_reg_stack_slots_num = slot_num - 1;
4287 ira_free (spilled_coalesced_allocnos);
4288 /* Sort regnos according the slot numbers. */
4289 regno_max_ref_mode = reg_max_ref_mode;
4290 qsort (pseudo_regnos, n, sizeof (int), coalesced_pseudo_reg_slot_compare);
4291 FOR_EACH_ALLOCNO (a, ai)
4292 ALLOCNO_ADD_DATA (a) = NULL;
4293 ira_free (allocno_coalesce_data);
4294 ira_free (regno_coalesced_allocno_num);
4295 ira_free (regno_coalesced_allocno_cost);
4296 }
4297
4298 \f
4299
4300 /* This page contains code used by the reload pass to improve the
4301 final code. */
4302
4303 /* The function is called from reload to mark changes in the
4304 allocation of REGNO made by the reload. Remember that reg_renumber
4305 reflects the change result. */
4306 void
4307 ira_mark_allocation_change (int regno)
4308 {
4309 ira_allocno_t a = ira_regno_allocno_map[regno];
4310 int old_hard_regno, hard_regno, cost;
4311 enum reg_class aclass = ALLOCNO_CLASS (a);
4312
4313 ira_assert (a != NULL);
4314 hard_regno = reg_renumber[regno];
4315 if ((old_hard_regno = ALLOCNO_HARD_REGNO (a)) == hard_regno)
4316 return;
4317 if (old_hard_regno < 0)
4318 cost = -ALLOCNO_MEMORY_COST (a);
4319 else
4320 {
4321 ira_assert (ira_class_hard_reg_index[aclass][old_hard_regno] >= 0);
4322 cost = -(ALLOCNO_HARD_REG_COSTS (a) == NULL
4323 ? ALLOCNO_CLASS_COST (a)
4324 : ALLOCNO_HARD_REG_COSTS (a)
4325 [ira_class_hard_reg_index[aclass][old_hard_regno]]);
4326 update_costs_from_copies (a, false, false);
4327 }
4328 ira_overall_cost -= cost;
4329 ALLOCNO_HARD_REGNO (a) = hard_regno;
4330 if (hard_regno < 0)
4331 {
4332 ALLOCNO_HARD_REGNO (a) = -1;
4333 cost += ALLOCNO_MEMORY_COST (a);
4334 }
4335 else if (ira_class_hard_reg_index[aclass][hard_regno] >= 0)
4336 {
4337 cost += (ALLOCNO_HARD_REG_COSTS (a) == NULL
4338 ? ALLOCNO_CLASS_COST (a)
4339 : ALLOCNO_HARD_REG_COSTS (a)
4340 [ira_class_hard_reg_index[aclass][hard_regno]]);
4341 update_costs_from_copies (a, true, false);
4342 }
4343 else
4344 /* Reload changed class of the allocno. */
4345 cost = 0;
4346 ira_overall_cost += cost;
4347 }
4348
4349 /* This function is called when reload deletes memory-memory move. In
4350 this case we marks that the allocation of the corresponding
4351 allocnos should be not changed in future. Otherwise we risk to get
4352 a wrong code. */
4353 void
4354 ira_mark_memory_move_deletion (int dst_regno, int src_regno)
4355 {
4356 ira_allocno_t dst = ira_regno_allocno_map[dst_regno];
4357 ira_allocno_t src = ira_regno_allocno_map[src_regno];
4358
4359 ira_assert (dst != NULL && src != NULL
4360 && ALLOCNO_HARD_REGNO (dst) < 0
4361 && ALLOCNO_HARD_REGNO (src) < 0);
4362 ALLOCNO_DONT_REASSIGN_P (dst) = true;
4363 ALLOCNO_DONT_REASSIGN_P (src) = true;
4364 }
4365
4366 /* Try to assign a hard register (except for FORBIDDEN_REGS) to
4367 allocno A and return TRUE in the case of success. */
4368 static bool
4369 allocno_reload_assign (ira_allocno_t a, HARD_REG_SET forbidden_regs)
4370 {
4371 int hard_regno;
4372 enum reg_class aclass;
4373 int regno = ALLOCNO_REGNO (a);
4374 HARD_REG_SET saved[2];
4375 int i, n;
4376
4377 n = ALLOCNO_NUM_OBJECTS (a);
4378 for (i = 0; i < n; i++)
4379 {
4380 ira_object_t obj = ALLOCNO_OBJECT (a, i);
4381 saved[i] = OBJECT_TOTAL_CONFLICT_HARD_REGS (obj);
4382 OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) |= forbidden_regs;
4383 if (! flag_caller_saves && ALLOCNO_CALLS_CROSSED_NUM (a) != 0)
4384 OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) |= ira_need_caller_save_regs (a);
4385 }
4386 ALLOCNO_ASSIGNED_P (a) = false;
4387 aclass = ALLOCNO_CLASS (a);
4388 update_curr_costs (a);
4389 assign_hard_reg (a, true);
4390 hard_regno = ALLOCNO_HARD_REGNO (a);
4391 reg_renumber[regno] = hard_regno;
4392 if (hard_regno < 0)
4393 ALLOCNO_HARD_REGNO (a) = -1;
4394 else
4395 {
4396 ira_assert (ira_class_hard_reg_index[aclass][hard_regno] >= 0);
4397 ira_overall_cost
4398 -= (ALLOCNO_MEMORY_COST (a)
4399 - (ALLOCNO_HARD_REG_COSTS (a) == NULL
4400 ? ALLOCNO_CLASS_COST (a)
4401 : ALLOCNO_HARD_REG_COSTS (a)[ira_class_hard_reg_index
4402 [aclass][hard_regno]]));
4403 if (ira_need_caller_save_p (a, hard_regno))
4404 {
4405 ira_assert (flag_caller_saves);
4406 caller_save_needed = 1;
4407 }
4408 }
4409
4410 /* If we found a hard register, modify the RTL for the pseudo
4411 register to show the hard register, and mark the pseudo register
4412 live. */
4413 if (reg_renumber[regno] >= 0)
4414 {
4415 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4416 fprintf (ira_dump_file, ": reassign to %d\n", reg_renumber[regno]);
4417 SET_REGNO (regno_reg_rtx[regno], reg_renumber[regno]);
4418 mark_home_live (regno);
4419 }
4420 else if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4421 fprintf (ira_dump_file, "\n");
4422 for (i = 0; i < n; i++)
4423 {
4424 ira_object_t obj = ALLOCNO_OBJECT (a, i);
4425 OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) = saved[i];
4426 }
4427 return reg_renumber[regno] >= 0;
4428 }
4429
4430 /* Sort pseudos according their usage frequencies (putting most
4431 frequently ones first). */
4432 static int
4433 pseudo_reg_compare (const void *v1p, const void *v2p)
4434 {
4435 int regno1 = *(const int *) v1p;
4436 int regno2 = *(const int *) v2p;
4437 int diff;
4438
4439 if ((diff = REG_FREQ (regno2) - REG_FREQ (regno1)) != 0)
4440 return diff;
4441 return regno1 - regno2;
4442 }
4443
4444 /* Try to allocate hard registers to SPILLED_PSEUDO_REGS (there are
4445 NUM of them) or spilled pseudos conflicting with pseudos in
4446 SPILLED_PSEUDO_REGS. Return TRUE and update SPILLED, if the
4447 allocation has been changed. The function doesn't use
4448 BAD_SPILL_REGS and hard registers in PSEUDO_FORBIDDEN_REGS and
4449 PSEUDO_PREVIOUS_REGS for the corresponding pseudos. The function
4450 is called by the reload pass at the end of each reload
4451 iteration. */
4452 bool
4453 ira_reassign_pseudos (int *spilled_pseudo_regs, int num,
4454 HARD_REG_SET bad_spill_regs,
4455 HARD_REG_SET *pseudo_forbidden_regs,
4456 HARD_REG_SET *pseudo_previous_regs,
4457 bitmap spilled)
4458 {
4459 int i, n, regno;
4460 bool changed_p;
4461 ira_allocno_t a;
4462 HARD_REG_SET forbidden_regs;
4463 bitmap temp = BITMAP_ALLOC (NULL);
4464
4465 /* Add pseudos which conflict with pseudos already in
4466 SPILLED_PSEUDO_REGS to SPILLED_PSEUDO_REGS. This is preferable
4467 to allocating in two steps as some of the conflicts might have
4468 a higher priority than the pseudos passed in SPILLED_PSEUDO_REGS. */
4469 for (i = 0; i < num; i++)
4470 bitmap_set_bit (temp, spilled_pseudo_regs[i]);
4471
4472 for (i = 0, n = num; i < n; i++)
4473 {
4474 int nr, j;
4475 int regno = spilled_pseudo_regs[i];
4476 bitmap_set_bit (temp, regno);
4477
4478 a = ira_regno_allocno_map[regno];
4479 nr = ALLOCNO_NUM_OBJECTS (a);
4480 for (j = 0; j < nr; j++)
4481 {
4482 ira_object_t conflict_obj;
4483 ira_object_t obj = ALLOCNO_OBJECT (a, j);
4484 ira_object_conflict_iterator oci;
4485
4486 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
4487 {
4488 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
4489 if (ALLOCNO_HARD_REGNO (conflict_a) < 0
4490 && ! ALLOCNO_DONT_REASSIGN_P (conflict_a)
4491 && bitmap_set_bit (temp, ALLOCNO_REGNO (conflict_a)))
4492 {
4493 spilled_pseudo_regs[num++] = ALLOCNO_REGNO (conflict_a);
4494 /* ?!? This seems wrong. */
4495 bitmap_set_bit (consideration_allocno_bitmap,
4496 ALLOCNO_NUM (conflict_a));
4497 }
4498 }
4499 }
4500 }
4501
4502 if (num > 1)
4503 qsort (spilled_pseudo_regs, num, sizeof (int), pseudo_reg_compare);
4504 changed_p = false;
4505 /* Try to assign hard registers to pseudos from
4506 SPILLED_PSEUDO_REGS. */
4507 for (i = 0; i < num; i++)
4508 {
4509 regno = spilled_pseudo_regs[i];
4510 forbidden_regs = (bad_spill_regs
4511 | pseudo_forbidden_regs[regno]
4512 | pseudo_previous_regs[regno]);
4513 gcc_assert (reg_renumber[regno] < 0);
4514 a = ira_regno_allocno_map[regno];
4515 ira_mark_allocation_change (regno);
4516 ira_assert (reg_renumber[regno] < 0);
4517 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4518 fprintf (ira_dump_file,
4519 " Try Assign %d(a%d), cost=%d", regno, ALLOCNO_NUM (a),
4520 ALLOCNO_MEMORY_COST (a)
4521 - ALLOCNO_CLASS_COST (a));
4522 allocno_reload_assign (a, forbidden_regs);
4523 if (reg_renumber[regno] >= 0)
4524 {
4525 CLEAR_REGNO_REG_SET (spilled, regno);
4526 changed_p = true;
4527 }
4528 }
4529 BITMAP_FREE (temp);
4530 return changed_p;
4531 }
4532
4533 /* The function is called by reload and returns already allocated
4534 stack slot (if any) for REGNO with given INHERENT_SIZE and
4535 TOTAL_SIZE. In the case of failure to find a slot which can be
4536 used for REGNO, the function returns NULL. */
4537 rtx
4538 ira_reuse_stack_slot (int regno, poly_uint64 inherent_size,
4539 poly_uint64 total_size)
4540 {
4541 unsigned int i;
4542 int slot_num, best_slot_num;
4543 int cost, best_cost;
4544 ira_copy_t cp, next_cp;
4545 ira_allocno_t another_allocno, allocno = ira_regno_allocno_map[regno];
4546 rtx x;
4547 bitmap_iterator bi;
4548 class ira_spilled_reg_stack_slot *slot = NULL;
4549
4550 ira_assert (! ira_use_lra_p);
4551
4552 ira_assert (known_eq (inherent_size, PSEUDO_REGNO_BYTES (regno))
4553 && known_le (inherent_size, total_size)
4554 && ALLOCNO_HARD_REGNO (allocno) < 0);
4555 if (! flag_ira_share_spill_slots)
4556 return NULL_RTX;
4557 slot_num = -ALLOCNO_HARD_REGNO (allocno) - 2;
4558 if (slot_num != -1)
4559 {
4560 slot = &ira_spilled_reg_stack_slots[slot_num];
4561 x = slot->mem;
4562 }
4563 else
4564 {
4565 best_cost = best_slot_num = -1;
4566 x = NULL_RTX;
4567 /* It means that the pseudo was spilled in the reload pass, try
4568 to reuse a slot. */
4569 for (slot_num = 0;
4570 slot_num < ira_spilled_reg_stack_slots_num;
4571 slot_num++)
4572 {
4573 slot = &ira_spilled_reg_stack_slots[slot_num];
4574 if (slot->mem == NULL_RTX)
4575 continue;
4576 if (maybe_lt (slot->width, total_size)
4577 || maybe_lt (GET_MODE_SIZE (GET_MODE (slot->mem)), inherent_size))
4578 continue;
4579
4580 EXECUTE_IF_SET_IN_BITMAP (&slot->spilled_regs,
4581 FIRST_PSEUDO_REGISTER, i, bi)
4582 {
4583 another_allocno = ira_regno_allocno_map[i];
4584 if (allocnos_conflict_by_live_ranges_p (allocno,
4585 another_allocno))
4586 goto cont;
4587 }
4588 for (cost = 0, cp = ALLOCNO_COPIES (allocno);
4589 cp != NULL;
4590 cp = next_cp)
4591 {
4592 if (cp->first == allocno)
4593 {
4594 next_cp = cp->next_first_allocno_copy;
4595 another_allocno = cp->second;
4596 }
4597 else if (cp->second == allocno)
4598 {
4599 next_cp = cp->next_second_allocno_copy;
4600 another_allocno = cp->first;
4601 }
4602 else
4603 gcc_unreachable ();
4604 if (cp->insn == NULL_RTX)
4605 continue;
4606 if (bitmap_bit_p (&slot->spilled_regs,
4607 ALLOCNO_REGNO (another_allocno)))
4608 cost += cp->freq;
4609 }
4610 if (cost > best_cost)
4611 {
4612 best_cost = cost;
4613 best_slot_num = slot_num;
4614 }
4615 cont:
4616 ;
4617 }
4618 if (best_cost >= 0)
4619 {
4620 slot_num = best_slot_num;
4621 slot = &ira_spilled_reg_stack_slots[slot_num];
4622 SET_REGNO_REG_SET (&slot->spilled_regs, regno);
4623 x = slot->mem;
4624 ALLOCNO_HARD_REGNO (allocno) = -slot_num - 2;
4625 }
4626 }
4627 if (x != NULL_RTX)
4628 {
4629 ira_assert (known_ge (slot->width, total_size));
4630 #ifdef ENABLE_IRA_CHECKING
4631 EXECUTE_IF_SET_IN_BITMAP (&slot->spilled_regs,
4632 FIRST_PSEUDO_REGISTER, i, bi)
4633 {
4634 ira_assert (! conflict_by_live_ranges_p (regno, i));
4635 }
4636 #endif
4637 SET_REGNO_REG_SET (&slot->spilled_regs, regno);
4638 if (internal_flag_ira_verbose > 3 && ira_dump_file)
4639 {
4640 fprintf (ira_dump_file, " Assigning %d(freq=%d) slot %d of",
4641 regno, REG_FREQ (regno), slot_num);
4642 EXECUTE_IF_SET_IN_BITMAP (&slot->spilled_regs,
4643 FIRST_PSEUDO_REGISTER, i, bi)
4644 {
4645 if ((unsigned) regno != i)
4646 fprintf (ira_dump_file, " %d", i);
4647 }
4648 fprintf (ira_dump_file, "\n");
4649 }
4650 }
4651 return x;
4652 }
4653
4654 /* This is called by reload every time a new stack slot X with
4655 TOTAL_SIZE was allocated for REGNO. We store this info for
4656 subsequent ira_reuse_stack_slot calls. */
4657 void
4658 ira_mark_new_stack_slot (rtx x, int regno, poly_uint64 total_size)
4659 {
4660 class ira_spilled_reg_stack_slot *slot;
4661 int slot_num;
4662 ira_allocno_t allocno;
4663
4664 ira_assert (! ira_use_lra_p);
4665
4666 ira_assert (known_le (PSEUDO_REGNO_BYTES (regno), total_size));
4667 allocno = ira_regno_allocno_map[regno];
4668 slot_num = -ALLOCNO_HARD_REGNO (allocno) - 2;
4669 if (slot_num == -1)
4670 {
4671 slot_num = ira_spilled_reg_stack_slots_num++;
4672 ALLOCNO_HARD_REGNO (allocno) = -slot_num - 2;
4673 }
4674 slot = &ira_spilled_reg_stack_slots[slot_num];
4675 INIT_REG_SET (&slot->spilled_regs);
4676 SET_REGNO_REG_SET (&slot->spilled_regs, regno);
4677 slot->mem = x;
4678 slot->width = total_size;
4679 if (internal_flag_ira_verbose > 3 && ira_dump_file)
4680 fprintf (ira_dump_file, " Assigning %d(freq=%d) a new slot %d\n",
4681 regno, REG_FREQ (regno), slot_num);
4682 }
4683
4684
4685 /* Return spill cost for pseudo-registers whose numbers are in array
4686 REGNOS (with a negative number as an end marker) for reload with
4687 given IN and OUT for INSN. Return also number points (through
4688 EXCESS_PRESSURE_LIVE_LENGTH) where the pseudo-register lives and
4689 the register pressure is high, number of references of the
4690 pseudo-registers (through NREFS), the number of psuedo registers
4691 whose allocated register wouldn't need saving in the prologue
4692 (through CALL_USED_COUNT), and the first hard regno occupied by the
4693 pseudo-registers (through FIRST_HARD_REGNO). */
4694 static int
4695 calculate_spill_cost (int *regnos, rtx in, rtx out, rtx_insn *insn,
4696 int *excess_pressure_live_length,
4697 int *nrefs, int *call_used_count, int *first_hard_regno)
4698 {
4699 int i, cost, regno, hard_regno, count, saved_cost;
4700 bool in_p, out_p;
4701 int length;
4702 ira_allocno_t a;
4703
4704 *nrefs = 0;
4705 for (length = count = cost = i = 0;; i++)
4706 {
4707 regno = regnos[i];
4708 if (regno < 0)
4709 break;
4710 *nrefs += REG_N_REFS (regno);
4711 hard_regno = reg_renumber[regno];
4712 ira_assert (hard_regno >= 0);
4713 a = ira_regno_allocno_map[regno];
4714 length += ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a) / ALLOCNO_NUM_OBJECTS (a);
4715 cost += ALLOCNO_MEMORY_COST (a) - ALLOCNO_CLASS_COST (a);
4716 if (in_hard_reg_set_p (crtl->abi->full_reg_clobbers (),
4717 ALLOCNO_MODE (a), hard_regno))
4718 count++;
4719 in_p = in && REG_P (in) && (int) REGNO (in) == hard_regno;
4720 out_p = out && REG_P (out) && (int) REGNO (out) == hard_regno;
4721 if ((in_p || out_p)
4722 && find_regno_note (insn, REG_DEAD, hard_regno) != NULL_RTX)
4723 {
4724 saved_cost = 0;
4725 if (in_p)
4726 saved_cost += ira_memory_move_cost
4727 [ALLOCNO_MODE (a)][ALLOCNO_CLASS (a)][1];
4728 if (out_p)
4729 saved_cost
4730 += ira_memory_move_cost
4731 [ALLOCNO_MODE (a)][ALLOCNO_CLASS (a)][0];
4732 cost -= REG_FREQ_FROM_BB (BLOCK_FOR_INSN (insn)) * saved_cost;
4733 }
4734 }
4735 *excess_pressure_live_length = length;
4736 *call_used_count = count;
4737 hard_regno = -1;
4738 if (regnos[0] >= 0)
4739 {
4740 hard_regno = reg_renumber[regnos[0]];
4741 }
4742 *first_hard_regno = hard_regno;
4743 return cost;
4744 }
4745
4746 /* Return TRUE if spilling pseudo-registers whose numbers are in array
4747 REGNOS is better than spilling pseudo-registers with numbers in
4748 OTHER_REGNOS for reload with given IN and OUT for INSN. The
4749 function used by the reload pass to make better register spilling
4750 decisions. */
4751 bool
4752 ira_better_spill_reload_regno_p (int *regnos, int *other_regnos,
4753 rtx in, rtx out, rtx_insn *insn)
4754 {
4755 int cost, other_cost;
4756 int length, other_length;
4757 int nrefs, other_nrefs;
4758 int call_used_count, other_call_used_count;
4759 int hard_regno, other_hard_regno;
4760
4761 cost = calculate_spill_cost (regnos, in, out, insn,
4762 &length, &nrefs, &call_used_count, &hard_regno);
4763 other_cost = calculate_spill_cost (other_regnos, in, out, insn,
4764 &other_length, &other_nrefs,
4765 &other_call_used_count,
4766 &other_hard_regno);
4767 if (nrefs == 0 && other_nrefs != 0)
4768 return true;
4769 if (nrefs != 0 && other_nrefs == 0)
4770 return false;
4771 if (cost != other_cost)
4772 return cost < other_cost;
4773 if (length != other_length)
4774 return length > other_length;
4775 #ifdef REG_ALLOC_ORDER
4776 if (hard_regno >= 0 && other_hard_regno >= 0)
4777 return (inv_reg_alloc_order[hard_regno]
4778 < inv_reg_alloc_order[other_hard_regno]);
4779 #else
4780 if (call_used_count != other_call_used_count)
4781 return call_used_count > other_call_used_count;
4782 #endif
4783 return false;
4784 }
4785
4786 \f
4787
4788 /* Allocate and initialize data necessary for assign_hard_reg. */
4789 void
4790 ira_initiate_assign (void)
4791 {
4792 sorted_allocnos
4793 = (ira_allocno_t *) ira_allocate (sizeof (ira_allocno_t)
4794 * ira_allocnos_num);
4795 consideration_allocno_bitmap = ira_allocate_bitmap ();
4796 initiate_cost_update ();
4797 allocno_priorities = (int *) ira_allocate (sizeof (int) * ira_allocnos_num);
4798 sorted_copies = (ira_copy_t *) ira_allocate (ira_copies_num
4799 * sizeof (ira_copy_t));
4800 }
4801
4802 /* Deallocate data used by assign_hard_reg. */
4803 void
4804 ira_finish_assign (void)
4805 {
4806 ira_free (sorted_allocnos);
4807 ira_free_bitmap (consideration_allocno_bitmap);
4808 finish_cost_update ();
4809 ira_free (allocno_priorities);
4810 ira_free (sorted_copies);
4811 }
4812
4813 \f
4814
4815 /* Entry function doing color-based register allocation. */
4816 static void
4817 color (void)
4818 {
4819 allocno_stack_vec.create (ira_allocnos_num);
4820 memset (allocated_hardreg_p, 0, sizeof (allocated_hardreg_p));
4821 ira_initiate_assign ();
4822 do_coloring ();
4823 ira_finish_assign ();
4824 allocno_stack_vec.release ();
4825 move_spill_restore ();
4826 }
4827
4828 \f
4829
4830 /* This page contains a simple register allocator without usage of
4831 allocno conflicts. This is used for fast allocation for -O0. */
4832
4833 /* Do register allocation by not using allocno conflicts. It uses
4834 only allocno live ranges. The algorithm is close to Chow's
4835 priority coloring. */
4836 static void
4837 fast_allocation (void)
4838 {
4839 int i, j, k, num, class_size, hard_regno, best_hard_regno, cost, min_cost;
4840 int *costs;
4841 #ifdef STACK_REGS
4842 bool no_stack_reg_p;
4843 #endif
4844 enum reg_class aclass;
4845 machine_mode mode;
4846 ira_allocno_t a;
4847 ira_allocno_iterator ai;
4848 live_range_t r;
4849 HARD_REG_SET conflict_hard_regs, *used_hard_regs;
4850
4851 sorted_allocnos = (ira_allocno_t *) ira_allocate (sizeof (ira_allocno_t)
4852 * ira_allocnos_num);
4853 num = 0;
4854 FOR_EACH_ALLOCNO (a, ai)
4855 sorted_allocnos[num++] = a;
4856 allocno_priorities = (int *) ira_allocate (sizeof (int) * ira_allocnos_num);
4857 setup_allocno_priorities (sorted_allocnos, num);
4858 used_hard_regs = (HARD_REG_SET *) ira_allocate (sizeof (HARD_REG_SET)
4859 * ira_max_point);
4860 for (i = 0; i < ira_max_point; i++)
4861 CLEAR_HARD_REG_SET (used_hard_regs[i]);
4862 qsort (sorted_allocnos, num, sizeof (ira_allocno_t),
4863 allocno_priority_compare_func);
4864 for (i = 0; i < num; i++)
4865 {
4866 int nr, l;
4867
4868 a = sorted_allocnos[i];
4869 nr = ALLOCNO_NUM_OBJECTS (a);
4870 CLEAR_HARD_REG_SET (conflict_hard_regs);
4871 for (l = 0; l < nr; l++)
4872 {
4873 ira_object_t obj = ALLOCNO_OBJECT (a, l);
4874 conflict_hard_regs |= OBJECT_CONFLICT_HARD_REGS (obj);
4875 for (r = OBJECT_LIVE_RANGES (obj); r != NULL; r = r->next)
4876 for (j = r->start; j <= r->finish; j++)
4877 conflict_hard_regs |= used_hard_regs[j];
4878 }
4879 aclass = ALLOCNO_CLASS (a);
4880 ALLOCNO_ASSIGNED_P (a) = true;
4881 ALLOCNO_HARD_REGNO (a) = -1;
4882 if (hard_reg_set_subset_p (reg_class_contents[aclass],
4883 conflict_hard_regs))
4884 continue;
4885 mode = ALLOCNO_MODE (a);
4886 #ifdef STACK_REGS
4887 no_stack_reg_p = ALLOCNO_NO_STACK_REG_P (a);
4888 #endif
4889 class_size = ira_class_hard_regs_num[aclass];
4890 costs = ALLOCNO_HARD_REG_COSTS (a);
4891 min_cost = INT_MAX;
4892 best_hard_regno = -1;
4893 for (j = 0; j < class_size; j++)
4894 {
4895 hard_regno = ira_class_hard_regs[aclass][j];
4896 #ifdef STACK_REGS
4897 if (no_stack_reg_p && FIRST_STACK_REG <= hard_regno
4898 && hard_regno <= LAST_STACK_REG)
4899 continue;
4900 #endif
4901 if (ira_hard_reg_set_intersection_p (hard_regno, mode, conflict_hard_regs)
4902 || (TEST_HARD_REG_BIT
4903 (ira_prohibited_class_mode_regs[aclass][mode], hard_regno)))
4904 continue;
4905 if (costs == NULL)
4906 {
4907 best_hard_regno = hard_regno;
4908 break;
4909 }
4910 cost = costs[j];
4911 if (min_cost > cost)
4912 {
4913 min_cost = cost;
4914 best_hard_regno = hard_regno;
4915 }
4916 }
4917 if (best_hard_regno < 0)
4918 continue;
4919 ALLOCNO_HARD_REGNO (a) = hard_regno = best_hard_regno;
4920 for (l = 0; l < nr; l++)
4921 {
4922 ira_object_t obj = ALLOCNO_OBJECT (a, l);
4923 for (r = OBJECT_LIVE_RANGES (obj); r != NULL; r = r->next)
4924 for (k = r->start; k <= r->finish; k++)
4925 used_hard_regs[k] |= ira_reg_mode_hard_regset[hard_regno][mode];
4926 }
4927 }
4928 ira_free (sorted_allocnos);
4929 ira_free (used_hard_regs);
4930 ira_free (allocno_priorities);
4931 if (internal_flag_ira_verbose > 1 && ira_dump_file != NULL)
4932 ira_print_disposition (ira_dump_file);
4933 }
4934
4935 \f
4936
4937 /* Entry function doing coloring. */
4938 void
4939 ira_color (void)
4940 {
4941 ira_allocno_t a;
4942 ira_allocno_iterator ai;
4943
4944 /* Setup updated costs. */
4945 FOR_EACH_ALLOCNO (a, ai)
4946 {
4947 ALLOCNO_UPDATED_MEMORY_COST (a) = ALLOCNO_MEMORY_COST (a);
4948 ALLOCNO_UPDATED_CLASS_COST (a) = ALLOCNO_CLASS_COST (a);
4949 }
4950 if (ira_conflicts_p)
4951 color ();
4952 else
4953 fast_allocation ();
4954 }