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