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