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