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