1 /* IRA allocation based on graph coloring.
2 Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012
3 Free Software Foundation, Inc.
4 Contributed by Vladimir Makarov <vmakarov@redhat.com>.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
24 #include "coretypes.h"
33 #include "hard-reg-set.h"
34 #include "basic-block.h"
36 #include "diagnostic-core.h"
42 typedef struct allocno_hard_regs
*allocno_hard_regs_t
;
44 /* The structure contains information about hard registers can be
45 assigned to allocnos. Usually it is allocno profitable hard
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. */
50 struct allocno_hard_regs
52 /* Hard registers can be assigned to an allocno. */
54 /* Overall (spilling) cost of all allocnos with given register
59 typedef struct allocno_hard_regs_node
*allocno_hard_regs_node_t
;
61 /* A node representing allocno hard registers. Such nodes form a
62 forest (set of trees). Each subnode of given node in the forest
63 refers for hard register set (usually allocno profitable hard
64 register set) which is a subset of one referred from given
66 struct allocno_hard_regs_node
68 /* Set up number of the node in preorder traversing of the forest. */
70 /* Used for different calculation like finding conflict size of an
73 /* Used for calculation of conflict size of an allocno. The
74 conflict size of the allocno is maximal number of given allocno
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. */
80 /* The number of hard registers given by member hard_regs. */
82 /* The following member is used to form the final forest. */
84 /* Pointer to the corresponding profitable hard registers. */
85 allocno_hard_regs_t hard_regs
;
86 /* Parent, first subnode, previous and next node with the same
87 parent in the forest. */
88 allocno_hard_regs_node_t parent
, first
, prev
, next
;
91 /* To decrease footprint of ira_allocno structure we store all data
92 needed only for coloring in the following structure. */
93 struct allocno_color_data
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
100 unsigned int may_be_spilled_p
: 1;
101 /* TRUE if the allocno is trivially colorable. */
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
109 ira_allocno_t next_bucket_allocno
;
110 ira_allocno_t prev_bucket_allocno
;
111 /* Used for temporary purposes. */
113 /* Used to exclude repeated processing. */
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
119 HARD_REG_SET profitable_hard_regs
;
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
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
;
132 typedef struct allocno_color_data
*allocno_color_data_t
;
134 /* Container for storing allocno data concerning coloring. */
135 static allocno_color_data_t allocno_color_data
;
137 /* Macro to access the data concerning coloring. */
138 #define ALLOCNO_COLOR_DATA(a) ((allocno_color_data_t) ALLOCNO_ADD_DATA (a))
140 /* Used for finding allocno colorability to exclude repeated allocno
141 processing and for updating preferencing to exclude repeated
142 allocno processing during assignment. */
143 static int curr_allocno_process
;
145 /* This file contains code for regional graph coloring, spill/restore
146 code placement optimization, and code helping the reload pass to do
149 /* Bitmap of allocnos which should be colored. */
150 static bitmap coloring_allocno_bitmap
;
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
156 static bitmap consideration_allocno_bitmap
;
158 /* All allocnos sorted according their priorities. */
159 static ira_allocno_t
*sorted_allocnos
;
161 /* Vec representing the stack of allocnos used during coloring. */
162 static vec
<ira_allocno_t
> allocno_stack_vec
;
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)
172 /* Definition of vector of allocno hard registers. */
174 /* Vector of unique allocno hard registers. */
175 static vec
<allocno_hard_regs_t
> allocno_hard_regs_vec
;
177 /* Returns hash value for allocno hard registers V. */
179 allocno_hard_regs_hash (const void *v
)
181 const struct allocno_hard_regs
*hv
= (const struct allocno_hard_regs
*) v
;
183 return iterative_hash (&hv
->set
, sizeof (HARD_REG_SET
), 0);
186 /* Compares allocno hard registers V1 and V2. */
188 allocno_hard_regs_eq (const void *v1
, const void *v2
)
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
;
193 return hard_reg_set_equal_p (hv1
->set
, hv2
->set
);
196 /* Hash table of unique allocno hard registers. */
197 static htab_t allocno_hard_regs_htab
;
199 /* Return allocno hard registers in the hash table equal to HV. */
200 static allocno_hard_regs_t
201 find_hard_regs (allocno_hard_regs_t hv
)
203 return (allocno_hard_regs_t
) htab_find (allocno_hard_regs_htab
, hv
);
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. */
208 static allocno_hard_regs_t
209 insert_hard_regs (allocno_hard_regs_t hv
)
211 PTR
*slot
= htab_find_slot (allocno_hard_regs_htab
, hv
, INSERT
);
215 return (allocno_hard_regs_t
) *slot
;
218 /* Initialize data concerning allocno hard registers. */
220 init_allocno_hard_regs (void)
222 allocno_hard_regs_vec
.create (200);
223 allocno_hard_regs_htab
224 = htab_create (200, allocno_hard_regs_hash
, allocno_hard_regs_eq
, NULL
);
227 /* Add (or update info about) allocno hard registers with SET and
229 static allocno_hard_regs_t
230 add_allocno_hard_regs (HARD_REG_SET set
, HOST_WIDEST_INT cost
)
232 struct allocno_hard_regs temp
;
233 allocno_hard_regs_t hv
;
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
)
241 hv
= ((struct allocno_hard_regs
*)
242 ira_allocate (sizeof (struct allocno_hard_regs
)));
243 COPY_HARD_REG_SET (hv
->set
, set
);
245 allocno_hard_regs_vec
.safe_push (hv
);
246 insert_hard_regs (hv
);
251 /* Finalize data concerning allocno hard registers. */
253 finish_allocno_hard_regs (void)
256 allocno_hard_regs_t hv
;
259 allocno_hard_regs_vec
.iterate (i
, &hv
);
262 htab_delete (allocno_hard_regs_htab
);
263 allocno_hard_regs_vec
.release ();
266 /* Sort hard regs according to their frequency of usage. */
268 allocno_hard_regs_compare (const void *v1p
, const void *v2p
)
270 allocno_hard_regs_t hv1
= *(const allocno_hard_regs_t
*) v1p
;
271 allocno_hard_regs_t hv2
= *(const allocno_hard_regs_t
*) v2p
;
273 if (hv2
->cost
> hv1
->cost
)
275 else if (hv2
->cost
< hv1
->cost
)
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.
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. */
291 static int node_check_tick
;
293 /* Roots of the forest containing hard register sets can be assigned
295 static allocno_hard_regs_node_t hard_regs_roots
;
297 /* Definition of vector of allocno hard register nodes. */
299 /* Vector used to create the forest. */
300 static vec
<allocno_hard_regs_node_t
> hard_regs_node_vec
;
302 /* Create and return allocno hard registers node containing allocno
303 hard registers HV. */
304 static allocno_hard_regs_node_t
305 create_new_allocno_hard_regs_node (allocno_hard_regs_t hv
)
307 allocno_hard_regs_node_t new_node
;
309 new_node
= ((struct allocno_hard_regs_node
*)
310 ira_allocate (sizeof (struct allocno_hard_regs_node
)));
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;
319 /* Add allocno hard registers node NEW_NODE to the forest on its level
322 add_new_allocno_hard_regs_node_to_forest (allocno_hard_regs_node_t
*roots
,
323 allocno_hard_regs_node_t new_node
)
325 new_node
->next
= *roots
;
326 if (new_node
->next
!= NULL
)
327 new_node
->next
->prev
= new_node
;
328 new_node
->prev
= NULL
;
332 /* Add allocno hard registers HV (or its best approximation if it is
333 not possible) to the forest on its level given by ROOTS. */
335 add_allocno_hard_regs_to_forest (allocno_hard_regs_node_t
*roots
,
336 allocno_hard_regs_t hv
)
338 unsigned int i
, start
;
339 allocno_hard_regs_node_t node
, prev
, new_node
;
340 HARD_REG_SET temp_set
;
341 allocno_hard_regs_t hv2
;
343 start
= hard_regs_node_vec
.length ();
344 for (node
= *roots
; node
!= NULL
; node
= node
->next
)
346 if (hard_reg_set_equal_p (hv
->set
, node
->hard_regs
->set
))
348 if (hard_reg_set_subset_p (hv
->set
, node
->hard_regs
->set
))
350 add_allocno_hard_regs_to_forest (&node
->first
, hv
);
353 if (hard_reg_set_subset_p (node
->hard_regs
->set
, hv
->set
))
354 hard_regs_node_vec
.safe_push (node
);
355 else if (hard_reg_set_intersect_p (hv
->set
, node
->hard_regs
->set
))
357 COPY_HARD_REG_SET (temp_set
, hv
->set
);
358 AND_HARD_REG_SET (temp_set
, node
->hard_regs
->set
);
359 hv2
= add_allocno_hard_regs (temp_set
, hv
->cost
);
360 add_allocno_hard_regs_to_forest (&node
->first
, hv2
);
363 if (hard_regs_node_vec
.length ()
366 /* Create a new node which contains nodes in hard_regs_node_vec. */
367 CLEAR_HARD_REG_SET (temp_set
);
369 i
< hard_regs_node_vec
.length ();
372 node
= hard_regs_node_vec
[i
];
373 IOR_HARD_REG_SET (temp_set
, node
->hard_regs
->set
);
375 hv
= add_allocno_hard_regs (temp_set
, hv
->cost
);
376 new_node
= create_new_allocno_hard_regs_node (hv
);
379 i
< hard_regs_node_vec
.length ();
382 node
= hard_regs_node_vec
[i
];
383 if (node
->prev
== NULL
)
386 node
->prev
->next
= node
->next
;
387 if (node
->next
!= NULL
)
388 node
->next
->prev
= node
->prev
;
390 new_node
->first
= node
;
397 add_new_allocno_hard_regs_node_to_forest (roots
, new_node
);
399 hard_regs_node_vec
.truncate (start
);
402 /* Add allocno hard registers nodes starting with the forest level
403 given by FIRST which contains biggest set inside SET. */
405 collect_allocno_hard_regs_cover (allocno_hard_regs_node_t first
,
408 allocno_hard_regs_node_t node
;
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
))
413 hard_regs_node_vec
.safe_push (node
);
414 else if (hard_reg_set_intersect_p (set
, node
->hard_regs
->set
))
415 collect_allocno_hard_regs_cover (node
->first
, set
);
418 /* Set up field parent as PARENT in all allocno hard registers nodes
419 in forest given by FIRST. */
421 setup_allocno_hard_regs_nodes_parent (allocno_hard_regs_node_t first
,
422 allocno_hard_regs_node_t parent
)
424 allocno_hard_regs_node_t node
;
426 for (node
= first
; node
!= NULL
; node
= node
->next
)
428 node
->parent
= parent
;
429 setup_allocno_hard_regs_nodes_parent (node
->first
, node
);
433 /* Return allocno hard registers node which is a first common ancestor
434 node of FIRST and SECOND in the forest. */
435 static allocno_hard_regs_node_t
436 first_common_ancestor_node (allocno_hard_regs_node_t first
,
437 allocno_hard_regs_node_t second
)
439 allocno_hard_regs_node_t node
;
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
)
447 return first_common_ancestor_node (second
, first
);
450 /* Print hard reg set SET to F. */
452 print_hard_reg_set (FILE *f
, HARD_REG_SET set
, bool new_line_p
)
456 for (start
= -1, i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
458 if (TEST_HARD_REG_BIT (set
, i
))
460 if (i
== 0 || ! TEST_HARD_REG_BIT (set
, i
- 1))
464 && (i
== FIRST_PSEUDO_REGISTER
- 1 || ! TEST_HARD_REG_BIT (set
, i
)))
467 fprintf (f
, " %d", start
);
468 else if (start
== i
- 2)
469 fprintf (f
, " %d %d", start
, start
+ 1);
471 fprintf (f
, " %d-%d", start
, i
- 1);
479 /* Print allocno hard register subforest given by ROOTS and its LEVEL
482 print_hard_regs_subforest (FILE *f
, allocno_hard_regs_node_t roots
,
486 allocno_hard_regs_node_t node
;
488 for (node
= roots
; node
!= NULL
; node
= node
->next
)
491 for (i
= 0; i
< level
* 2; i
++)
493 fprintf (f
, "%d:(", node
->preorder_num
);
494 print_hard_reg_set (f
, node
->hard_regs
->set
, false);
495 fprintf (f
, ")@" HOST_WIDEST_INT_PRINT_DEC
"\n", node
->hard_regs
->cost
);
496 print_hard_regs_subforest (f
, node
->first
, level
+ 1);
500 /* Print the allocno hard register forest to F. */
502 print_hard_regs_forest (FILE *f
)
504 fprintf (f
, " Hard reg set forest:\n");
505 print_hard_regs_subforest (f
, hard_regs_roots
, 1);
508 /* Print the allocno hard register forest to stderr. */
510 ira_debug_hard_regs_forest (void)
512 print_hard_regs_forest (stderr
);
515 /* Remove unused allocno hard registers nodes from forest given by its
518 remove_unused_allocno_hard_regs_nodes (allocno_hard_regs_node_t
*roots
)
520 allocno_hard_regs_node_t node
, prev
, next
, last
;
522 for (prev
= NULL
, node
= *roots
; node
!= NULL
; node
= next
)
527 remove_unused_allocno_hard_regs_nodes (&node
->first
);
532 for (last
= node
->first
;
533 last
!= NULL
&& last
->next
!= NULL
;
539 *roots
= node
->first
;
541 prev
->next
= node
->first
;
561 /* Set up fields preorder_num starting with START_NUM in all allocno
562 hard registers nodes in forest given by FIRST. Return biggest set
563 PREORDER_NUM increased by 1. */
565 enumerate_allocno_hard_regs_nodes (allocno_hard_regs_node_t first
,
566 allocno_hard_regs_node_t parent
,
569 allocno_hard_regs_node_t node
;
571 for (node
= first
; node
!= NULL
; node
= node
->next
)
573 node
->preorder_num
= start_num
++;
574 node
->parent
= parent
;
575 start_num
= enumerate_allocno_hard_regs_nodes (node
->first
, node
,
581 /* Number of allocno hard registers nodes in the forest. */
582 static int allocno_hard_regs_nodes_num
;
584 /* Table preorder number of allocno hard registers node in the forest
585 -> the allocno hard registers node. */
586 static allocno_hard_regs_node_t
*allocno_hard_regs_nodes
;
589 typedef struct allocno_hard_regs_subnode
*allocno_hard_regs_subnode_t
;
591 /* The structure is used to describes all subnodes (not only immediate
592 ones) in the mentioned above tree for given allocno hard register
593 node. The usage of such data accelerates calculation of
594 colorability of given allocno. */
595 struct allocno_hard_regs_subnode
597 /* The conflict size of conflicting allocnos whose hard register
598 sets are equal sets (plus supersets if given node is given
599 allocno hard registers node) of one in the given node. */
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,
608 short left_conflict_subnodes_size
;
609 short max_node_impact
;
612 /* Container for hard regs subnodes of all allocnos. */
613 static allocno_hard_regs_subnode_t allocno_hard_regs_subnodes
;
615 /* Table (preorder number of allocno hard registers node in the
616 forest, preorder number of allocno hard registers subnode) -> index
617 of the subnode relative to the node. -1 if it is not a
619 static int *allocno_hard_regs_subnode_index
;
621 /* Setup arrays ALLOCNO_HARD_REGS_NODES and
622 ALLOCNO_HARD_REGS_SUBNODE_INDEX. */
624 setup_allocno_hard_regs_subnode_index (allocno_hard_regs_node_t first
)
626 allocno_hard_regs_node_t node
, parent
;
629 for (node
= first
; node
!= NULL
; node
= node
->next
)
631 allocno_hard_regs_nodes
[node
->preorder_num
] = node
;
632 for (parent
= node
; parent
!= NULL
; parent
= parent
->parent
)
634 index
= parent
->preorder_num
* allocno_hard_regs_nodes_num
;
635 allocno_hard_regs_subnode_index
[index
+ node
->preorder_num
]
636 = node
->preorder_num
- parent
->preorder_num
;
638 setup_allocno_hard_regs_subnode_index (node
->first
);
642 /* Count all allocno hard registers nodes in tree ROOT. */
644 get_allocno_hard_regs_subnodes_num (allocno_hard_regs_node_t root
)
648 for (root
= root
->first
; root
!= NULL
; root
= root
->next
)
649 len
+= get_allocno_hard_regs_subnodes_num (root
);
653 /* Build the forest of allocno hard registers nodes and assign each
654 allocno a node from the forest. */
656 form_allocno_hard_regs_nodes_forest (void)
658 unsigned int i
, j
, size
, len
;
661 allocno_hard_regs_t hv
;
664 allocno_hard_regs_node_t node
, allocno_hard_regs_node
;
665 allocno_color_data_t allocno_data
;
668 init_allocno_hard_regs ();
669 hard_regs_roots
= NULL
;
670 hard_regs_node_vec
.create (100);
671 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
672 if (! TEST_HARD_REG_BIT (ira_no_alloc_regs
, i
))
674 CLEAR_HARD_REG_SET (temp
);
675 SET_HARD_REG_BIT (temp
, i
);
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
);
680 start
= allocno_hard_regs_vec
.length ();
681 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap
, 0, i
, bi
)
684 allocno_data
= ALLOCNO_COLOR_DATA (a
);
686 if (hard_reg_set_empty_p (allocno_data
->profitable_hard_regs
))
688 hv
= (add_allocno_hard_regs
689 (allocno_data
->profitable_hard_regs
,
690 ALLOCNO_MEMORY_COST (a
) - ALLOCNO_CLASS_COST (a
)));
692 SET_HARD_REG_SET (temp
);
693 AND_COMPL_HARD_REG_SET (temp
, ira_no_alloc_regs
);
694 add_allocno_hard_regs (temp
, 0);
695 qsort (allocno_hard_regs_vec
.address () + start
,
696 allocno_hard_regs_vec
.length () - start
,
697 sizeof (allocno_hard_regs_t
), allocno_hard_regs_compare
);
699 allocno_hard_regs_vec
.iterate (i
, &hv
);
702 add_allocno_hard_regs_to_forest (&hard_regs_roots
, hv
);
703 ira_assert (hard_regs_node_vec
.length () == 0);
705 /* We need to set up parent fields for right work of
706 first_common_ancestor_node. */
707 setup_allocno_hard_regs_nodes_parent (hard_regs_roots
, NULL
);
708 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap
, 0, i
, bi
)
711 allocno_data
= ALLOCNO_COLOR_DATA (a
);
712 if (hard_reg_set_empty_p (allocno_data
->profitable_hard_regs
))
714 hard_regs_node_vec
.truncate (0);
715 collect_allocno_hard_regs_cover (hard_regs_roots
,
716 allocno_data
->profitable_hard_regs
);
717 allocno_hard_regs_node
= NULL
;
718 for (j
= 0; hard_regs_node_vec
.iterate (j
, &node
); j
++)
719 allocno_hard_regs_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
;
727 ira_assert (hard_regs_roots
->next
== NULL
);
728 hard_regs_roots
->used_p
= true;
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
738 = (int *) ira_allocate (size
* sizeof (int));
739 for (i
= 0; i
< size
; i
++)
740 allocno_hard_regs_subnode_index
[i
] = -1;
741 setup_allocno_hard_regs_subnode_index (hard_regs_roots
);
743 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap
, 0, i
, bi
)
746 allocno_data
= ALLOCNO_COLOR_DATA (a
);
747 if (hard_reg_set_empty_p (allocno_data
->profitable_hard_regs
))
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
;
754 allocno_hard_regs_subnodes
755 = ((allocno_hard_regs_subnode_t
)
756 ira_allocate (sizeof (struct allocno_hard_regs_subnode
) * start
));
757 hard_regs_node_vec
.release ();
760 /* Free tree of allocno hard registers nodes given by its ROOT. */
762 finish_allocno_hard_regs_nodes_tree (allocno_hard_regs_node_t root
)
764 allocno_hard_regs_node_t child
, next
;
766 for (child
= root
->first
; child
!= NULL
; child
= next
)
769 finish_allocno_hard_regs_nodes_tree (child
);
774 /* Finish work with the forest of allocno hard registers nodes. */
776 finish_allocno_hard_regs_nodes_forest (void)
778 allocno_hard_regs_node_t node
, next
;
780 ira_free (allocno_hard_regs_subnodes
);
781 for (node
= hard_regs_roots
; node
!= NULL
; node
= next
)
784 finish_allocno_hard_regs_nodes_tree (node
);
786 ira_free (allocno_hard_regs_nodes
);
787 ira_free (allocno_hard_regs_subnode_index
);
788 finish_allocno_hard_regs ();
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. */
795 setup_left_conflict_sizes_p (ira_allocno_t a
)
797 int i
, k
, nobj
, start
;
798 int conflict_size
, left_conflict_subnodes_size
, node_preorder_num
;
799 allocno_color_data_t data
;
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
;
805 nobj
= ALLOCNO_NUM_OBJECTS (a
);
807 data
= ALLOCNO_COLOR_DATA (a
);
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
);
814 for (k
= 0; k
< nobj
; k
++)
816 ira_object_t obj
= ALLOCNO_OBJECT (a
, k
);
817 ira_object_t conflict_obj
;
818 ira_object_conflict_iterator oci
;
820 FOR_EACH_OBJECT_CONFLICT (obj
, conflict_obj
, oci
)
823 ira_allocno_t conflict_a
= OBJECT_ALLOCNO (conflict_obj
);
824 allocno_hard_regs_node_t conflict_node
, temp_node
;
825 HARD_REG_SET conflict_node_set
;
826 allocno_color_data_t conflict_data
;
828 conflict_data
= ALLOCNO_COLOR_DATA (conflict_a
);
829 if (! ALLOCNO_COLOR_DATA (conflict_a
)->in_graph_p
830 || ! hard_reg_set_intersect_p (profitable_hard_regs
,
832 ->profitable_hard_regs
))
834 conflict_node
= conflict_data
->hard_regs_node
;
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
))
840 ira_assert (hard_reg_set_subset_p (conflict_node_set
, node_set
));
841 temp_node
= conflict_node
;
843 if (temp_node
->check
!= node_check_tick
)
845 temp_node
->check
= node_check_tick
;
846 temp_node
->conflict_size
= 0;
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. */
853 temp_node
->conflict_size
+= size
;
856 for (i
= 0; i
< data
->hard_regs_subnodes_num
; i
++)
858 allocno_hard_regs_node_t temp_node
;
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
;
869 HARD_REG_SET temp_set
;
870 int j
, n
, hard_regno
;
871 enum reg_class aclass
;
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
--)
878 hard_regno
= ira_class_hard_regs
[aclass
][j
];
879 if (TEST_HARD_REG_BIT (temp_set
, hard_regno
))
882 subnodes
[i
].max_node_impact
= n
;
884 subnodes
[i
].left_conflict_subnodes_size
= 0;
886 start
= node_preorder_num
* allocno_hard_regs_nodes_num
;
887 for (i
= data
->hard_regs_subnodes_num
- 1; i
>= 0; i
--)
890 allocno_hard_regs_node_t parent
;
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
;
900 = allocno_hard_regs_subnode_index
[start
+ parent
->preorder_num
];
903 subnodes
[parent_i
].left_conflict_subnodes_size
+= size
;
905 left_conflict_subnodes_size
= subnodes
[0].left_conflict_subnodes_size
;
907 += (left_conflict_subnodes_size
908 + MIN (subnodes
[0].max_node_impact
- left_conflict_subnodes_size
,
909 subnodes
[0].left_conflict_size
));
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
;
915 /* Update left conflict sizes of hard registers subnodes of allocno A
916 after removing allocno REMOVED_A with SIZE from the conflict graph.
917 Return TRUE if A is trivially colorable. */
919 update_left_conflict_sizes_p (ira_allocno_t a
,
920 ira_allocno_t removed_a
, int size
)
922 int i
, conflict_size
, before_conflict_size
, diff
, start
;
923 int node_preorder_num
, parent_i
;
924 allocno_hard_regs_node_t node
, removed_node
, parent
;
925 allocno_hard_regs_subnode_t subnodes
;
926 allocno_color_data_t data
= ALLOCNO_COLOR_DATA (a
);
928 ira_assert (! data
->colorable_p
);
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
];
940 subnodes
= allocno_hard_regs_subnodes
+ data
->hard_regs_subnodes_start
;
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
;
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)
956 ira_assert (conflict_size
< before_conflict_size
);
957 parent
= allocno_hard_regs_nodes
[i
+ node_preorder_num
]->parent
;
961 = allocno_hard_regs_subnode_index
[start
+ parent
->preorder_num
];
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
));
970 subnodes
[i
].left_conflict_subnodes_size
-= diff
;
974 + ira_reg_class_max_nregs
[ALLOCNO_CLASS (a
)][ALLOCNO_MODE (a
)]
975 > data
->available_regs_num
))
977 data
->colorable_p
= true;
981 /* Return true if allocno A has empty profitable hard regs. */
983 empty_profitable_hard_regs (ira_allocno_t a
)
985 allocno_color_data_t data
= ALLOCNO_COLOR_DATA (a
);
987 return hard_reg_set_empty_p (data
->profitable_hard_regs
);
990 /* Set up profitable hard registers for each allocno being
993 setup_profitable_hard_regs (void)
996 int j
, k
, nobj
, hard_regno
, nregs
, class_size
;
999 enum reg_class aclass
;
1000 enum machine_mode mode
;
1001 allocno_color_data_t data
;
1003 /* Initial set up from allocno classes and explicitly conflicting
1005 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap
, 0, i
, bi
)
1007 a
= ira_allocnos
[i
];
1008 if ((aclass
= ALLOCNO_CLASS (a
)) == NO_REGS
)
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
);
1016 mode
= ALLOCNO_MODE (a
);
1017 COPY_HARD_REG_SET (data
->profitable_hard_regs
,
1018 ira_useful_class_mode_regs
[aclass
][mode
]);
1019 nobj
= ALLOCNO_NUM_OBJECTS (a
);
1020 for (k
= 0; k
< nobj
; k
++)
1022 ira_object_t obj
= ALLOCNO_OBJECT (a
, k
);
1024 AND_COMPL_HARD_REG_SET (data
->profitable_hard_regs
,
1025 OBJECT_TOTAL_CONFLICT_HARD_REGS (obj
));
1029 /* Exclude hard regs already assigned for conflicting objects. */
1030 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap
, 0, i
, bi
)
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)
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
++)
1042 ira_object_t obj
= ALLOCNO_OBJECT (a
, k
);
1043 ira_object_t conflict_obj
;
1044 ira_object_conflict_iterator oci
;
1046 FOR_EACH_OBJECT_CONFLICT (obj
, conflict_obj
, oci
)
1048 ira_allocno_t conflict_a
= OBJECT_ALLOCNO (conflict_obj
);
1050 /* We can process the conflict allocno repeatedly with
1052 if (nregs
== nobj
&& nregs
> 1)
1054 int num
= OBJECT_SUBWORD (conflict_obj
);
1056 if (REG_WORDS_BIG_ENDIAN
)
1058 (ALLOCNO_COLOR_DATA (conflict_a
)->profitable_hard_regs
,
1059 hard_regno
+ nobj
- num
- 1);
1062 (ALLOCNO_COLOR_DATA (conflict_a
)->profitable_hard_regs
,
1066 AND_COMPL_HARD_REG_SET
1067 (ALLOCNO_COLOR_DATA (conflict_a
)->profitable_hard_regs
,
1068 ira_reg_mode_hard_regset
[hard_regno
][mode
]);
1072 /* Exclude too costly hard regs. */
1073 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap
, 0, i
, bi
)
1075 int min_cost
= INT_MAX
;
1078 a
= ira_allocnos
[i
];
1079 if ((aclass
= ALLOCNO_CLASS (a
)) == NO_REGS
1080 || empty_profitable_hard_regs (a
))
1082 data
= ALLOCNO_COLOR_DATA (a
);
1083 mode
= ALLOCNO_MODE (a
);
1084 if ((costs
= ALLOCNO_UPDATED_HARD_REG_COSTS (a
)) != NULL
1085 || (costs
= ALLOCNO_HARD_REG_COSTS (a
)) != NULL
)
1087 class_size
= ira_class_hard_regs_num
[aclass
];
1088 for (j
= 0; j
< class_size
; j
++)
1090 hard_regno
= ira_class_hard_regs
[aclass
][j
];
1091 if (! TEST_HARD_REG_BIT (data
->profitable_hard_regs
,
1094 if (ALLOCNO_UPDATED_MEMORY_COST (a
) < costs
[j
])
1095 CLEAR_HARD_REG_BIT (data
->profitable_hard_regs
,
1097 else if (min_cost
> costs
[j
])
1098 min_cost
= costs
[j
];
1101 else if (ALLOCNO_UPDATED_MEMORY_COST (a
)
1102 < ALLOCNO_UPDATED_CLASS_COST (a
))
1103 CLEAR_HARD_REG_SET (data
->profitable_hard_regs
);
1104 if (ALLOCNO_UPDATED_CLASS_COST (a
) > min_cost
)
1105 ALLOCNO_UPDATED_CLASS_COST (a
) = min_cost
;
1111 /* This page contains functions used to choose hard registers for
1114 /* Array whose element value is TRUE if the corresponding hard
1115 register was already allocated for an allocno. */
1116 static bool allocated_hardreg_p
[FIRST_PSEUDO_REGISTER
];
1118 /* Describes one element in a queue of allocnos whose costs need to be
1119 updated. Each allocno in the queue is known to have an allocno
1121 struct update_cost_queue_elem
1123 /* This element is in the queue iff CHECK == update_cost_check. */
1126 /* COST_HOP_DIVISOR**N, where N is the length of the shortest path
1127 connecting this allocno to the one being allocated. */
1130 /* The next allocno in the queue, or null if this is the last element. */
1134 /* The first element in a queue of allocnos whose copy costs need to be
1135 updated. Null if the queue is empty. */
1136 static ira_allocno_t update_cost_queue
;
1138 /* The last element in the queue described by update_cost_queue.
1139 Not valid if update_cost_queue is null. */
1140 static struct update_cost_queue_elem
*update_cost_queue_tail
;
1142 /* A pool of elements in the queue described by update_cost_queue.
1143 Elements are indexed by ALLOCNO_NUM. */
1144 static struct update_cost_queue_elem
*update_cost_queue_elems
;
1146 /* The current value of update_copy_cost call count. */
1147 static int update_cost_check
;
1149 /* Allocate and initialize data necessary for function
1150 update_copy_costs. */
1152 initiate_cost_update (void)
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
);
1160 update_cost_check
= 0;
1163 /* Deallocate data used by function update_copy_costs. */
1165 finish_cost_update (void)
1167 ira_free (update_cost_queue_elems
);
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
1175 /* Start a new cost-updating pass. */
1177 start_update_cost (void)
1179 update_cost_check
++;
1180 update_cost_queue
= NULL
;
1183 /* Add (ALLOCNO, DIVISOR) to the end of update_cost_queue, unless
1184 ALLOCNO is already in the queue, or has NO_REGS class. */
1186 queue_update_cost (ira_allocno_t allocno
, int divisor
)
1188 struct update_cost_queue_elem
*elem
;
1190 elem
= &update_cost_queue_elems
[ALLOCNO_NUM (allocno
)];
1191 if (elem
->check
!= update_cost_check
1192 && ALLOCNO_CLASS (allocno
) != NO_REGS
)
1194 elem
->check
= update_cost_check
;
1195 elem
->divisor
= divisor
;
1197 if (update_cost_queue
== NULL
)
1198 update_cost_queue
= allocno
;
1200 update_cost_queue_tail
->next
= allocno
;
1201 update_cost_queue_tail
= elem
;
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. */
1209 get_next_update_cost (ira_allocno_t
*allocno
, int *divisor
)
1211 struct update_cost_queue_elem
*elem
;
1213 if (update_cost_queue
== NULL
)
1216 *allocno
= update_cost_queue
;
1217 elem
= &update_cost_queue_elems
[ALLOCNO_NUM (*allocno
)];
1218 *divisor
= elem
->divisor
;
1219 update_cost_queue
= elem
->next
;
1223 /* Update the cost of allocnos to increase chances to remove some
1224 copies as the result of subsequent assignment. */
1226 update_copy_costs (ira_allocno_t allocno
, bool decr_p
)
1228 int i
, cost
, update_cost
, hard_regno
, divisor
;
1229 enum machine_mode mode
;
1230 enum reg_class rclass
, aclass
;
1231 ira_allocno_t another_allocno
;
1232 ira_copy_t cp
, next_cp
;
1234 hard_regno
= ALLOCNO_HARD_REGNO (allocno
);
1235 ira_assert (hard_regno
>= 0);
1237 aclass
= ALLOCNO_CLASS (allocno
);
1238 if (aclass
== NO_REGS
)
1240 i
= ira_class_hard_reg_index
[aclass
][hard_regno
];
1241 ira_assert (i
>= 0);
1242 rclass
= REGNO_REG_CLASS (hard_regno
);
1244 start_update_cost ();
1248 mode
= ALLOCNO_MODE (allocno
);
1249 ira_init_register_move_cost_if_necessary (mode
);
1250 for (cp
= ALLOCNO_COPIES (allocno
); cp
!= NULL
; cp
= next_cp
)
1252 if (cp
->first
== allocno
)
1254 next_cp
= cp
->next_first_allocno_copy
;
1255 another_allocno
= cp
->second
;
1257 else if (cp
->second
== allocno
)
1259 next_cp
= cp
->next_second_allocno_copy
;
1260 another_allocno
= cp
->first
;
1265 aclass
= ALLOCNO_CLASS (another_allocno
);
1266 if (! TEST_HARD_REG_BIT (reg_class_contents
[aclass
],
1268 || ALLOCNO_ASSIGNED_P (another_allocno
))
1271 cost
= (cp
->second
== allocno
1272 ? ira_register_move_cost
[mode
][rclass
][aclass
]
1273 : ira_register_move_cost
[mode
][aclass
][rclass
]);
1277 update_cost
= cp
->freq
* cost
/ divisor
;
1278 if (update_cost
== 0)
1281 ira_allocate_and_set_or_copy_costs
1282 (&ALLOCNO_UPDATED_HARD_REG_COSTS (another_allocno
), aclass
,
1283 ALLOCNO_UPDATED_CLASS_COST (another_allocno
),
1284 ALLOCNO_HARD_REG_COSTS (another_allocno
));
1285 ira_allocate_and_set_or_copy_costs
1286 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (another_allocno
),
1287 aclass
, 0, ALLOCNO_CONFLICT_HARD_REG_COSTS (another_allocno
));
1288 i
= ira_class_hard_reg_index
[aclass
][hard_regno
];
1291 ALLOCNO_UPDATED_HARD_REG_COSTS (another_allocno
)[i
] += update_cost
;
1292 ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (another_allocno
)[i
]
1295 queue_update_cost (another_allocno
, divisor
* COST_HOP_DIVISOR
);
1298 while (get_next_update_cost (&allocno
, &divisor
));
1301 /* This function updates COSTS (decrease if DECR_P) for hard_registers
1302 of ACLASS by conflict costs of the unassigned allocnos
1303 connected by copies with allocnos in update_cost_queue. This
1304 update increases chances to remove some copies. */
1306 update_conflict_hard_regno_costs (int *costs
, enum reg_class aclass
,
1309 int i
, cost
, class_size
, freq
, mult
, div
, divisor
;
1310 int index
, hard_regno
;
1311 int *conflict_costs
;
1313 enum reg_class another_aclass
;
1314 ira_allocno_t allocno
, another_allocno
;
1315 ira_copy_t cp
, next_cp
;
1317 while (get_next_update_cost (&allocno
, &divisor
))
1318 for (cp
= ALLOCNO_COPIES (allocno
); cp
!= NULL
; cp
= next_cp
)
1320 if (cp
->first
== allocno
)
1322 next_cp
= cp
->next_first_allocno_copy
;
1323 another_allocno
= cp
->second
;
1325 else if (cp
->second
== allocno
)
1327 next_cp
= cp
->next_second_allocno_copy
;
1328 another_allocno
= cp
->first
;
1332 another_aclass
= ALLOCNO_CLASS (another_allocno
);
1333 if (! ira_reg_classes_intersect_p
[aclass
][another_aclass
]
1334 || ALLOCNO_ASSIGNED_P (another_allocno
)
1335 || ALLOCNO_COLOR_DATA (another_allocno
)->may_be_spilled_p
)
1337 class_size
= ira_class_hard_regs_num
[another_aclass
];
1338 ira_allocate_and_copy_costs
1339 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (another_allocno
),
1340 another_aclass
, ALLOCNO_CONFLICT_HARD_REG_COSTS (another_allocno
));
1342 = ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (another_allocno
);
1343 if (conflict_costs
== NULL
)
1348 freq
= ALLOCNO_FREQ (another_allocno
);
1351 div
= freq
* divisor
;
1353 for (i
= class_size
- 1; i
>= 0; i
--)
1355 hard_regno
= ira_class_hard_regs
[another_aclass
][i
];
1356 ira_assert (hard_regno
>= 0);
1357 index
= ira_class_hard_reg_index
[aclass
][hard_regno
];
1360 cost
= conflict_costs
[i
] * mult
/ div
;
1366 costs
[index
] += cost
;
1369 /* Probably 5 hops will be enough. */
1371 && divisor
<= (COST_HOP_DIVISOR
1374 * COST_HOP_DIVISOR
))
1375 queue_update_cost (another_allocno
, divisor
* COST_HOP_DIVISOR
);
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
1386 get_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
)
1393 nwords
= ALLOCNO_NUM_OBJECTS (a
);
1394 for (i
= 0; i
< nwords
; i
++)
1396 obj
= ALLOCNO_OBJECT (a
, i
);
1397 COPY_HARD_REG_SET (conflict_regs
[i
],
1398 OBJECT_TOTAL_CONFLICT_HARD_REGS (obj
));
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
)]);
1409 COPY_HARD_REG_SET (*start_profitable_regs
,
1410 ALLOCNO_COLOR_DATA (a
)->profitable_hard_regs
);
1413 /* Return true if HARD_REGNO is ok for assigning to allocno A with
1414 PROFITABLE_REGS and whose objects have CONFLICT_REGS. */
1416 check_hard_reg_p (ira_allocno_t a
, int hard_regno
,
1417 HARD_REG_SET
*conflict_regs
, HARD_REG_SET profitable_regs
)
1419 int j
, nwords
, nregs
;
1420 enum reg_class aclass
;
1421 enum machine_mode mode
;
1423 aclass
= ALLOCNO_CLASS (a
);
1424 mode
= ALLOCNO_MODE (a
);
1425 if (TEST_HARD_REG_BIT (ira_prohibited_class_mode_regs
[aclass
][mode
],
1428 /* Checking only profitable hard regs. */
1429 if (! TEST_HARD_REG_BIT (profitable_regs
, hard_regno
))
1431 nregs
= hard_regno_nregs
[hard_regno
][mode
];
1432 nwords
= ALLOCNO_NUM_OBJECTS (a
);
1433 for (j
= 0; j
< nregs
; j
++)
1436 int set_to_test_start
= 0, set_to_test_end
= nwords
;
1438 if (nregs
== nwords
)
1440 if (REG_WORDS_BIG_ENDIAN
)
1441 set_to_test_start
= nwords
- j
- 1;
1443 set_to_test_start
= j
;
1444 set_to_test_end
= set_to_test_start
+ 1;
1446 for (k
= set_to_test_start
; k
< set_to_test_end
; k
++)
1447 if (TEST_HARD_REG_BIT (conflict_regs
[k
], hard_regno
+ j
))
1449 if (k
!= set_to_test_end
)
1454 #ifndef HONOR_REG_ALLOC_ORDER
1456 /* Return number of registers needed to be saved and restored at
1457 function prologue/epilogue if we allocate HARD_REGNO to hold value
1460 calculate_saved_nregs (int hard_regno
, enum machine_mode mode
)
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
))
1475 /* Choose a hard register for allocno A. If RETRY_P is TRUE, it means
1476 that the function called from function
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.
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.
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
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. */
1499 assign_hard_reg (ira_allocno_t a
, bool retry_p
)
1501 HARD_REG_SET conflicting_regs
[2], profitable_hard_regs
;
1502 int i
, j
, hard_regno
, best_hard_regno
, class_size
;
1503 int cost
, mem_cost
, min_cost
, full_cost
, min_full_cost
, nwords
, word
;
1505 enum reg_class aclass
;
1506 enum machine_mode mode
;
1507 static int costs
[FIRST_PSEUDO_REGISTER
], full_costs
[FIRST_PSEUDO_REGISTER
];
1508 #ifndef HONOR_REG_ALLOC_ORDER
1510 enum reg_class rclass
;
1514 bool no_stack_reg_p
;
1517 ira_assert (! ALLOCNO_ASSIGNED_P (a
));
1518 get_conflict_and_start_profitable_regs (a
, retry_p
,
1520 &profitable_hard_regs
);
1521 aclass
= ALLOCNO_CLASS (a
);
1522 class_size
= ira_class_hard_regs_num
[aclass
];
1523 best_hard_regno
= -1;
1524 memset (full_costs
, 0, sizeof (int) * class_size
);
1526 memset (costs
, 0, sizeof (int) * class_size
);
1527 memset (full_costs
, 0, sizeof (int) * class_size
);
1529 no_stack_reg_p
= false;
1532 start_update_cost ();
1533 mem_cost
+= ALLOCNO_UPDATED_MEMORY_COST (a
);
1535 ira_allocate_and_copy_costs (&ALLOCNO_UPDATED_HARD_REG_COSTS (a
),
1536 aclass
, ALLOCNO_HARD_REG_COSTS (a
));
1537 a_costs
= ALLOCNO_UPDATED_HARD_REG_COSTS (a
);
1539 no_stack_reg_p
= no_stack_reg_p
|| ALLOCNO_TOTAL_NO_STACK_REG_P (a
);
1541 cost
= ALLOCNO_UPDATED_CLASS_COST (a
);
1542 for (i
= 0; i
< class_size
; i
++)
1543 if (a_costs
!= NULL
)
1545 costs
[i
] += a_costs
[i
];
1546 full_costs
[i
] += a_costs
[i
];
1551 full_costs
[i
] += cost
;
1553 nwords
= ALLOCNO_NUM_OBJECTS (a
);
1554 curr_allocno_process
++;
1555 for (word
= 0; word
< nwords
; word
++)
1557 ira_object_t conflict_obj
;
1558 ira_object_t obj
= ALLOCNO_OBJECT (a
, word
);
1559 ira_object_conflict_iterator oci
;
1561 /* Take preferences of conflicting allocnos into account. */
1562 FOR_EACH_OBJECT_CONFLICT (obj
, conflict_obj
, oci
)
1564 ira_allocno_t conflict_a
= OBJECT_ALLOCNO (conflict_obj
);
1565 enum reg_class conflict_aclass
;
1567 /* Reload can give another class so we need to check all
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
1575 (profitable_hard_regs
,
1577 (conflict_a
)->profitable_hard_regs
)))))
1579 conflict_aclass
= ALLOCNO_CLASS (conflict_a
);
1580 ira_assert (ira_reg_classes_intersect_p
1581 [aclass
][conflict_aclass
]);
1582 if (ALLOCNO_ASSIGNED_P (conflict_a
))
1584 hard_regno
= ALLOCNO_HARD_REGNO (conflict_a
);
1586 && (ira_hard_reg_set_intersection_p
1587 (hard_regno
, ALLOCNO_MODE (conflict_a
),
1588 reg_class_contents
[aclass
])))
1590 int n_objects
= ALLOCNO_NUM_OBJECTS (conflict_a
);
1593 mode
= ALLOCNO_MODE (conflict_a
);
1594 conflict_nregs
= hard_regno_nregs
[hard_regno
][mode
];
1595 if (conflict_nregs
== n_objects
&& conflict_nregs
> 1)
1597 int num
= OBJECT_SUBWORD (conflict_obj
);
1599 if (REG_WORDS_BIG_ENDIAN
)
1600 SET_HARD_REG_BIT (conflicting_regs
[word
],
1601 hard_regno
+ n_objects
- num
- 1);
1603 SET_HARD_REG_BIT (conflicting_regs
[word
],
1608 (conflicting_regs
[word
],
1609 ira_reg_mode_hard_regset
[hard_regno
][mode
]);
1610 if (hard_reg_set_subset_p (profitable_hard_regs
,
1611 conflicting_regs
[word
]))
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
))
1621 int k
, *conflict_costs
;
1623 ALLOCNO_COLOR_DATA (conflict_a
)->last_process
1624 = curr_allocno_process
;
1625 ira_allocate_and_copy_costs
1626 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (conflict_a
),
1628 ALLOCNO_CONFLICT_HARD_REG_COSTS (conflict_a
));
1630 = ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (conflict_a
);
1631 if (conflict_costs
!= NULL
)
1632 for (j
= class_size
- 1; j
>= 0; j
--)
1634 hard_regno
= ira_class_hard_regs
[aclass
][j
];
1635 ira_assert (hard_regno
>= 0);
1636 k
= ira_class_hard_reg_index
[conflict_aclass
][hard_regno
];
1639 full_costs
[j
] -= conflict_costs
[k
];
1641 queue_update_cost (conflict_a
, COST_HOP_DIVISOR
);
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);
1650 /* Take preferences of allocnos connected by copies into
1654 start_update_cost ();
1655 queue_update_cost (a
, COST_HOP_DIVISOR
);
1656 update_conflict_hard_regno_costs (full_costs
, aclass
, false);
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). */
1663 mode
= ALLOCNO_MODE (a
);
1664 for (i
= 0; i
< class_size
; i
++)
1666 hard_regno
= ira_class_hard_regs
[aclass
][i
];
1669 && FIRST_STACK_REG
<= hard_regno
&& hard_regno
<= LAST_STACK_REG
)
1672 if (! check_hard_reg_p (a
, hard_regno
,
1673 conflicting_regs
, profitable_hard_regs
))
1676 full_cost
= full_costs
[i
];
1677 #ifndef HONOR_REG_ALLOC_ORDER
1678 if ((saved_nregs
= calculate_saved_nregs (hard_regno
, mode
)) != 0)
1679 /* We need to save/restore the hard register in
1680 epilogue/prologue. Therefore we increase the cost. */
1682 rclass
= REGNO_REG_CLASS (hard_regno
);
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);
1687 full_cost
+= add_cost
;
1690 if (min_cost
> cost
)
1692 if (min_full_cost
> full_cost
)
1694 min_full_cost
= full_cost
;
1695 best_hard_regno
= hard_regno
;
1696 ira_assert (hard_regno
>= 0);
1699 if (min_full_cost
> mem_cost
)
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;
1707 if (best_hard_regno
>= 0)
1709 for (i
= hard_regno_nregs
[best_hard_regno
][mode
] - 1; i
>= 0; i
--)
1710 allocated_hardreg_p
[best_hard_regno
+ i
] = true;
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);
1716 ira_assert (ALLOCNO_CLASS (a
) == aclass
);
1717 /* We don't need updated costs anymore: */
1718 ira_free_allocno_updated_costs (a
);
1719 return best_hard_regno
>= 0;
1724 /* This page contains the allocator based on the Chaitin-Briggs algorithm. */
1726 /* Bucket of allocnos that can colored currently without spilling. */
1727 static ira_allocno_t colorable_allocno_bucket
;
1729 /* Bucket of allocnos that might be not colored currently without
1731 static ira_allocno_t uncolorable_allocno_bucket
;
1733 /* The current number of allocnos in the uncolorable_bucket. */
1734 static int uncolorable_allocnos_num
;
1736 /* Return the current spill priority of allocno A. The less the
1737 number, the more preferable the allocno for spilling. */
1739 allocno_spill_priority (ira_allocno_t a
)
1741 allocno_color_data_t data
= ALLOCNO_COLOR_DATA (a
);
1744 / (ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a
)
1745 * ira_reg_class_max_nregs
[ALLOCNO_CLASS (a
)][ALLOCNO_MODE (a
)]
1749 /* Add allocno A to bucket *BUCKET_PTR. A should be not in a bucket
1752 add_allocno_to_bucket (ira_allocno_t a
, ira_allocno_t
*bucket_ptr
)
1754 ira_allocno_t first_a
;
1755 allocno_color_data_t data
;
1757 if (bucket_ptr
== &uncolorable_allocno_bucket
1758 && ALLOCNO_CLASS (a
) != NO_REGS
)
1760 uncolorable_allocnos_num
++;
1761 ira_assert (uncolorable_allocnos_num
> 0);
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
;
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. */
1780 bucket_allocno_compare_func (const void *v1p
, const void *v2p
)
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
;
1785 int cl1
= ALLOCNO_CLASS (a1
), cl2
= ALLOCNO_CLASS (a2
);
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)
1794 a1_freq
= ALLOCNO_FREQ (a1
);
1795 a2_freq
= ALLOCNO_FREQ (a2
);
1796 if ((diff
= a1_freq
- a2_freq
) != 0)
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)
1802 return ALLOCNO_NUM (a2
) - ALLOCNO_NUM (a1
);
1805 /* Sort bucket *BUCKET_PTR and return the result through
1808 sort_bucket (ira_allocno_t
*bucket_ptr
,
1809 int (*compare_func
) (const void *, const void *))
1811 ira_allocno_t a
, head
;
1814 for (n
= 0, a
= *bucket_ptr
;
1816 a
= ALLOCNO_COLOR_DATA (a
)->next_bucket_allocno
)
1817 sorted_allocnos
[n
++] = a
;
1820 qsort (sorted_allocnos
, n
, sizeof (ira_allocno_t
), compare_func
);
1822 for (n
--; n
>= 0; n
--)
1824 a
= sorted_allocnos
[n
];
1825 ALLOCNO_COLOR_DATA (a
)->next_bucket_allocno
= head
;
1826 ALLOCNO_COLOR_DATA (a
)->prev_bucket_allocno
= NULL
;
1828 ALLOCNO_COLOR_DATA (head
)->prev_bucket_allocno
= a
;
1834 /* Add ALLOCNO to bucket *BUCKET_PTR maintaining the order according
1835 their priority. ALLOCNO should be not in a bucket before the
1838 add_allocno_to_ordered_bucket (ira_allocno_t allocno
,
1839 ira_allocno_t
*bucket_ptr
)
1841 ira_allocno_t before
, after
;
1843 if (bucket_ptr
== &uncolorable_allocno_bucket
1844 && ALLOCNO_CLASS (allocno
) != NO_REGS
)
1846 uncolorable_allocnos_num
++;
1847 ira_assert (uncolorable_allocnos_num
> 0);
1849 for (before
= *bucket_ptr
, after
= NULL
;
1852 before
= ALLOCNO_COLOR_DATA (before
)->next_bucket_allocno
)
1853 if (bucket_allocno_compare_func (&allocno
, &before
) < 0)
1855 ALLOCNO_COLOR_DATA (allocno
)->next_bucket_allocno
= before
;
1856 ALLOCNO_COLOR_DATA (allocno
)->prev_bucket_allocno
= after
;
1858 *bucket_ptr
= allocno
;
1860 ALLOCNO_COLOR_DATA (after
)->next_bucket_allocno
= allocno
;
1862 ALLOCNO_COLOR_DATA (before
)->prev_bucket_allocno
= allocno
;
1865 /* Delete ALLOCNO from bucket *BUCKET_PTR. It should be there before
1868 delete_allocno_from_bucket (ira_allocno_t allocno
, ira_allocno_t
*bucket_ptr
)
1870 ira_allocno_t prev_allocno
, next_allocno
;
1872 if (bucket_ptr
== &uncolorable_allocno_bucket
1873 && ALLOCNO_CLASS (allocno
) != NO_REGS
)
1875 uncolorable_allocnos_num
--;
1876 ira_assert (uncolorable_allocnos_num
>= 0);
1878 prev_allocno
= ALLOCNO_COLOR_DATA (allocno
)->prev_bucket_allocno
;
1879 next_allocno
= ALLOCNO_COLOR_DATA (allocno
)->next_bucket_allocno
;
1880 if (prev_allocno
!= NULL
)
1881 ALLOCNO_COLOR_DATA (prev_allocno
)->next_bucket_allocno
= next_allocno
;
1884 ira_assert (*bucket_ptr
== allocno
);
1885 *bucket_ptr
= next_allocno
;
1887 if (next_allocno
!= NULL
)
1888 ALLOCNO_COLOR_DATA (next_allocno
)->prev_bucket_allocno
= prev_allocno
;
1891 /* Put allocno A onto the coloring stack without removing it from its
1892 bucket. Pushing allocno to the coloring stack can result in moving
1893 conflicting allocnos from the uncolorable bucket to the colorable
1896 push_allocno_to_stack (ira_allocno_t a
)
1898 enum reg_class aclass
;
1899 allocno_color_data_t data
, conflict_data
;
1900 int size
, i
, n
= ALLOCNO_NUM_OBJECTS (a
);
1902 data
= ALLOCNO_COLOR_DATA (a
);
1903 data
->in_graph_p
= false;
1904 allocno_stack_vec
.safe_push (a
);
1905 aclass
= ALLOCNO_CLASS (a
);
1906 if (aclass
== NO_REGS
)
1908 size
= ira_reg_class_max_nregs
[aclass
][ALLOCNO_MODE (a
)];
1911 /* We will deal with the subwords individually. */
1912 gcc_assert (size
== ALLOCNO_NUM_OBJECTS (a
));
1915 for (i
= 0; i
< n
; i
++)
1917 ira_object_t obj
= ALLOCNO_OBJECT (a
, i
);
1918 ira_object_t conflict_obj
;
1919 ira_object_conflict_iterator oci
;
1921 FOR_EACH_OBJECT_CONFLICT (obj
, conflict_obj
, oci
)
1923 ira_allocno_t conflict_a
= OBJECT_ALLOCNO (conflict_obj
);
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
1930 (ALLOCNO_COLOR_DATA (a
)->profitable_hard_regs
,
1931 conflict_data
->profitable_hard_regs
)))
1933 ira_assert (bitmap_bit_p (coloring_allocno_bitmap
,
1934 ALLOCNO_NUM (conflict_a
)));
1935 if (update_left_conflict_sizes_p (conflict_a
, a
, size
))
1937 delete_allocno_from_bucket
1938 (conflict_a
, &uncolorable_allocno_bucket
);
1939 add_allocno_to_ordered_bucket
1940 (conflict_a
, &colorable_allocno_bucket
);
1941 if (internal_flag_ira_verbose
> 4 && ira_dump_file
!= NULL
)
1943 fprintf (ira_dump_file
, " Making");
1944 ira_print_expanded_allocno (conflict_a
);
1945 fprintf (ira_dump_file
, " colorable\n");
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. */
1956 remove_allocno_from_bucket_and_push (ira_allocno_t allocno
, bool colorable_p
)
1959 delete_allocno_from_bucket (allocno
, &colorable_allocno_bucket
);
1961 delete_allocno_from_bucket (allocno
, &uncolorable_allocno_bucket
);
1962 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
1964 fprintf (ira_dump_file
, " Pushing");
1965 ira_print_expanded_allocno (allocno
);
1967 fprintf (ira_dump_file
, "(cost %d)\n",
1968 ALLOCNO_COLOR_DATA (allocno
)->temp
);
1970 fprintf (ira_dump_file
, "(potential spill: %spri=%d, cost=%d)\n",
1971 ALLOCNO_BAD_SPILL_P (allocno
) ? "bad spill, " : "",
1972 allocno_spill_priority (allocno
),
1973 ALLOCNO_COLOR_DATA (allocno
)->temp
);
1976 ALLOCNO_COLOR_DATA (allocno
)->may_be_spilled_p
= true;
1977 push_allocno_to_stack (allocno
);
1980 /* Put all allocnos from colorable bucket onto the coloring stack. */
1982 push_only_colorable (void)
1984 sort_bucket (&colorable_allocno_bucket
, bucket_allocno_compare_func
);
1985 for (;colorable_allocno_bucket
!= NULL
;)
1986 remove_allocno_from_bucket_and_push (colorable_allocno_bucket
, true);
1989 /* Return the frequency of exit edges (if EXIT_P) or entry from/to the
1990 loop given by its LOOP_NODE. */
1992 ira_loop_edge_freq (ira_loop_tree_node_t loop_node
, int regno
, bool exit_p
)
1999 ira_assert (current_loops
!= NULL
&& loop_node
->loop
!= NULL
2000 && (regno
< 0 || regno
>= FIRST_PSEUDO_REGISTER
));
2004 FOR_EACH_EDGE (e
, ei
, loop_node
->loop
->header
->preds
)
2005 if (e
->src
!= loop_node
->loop
->latch
2007 || (bitmap_bit_p (df_get_live_out (e
->src
), regno
)
2008 && bitmap_bit_p (df_get_live_in (e
->dest
), regno
))))
2009 freq
+= EDGE_FREQUENCY (e
);
2013 edges
= get_loop_exit_edges (loop_node
->loop
);
2014 FOR_EACH_VEC_ELT (edges
, i
, e
)
2016 || (bitmap_bit_p (df_get_live_out (e
->src
), regno
)
2017 && bitmap_bit_p (df_get_live_in (e
->dest
), regno
)))
2018 freq
+= EDGE_FREQUENCY (e
);
2022 return REG_FREQ_FROM_EDGE_FREQ (freq
);
2025 /* Calculate and return the cost of putting allocno A into memory. */
2027 calculate_allocno_spill_cost (ira_allocno_t a
)
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
;
2035 regno
= ALLOCNO_REGNO (a
);
2036 cost
= ALLOCNO_UPDATED_MEMORY_COST (a
) - ALLOCNO_UPDATED_CLASS_COST (a
);
2037 if (ALLOCNO_CAP (a
) != NULL
)
2039 loop_node
= ALLOCNO_LOOP_TREE_NODE (a
);
2040 if ((parent_node
= loop_node
->parent
) == NULL
)
2042 if ((parent_allocno
= parent_node
->regno_allocno_map
[regno
]) == NULL
)
2044 mode
= ALLOCNO_MODE (a
);
2045 rclass
= ALLOCNO_CLASS (a
);
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));
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))));
2065 /* Used for sorting allocnos for spilling. */
2067 allocno_spill_priority_compare (ira_allocno_t a1
, ira_allocno_t a2
)
2069 int pri1
, pri2
, diff
;
2071 if (ALLOCNO_BAD_SPILL_P (a1
) && ! ALLOCNO_BAD_SPILL_P (a2
))
2073 if (ALLOCNO_BAD_SPILL_P (a2
) && ! ALLOCNO_BAD_SPILL_P (a1
))
2075 pri1
= allocno_spill_priority (a1
);
2076 pri2
= allocno_spill_priority (a2
);
2077 if ((diff
= pri1
- pri2
) != 0)
2080 = ALLOCNO_COLOR_DATA (a1
)->temp
- ALLOCNO_COLOR_DATA (a2
)->temp
) != 0)
2082 return ALLOCNO_NUM (a1
) - ALLOCNO_NUM (a2
);
2085 /* Used for sorting allocnos for spilling. */
2087 allocno_spill_sort_compare (const void *v1p
, const void *v2p
)
2089 ira_allocno_t p1
= *(const ira_allocno_t
*) v1p
;
2090 ira_allocno_t p2
= *(const ira_allocno_t
*) v2p
;
2092 return allocno_spill_priority_compare (p1
, p2
);
2095 /* Push allocnos to the coloring stack. The order of allocnos in the
2096 stack defines the order for the subsequent coloring. */
2098 push_allocnos_to_stack (void)
2103 /* Calculate uncolorable allocno spill costs. */
2104 for (a
= uncolorable_allocno_bucket
;
2106 a
= ALLOCNO_COLOR_DATA (a
)->next_bucket_allocno
)
2107 if (ALLOCNO_CLASS (a
) != NO_REGS
)
2109 cost
= calculate_allocno_spill_cost (a
);
2110 /* ??? Remove cost of copies between the coalesced
2112 ALLOCNO_COLOR_DATA (a
)->temp
= cost
;
2114 sort_bucket (&uncolorable_allocno_bucket
, allocno_spill_sort_compare
);
2117 push_only_colorable ();
2118 a
= uncolorable_allocno_bucket
;
2121 remove_allocno_from_bucket_and_push (a
, false);
2123 ira_assert (colorable_allocno_bucket
== NULL
2124 && uncolorable_allocno_bucket
== NULL
);
2125 ira_assert (uncolorable_allocnos_num
== 0);
2128 /* Pop the coloring stack and assign hard registers to the popped
2131 pop_allocnos_from_stack (void)
2133 ira_allocno_t allocno
;
2134 enum reg_class aclass
;
2136 for (;allocno_stack_vec
.length () != 0;)
2138 allocno
= allocno_stack_vec
.pop ();
2139 aclass
= ALLOCNO_CLASS (allocno
);
2140 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
2142 fprintf (ira_dump_file
, " Popping");
2143 ira_print_expanded_allocno (allocno
);
2144 fprintf (ira_dump_file
, " -- ");
2146 if (aclass
== NO_REGS
)
2148 ALLOCNO_HARD_REGNO (allocno
) = -1;
2149 ALLOCNO_ASSIGNED_P (allocno
) = true;
2150 ira_assert (ALLOCNO_UPDATED_HARD_REG_COSTS (allocno
) == NULL
);
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");
2156 else if (assign_hard_reg (allocno
, false))
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
));
2162 else if (ALLOCNO_ASSIGNED_P (allocno
))
2164 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
2165 fprintf (ira_dump_file
, "spill\n");
2167 ALLOCNO_COLOR_DATA (allocno
)->in_graph_p
= true;
2171 /* Set up number of available hard registers for allocno A. */
2173 setup_allocno_available_regs_num (ira_allocno_t a
)
2175 int i
, n
, hard_regno
, hard_regs_num
, nwords
;
2176 enum reg_class aclass
;
2177 allocno_color_data_t data
;
2179 aclass
= ALLOCNO_CLASS (a
);
2180 data
= ALLOCNO_COLOR_DATA (a
);
2181 data
->available_regs_num
= 0;
2182 if (aclass
== NO_REGS
)
2184 hard_regs_num
= ira_class_hard_regs_num
[aclass
];
2185 nwords
= ALLOCNO_NUM_OBJECTS (a
);
2186 for (n
= 0, i
= hard_regs_num
- 1; i
>= 0; i
--)
2188 hard_regno
= ira_class_hard_regs
[aclass
][i
];
2189 /* Checking only profitable hard regs. */
2190 if (TEST_HARD_REG_BIT (data
->profitable_hard_regs
, hard_regno
))
2193 data
->available_regs_num
= n
;
2194 if (internal_flag_ira_verbose
<= 2 || ira_dump_file
== NULL
)
2198 " Allocno a%dr%d of %s(%d) has %d avail. regs ",
2199 ALLOCNO_NUM (a
), ALLOCNO_REGNO (a
),
2200 reg_class_names
[aclass
], ira_class_hard_regs_num
[aclass
], n
);
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
)
2206 print_hard_reg_set (ira_dump_file
,
2207 data
->hard_regs_node
->hard_regs
->set
, false);
2208 for (i
= 0; i
< nwords
; i
++)
2210 ira_object_t obj
= ALLOCNO_OBJECT (a
, i
);
2215 fprintf (ira_dump_file
, ", ");
2216 fprintf (ira_dump_file
, " obj %d", i
);
2218 fprintf (ira_dump_file
, " (confl regs = ");
2219 print_hard_reg_set (ira_dump_file
, OBJECT_TOTAL_CONFLICT_HARD_REGS (obj
),
2221 fprintf (ira_dump_file
, ")");
2223 fprintf (ira_dump_file
, "\n");
2226 /* Put ALLOCNO in a bucket corresponding to its number and size of its
2227 conflicting allocnos and hard registers. */
2229 put_allocno_into_bucket (ira_allocno_t allocno
)
2231 ALLOCNO_COLOR_DATA (allocno
)->in_graph_p
= true;
2232 setup_allocno_available_regs_num (allocno
);
2233 if (setup_left_conflict_sizes_p (allocno
))
2234 add_allocno_to_bucket (allocno
, &colorable_allocno_bucket
);
2236 add_allocno_to_bucket (allocno
, &uncolorable_allocno_bucket
);
2239 /* Map: allocno number -> allocno priority. */
2240 static int *allocno_priorities
;
2242 /* Set up priorities for N allocnos in array
2243 CONSIDERATION_ALLOCNOS. */
2245 setup_allocno_priorities (ira_allocno_t
*consideration_allocnos
, int n
)
2247 int i
, length
, nrefs
, priority
, max_priority
, mult
;
2251 for (i
= 0; i
< n
; i
++)
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
)]
2261 * (ALLOCNO_MEMORY_COST (a
) - ALLOCNO_CLASS_COST (a
))
2262 * ira_reg_class_max_nregs
[ALLOCNO_CLASS (a
)][ALLOCNO_MODE (a
)]);
2264 priority
= -priority
;
2265 if (max_priority
< priority
)
2266 max_priority
= priority
;
2268 mult
= max_priority
== 0 ? 1 : INT_MAX
/ max_priority
;
2269 for (i
= 0; i
< n
; i
++)
2271 a
= consideration_allocnos
[i
];
2272 length
= ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a
);
2273 if (ALLOCNO_NUM_OBJECTS (a
) > 1)
2274 length
/= ALLOCNO_NUM_OBJECTS (a
);
2277 allocno_priorities
[ALLOCNO_NUM (a
)]
2278 = allocno_priorities
[ALLOCNO_NUM (a
)] * mult
/ length
;
2282 /* Sort allocnos according to the profit of usage of a hard register
2283 instead of memory for them. */
2285 allocno_cost_compare_func (const void *v1p
, const void *v2p
)
2287 ira_allocno_t p1
= *(const ira_allocno_t
*) v1p
;
2288 ira_allocno_t p2
= *(const ira_allocno_t
*) v2p
;
2291 c1
= ALLOCNO_UPDATED_MEMORY_COST (p1
) - ALLOCNO_UPDATED_CLASS_COST (p1
);
2292 c2
= ALLOCNO_UPDATED_MEMORY_COST (p2
) - ALLOCNO_UPDATED_CLASS_COST (p2
);
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
);
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. */
2307 improve_allocation (void)
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
;
2313 enum reg_class aclass
;
2314 enum machine_mode mode
;
2316 int costs
[FIRST_PSEUDO_REGISTER
];
2317 HARD_REG_SET conflicting_regs
[2], profitable_hard_regs
;
2321 /* Clear counts used to process conflicting allocnos only once for
2323 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap
, 0, i
, bi
)
2324 ALLOCNO_COLOR_DATA (ira_allocnos
[i
])->temp
= 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
)
2330 a
= ira_allocnos
[i
];
2331 ALLOCNO_COLOR_DATA (a
)->temp
= 0;
2332 if (empty_profitable_hard_regs (a
))
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
2347 base_cost
= allocno_costs
[ira_class_hard_reg_index
[aclass
][hregno
]];
2349 get_conflict_and_start_profitable_regs (a
, false,
2351 &profitable_hard_regs
);
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
++)
2357 hregno
= ira_class_hard_regs
[aclass
][j
];
2358 if (! check_hard_reg_p (a
, hregno
,
2359 conflicting_regs
, profitable_hard_regs
))
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)
2370 /* There is no chance to improve the allocation cost by
2371 assigning hard register to allocno A even without spilling
2372 conflicting allocnos. */
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
2381 for (word
= 0; word
< nwords
; word
++)
2383 ira_object_t conflict_obj
;
2384 ira_object_t obj
= ALLOCNO_OBJECT (a
, word
);
2385 ira_object_conflict_iterator oci
;
2387 FOR_EACH_OBJECT_CONFLICT (obj
, conflict_obj
, oci
)
2389 ira_allocno_t conflict_a
= OBJECT_ALLOCNO (conflict_obj
);
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. */
2396 ALLOCNO_COLOR_DATA (conflict_a
)->temp
= check
;
2397 if ((conflict_hregno
= ALLOCNO_HARD_REGNO (conflict_a
)) < 0)
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
))
2405 spill_cost
-= allocno_costs
[k
];
2406 else if ((allocno_costs
= ALLOCNO_HARD_REG_COSTS (conflict_a
))
2408 spill_cost
-= allocno_costs
[k
];
2410 spill_cost
-= ALLOCNO_UPDATED_CLASS_COST (conflict_a
);
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
;
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
;
2422 if (check_hard_reg_p (a
, r
,
2423 conflicting_regs
, profitable_hard_regs
))
2424 costs
[r
] += spill_cost
;
2429 /* Now we choose hard register for A which results in highest
2430 allocation cost improvement. */
2431 for (j
= 0; j
< class_size
; j
++)
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
])
2439 min_cost
= costs
[hregno
];
2443 /* We are in a situation when assigning any hard register to A
2444 by spilling some conflicting allocnos does not improve the
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
++)
2452 ira_object_t conflict_obj
;
2453 ira_object_t obj
= ALLOCNO_OBJECT (a
, word
);
2454 ira_object_conflict_iterator oci
;
2456 FOR_EACH_OBJECT_CONFLICT (obj
, conflict_obj
, oci
)
2458 ira_allocno_t conflict_a
= OBJECT_ALLOCNO (conflict_obj
);
2460 if ((conflict_hregno
= ALLOCNO_HARD_REGNO (conflict_a
)) < 0)
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. */
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
));
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
));
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
++)
2497 a
= sorted_allocnos
[j
];
2498 ALLOCNO_ASSIGNED_P (a
) = false;
2499 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
2501 fprintf (ira_dump_file
, " ");
2502 ira_print_expanded_allocno (a
);
2503 fprintf (ira_dump_file
, " -- ");
2505 if (assign_hard_reg (a
, false))
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
));
2513 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
2514 fprintf (ira_dump_file
, "assign memory\n");
2519 /* Sort allocnos according to their priorities. */
2521 allocno_priority_compare_func (const void *v1p
, const void *v2p
)
2523 ira_allocno_t a1
= *(const ira_allocno_t
*) v1p
;
2524 ira_allocno_t a2
= *(const ira_allocno_t
*) v2p
;
2527 pri1
= allocno_priorities
[ALLOCNO_NUM (a1
)];
2528 pri2
= allocno_priorities
[ALLOCNO_NUM (a2
)];
2530 return SORTGT (pri2
, pri1
);
2532 /* If regs are equally good, sort by allocnos, so that the results of
2533 qsort leave nothing to chance. */
2534 return ALLOCNO_NUM (a1
) - ALLOCNO_NUM (a2
);
2537 /* Chaitin-Briggs coloring for allocnos in COLORING_ALLOCNO_BITMAP
2538 taking into account allocnos in CONSIDERATION_ALLOCNO_BITMAP. */
2540 color_allocnos (void)
2546 setup_profitable_hard_regs ();
2547 if (flag_ira_algorithm
== IRA_ALGORITHM_PRIORITY
)
2550 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap
, 0, i
, bi
)
2552 a
= ira_allocnos
[i
];
2553 if (ALLOCNO_CLASS (a
) == NO_REGS
)
2555 ALLOCNO_HARD_REGNO (a
) = -1;
2556 ALLOCNO_ASSIGNED_P (a
) = true;
2557 ira_assert (ALLOCNO_UPDATED_HARD_REG_COSTS (a
) == NULL
);
2558 ira_assert (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a
) == NULL
);
2559 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
2561 fprintf (ira_dump_file
, " Spill");
2562 ira_print_expanded_allocno (a
);
2563 fprintf (ira_dump_file
, "\n");
2567 sorted_allocnos
[n
++] = a
;
2571 setup_allocno_priorities (sorted_allocnos
, n
);
2572 qsort (sorted_allocnos
, n
, sizeof (ira_allocno_t
),
2573 allocno_priority_compare_func
);
2574 for (i
= 0; i
< n
; i
++)
2576 a
= sorted_allocnos
[i
];
2577 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
2579 fprintf (ira_dump_file
, " ");
2580 ira_print_expanded_allocno (a
);
2581 fprintf (ira_dump_file
, " -- ");
2583 if (assign_hard_reg (a
, false))
2585 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
2586 fprintf (ira_dump_file
, "assign hard reg %d\n",
2587 ALLOCNO_HARD_REGNO (a
));
2591 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
2592 fprintf (ira_dump_file
, "assign memory\n");
2599 form_allocno_hard_regs_nodes_forest ();
2600 if (internal_flag_ira_verbose
> 2 && ira_dump_file
!= NULL
)
2601 print_hard_regs_forest (ira_dump_file
);
2602 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap
, 0, i
, bi
)
2604 a
= ira_allocnos
[i
];
2605 if (ALLOCNO_CLASS (a
) != NO_REGS
&& ! empty_profitable_hard_regs (a
))
2606 ALLOCNO_COLOR_DATA (a
)->in_graph_p
= true;
2609 ALLOCNO_HARD_REGNO (a
) = -1;
2610 ALLOCNO_ASSIGNED_P (a
) = true;
2611 /* We don't need updated costs anymore. */
2612 ira_free_allocno_updated_costs (a
);
2613 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
2615 fprintf (ira_dump_file
, " Spill");
2616 ira_print_expanded_allocno (a
);
2617 fprintf (ira_dump_file
, "\n");
2621 /* Put the allocnos into the corresponding buckets. */
2622 colorable_allocno_bucket
= NULL
;
2623 uncolorable_allocno_bucket
= NULL
;
2624 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap
, 0, i
, bi
)
2626 a
= ira_allocnos
[i
];
2627 if (ALLOCNO_COLOR_DATA (a
)->in_graph_p
)
2628 put_allocno_into_bucket (a
);
2630 push_allocnos_to_stack ();
2631 pop_allocnos_from_stack ();
2632 finish_allocno_hard_regs_nodes_forest ();
2634 improve_allocation ();
2639 /* Output information about the loop given by its LOOP_TREE_NODE. */
2641 print_loop_title (ira_loop_tree_node_t loop_tree_node
)
2645 ira_loop_tree_node_t subloop_node
, dest_loop_node
;
2649 if (loop_tree_node
->parent
== NULL
)
2650 fprintf (ira_dump_file
,
2651 "\n Loop 0 (parent -1, header bb%d, depth 0)\n bbs:",
2655 ira_assert (current_loops
!= NULL
&& loop_tree_node
->loop
!= NULL
);
2656 fprintf (ira_dump_file
,
2657 "\n Loop %d (parent %d, header bb%d, depth %d)\n bbs:",
2658 loop_tree_node
->loop_num
, loop_tree_node
->parent
->loop_num
,
2659 loop_tree_node
->loop
->header
->index
,
2660 loop_depth (loop_tree_node
->loop
));
2662 for (subloop_node
= loop_tree_node
->children
;
2663 subloop_node
!= NULL
;
2664 subloop_node
= subloop_node
->next
)
2665 if (subloop_node
->bb
!= NULL
)
2667 fprintf (ira_dump_file
, " %d", subloop_node
->bb
->index
);
2668 FOR_EACH_EDGE (e
, ei
, subloop_node
->bb
->succs
)
2669 if (e
->dest
!= EXIT_BLOCK_PTR
2670 && ((dest_loop_node
= IRA_BB_NODE (e
->dest
)->parent
)
2672 fprintf (ira_dump_file
, "(->%d:l%d)",
2673 e
->dest
->index
, dest_loop_node
->loop_num
);
2675 fprintf (ira_dump_file
, "\n all:");
2676 EXECUTE_IF_SET_IN_BITMAP (loop_tree_node
->all_allocnos
, 0, j
, bi
)
2677 fprintf (ira_dump_file
, " %dr%d", j
, ALLOCNO_REGNO (ira_allocnos
[j
]));
2678 fprintf (ira_dump_file
, "\n modified regnos:");
2679 EXECUTE_IF_SET_IN_BITMAP (loop_tree_node
->modified_regnos
, 0, j
, bi
)
2680 fprintf (ira_dump_file
, " %d", j
);
2681 fprintf (ira_dump_file
, "\n border:");
2682 EXECUTE_IF_SET_IN_BITMAP (loop_tree_node
->border_allocnos
, 0, j
, bi
)
2683 fprintf (ira_dump_file
, " %dr%d", j
, ALLOCNO_REGNO (ira_allocnos
[j
]));
2684 fprintf (ira_dump_file
, "\n Pressure:");
2685 for (j
= 0; (int) j
< ira_pressure_classes_num
; j
++)
2687 enum reg_class pclass
;
2689 pclass
= ira_pressure_classes
[j
];
2690 if (loop_tree_node
->reg_pressure
[pclass
] == 0)
2692 fprintf (ira_dump_file
, " %s=%d", reg_class_names
[pclass
],
2693 loop_tree_node
->reg_pressure
[pclass
]);
2695 fprintf (ira_dump_file
, "\n");
2698 /* Color the allocnos inside loop (in the extreme case it can be all
2699 of the function) given the corresponding LOOP_TREE_NODE. The
2700 function is called for each loop during top-down traverse of the
2703 color_pass (ira_loop_tree_node_t loop_tree_node
)
2705 int regno
, hard_regno
, index
= -1, n
;
2706 int cost
, exit_freq
, enter_freq
;
2709 enum machine_mode mode
;
2710 enum reg_class rclass
, aclass
, pclass
;
2711 ira_allocno_t a
, subloop_allocno
;
2712 ira_loop_tree_node_t subloop_node
;
2714 ira_assert (loop_tree_node
->bb
== NULL
);
2715 if (internal_flag_ira_verbose
> 1 && ira_dump_file
!= NULL
)
2716 print_loop_title (loop_tree_node
);
2718 bitmap_copy (coloring_allocno_bitmap
, loop_tree_node
->all_allocnos
);
2719 bitmap_copy (consideration_allocno_bitmap
, coloring_allocno_bitmap
);
2721 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap
, 0, j
, bi
)
2723 a
= ira_allocnos
[j
];
2725 if (! ALLOCNO_ASSIGNED_P (a
))
2727 bitmap_clear_bit (coloring_allocno_bitmap
, ALLOCNO_NUM (a
));
2730 = (allocno_color_data_t
) ira_allocate (sizeof (struct allocno_color_data
)
2732 memset (allocno_color_data
, 0, sizeof (struct allocno_color_data
) * n
);
2733 curr_allocno_process
= 0;
2735 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap
, 0, j
, bi
)
2737 a
= ira_allocnos
[j
];
2738 ALLOCNO_ADD_DATA (a
) = allocno_color_data
+ n
;
2741 /* Color all mentioned allocnos including transparent ones. */
2743 /* Process caps. They are processed just once. */
2744 if (flag_ira_region
== IRA_REGION_MIXED
2745 || flag_ira_region
== IRA_REGION_ALL
)
2746 EXECUTE_IF_SET_IN_BITMAP (loop_tree_node
->all_allocnos
, 0, j
, bi
)
2748 a
= ira_allocnos
[j
];
2749 if (ALLOCNO_CAP_MEMBER (a
) == NULL
)
2751 /* Remove from processing in the next loop. */
2752 bitmap_clear_bit (consideration_allocno_bitmap
, j
);
2753 rclass
= ALLOCNO_CLASS (a
);
2754 pclass
= ira_pressure_class_translate
[rclass
];
2755 if (flag_ira_region
== IRA_REGION_MIXED
2756 && (loop_tree_node
->reg_pressure
[pclass
]
2757 <= ira_class_hard_regs_num
[pclass
]))
2759 mode
= ALLOCNO_MODE (a
);
2760 hard_regno
= ALLOCNO_HARD_REGNO (a
);
2761 if (hard_regno
>= 0)
2763 index
= ira_class_hard_reg_index
[rclass
][hard_regno
];
2764 ira_assert (index
>= 0);
2766 regno
= ALLOCNO_REGNO (a
);
2767 subloop_allocno
= ALLOCNO_CAP_MEMBER (a
);
2768 subloop_node
= ALLOCNO_LOOP_TREE_NODE (subloop_allocno
);
2769 ira_assert (!ALLOCNO_ASSIGNED_P (subloop_allocno
));
2770 ALLOCNO_HARD_REGNO (subloop_allocno
) = hard_regno
;
2771 ALLOCNO_ASSIGNED_P (subloop_allocno
) = true;
2772 if (hard_regno
>= 0)
2773 update_copy_costs (subloop_allocno
, true);
2774 /* We don't need updated costs anymore: */
2775 ira_free_allocno_updated_costs (subloop_allocno
);
2778 /* Update costs of the corresponding allocnos (not caps) in the
2780 for (subloop_node
= loop_tree_node
->subloops
;
2781 subloop_node
!= NULL
;
2782 subloop_node
= subloop_node
->subloop_next
)
2784 ira_assert (subloop_node
->bb
== NULL
);
2785 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap
, 0, j
, bi
)
2787 a
= ira_allocnos
[j
];
2788 ira_assert (ALLOCNO_CAP_MEMBER (a
) == NULL
);
2789 mode
= ALLOCNO_MODE (a
);
2790 rclass
= ALLOCNO_CLASS (a
);
2791 pclass
= ira_pressure_class_translate
[rclass
];
2792 hard_regno
= ALLOCNO_HARD_REGNO (a
);
2793 /* Use hard register class here. ??? */
2794 if (hard_regno
>= 0)
2796 index
= ira_class_hard_reg_index
[rclass
][hard_regno
];
2797 ira_assert (index
>= 0);
2799 regno
= ALLOCNO_REGNO (a
);
2800 /* ??? conflict costs */
2801 subloop_allocno
= subloop_node
->regno_allocno_map
[regno
];
2802 if (subloop_allocno
== NULL
2803 || ALLOCNO_CAP (subloop_allocno
) != NULL
)
2805 ira_assert (ALLOCNO_CLASS (subloop_allocno
) == rclass
);
2806 ira_assert (bitmap_bit_p (subloop_node
->all_allocnos
,
2807 ALLOCNO_NUM (subloop_allocno
)));
2808 if ((flag_ira_region
== IRA_REGION_MIXED
)
2809 && (loop_tree_node
->reg_pressure
[pclass
]
2810 <= ira_class_hard_regs_num
[pclass
]))
2812 if (! ALLOCNO_ASSIGNED_P (subloop_allocno
))
2814 ALLOCNO_HARD_REGNO (subloop_allocno
) = hard_regno
;
2815 ALLOCNO_ASSIGNED_P (subloop_allocno
) = true;
2816 if (hard_regno
>= 0)
2817 update_copy_costs (subloop_allocno
, true);
2818 /* We don't need updated costs anymore: */
2819 ira_free_allocno_updated_costs (subloop_allocno
);
2823 exit_freq
= ira_loop_edge_freq (subloop_node
, regno
, true);
2824 enter_freq
= ira_loop_edge_freq (subloop_node
, regno
, false);
2825 ira_assert (regno
< ira_reg_equiv_len
);
2826 if (ira_equiv_no_lvalue_p (regno
))
2828 if (! ALLOCNO_ASSIGNED_P (subloop_allocno
))
2830 ALLOCNO_HARD_REGNO (subloop_allocno
) = hard_regno
;
2831 ALLOCNO_ASSIGNED_P (subloop_allocno
) = true;
2832 if (hard_regno
>= 0)
2833 update_copy_costs (subloop_allocno
, true);
2834 /* We don't need updated costs anymore: */
2835 ira_free_allocno_updated_costs (subloop_allocno
);
2838 else if (hard_regno
< 0)
2840 ALLOCNO_UPDATED_MEMORY_COST (subloop_allocno
)
2841 -= ((ira_memory_move_cost
[mode
][rclass
][1] * enter_freq
)
2842 + (ira_memory_move_cost
[mode
][rclass
][0] * exit_freq
));
2846 aclass
= ALLOCNO_CLASS (subloop_allocno
);
2847 ira_init_register_move_cost_if_necessary (mode
);
2848 cost
= (ira_register_move_cost
[mode
][rclass
][rclass
]
2849 * (exit_freq
+ enter_freq
));
2850 ira_allocate_and_set_or_copy_costs
2851 (&ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno
), aclass
,
2852 ALLOCNO_UPDATED_CLASS_COST (subloop_allocno
),
2853 ALLOCNO_HARD_REG_COSTS (subloop_allocno
));
2854 ira_allocate_and_set_or_copy_costs
2855 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (subloop_allocno
),
2856 aclass
, 0, ALLOCNO_CONFLICT_HARD_REG_COSTS (subloop_allocno
));
2857 ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno
)[index
] -= cost
;
2858 ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (subloop_allocno
)[index
]
2860 if (ALLOCNO_UPDATED_CLASS_COST (subloop_allocno
)
2861 > ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno
)[index
])
2862 ALLOCNO_UPDATED_CLASS_COST (subloop_allocno
)
2863 = ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno
)[index
];
2864 ALLOCNO_UPDATED_MEMORY_COST (subloop_allocno
)
2865 += (ira_memory_move_cost
[mode
][rclass
][0] * enter_freq
2866 + ira_memory_move_cost
[mode
][rclass
][1] * exit_freq
);
2870 ira_free (allocno_color_data
);
2871 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap
, 0, j
, bi
)
2873 a
= ira_allocnos
[j
];
2874 ALLOCNO_ADD_DATA (a
) = NULL
;
2878 /* Initialize the common data for coloring and calls functions to do
2879 Chaitin-Briggs and regional coloring. */
2883 coloring_allocno_bitmap
= ira_allocate_bitmap ();
2884 if (internal_flag_ira_verbose
> 0 && ira_dump_file
!= NULL
)
2885 fprintf (ira_dump_file
, "\n**** Allocnos coloring:\n\n");
2887 ira_traverse_loop_tree (false, ira_loop_tree_root
, color_pass
, NULL
);
2889 if (internal_flag_ira_verbose
> 1 && ira_dump_file
!= NULL
)
2890 ira_print_disposition (ira_dump_file
);
2892 ira_free_bitmap (coloring_allocno_bitmap
);
2897 /* Move spill/restore code, which are to be generated in ira-emit.c,
2898 to less frequent points (if it is profitable) by reassigning some
2899 allocnos (in loop with subloops containing in another loop) to
2900 memory which results in longer live-range where the corresponding
2901 pseudo-registers will be in memory. */
2903 move_spill_restore (void)
2905 int cost
, regno
, hard_regno
, hard_regno2
, index
;
2907 int enter_freq
, exit_freq
;
2908 enum machine_mode mode
;
2909 enum reg_class rclass
;
2910 ira_allocno_t a
, parent_allocno
, subloop_allocno
;
2911 ira_loop_tree_node_t parent
, loop_node
, subloop_node
;
2912 ira_allocno_iterator ai
;
2917 if (internal_flag_ira_verbose
> 0 && ira_dump_file
!= NULL
)
2918 fprintf (ira_dump_file
, "New iteration of spill/restore move\n");
2919 FOR_EACH_ALLOCNO (a
, ai
)
2921 regno
= ALLOCNO_REGNO (a
);
2922 loop_node
= ALLOCNO_LOOP_TREE_NODE (a
);
2923 if (ALLOCNO_CAP_MEMBER (a
) != NULL
2924 || ALLOCNO_CAP (a
) != NULL
2925 || (hard_regno
= ALLOCNO_HARD_REGNO (a
)) < 0
2926 || loop_node
->children
== NULL
2927 /* don't do the optimization because it can create
2928 copies and the reload pass can spill the allocno set
2929 by copy although the allocno will not get memory
2931 || ira_equiv_no_lvalue_p (regno
)
2932 || !bitmap_bit_p (loop_node
->border_allocnos
, ALLOCNO_NUM (a
)))
2934 mode
= ALLOCNO_MODE (a
);
2935 rclass
= ALLOCNO_CLASS (a
);
2936 index
= ira_class_hard_reg_index
[rclass
][hard_regno
];
2937 ira_assert (index
>= 0);
2938 cost
= (ALLOCNO_MEMORY_COST (a
)
2939 - (ALLOCNO_HARD_REG_COSTS (a
) == NULL
2940 ? ALLOCNO_CLASS_COST (a
)
2941 : ALLOCNO_HARD_REG_COSTS (a
)[index
]));
2942 ira_init_register_move_cost_if_necessary (mode
);
2943 for (subloop_node
= loop_node
->subloops
;
2944 subloop_node
!= NULL
;
2945 subloop_node
= subloop_node
->subloop_next
)
2947 ira_assert (subloop_node
->bb
== NULL
);
2948 subloop_allocno
= subloop_node
->regno_allocno_map
[regno
];
2949 if (subloop_allocno
== NULL
)
2951 ira_assert (rclass
== ALLOCNO_CLASS (subloop_allocno
));
2952 /* We have accumulated cost. To get the real cost of
2953 allocno usage in the loop we should subtract costs of
2954 the subloop allocnos. */
2955 cost
-= (ALLOCNO_MEMORY_COST (subloop_allocno
)
2956 - (ALLOCNO_HARD_REG_COSTS (subloop_allocno
) == NULL
2957 ? ALLOCNO_CLASS_COST (subloop_allocno
)
2958 : ALLOCNO_HARD_REG_COSTS (subloop_allocno
)[index
]));
2959 exit_freq
= ira_loop_edge_freq (subloop_node
, regno
, true);
2960 enter_freq
= ira_loop_edge_freq (subloop_node
, regno
, false);
2961 if ((hard_regno2
= ALLOCNO_HARD_REGNO (subloop_allocno
)) < 0)
2962 cost
-= (ira_memory_move_cost
[mode
][rclass
][0] * exit_freq
2963 + ira_memory_move_cost
[mode
][rclass
][1] * enter_freq
);
2967 += (ira_memory_move_cost
[mode
][rclass
][0] * exit_freq
2968 + ira_memory_move_cost
[mode
][rclass
][1] * enter_freq
);
2969 if (hard_regno2
!= hard_regno
)
2970 cost
-= (ira_register_move_cost
[mode
][rclass
][rclass
]
2971 * (exit_freq
+ enter_freq
));
2974 if ((parent
= loop_node
->parent
) != NULL
2975 && (parent_allocno
= parent
->regno_allocno_map
[regno
]) != NULL
)
2977 ira_assert (rclass
== ALLOCNO_CLASS (parent_allocno
));
2978 exit_freq
= ira_loop_edge_freq (loop_node
, regno
, true);
2979 enter_freq
= ira_loop_edge_freq (loop_node
, regno
, false);
2980 if ((hard_regno2
= ALLOCNO_HARD_REGNO (parent_allocno
)) < 0)
2981 cost
-= (ira_memory_move_cost
[mode
][rclass
][0] * exit_freq
2982 + ira_memory_move_cost
[mode
][rclass
][1] * enter_freq
);
2986 += (ira_memory_move_cost
[mode
][rclass
][1] * exit_freq
2987 + ira_memory_move_cost
[mode
][rclass
][0] * enter_freq
);
2988 if (hard_regno2
!= hard_regno
)
2989 cost
-= (ira_register_move_cost
[mode
][rclass
][rclass
]
2990 * (exit_freq
+ enter_freq
));
2995 ALLOCNO_HARD_REGNO (a
) = -1;
2996 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
3000 " Moving spill/restore for a%dr%d up from loop %d",
3001 ALLOCNO_NUM (a
), regno
, loop_node
->loop_num
);
3002 fprintf (ira_dump_file
, " - profit %d\n", -cost
);
3014 /* Update current hard reg costs and current conflict hard reg costs
3015 for allocno A. It is done by processing its copies containing
3016 other allocnos already assigned. */
3018 update_curr_costs (ira_allocno_t a
)
3020 int i
, hard_regno
, cost
;
3021 enum machine_mode mode
;
3022 enum reg_class aclass
, rclass
;
3023 ira_allocno_t another_a
;
3024 ira_copy_t cp
, next_cp
;
3026 ira_free_allocno_updated_costs (a
);
3027 ira_assert (! ALLOCNO_ASSIGNED_P (a
));
3028 aclass
= ALLOCNO_CLASS (a
);
3029 if (aclass
== NO_REGS
)
3031 mode
= ALLOCNO_MODE (a
);
3032 ira_init_register_move_cost_if_necessary (mode
);
3033 for (cp
= ALLOCNO_COPIES (a
); cp
!= NULL
; cp
= next_cp
)
3037 next_cp
= cp
->next_first_allocno_copy
;
3038 another_a
= cp
->second
;
3040 else if (cp
->second
== a
)
3042 next_cp
= cp
->next_second_allocno_copy
;
3043 another_a
= cp
->first
;
3047 if (! ira_reg_classes_intersect_p
[aclass
][ALLOCNO_CLASS (another_a
)]
3048 || ! ALLOCNO_ASSIGNED_P (another_a
)
3049 || (hard_regno
= ALLOCNO_HARD_REGNO (another_a
)) < 0)
3051 rclass
= REGNO_REG_CLASS (hard_regno
);
3052 i
= ira_class_hard_reg_index
[aclass
][hard_regno
];
3055 cost
= (cp
->first
== a
3056 ? ira_register_move_cost
[mode
][rclass
][aclass
]
3057 : ira_register_move_cost
[mode
][aclass
][rclass
]);
3058 ira_allocate_and_set_or_copy_costs
3059 (&ALLOCNO_UPDATED_HARD_REG_COSTS (a
), aclass
, ALLOCNO_CLASS_COST (a
),
3060 ALLOCNO_HARD_REG_COSTS (a
));
3061 ira_allocate_and_set_or_copy_costs
3062 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a
),
3063 aclass
, 0, ALLOCNO_CONFLICT_HARD_REG_COSTS (a
));
3064 ALLOCNO_UPDATED_HARD_REG_COSTS (a
)[i
] -= cp
->freq
* cost
;
3065 ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a
)[i
] -= cp
->freq
* cost
;
3069 /* Try to assign hard registers to the unassigned allocnos and
3070 allocnos conflicting with them or conflicting with allocnos whose
3071 regno >= START_REGNO. The function is called after ira_flattening,
3072 so more allocnos (including ones created in ira-emit.c) will have a
3073 chance to get a hard register. We use simple assignment algorithm
3074 based on priorities. */
3076 ira_reassign_conflict_allocnos (int start_regno
)
3078 int i
, allocnos_to_color_num
;
3080 enum reg_class aclass
;
3081 bitmap allocnos_to_color
;
3082 ira_allocno_iterator ai
;
3084 allocnos_to_color
= ira_allocate_bitmap ();
3085 allocnos_to_color_num
= 0;
3086 FOR_EACH_ALLOCNO (a
, ai
)
3088 int n
= ALLOCNO_NUM_OBJECTS (a
);
3090 if (! ALLOCNO_ASSIGNED_P (a
)
3091 && ! bitmap_bit_p (allocnos_to_color
, ALLOCNO_NUM (a
)))
3093 if (ALLOCNO_CLASS (a
) != NO_REGS
)
3094 sorted_allocnos
[allocnos_to_color_num
++] = a
;
3097 ALLOCNO_ASSIGNED_P (a
) = true;
3098 ALLOCNO_HARD_REGNO (a
) = -1;
3099 ira_assert (ALLOCNO_UPDATED_HARD_REG_COSTS (a
) == NULL
);
3100 ira_assert (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a
) == NULL
);
3102 bitmap_set_bit (allocnos_to_color
, ALLOCNO_NUM (a
));
3104 if (ALLOCNO_REGNO (a
) < start_regno
3105 || (aclass
= ALLOCNO_CLASS (a
)) == NO_REGS
)
3107 for (i
= 0; i
< n
; i
++)
3109 ira_object_t obj
= ALLOCNO_OBJECT (a
, i
);
3110 ira_object_t conflict_obj
;
3111 ira_object_conflict_iterator oci
;
3113 FOR_EACH_OBJECT_CONFLICT (obj
, conflict_obj
, oci
)
3115 ira_allocno_t conflict_a
= OBJECT_ALLOCNO (conflict_obj
);
3117 ira_assert (ira_reg_classes_intersect_p
3118 [aclass
][ALLOCNO_CLASS (conflict_a
)]);
3119 if (!bitmap_set_bit (allocnos_to_color
, ALLOCNO_NUM (conflict_a
)))
3121 sorted_allocnos
[allocnos_to_color_num
++] = conflict_a
;
3125 ira_free_bitmap (allocnos_to_color
);
3126 if (allocnos_to_color_num
> 1)
3128 setup_allocno_priorities (sorted_allocnos
, allocnos_to_color_num
);
3129 qsort (sorted_allocnos
, allocnos_to_color_num
, sizeof (ira_allocno_t
),
3130 allocno_priority_compare_func
);
3132 for (i
= 0; i
< allocnos_to_color_num
; i
++)
3134 a
= sorted_allocnos
[i
];
3135 ALLOCNO_ASSIGNED_P (a
) = false;
3136 update_curr_costs (a
);
3138 for (i
= 0; i
< allocnos_to_color_num
; i
++)
3140 a
= sorted_allocnos
[i
];
3141 if (assign_hard_reg (a
, true))
3143 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
3146 " Secondary allocation: assign hard reg %d to reg %d\n",
3147 ALLOCNO_HARD_REGNO (a
), ALLOCNO_REGNO (a
));
3154 /* This page contains functions used to find conflicts using allocno
3157 /* Return TRUE if live ranges of allocnos A1 and A2 intersect. It is
3158 used to find a conflict for new allocnos or allocnos with the
3159 different allocno classes. */
3161 allocnos_conflict_by_live_ranges_p (ira_allocno_t a1
, ira_allocno_t a2
)
3165 int n1
= ALLOCNO_NUM_OBJECTS (a1
);
3166 int n2
= ALLOCNO_NUM_OBJECTS (a2
);
3170 reg1
= regno_reg_rtx
[ALLOCNO_REGNO (a1
)];
3171 reg2
= regno_reg_rtx
[ALLOCNO_REGNO (a2
)];
3172 if (reg1
!= NULL
&& reg2
!= NULL
3173 && ORIGINAL_REGNO (reg1
) == ORIGINAL_REGNO (reg2
))
3176 for (i
= 0; i
< n1
; i
++)
3178 ira_object_t c1
= ALLOCNO_OBJECT (a1
, i
);
3180 for (j
= 0; j
< n2
; j
++)
3182 ira_object_t c2
= ALLOCNO_OBJECT (a2
, j
);
3184 if (ira_live_ranges_intersect_p (OBJECT_LIVE_RANGES (c1
),
3185 OBJECT_LIVE_RANGES (c2
)))
3192 #ifdef ENABLE_IRA_CHECKING
3194 /* Return TRUE if live ranges of pseudo-registers REGNO1 and REGNO2
3195 intersect. This should be used when there is only one region.
3196 Currently this is used during reload. */
3198 conflict_by_live_ranges_p (int regno1
, int regno2
)
3200 ira_allocno_t a1
, a2
;
3202 ira_assert (regno1
>= FIRST_PSEUDO_REGISTER
3203 && regno2
>= FIRST_PSEUDO_REGISTER
);
3204 /* Reg info caclulated by dataflow infrastructure can be different
3205 from one calculated by regclass. */
3206 if ((a1
= ira_loop_tree_root
->regno_allocno_map
[regno1
]) == NULL
3207 || (a2
= ira_loop_tree_root
->regno_allocno_map
[regno2
]) == NULL
)
3209 return allocnos_conflict_by_live_ranges_p (a1
, a2
);
3216 /* This page contains code to coalesce memory stack slots used by
3217 spilled allocnos. This results in smaller stack frame, better data
3218 locality, and in smaller code for some architectures like
3219 x86/x86_64 where insn size depends on address displacement value.
3220 On the other hand, it can worsen insn scheduling after the RA but
3221 in practice it is less important than smaller stack frames. */
3223 /* TRUE if we coalesced some allocnos. In other words, if we got
3224 loops formed by members first_coalesced_allocno and
3225 next_coalesced_allocno containing more one allocno. */
3226 static bool allocno_coalesced_p
;
3228 /* Bitmap used to prevent a repeated allocno processing because of
3230 static bitmap processed_coalesced_allocno_bitmap
;
3233 typedef struct coalesce_data
*coalesce_data_t
;
3235 /* To decrease footprint of ira_allocno structure we store all data
3236 needed only for coalescing in the following structure. */
3237 struct coalesce_data
3239 /* Coalesced allocnos form a cyclic list. One allocno given by
3240 FIRST represents all coalesced allocnos. The
3241 list is chained by NEXT. */
3242 ira_allocno_t first
;
3247 /* Container for storing allocno data concerning coalescing. */
3248 static coalesce_data_t allocno_coalesce_data
;
3250 /* Macro to access the data concerning coalescing. */
3251 #define ALLOCNO_COALESCE_DATA(a) ((coalesce_data_t) ALLOCNO_ADD_DATA (a))
3253 /* The function is used to sort allocnos according to their execution
3256 copy_freq_compare_func (const void *v1p
, const void *v2p
)
3258 ira_copy_t cp1
= *(const ira_copy_t
*) v1p
, cp2
= *(const ira_copy_t
*) v2p
;
3266 /* If freqencies are equal, sort by copies, so that the results of
3267 qsort leave nothing to chance. */
3268 return cp1
->num
- cp2
->num
;
3271 /* Merge two sets of coalesced allocnos given correspondingly by
3272 allocnos A1 and A2 (more accurately merging A2 set into A1
3275 merge_allocnos (ira_allocno_t a1
, ira_allocno_t a2
)
3277 ira_allocno_t a
, first
, last
, next
;
3279 first
= ALLOCNO_COALESCE_DATA (a1
)->first
;
3280 a
= ALLOCNO_COALESCE_DATA (a2
)->first
;
3283 for (last
= a2
, a
= ALLOCNO_COALESCE_DATA (a2
)->next
;;
3284 a
= ALLOCNO_COALESCE_DATA (a
)->next
)
3286 ALLOCNO_COALESCE_DATA (a
)->first
= first
;
3291 next
= allocno_coalesce_data
[ALLOCNO_NUM (first
)].next
;
3292 allocno_coalesce_data
[ALLOCNO_NUM (first
)].next
= a2
;
3293 allocno_coalesce_data
[ALLOCNO_NUM (last
)].next
= next
;
3296 /* Return TRUE if there are conflicting allocnos from two sets of
3297 coalesced allocnos given correspondingly by allocnos A1 and A2. We
3298 use live ranges to find conflicts because conflicts are represented
3299 only for allocnos of the same allocno class and during the reload
3300 pass we coalesce allocnos for sharing stack memory slots. */
3302 coalesced_allocno_conflict_p (ira_allocno_t a1
, ira_allocno_t a2
)
3304 ira_allocno_t a
, conflict_a
;
3306 if (allocno_coalesced_p
)
3308 bitmap_clear (processed_coalesced_allocno_bitmap
);
3309 for (a
= ALLOCNO_COALESCE_DATA (a1
)->next
;;
3310 a
= ALLOCNO_COALESCE_DATA (a
)->next
)
3312 bitmap_set_bit (processed_coalesced_allocno_bitmap
, ALLOCNO_NUM (a
));
3317 for (a
= ALLOCNO_COALESCE_DATA (a2
)->next
;;
3318 a
= ALLOCNO_COALESCE_DATA (a
)->next
)
3320 for (conflict_a
= ALLOCNO_COALESCE_DATA (a1
)->next
;;
3321 conflict_a
= ALLOCNO_COALESCE_DATA (conflict_a
)->next
)
3323 if (allocnos_conflict_by_live_ranges_p (a
, conflict_a
))
3325 if (conflict_a
== a1
)
3334 /* The major function for aggressive allocno coalescing. We coalesce
3335 only spilled allocnos. If some allocnos have been coalesced, we
3336 set up flag allocno_coalesced_p. */
3338 coalesce_allocnos (void)
3341 ira_copy_t cp
, next_cp
, *sorted_copies
;
3343 int i
, n
, cp_num
, regno
;
3346 sorted_copies
= (ira_copy_t
*) ira_allocate (ira_copies_num
3347 * sizeof (ira_copy_t
));
3349 /* Collect copies. */
3350 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap
, 0, j
, bi
)
3352 a
= ira_allocnos
[j
];
3353 regno
= ALLOCNO_REGNO (a
);
3354 if (! ALLOCNO_ASSIGNED_P (a
) || ALLOCNO_HARD_REGNO (a
) >= 0
3355 || ira_equiv_no_lvalue_p (regno
))
3357 for (cp
= ALLOCNO_COPIES (a
); cp
!= NULL
; cp
= next_cp
)
3361 next_cp
= cp
->next_first_allocno_copy
;
3362 regno
= ALLOCNO_REGNO (cp
->second
);
3363 /* For priority coloring we coalesce allocnos only with
3364 the same allocno class not with intersected allocno
3365 classes as it were possible. It is done for
3367 if ((cp
->insn
!= NULL
|| cp
->constraint_p
)
3368 && ALLOCNO_ASSIGNED_P (cp
->second
)
3369 && ALLOCNO_HARD_REGNO (cp
->second
) < 0
3370 && ! ira_equiv_no_lvalue_p (regno
))
3371 sorted_copies
[cp_num
++] = cp
;
3373 else if (cp
->second
== a
)
3374 next_cp
= cp
->next_second_allocno_copy
;
3379 qsort (sorted_copies
, cp_num
, sizeof (ira_copy_t
), copy_freq_compare_func
);
3380 /* Coalesced copies, most frequently executed first. */
3381 for (; cp_num
!= 0;)
3383 for (i
= 0; i
< cp_num
; i
++)
3385 cp
= sorted_copies
[i
];
3386 if (! coalesced_allocno_conflict_p (cp
->first
, cp
->second
))
3388 allocno_coalesced_p
= true;
3389 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
3392 " Coalescing copy %d:a%dr%d-a%dr%d (freq=%d)\n",
3393 cp
->num
, ALLOCNO_NUM (cp
->first
), ALLOCNO_REGNO (cp
->first
),
3394 ALLOCNO_NUM (cp
->second
), ALLOCNO_REGNO (cp
->second
),
3396 merge_allocnos (cp
->first
, cp
->second
);
3401 /* Collect the rest of copies. */
3402 for (n
= 0; i
< cp_num
; i
++)
3404 cp
= sorted_copies
[i
];
3405 if (allocno_coalesce_data
[ALLOCNO_NUM (cp
->first
)].first
3406 != allocno_coalesce_data
[ALLOCNO_NUM (cp
->second
)].first
)
3407 sorted_copies
[n
++] = cp
;
3411 ira_free (sorted_copies
);
3414 /* Usage cost and order number of coalesced allocno set to which
3415 given pseudo register belongs to. */
3416 static int *regno_coalesced_allocno_cost
;
3417 static int *regno_coalesced_allocno_num
;
3419 /* Sort pseudos according frequencies of coalesced allocno sets they
3420 belong to (putting most frequently ones first), and according to
3421 coalesced allocno set order numbers. */
3423 coalesced_pseudo_reg_freq_compare (const void *v1p
, const void *v2p
)
3425 const int regno1
= *(const int *) v1p
;
3426 const int regno2
= *(const int *) v2p
;
3429 if ((diff
= (regno_coalesced_allocno_cost
[regno2
]
3430 - regno_coalesced_allocno_cost
[regno1
])) != 0)
3432 if ((diff
= (regno_coalesced_allocno_num
[regno1
]
3433 - regno_coalesced_allocno_num
[regno2
])) != 0)
3435 return regno1
- regno2
;
3438 /* Widest width in which each pseudo reg is referred to (via subreg).
3439 It is used for sorting pseudo registers. */
3440 static unsigned int *regno_max_ref_width
;
3442 /* Redefine STACK_GROWS_DOWNWARD in terms of 0 or 1. */
3443 #ifdef STACK_GROWS_DOWNWARD
3444 # undef STACK_GROWS_DOWNWARD
3445 # define STACK_GROWS_DOWNWARD 1
3447 # define STACK_GROWS_DOWNWARD 0
3450 /* Sort pseudos according their slot numbers (putting ones with
3451 smaller numbers first, or last when the frame pointer is not
3454 coalesced_pseudo_reg_slot_compare (const void *v1p
, const void *v2p
)
3456 const int regno1
= *(const int *) v1p
;
3457 const int regno2
= *(const int *) v2p
;
3458 ira_allocno_t a1
= ira_regno_allocno_map
[regno1
];
3459 ira_allocno_t a2
= ira_regno_allocno_map
[regno2
];
3460 int diff
, slot_num1
, slot_num2
;
3461 int total_size1
, total_size2
;
3463 if (a1
== NULL
|| ALLOCNO_HARD_REGNO (a1
) >= 0)
3465 if (a2
== NULL
|| ALLOCNO_HARD_REGNO (a2
) >= 0)
3466 return regno1
- regno2
;
3469 else if (a2
== NULL
|| ALLOCNO_HARD_REGNO (a2
) >= 0)
3471 slot_num1
= -ALLOCNO_HARD_REGNO (a1
);
3472 slot_num2
= -ALLOCNO_HARD_REGNO (a2
);
3473 if ((diff
= slot_num1
- slot_num2
) != 0)
3474 return (frame_pointer_needed
3475 || !FRAME_GROWS_DOWNWARD
== STACK_GROWS_DOWNWARD
? diff
: -diff
);
3476 total_size1
= MAX (PSEUDO_REGNO_BYTES (regno1
),
3477 regno_max_ref_width
[regno1
]);
3478 total_size2
= MAX (PSEUDO_REGNO_BYTES (regno2
),
3479 regno_max_ref_width
[regno2
]);
3480 if ((diff
= total_size2
- total_size1
) != 0)
3482 return regno1
- regno2
;
3485 /* Setup REGNO_COALESCED_ALLOCNO_COST and REGNO_COALESCED_ALLOCNO_NUM
3486 for coalesced allocno sets containing allocnos with their regnos
3487 given in array PSEUDO_REGNOS of length N. */
3489 setup_coalesced_allocno_costs_and_nums (int *pseudo_regnos
, int n
)
3491 int i
, num
, regno
, cost
;
3492 ira_allocno_t allocno
, a
;
3494 for (num
= i
= 0; i
< n
; i
++)
3496 regno
= pseudo_regnos
[i
];
3497 allocno
= ira_regno_allocno_map
[regno
];
3498 if (allocno
== NULL
)
3500 regno_coalesced_allocno_cost
[regno
] = 0;
3501 regno_coalesced_allocno_num
[regno
] = ++num
;
3504 if (ALLOCNO_COALESCE_DATA (allocno
)->first
!= allocno
)
3507 for (cost
= 0, a
= ALLOCNO_COALESCE_DATA (allocno
)->next
;;
3508 a
= ALLOCNO_COALESCE_DATA (a
)->next
)
3510 cost
+= ALLOCNO_FREQ (a
);
3514 for (a
= ALLOCNO_COALESCE_DATA (allocno
)->next
;;
3515 a
= ALLOCNO_COALESCE_DATA (a
)->next
)
3517 regno_coalesced_allocno_num
[ALLOCNO_REGNO (a
)] = num
;
3518 regno_coalesced_allocno_cost
[ALLOCNO_REGNO (a
)] = cost
;
3525 /* Collect spilled allocnos representing coalesced allocno sets (the
3526 first coalesced allocno). The collected allocnos are returned
3527 through array SPILLED_COALESCED_ALLOCNOS. The function returns the
3528 number of the collected allocnos. The allocnos are given by their
3529 regnos in array PSEUDO_REGNOS of length N. */
3531 collect_spilled_coalesced_allocnos (int *pseudo_regnos
, int n
,
3532 ira_allocno_t
*spilled_coalesced_allocnos
)
3535 ira_allocno_t allocno
;
3537 for (num
= i
= 0; i
< n
; i
++)
3539 regno
= pseudo_regnos
[i
];
3540 allocno
= ira_regno_allocno_map
[regno
];
3541 if (allocno
== NULL
|| ALLOCNO_HARD_REGNO (allocno
) >= 0
3542 || ALLOCNO_COALESCE_DATA (allocno
)->first
!= allocno
)
3544 spilled_coalesced_allocnos
[num
++] = allocno
;
3549 /* Array of live ranges of size IRA_ALLOCNOS_NUM. Live range for
3550 given slot contains live ranges of coalesced allocnos assigned to
3552 static live_range_t
*slot_coalesced_allocnos_live_ranges
;
3554 /* Return TRUE if coalesced allocnos represented by ALLOCNO has live
3555 ranges intersected with live ranges of coalesced allocnos assigned
3556 to slot with number N. */
3558 slot_coalesced_allocno_live_ranges_intersect_p (ira_allocno_t allocno
, int n
)
3562 for (a
= ALLOCNO_COALESCE_DATA (allocno
)->next
;;
3563 a
= ALLOCNO_COALESCE_DATA (a
)->next
)
3566 int nr
= ALLOCNO_NUM_OBJECTS (a
);
3568 for (i
= 0; i
< nr
; i
++)
3570 ira_object_t obj
= ALLOCNO_OBJECT (a
, i
);
3572 if (ira_live_ranges_intersect_p
3573 (slot_coalesced_allocnos_live_ranges
[n
],
3574 OBJECT_LIVE_RANGES (obj
)))
3583 /* Update live ranges of slot to which coalesced allocnos represented
3584 by ALLOCNO were assigned. */
3586 setup_slot_coalesced_allocno_live_ranges (ira_allocno_t allocno
)
3592 n
= ALLOCNO_COALESCE_DATA (allocno
)->temp
;
3593 for (a
= ALLOCNO_COALESCE_DATA (allocno
)->next
;;
3594 a
= ALLOCNO_COALESCE_DATA (a
)->next
)
3596 int nr
= ALLOCNO_NUM_OBJECTS (a
);
3597 for (i
= 0; i
< nr
; i
++)
3599 ira_object_t obj
= ALLOCNO_OBJECT (a
, i
);
3601 r
= ira_copy_live_range_list (OBJECT_LIVE_RANGES (obj
));
3602 slot_coalesced_allocnos_live_ranges
[n
]
3603 = ira_merge_live_ranges
3604 (slot_coalesced_allocnos_live_ranges
[n
], r
);
3611 /* We have coalesced allocnos involving in copies. Coalesce allocnos
3612 further in order to share the same memory stack slot. Allocnos
3613 representing sets of allocnos coalesced before the call are given
3614 in array SPILLED_COALESCED_ALLOCNOS of length NUM. Return TRUE if
3615 some allocnos were coalesced in the function. */
3617 coalesce_spill_slots (ira_allocno_t
*spilled_coalesced_allocnos
, int num
)
3619 int i
, j
, n
, last_coalesced_allocno_num
;
3620 ira_allocno_t allocno
, a
;
3621 bool merged_p
= false;
3622 bitmap set_jump_crosses
= regstat_get_setjmp_crosses ();
3624 slot_coalesced_allocnos_live_ranges
3625 = (live_range_t
*) ira_allocate (sizeof (live_range_t
) * ira_allocnos_num
);
3626 memset (slot_coalesced_allocnos_live_ranges
, 0,
3627 sizeof (live_range_t
) * ira_allocnos_num
);
3628 last_coalesced_allocno_num
= 0;
3629 /* Coalesce non-conflicting spilled allocnos preferring most
3631 for (i
= 0; i
< num
; i
++)
3633 allocno
= spilled_coalesced_allocnos
[i
];
3634 if (ALLOCNO_COALESCE_DATA (allocno
)->first
!= allocno
3635 || bitmap_bit_p (set_jump_crosses
, ALLOCNO_REGNO (allocno
))
3636 || ira_equiv_no_lvalue_p (ALLOCNO_REGNO (allocno
)))
3638 for (j
= 0; j
< i
; j
++)
3640 a
= spilled_coalesced_allocnos
[j
];
3641 n
= ALLOCNO_COALESCE_DATA (a
)->temp
;
3642 if (ALLOCNO_COALESCE_DATA (a
)->first
== a
3643 && ! bitmap_bit_p (set_jump_crosses
, ALLOCNO_REGNO (a
))
3644 && ! ira_equiv_no_lvalue_p (ALLOCNO_REGNO (a
))
3645 && ! slot_coalesced_allocno_live_ranges_intersect_p (allocno
, n
))
3650 /* No coalescing: set up number for coalesced allocnos
3651 represented by ALLOCNO. */
3652 ALLOCNO_COALESCE_DATA (allocno
)->temp
= last_coalesced_allocno_num
++;
3653 setup_slot_coalesced_allocno_live_ranges (allocno
);
3657 allocno_coalesced_p
= true;
3659 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
3660 fprintf (ira_dump_file
,
3661 " Coalescing spilled allocnos a%dr%d->a%dr%d\n",
3662 ALLOCNO_NUM (allocno
), ALLOCNO_REGNO (allocno
),
3663 ALLOCNO_NUM (a
), ALLOCNO_REGNO (a
));
3664 ALLOCNO_COALESCE_DATA (allocno
)->temp
3665 = ALLOCNO_COALESCE_DATA (a
)->temp
;
3666 setup_slot_coalesced_allocno_live_ranges (allocno
);
3667 merge_allocnos (a
, allocno
);
3668 ira_assert (ALLOCNO_COALESCE_DATA (a
)->first
== a
);
3671 for (i
= 0; i
< ira_allocnos_num
; i
++)
3672 ira_finish_live_range_list (slot_coalesced_allocnos_live_ranges
[i
]);
3673 ira_free (slot_coalesced_allocnos_live_ranges
);
3677 /* Sort pseudo-register numbers in array PSEUDO_REGNOS of length N for
3678 subsequent assigning stack slots to them in the reload pass. To do
3679 this we coalesce spilled allocnos first to decrease the number of
3680 memory-memory move insns. This function is called by the
3683 ira_sort_regnos_for_alter_reg (int *pseudo_regnos
, int n
,
3684 unsigned int *reg_max_ref_width
)
3686 int max_regno
= max_reg_num ();
3687 int i
, regno
, num
, slot_num
;
3688 ira_allocno_t allocno
, a
;
3689 ira_allocno_iterator ai
;
3690 ira_allocno_t
*spilled_coalesced_allocnos
;
3692 /* Set up allocnos can be coalesced. */
3693 coloring_allocno_bitmap
= ira_allocate_bitmap ();
3694 for (i
= 0; i
< n
; i
++)
3696 regno
= pseudo_regnos
[i
];
3697 allocno
= ira_regno_allocno_map
[regno
];
3698 if (allocno
!= NULL
)
3699 bitmap_set_bit (coloring_allocno_bitmap
, ALLOCNO_NUM (allocno
));
3701 allocno_coalesced_p
= false;
3702 processed_coalesced_allocno_bitmap
= ira_allocate_bitmap ();
3703 allocno_coalesce_data
3704 = (coalesce_data_t
) ira_allocate (sizeof (struct coalesce_data
)
3705 * ira_allocnos_num
);
3706 /* Initialize coalesce data for allocnos. */
3707 FOR_EACH_ALLOCNO (a
, ai
)
3709 ALLOCNO_ADD_DATA (a
) = allocno_coalesce_data
+ ALLOCNO_NUM (a
);
3710 ALLOCNO_COALESCE_DATA (a
)->first
= a
;
3711 ALLOCNO_COALESCE_DATA (a
)->next
= a
;
3713 coalesce_allocnos ();
3714 ira_free_bitmap (coloring_allocno_bitmap
);
3715 regno_coalesced_allocno_cost
3716 = (int *) ira_allocate (max_regno
* sizeof (int));
3717 regno_coalesced_allocno_num
3718 = (int *) ira_allocate (max_regno
* sizeof (int));
3719 memset (regno_coalesced_allocno_num
, 0, max_regno
* sizeof (int));
3720 setup_coalesced_allocno_costs_and_nums (pseudo_regnos
, n
);
3721 /* Sort regnos according frequencies of the corresponding coalesced
3723 qsort (pseudo_regnos
, n
, sizeof (int), coalesced_pseudo_reg_freq_compare
);
3724 spilled_coalesced_allocnos
3725 = (ira_allocno_t
*) ira_allocate (ira_allocnos_num
3726 * sizeof (ira_allocno_t
));
3727 /* Collect allocnos representing the spilled coalesced allocno
3729 num
= collect_spilled_coalesced_allocnos (pseudo_regnos
, n
,
3730 spilled_coalesced_allocnos
);
3731 if (flag_ira_share_spill_slots
3732 && coalesce_spill_slots (spilled_coalesced_allocnos
, num
))
3734 setup_coalesced_allocno_costs_and_nums (pseudo_regnos
, n
);
3735 qsort (pseudo_regnos
, n
, sizeof (int),
3736 coalesced_pseudo_reg_freq_compare
);
3737 num
= collect_spilled_coalesced_allocnos (pseudo_regnos
, n
,
3738 spilled_coalesced_allocnos
);
3740 ira_free_bitmap (processed_coalesced_allocno_bitmap
);
3741 allocno_coalesced_p
= false;
3742 /* Assign stack slot numbers to spilled allocno sets, use smaller
3743 numbers for most frequently used coalesced allocnos. -1 is
3744 reserved for dynamic search of stack slots for pseudos spilled by
3747 for (i
= 0; i
< num
; i
++)
3749 allocno
= spilled_coalesced_allocnos
[i
];
3750 if (ALLOCNO_COALESCE_DATA (allocno
)->first
!= allocno
3751 || ALLOCNO_HARD_REGNO (allocno
) >= 0
3752 || ira_equiv_no_lvalue_p (ALLOCNO_REGNO (allocno
)))
3754 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
3755 fprintf (ira_dump_file
, " Slot %d (freq,size):", slot_num
);
3757 for (a
= ALLOCNO_COALESCE_DATA (allocno
)->next
;;
3758 a
= ALLOCNO_COALESCE_DATA (a
)->next
)
3760 ira_assert (ALLOCNO_HARD_REGNO (a
) < 0);
3761 ALLOCNO_HARD_REGNO (a
) = -slot_num
;
3762 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
3763 fprintf (ira_dump_file
, " a%dr%d(%d,%d)",
3764 ALLOCNO_NUM (a
), ALLOCNO_REGNO (a
), ALLOCNO_FREQ (a
),
3765 MAX (PSEUDO_REGNO_BYTES (ALLOCNO_REGNO (a
)),
3766 reg_max_ref_width
[ALLOCNO_REGNO (a
)]));
3771 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
3772 fprintf (ira_dump_file
, "\n");
3774 ira_spilled_reg_stack_slots_num
= slot_num
- 1;
3775 ira_free (spilled_coalesced_allocnos
);
3776 /* Sort regnos according the slot numbers. */
3777 regno_max_ref_width
= reg_max_ref_width
;
3778 qsort (pseudo_regnos
, n
, sizeof (int), coalesced_pseudo_reg_slot_compare
);
3779 FOR_EACH_ALLOCNO (a
, ai
)
3780 ALLOCNO_ADD_DATA (a
) = NULL
;
3781 ira_free (allocno_coalesce_data
);
3782 ira_free (regno_coalesced_allocno_num
);
3783 ira_free (regno_coalesced_allocno_cost
);
3788 /* This page contains code used by the reload pass to improve the
3791 /* The function is called from reload to mark changes in the
3792 allocation of REGNO made by the reload. Remember that reg_renumber
3793 reflects the change result. */
3795 ira_mark_allocation_change (int regno
)
3797 ira_allocno_t a
= ira_regno_allocno_map
[regno
];
3798 int old_hard_regno
, hard_regno
, cost
;
3799 enum reg_class aclass
= ALLOCNO_CLASS (a
);
3801 ira_assert (a
!= NULL
);
3802 hard_regno
= reg_renumber
[regno
];
3803 if ((old_hard_regno
= ALLOCNO_HARD_REGNO (a
)) == hard_regno
)
3805 if (old_hard_regno
< 0)
3806 cost
= -ALLOCNO_MEMORY_COST (a
);
3809 ira_assert (ira_class_hard_reg_index
[aclass
][old_hard_regno
] >= 0);
3810 cost
= -(ALLOCNO_HARD_REG_COSTS (a
) == NULL
3811 ? ALLOCNO_CLASS_COST (a
)
3812 : ALLOCNO_HARD_REG_COSTS (a
)
3813 [ira_class_hard_reg_index
[aclass
][old_hard_regno
]]);
3814 update_copy_costs (a
, false);
3816 ira_overall_cost
-= cost
;
3817 ALLOCNO_HARD_REGNO (a
) = hard_regno
;
3820 ALLOCNO_HARD_REGNO (a
) = -1;
3821 cost
+= ALLOCNO_MEMORY_COST (a
);
3823 else if (ira_class_hard_reg_index
[aclass
][hard_regno
] >= 0)
3825 cost
+= (ALLOCNO_HARD_REG_COSTS (a
) == NULL
3826 ? ALLOCNO_CLASS_COST (a
)
3827 : ALLOCNO_HARD_REG_COSTS (a
)
3828 [ira_class_hard_reg_index
[aclass
][hard_regno
]]);
3829 update_copy_costs (a
, true);
3832 /* Reload changed class of the allocno. */
3834 ira_overall_cost
+= cost
;
3837 /* This function is called when reload deletes memory-memory move. In
3838 this case we marks that the allocation of the corresponding
3839 allocnos should be not changed in future. Otherwise we risk to get
3842 ira_mark_memory_move_deletion (int dst_regno
, int src_regno
)
3844 ira_allocno_t dst
= ira_regno_allocno_map
[dst_regno
];
3845 ira_allocno_t src
= ira_regno_allocno_map
[src_regno
];
3847 ira_assert (dst
!= NULL
&& src
!= NULL
3848 && ALLOCNO_HARD_REGNO (dst
) < 0
3849 && ALLOCNO_HARD_REGNO (src
) < 0);
3850 ALLOCNO_DONT_REASSIGN_P (dst
) = true;
3851 ALLOCNO_DONT_REASSIGN_P (src
) = true;
3854 /* Try to assign a hard register (except for FORBIDDEN_REGS) to
3855 allocno A and return TRUE in the case of success. */
3857 allocno_reload_assign (ira_allocno_t a
, HARD_REG_SET forbidden_regs
)
3860 enum reg_class aclass
;
3861 int regno
= ALLOCNO_REGNO (a
);
3862 HARD_REG_SET saved
[2];
3865 n
= ALLOCNO_NUM_OBJECTS (a
);
3866 for (i
= 0; i
< n
; i
++)
3868 ira_object_t obj
= ALLOCNO_OBJECT (a
, i
);
3869 COPY_HARD_REG_SET (saved
[i
], OBJECT_TOTAL_CONFLICT_HARD_REGS (obj
));
3870 IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj
), forbidden_regs
);
3871 if (! flag_caller_saves
&& ALLOCNO_CALLS_CROSSED_NUM (a
) != 0)
3872 IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj
),
3875 ALLOCNO_ASSIGNED_P (a
) = false;
3876 aclass
= ALLOCNO_CLASS (a
);
3877 update_curr_costs (a
);
3878 assign_hard_reg (a
, true);
3879 hard_regno
= ALLOCNO_HARD_REGNO (a
);
3880 reg_renumber
[regno
] = hard_regno
;
3882 ALLOCNO_HARD_REGNO (a
) = -1;
3885 ira_assert (ira_class_hard_reg_index
[aclass
][hard_regno
] >= 0);
3887 -= (ALLOCNO_MEMORY_COST (a
)
3888 - (ALLOCNO_HARD_REG_COSTS (a
) == NULL
3889 ? ALLOCNO_CLASS_COST (a
)
3890 : ALLOCNO_HARD_REG_COSTS (a
)[ira_class_hard_reg_index
3891 [aclass
][hard_regno
]]));
3892 if (ALLOCNO_CALLS_CROSSED_NUM (a
) != 0
3893 && ira_hard_reg_set_intersection_p (hard_regno
, ALLOCNO_MODE (a
),
3896 ira_assert (flag_caller_saves
);
3897 caller_save_needed
= 1;
3901 /* If we found a hard register, modify the RTL for the pseudo
3902 register to show the hard register, and mark the pseudo register
3904 if (reg_renumber
[regno
] >= 0)
3906 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
3907 fprintf (ira_dump_file
, ": reassign to %d\n", reg_renumber
[regno
]);
3908 SET_REGNO (regno_reg_rtx
[regno
], reg_renumber
[regno
]);
3909 mark_home_live (regno
);
3911 else if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
3912 fprintf (ira_dump_file
, "\n");
3913 for (i
= 0; i
< n
; i
++)
3915 ira_object_t obj
= ALLOCNO_OBJECT (a
, i
);
3916 COPY_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj
), saved
[i
]);
3918 return reg_renumber
[regno
] >= 0;
3921 /* Sort pseudos according their usage frequencies (putting most
3922 frequently ones first). */
3924 pseudo_reg_compare (const void *v1p
, const void *v2p
)
3926 int regno1
= *(const int *) v1p
;
3927 int regno2
= *(const int *) v2p
;
3930 if ((diff
= REG_FREQ (regno2
) - REG_FREQ (regno1
)) != 0)
3932 return regno1
- regno2
;
3935 /* Try to allocate hard registers to SPILLED_PSEUDO_REGS (there are
3936 NUM of them) or spilled pseudos conflicting with pseudos in
3937 SPILLED_PSEUDO_REGS. Return TRUE and update SPILLED, if the
3938 allocation has been changed. The function doesn't use
3939 BAD_SPILL_REGS and hard registers in PSEUDO_FORBIDDEN_REGS and
3940 PSEUDO_PREVIOUS_REGS for the corresponding pseudos. The function
3941 is called by the reload pass at the end of each reload
3944 ira_reassign_pseudos (int *spilled_pseudo_regs
, int num
,
3945 HARD_REG_SET bad_spill_regs
,
3946 HARD_REG_SET
*pseudo_forbidden_regs
,
3947 HARD_REG_SET
*pseudo_previous_regs
,
3953 HARD_REG_SET forbidden_regs
;
3954 bitmap temp
= BITMAP_ALLOC (NULL
);
3956 /* Add pseudos which conflict with pseudos already in
3957 SPILLED_PSEUDO_REGS to SPILLED_PSEUDO_REGS. This is preferable
3958 to allocating in two steps as some of the conflicts might have
3959 a higher priority than the pseudos passed in SPILLED_PSEUDO_REGS. */
3960 for (i
= 0; i
< num
; i
++)
3961 bitmap_set_bit (temp
, spilled_pseudo_regs
[i
]);
3963 for (i
= 0, n
= num
; i
< n
; i
++)
3966 int regno
= spilled_pseudo_regs
[i
];
3967 bitmap_set_bit (temp
, regno
);
3969 a
= ira_regno_allocno_map
[regno
];
3970 nr
= ALLOCNO_NUM_OBJECTS (a
);
3971 for (j
= 0; j
< nr
; j
++)
3973 ira_object_t conflict_obj
;
3974 ira_object_t obj
= ALLOCNO_OBJECT (a
, j
);
3975 ira_object_conflict_iterator oci
;
3977 FOR_EACH_OBJECT_CONFLICT (obj
, conflict_obj
, oci
)
3979 ira_allocno_t conflict_a
= OBJECT_ALLOCNO (conflict_obj
);
3980 if (ALLOCNO_HARD_REGNO (conflict_a
) < 0
3981 && ! ALLOCNO_DONT_REASSIGN_P (conflict_a
)
3982 && bitmap_set_bit (temp
, ALLOCNO_REGNO (conflict_a
)))
3984 spilled_pseudo_regs
[num
++] = ALLOCNO_REGNO (conflict_a
);
3985 /* ?!? This seems wrong. */
3986 bitmap_set_bit (consideration_allocno_bitmap
,
3987 ALLOCNO_NUM (conflict_a
));
3994 qsort (spilled_pseudo_regs
, num
, sizeof (int), pseudo_reg_compare
);
3996 /* Try to assign hard registers to pseudos from
3997 SPILLED_PSEUDO_REGS. */
3998 for (i
= 0; i
< num
; i
++)
4000 regno
= spilled_pseudo_regs
[i
];
4001 COPY_HARD_REG_SET (forbidden_regs
, bad_spill_regs
);
4002 IOR_HARD_REG_SET (forbidden_regs
, pseudo_forbidden_regs
[regno
]);
4003 IOR_HARD_REG_SET (forbidden_regs
, pseudo_previous_regs
[regno
]);
4004 gcc_assert (reg_renumber
[regno
] < 0);
4005 a
= ira_regno_allocno_map
[regno
];
4006 ira_mark_allocation_change (regno
);
4007 ira_assert (reg_renumber
[regno
] < 0);
4008 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
4009 fprintf (ira_dump_file
,
4010 " Try Assign %d(a%d), cost=%d", regno
, ALLOCNO_NUM (a
),
4011 ALLOCNO_MEMORY_COST (a
)
4012 - ALLOCNO_CLASS_COST (a
));
4013 allocno_reload_assign (a
, forbidden_regs
);
4014 if (reg_renumber
[regno
] >= 0)
4016 CLEAR_REGNO_REG_SET (spilled
, regno
);
4024 /* The function is called by reload and returns already allocated
4025 stack slot (if any) for REGNO with given INHERENT_SIZE and
4026 TOTAL_SIZE. In the case of failure to find a slot which can be
4027 used for REGNO, the function returns NULL. */
4029 ira_reuse_stack_slot (int regno
, unsigned int inherent_size
,
4030 unsigned int total_size
)
4033 int slot_num
, best_slot_num
;
4034 int cost
, best_cost
;
4035 ira_copy_t cp
, next_cp
;
4036 ira_allocno_t another_allocno
, allocno
= ira_regno_allocno_map
[regno
];
4039 struct ira_spilled_reg_stack_slot
*slot
= NULL
;
4041 ira_assert (inherent_size
== PSEUDO_REGNO_BYTES (regno
)
4042 && inherent_size
<= total_size
4043 && ALLOCNO_HARD_REGNO (allocno
) < 0);
4044 if (! flag_ira_share_spill_slots
)
4046 slot_num
= -ALLOCNO_HARD_REGNO (allocno
) - 2;
4049 slot
= &ira_spilled_reg_stack_slots
[slot_num
];
4054 best_cost
= best_slot_num
= -1;
4056 /* It means that the pseudo was spilled in the reload pass, try
4059 slot_num
< ira_spilled_reg_stack_slots_num
;
4062 slot
= &ira_spilled_reg_stack_slots
[slot_num
];
4063 if (slot
->mem
== NULL_RTX
)
4065 if (slot
->width
< total_size
4066 || GET_MODE_SIZE (GET_MODE (slot
->mem
)) < inherent_size
)
4069 EXECUTE_IF_SET_IN_BITMAP (&slot
->spilled_regs
,
4070 FIRST_PSEUDO_REGISTER
, i
, bi
)
4072 another_allocno
= ira_regno_allocno_map
[i
];
4073 if (allocnos_conflict_by_live_ranges_p (allocno
,
4077 for (cost
= 0, cp
= ALLOCNO_COPIES (allocno
);
4081 if (cp
->first
== allocno
)
4083 next_cp
= cp
->next_first_allocno_copy
;
4084 another_allocno
= cp
->second
;
4086 else if (cp
->second
== allocno
)
4088 next_cp
= cp
->next_second_allocno_copy
;
4089 another_allocno
= cp
->first
;
4093 if (cp
->insn
== NULL_RTX
)
4095 if (bitmap_bit_p (&slot
->spilled_regs
,
4096 ALLOCNO_REGNO (another_allocno
)))
4099 if (cost
> best_cost
)
4102 best_slot_num
= slot_num
;
4109 slot_num
= best_slot_num
;
4110 slot
= &ira_spilled_reg_stack_slots
[slot_num
];
4111 SET_REGNO_REG_SET (&slot
->spilled_regs
, regno
);
4113 ALLOCNO_HARD_REGNO (allocno
) = -slot_num
- 2;
4118 ira_assert (slot
->width
>= total_size
);
4119 #ifdef ENABLE_IRA_CHECKING
4120 EXECUTE_IF_SET_IN_BITMAP (&slot
->spilled_regs
,
4121 FIRST_PSEUDO_REGISTER
, i
, bi
)
4123 ira_assert (! conflict_by_live_ranges_p (regno
, i
));
4126 SET_REGNO_REG_SET (&slot
->spilled_regs
, regno
);
4127 if (internal_flag_ira_verbose
> 3 && ira_dump_file
)
4129 fprintf (ira_dump_file
, " Assigning %d(freq=%d) slot %d of",
4130 regno
, REG_FREQ (regno
), slot_num
);
4131 EXECUTE_IF_SET_IN_BITMAP (&slot
->spilled_regs
,
4132 FIRST_PSEUDO_REGISTER
, i
, bi
)
4134 if ((unsigned) regno
!= i
)
4135 fprintf (ira_dump_file
, " %d", i
);
4137 fprintf (ira_dump_file
, "\n");
4143 /* This is called by reload every time a new stack slot X with
4144 TOTAL_SIZE was allocated for REGNO. We store this info for
4145 subsequent ira_reuse_stack_slot calls. */
4147 ira_mark_new_stack_slot (rtx x
, int regno
, unsigned int total_size
)
4149 struct ira_spilled_reg_stack_slot
*slot
;
4151 ira_allocno_t allocno
;
4153 ira_assert (PSEUDO_REGNO_BYTES (regno
) <= total_size
);
4154 allocno
= ira_regno_allocno_map
[regno
];
4155 slot_num
= -ALLOCNO_HARD_REGNO (allocno
) - 2;
4158 slot_num
= ira_spilled_reg_stack_slots_num
++;
4159 ALLOCNO_HARD_REGNO (allocno
) = -slot_num
- 2;
4161 slot
= &ira_spilled_reg_stack_slots
[slot_num
];
4162 INIT_REG_SET (&slot
->spilled_regs
);
4163 SET_REGNO_REG_SET (&slot
->spilled_regs
, regno
);
4165 slot
->width
= total_size
;
4166 if (internal_flag_ira_verbose
> 3 && ira_dump_file
)
4167 fprintf (ira_dump_file
, " Assigning %d(freq=%d) a new slot %d\n",
4168 regno
, REG_FREQ (regno
), slot_num
);
4172 /* Return spill cost for pseudo-registers whose numbers are in array
4173 REGNOS (with a negative number as an end marker) for reload with
4174 given IN and OUT for INSN. Return also number points (through
4175 EXCESS_PRESSURE_LIVE_LENGTH) where the pseudo-register lives and
4176 the register pressure is high, number of references of the
4177 pseudo-registers (through NREFS), number of callee-clobbered
4178 hard-registers occupied by the pseudo-registers (through
4179 CALL_USED_COUNT), and the first hard regno occupied by the
4180 pseudo-registers (through FIRST_HARD_REGNO). */
4182 calculate_spill_cost (int *regnos
, rtx in
, rtx out
, rtx insn
,
4183 int *excess_pressure_live_length
,
4184 int *nrefs
, int *call_used_count
, int *first_hard_regno
)
4186 int i
, cost
, regno
, hard_regno
, j
, count
, saved_cost
, nregs
;
4192 for (length
= count
= cost
= i
= 0;; i
++)
4197 *nrefs
+= REG_N_REFS (regno
);
4198 hard_regno
= reg_renumber
[regno
];
4199 ira_assert (hard_regno
>= 0);
4200 a
= ira_regno_allocno_map
[regno
];
4201 length
+= ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a
) / ALLOCNO_NUM_OBJECTS (a
);
4202 cost
+= ALLOCNO_MEMORY_COST (a
) - ALLOCNO_CLASS_COST (a
);
4203 nregs
= hard_regno_nregs
[hard_regno
][ALLOCNO_MODE (a
)];
4204 for (j
= 0; j
< nregs
; j
++)
4205 if (! TEST_HARD_REG_BIT (call_used_reg_set
, hard_regno
+ j
))
4209 in_p
= in
&& REG_P (in
) && (int) REGNO (in
) == hard_regno
;
4210 out_p
= out
&& REG_P (out
) && (int) REGNO (out
) == hard_regno
;
4212 && find_regno_note (insn
, REG_DEAD
, hard_regno
) != NULL_RTX
)
4216 saved_cost
+= ira_memory_move_cost
4217 [ALLOCNO_MODE (a
)][ALLOCNO_CLASS (a
)][1];
4220 += ira_memory_move_cost
4221 [ALLOCNO_MODE (a
)][ALLOCNO_CLASS (a
)][0];
4222 cost
-= REG_FREQ_FROM_BB (BLOCK_FOR_INSN (insn
)) * saved_cost
;
4225 *excess_pressure_live_length
= length
;
4226 *call_used_count
= count
;
4230 hard_regno
= reg_renumber
[regnos
[0]];
4232 *first_hard_regno
= hard_regno
;
4236 /* Return TRUE if spilling pseudo-registers whose numbers are in array
4237 REGNOS is better than spilling pseudo-registers with numbers in
4238 OTHER_REGNOS for reload with given IN and OUT for INSN. The
4239 function used by the reload pass to make better register spilling
4242 ira_better_spill_reload_regno_p (int *regnos
, int *other_regnos
,
4243 rtx in
, rtx out
, rtx insn
)
4245 int cost
, other_cost
;
4246 int length
, other_length
;
4247 int nrefs
, other_nrefs
;
4248 int call_used_count
, other_call_used_count
;
4249 int hard_regno
, other_hard_regno
;
4251 cost
= calculate_spill_cost (regnos
, in
, out
, insn
,
4252 &length
, &nrefs
, &call_used_count
, &hard_regno
);
4253 other_cost
= calculate_spill_cost (other_regnos
, in
, out
, insn
,
4254 &other_length
, &other_nrefs
,
4255 &other_call_used_count
,
4257 if (nrefs
== 0 && other_nrefs
!= 0)
4259 if (nrefs
!= 0 && other_nrefs
== 0)
4261 if (cost
!= other_cost
)
4262 return cost
< other_cost
;
4263 if (length
!= other_length
)
4264 return length
> other_length
;
4265 #ifdef REG_ALLOC_ORDER
4266 if (hard_regno
>= 0 && other_hard_regno
>= 0)
4267 return (inv_reg_alloc_order
[hard_regno
]
4268 < inv_reg_alloc_order
[other_hard_regno
]);
4270 if (call_used_count
!= other_call_used_count
)
4271 return call_used_count
> other_call_used_count
;
4278 /* Allocate and initialize data necessary for assign_hard_reg. */
4280 ira_initiate_assign (void)
4283 = (ira_allocno_t
*) ira_allocate (sizeof (ira_allocno_t
)
4284 * ira_allocnos_num
);
4285 consideration_allocno_bitmap
= ira_allocate_bitmap ();
4286 initiate_cost_update ();
4287 allocno_priorities
= (int *) ira_allocate (sizeof (int) * ira_allocnos_num
);
4290 /* Deallocate data used by assign_hard_reg. */
4292 ira_finish_assign (void)
4294 ira_free (sorted_allocnos
);
4295 ira_free_bitmap (consideration_allocno_bitmap
);
4296 finish_cost_update ();
4297 ira_free (allocno_priorities
);
4302 /* Entry function doing color-based register allocation. */
4306 allocno_stack_vec
.create (ira_allocnos_num
);
4307 memset (allocated_hardreg_p
, 0, sizeof (allocated_hardreg_p
));
4308 ira_initiate_assign ();
4310 ira_finish_assign ();
4311 allocno_stack_vec
.release ();
4312 move_spill_restore ();
4317 /* This page contains a simple register allocator without usage of
4318 allocno conflicts. This is used for fast allocation for -O0. */
4320 /* Do register allocation by not using allocno conflicts. It uses
4321 only allocno live ranges. The algorithm is close to Chow's
4322 priority coloring. */
4324 fast_allocation (void)
4326 int i
, j
, k
, num
, class_size
, hard_regno
;
4328 bool no_stack_reg_p
;
4330 enum reg_class aclass
;
4331 enum machine_mode mode
;
4333 ira_allocno_iterator ai
;
4335 HARD_REG_SET conflict_hard_regs
, *used_hard_regs
;
4337 sorted_allocnos
= (ira_allocno_t
*) ira_allocate (sizeof (ira_allocno_t
)
4338 * ira_allocnos_num
);
4340 FOR_EACH_ALLOCNO (a
, ai
)
4341 sorted_allocnos
[num
++] = a
;
4342 allocno_priorities
= (int *) ira_allocate (sizeof (int) * ira_allocnos_num
);
4343 setup_allocno_priorities (sorted_allocnos
, num
);
4344 used_hard_regs
= (HARD_REG_SET
*) ira_allocate (sizeof (HARD_REG_SET
)
4346 for (i
= 0; i
< ira_max_point
; i
++)
4347 CLEAR_HARD_REG_SET (used_hard_regs
[i
]);
4348 qsort (sorted_allocnos
, num
, sizeof (ira_allocno_t
),
4349 allocno_priority_compare_func
);
4350 for (i
= 0; i
< num
; i
++)
4354 a
= sorted_allocnos
[i
];
4355 nr
= ALLOCNO_NUM_OBJECTS (a
);
4356 CLEAR_HARD_REG_SET (conflict_hard_regs
);
4357 for (l
= 0; l
< nr
; l
++)
4359 ira_object_t obj
= ALLOCNO_OBJECT (a
, l
);
4360 IOR_HARD_REG_SET (conflict_hard_regs
,
4361 OBJECT_CONFLICT_HARD_REGS (obj
));
4362 for (r
= OBJECT_LIVE_RANGES (obj
); r
!= NULL
; r
= r
->next
)
4363 for (j
= r
->start
; j
<= r
->finish
; j
++)
4364 IOR_HARD_REG_SET (conflict_hard_regs
, used_hard_regs
[j
]);
4366 aclass
= ALLOCNO_CLASS (a
);
4367 ALLOCNO_ASSIGNED_P (a
) = true;
4368 ALLOCNO_HARD_REGNO (a
) = -1;
4369 if (hard_reg_set_subset_p (reg_class_contents
[aclass
],
4370 conflict_hard_regs
))
4372 mode
= ALLOCNO_MODE (a
);
4374 no_stack_reg_p
= ALLOCNO_NO_STACK_REG_P (a
);
4376 class_size
= ira_class_hard_regs_num
[aclass
];
4377 for (j
= 0; j
< class_size
; j
++)
4379 hard_regno
= ira_class_hard_regs
[aclass
][j
];
4381 if (no_stack_reg_p
&& FIRST_STACK_REG
<= hard_regno
4382 && hard_regno
<= LAST_STACK_REG
)
4385 if (ira_hard_reg_set_intersection_p (hard_regno
, mode
, conflict_hard_regs
)
4386 || (TEST_HARD_REG_BIT
4387 (ira_prohibited_class_mode_regs
[aclass
][mode
], hard_regno
)))
4389 ALLOCNO_HARD_REGNO (a
) = hard_regno
;
4390 for (l
= 0; l
< nr
; l
++)
4392 ira_object_t obj
= ALLOCNO_OBJECT (a
, l
);
4393 for (r
= OBJECT_LIVE_RANGES (obj
); r
!= NULL
; r
= r
->next
)
4394 for (k
= r
->start
; k
<= r
->finish
; k
++)
4395 IOR_HARD_REG_SET (used_hard_regs
[k
],
4396 ira_reg_mode_hard_regset
[hard_regno
][mode
]);
4401 ira_free (sorted_allocnos
);
4402 ira_free (used_hard_regs
);
4403 ira_free (allocno_priorities
);
4404 if (internal_flag_ira_verbose
> 1 && ira_dump_file
!= NULL
)
4405 ira_print_disposition (ira_dump_file
);
4410 /* Entry function doing coloring. */
4415 ira_allocno_iterator ai
;
4417 /* Setup updated costs. */
4418 FOR_EACH_ALLOCNO (a
, ai
)
4420 ALLOCNO_UPDATED_MEMORY_COST (a
) = ALLOCNO_MEMORY_COST (a
);
4421 ALLOCNO_UPDATED_CLASS_COST (a
) = ALLOCNO_CLASS_COST (a
);
4423 if (ira_conflicts_p
)