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