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