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