1 /* IRA allocation based on graph coloring.
2 Copyright (C) 2006-2013 Free Software Foundation, Inc.
3 Contributed by Vladimir Makarov <vmakarov@redhat.com>.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
23 #include "coretypes.h"
32 #include "hash-table.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 /* Info about changing hard reg costs of an allocno. */
92 struct update_cost_record
94 /* Hard regno for which we changed the cost. */
96 /* Divisor used when we changed the cost of HARD_REGNO. */
98 /* Next record for given allocno. */
99 struct update_cost_record
*next
;
102 /* To decrease footprint of ira_allocno structure we store all data
103 needed only for coloring in the following structure. */
104 struct allocno_color_data
106 /* TRUE value means that the allocno was not removed yet from the
107 conflicting graph during colouring. */
108 unsigned int in_graph_p
: 1;
109 /* TRUE if it is put on the stack to make other allocnos
111 unsigned int may_be_spilled_p
: 1;
112 /* TRUE if the allocno is trivially colorable. */
113 unsigned int colorable_p
: 1;
114 /* Number of hard registers of the allocno class really
115 available for the allocno allocation. It is number of the
116 profitable hard regs. */
117 int available_regs_num
;
118 /* Allocnos in a bucket (used in coloring) chained by the following
120 ira_allocno_t next_bucket_allocno
;
121 ira_allocno_t prev_bucket_allocno
;
122 /* Used for temporary purposes. */
124 /* Used to exclude repeated processing. */
126 /* Profitable hard regs available for this pseudo allocation. It
127 means that the set excludes unavailable hard regs and hard regs
128 conflicting with given pseudo. They should be of the allocno
130 HARD_REG_SET profitable_hard_regs
;
131 /* The allocno hard registers node. */
132 allocno_hard_regs_node_t hard_regs_node
;
133 /* Array of structures allocno_hard_regs_subnode representing
134 given allocno hard registers node (the 1st element in the array)
135 and all its subnodes in the tree (forest) of allocno hard
136 register nodes (see comments above). */
137 int hard_regs_subnodes_start
;
138 /* The length of the previous array. */
139 int hard_regs_subnodes_num
;
140 /* Records about updating allocno hard reg costs from copies. If
141 the allocno did not get expected hard register, these records are
142 used to restore original hard reg costs of allocnos connected to
143 this allocno by copies. */
144 struct update_cost_record
*update_cost_records
;
148 typedef struct allocno_color_data
*allocno_color_data_t
;
150 /* Container for storing allocno data concerning coloring. */
151 static allocno_color_data_t allocno_color_data
;
153 /* Macro to access the data concerning coloring. */
154 #define ALLOCNO_COLOR_DATA(a) ((allocno_color_data_t) ALLOCNO_ADD_DATA (a))
156 /* Used for finding allocno colorability to exclude repeated allocno
157 processing and for updating preferencing to exclude repeated
158 allocno processing during assignment. */
159 static int curr_allocno_process
;
161 /* This file contains code for regional graph coloring, spill/restore
162 code placement optimization, and code helping the reload pass to do
165 /* Bitmap of allocnos which should be colored. */
166 static bitmap coloring_allocno_bitmap
;
168 /* Bitmap of allocnos which should be taken into account during
169 coloring. In general case it contains allocnos from
170 coloring_allocno_bitmap plus other already colored conflicting
172 static bitmap consideration_allocno_bitmap
;
174 /* All allocnos sorted according their priorities. */
175 static ira_allocno_t
*sorted_allocnos
;
177 /* Vec representing the stack of allocnos used during coloring. */
178 static vec
<ira_allocno_t
> allocno_stack_vec
;
180 /* Helper for qsort comparison callbacks - return a positive integer if
181 X > Y, or a negative value otherwise. Use a conditional expression
182 instead of a difference computation to insulate from possible overflow
183 issues, e.g. X - Y < 0 for some X > 0 and Y < 0. */
184 #define SORTGT(x,y) (((x) > (y)) ? 1 : -1)
188 /* Definition of vector of allocno hard registers. */
190 /* Vector of unique allocno hard registers. */
191 static vec
<allocno_hard_regs_t
> allocno_hard_regs_vec
;
193 struct allocno_hard_regs_hasher
: typed_noop_remove
<allocno_hard_regs
>
195 typedef allocno_hard_regs value_type
;
196 typedef allocno_hard_regs compare_type
;
197 static inline hashval_t
hash (const value_type
*);
198 static inline bool equal (const value_type
*, const compare_type
*);
201 /* Returns hash value for allocno hard registers V. */
203 allocno_hard_regs_hasher::hash (const value_type
*hv
)
205 return iterative_hash (&hv
->set
, sizeof (HARD_REG_SET
), 0);
208 /* Compares allocno hard registers V1 and V2. */
210 allocno_hard_regs_hasher::equal (const value_type
*hv1
, const compare_type
*hv2
)
212 return hard_reg_set_equal_p (hv1
->set
, hv2
->set
);
215 /* Hash table of unique allocno hard registers. */
216 static hash_table
<allocno_hard_regs_hasher
> allocno_hard_regs_htab
;
218 /* Return allocno hard registers in the hash table equal to HV. */
219 static allocno_hard_regs_t
220 find_hard_regs (allocno_hard_regs_t hv
)
222 return allocno_hard_regs_htab
.find (hv
);
225 /* Insert allocno hard registers HV in the hash table (if it is not
226 there yet) and return the value which in the table. */
227 static allocno_hard_regs_t
228 insert_hard_regs (allocno_hard_regs_t hv
)
230 allocno_hard_regs
**slot
= allocno_hard_regs_htab
.find_slot (hv
, INSERT
);
237 /* Initialize data concerning allocno hard registers. */
239 init_allocno_hard_regs (void)
241 allocno_hard_regs_vec
.create (200);
242 allocno_hard_regs_htab
.create (200);
245 /* Add (or update info about) allocno hard registers with SET and
247 static allocno_hard_regs_t
248 add_allocno_hard_regs (HARD_REG_SET set
, HOST_WIDEST_INT cost
)
250 struct allocno_hard_regs temp
;
251 allocno_hard_regs_t hv
;
253 gcc_assert (! hard_reg_set_empty_p (set
));
254 COPY_HARD_REG_SET (temp
.set
, set
);
255 if ((hv
= find_hard_regs (&temp
)) != NULL
)
259 hv
= ((struct allocno_hard_regs
*)
260 ira_allocate (sizeof (struct allocno_hard_regs
)));
261 COPY_HARD_REG_SET (hv
->set
, set
);
263 allocno_hard_regs_vec
.safe_push (hv
);
264 insert_hard_regs (hv
);
269 /* Finalize data concerning allocno hard registers. */
271 finish_allocno_hard_regs (void)
274 allocno_hard_regs_t hv
;
277 allocno_hard_regs_vec
.iterate (i
, &hv
);
280 allocno_hard_regs_htab
.dispose ();
281 allocno_hard_regs_vec
.release ();
284 /* Sort hard regs according to their frequency of usage. */
286 allocno_hard_regs_compare (const void *v1p
, const void *v2p
)
288 allocno_hard_regs_t hv1
= *(const allocno_hard_regs_t
*) v1p
;
289 allocno_hard_regs_t hv2
= *(const allocno_hard_regs_t
*) v2p
;
291 if (hv2
->cost
> hv1
->cost
)
293 else if (hv2
->cost
< hv1
->cost
)
301 /* Used for finding a common ancestor of two allocno hard registers
302 nodes in the forest. We use the current value of
303 'node_check_tick' to mark all nodes from one node to the top and
304 then walking up from another node until we find a marked node.
306 It is also used to figure out allocno colorability as a mark that
307 we already reset value of member 'conflict_size' for the forest
308 node corresponding to the processed allocno. */
309 static int node_check_tick
;
311 /* Roots of the forest containing hard register sets can be assigned
313 static allocno_hard_regs_node_t hard_regs_roots
;
315 /* Definition of vector of allocno hard register nodes. */
317 /* Vector used to create the forest. */
318 static vec
<allocno_hard_regs_node_t
> hard_regs_node_vec
;
320 /* Create and return allocno hard registers node containing allocno
321 hard registers HV. */
322 static allocno_hard_regs_node_t
323 create_new_allocno_hard_regs_node (allocno_hard_regs_t hv
)
325 allocno_hard_regs_node_t new_node
;
327 new_node
= ((struct allocno_hard_regs_node
*)
328 ira_allocate (sizeof (struct allocno_hard_regs_node
)));
330 new_node
->hard_regs
= hv
;
331 new_node
->hard_regs_num
= hard_reg_set_size (hv
->set
);
332 new_node
->first
= NULL
;
333 new_node
->used_p
= false;
337 /* Add allocno hard registers node NEW_NODE to the forest on its level
340 add_new_allocno_hard_regs_node_to_forest (allocno_hard_regs_node_t
*roots
,
341 allocno_hard_regs_node_t new_node
)
343 new_node
->next
= *roots
;
344 if (new_node
->next
!= NULL
)
345 new_node
->next
->prev
= new_node
;
346 new_node
->prev
= NULL
;
350 /* Add allocno hard registers HV (or its best approximation if it is
351 not possible) to the forest on its level given by ROOTS. */
353 add_allocno_hard_regs_to_forest (allocno_hard_regs_node_t
*roots
,
354 allocno_hard_regs_t hv
)
356 unsigned int i
, start
;
357 allocno_hard_regs_node_t node
, prev
, new_node
;
358 HARD_REG_SET temp_set
;
359 allocno_hard_regs_t hv2
;
361 start
= hard_regs_node_vec
.length ();
362 for (node
= *roots
; node
!= NULL
; node
= node
->next
)
364 if (hard_reg_set_equal_p (hv
->set
, node
->hard_regs
->set
))
366 if (hard_reg_set_subset_p (hv
->set
, node
->hard_regs
->set
))
368 add_allocno_hard_regs_to_forest (&node
->first
, hv
);
371 if (hard_reg_set_subset_p (node
->hard_regs
->set
, hv
->set
))
372 hard_regs_node_vec
.safe_push (node
);
373 else if (hard_reg_set_intersect_p (hv
->set
, node
->hard_regs
->set
))
375 COPY_HARD_REG_SET (temp_set
, hv
->set
);
376 AND_HARD_REG_SET (temp_set
, node
->hard_regs
->set
);
377 hv2
= add_allocno_hard_regs (temp_set
, hv
->cost
);
378 add_allocno_hard_regs_to_forest (&node
->first
, hv2
);
381 if (hard_regs_node_vec
.length ()
384 /* Create a new node which contains nodes in hard_regs_node_vec. */
385 CLEAR_HARD_REG_SET (temp_set
);
387 i
< hard_regs_node_vec
.length ();
390 node
= hard_regs_node_vec
[i
];
391 IOR_HARD_REG_SET (temp_set
, node
->hard_regs
->set
);
393 hv
= add_allocno_hard_regs (temp_set
, hv
->cost
);
394 new_node
= create_new_allocno_hard_regs_node (hv
);
397 i
< hard_regs_node_vec
.length ();
400 node
= hard_regs_node_vec
[i
];
401 if (node
->prev
== NULL
)
404 node
->prev
->next
= node
->next
;
405 if (node
->next
!= NULL
)
406 node
->next
->prev
= node
->prev
;
408 new_node
->first
= node
;
415 add_new_allocno_hard_regs_node_to_forest (roots
, new_node
);
417 hard_regs_node_vec
.truncate (start
);
420 /* Add allocno hard registers nodes starting with the forest level
421 given by FIRST which contains biggest set inside SET. */
423 collect_allocno_hard_regs_cover (allocno_hard_regs_node_t first
,
426 allocno_hard_regs_node_t node
;
428 ira_assert (first
!= NULL
);
429 for (node
= first
; node
!= NULL
; node
= node
->next
)
430 if (hard_reg_set_subset_p (node
->hard_regs
->set
, set
))
431 hard_regs_node_vec
.safe_push (node
);
432 else if (hard_reg_set_intersect_p (set
, node
->hard_regs
->set
))
433 collect_allocno_hard_regs_cover (node
->first
, set
);
436 /* Set up field parent as PARENT in all allocno hard registers nodes
437 in forest given by FIRST. */
439 setup_allocno_hard_regs_nodes_parent (allocno_hard_regs_node_t first
,
440 allocno_hard_regs_node_t parent
)
442 allocno_hard_regs_node_t node
;
444 for (node
= first
; node
!= NULL
; node
= node
->next
)
446 node
->parent
= parent
;
447 setup_allocno_hard_regs_nodes_parent (node
->first
, node
);
451 /* Return allocno hard registers node which is a first common ancestor
452 node of FIRST and SECOND in the forest. */
453 static allocno_hard_regs_node_t
454 first_common_ancestor_node (allocno_hard_regs_node_t first
,
455 allocno_hard_regs_node_t second
)
457 allocno_hard_regs_node_t node
;
460 for (node
= first
; node
!= NULL
; node
= node
->parent
)
461 node
->check
= node_check_tick
;
462 for (node
= second
; node
!= NULL
; node
= node
->parent
)
463 if (node
->check
== node_check_tick
)
465 return first_common_ancestor_node (second
, first
);
468 /* Print hard reg set SET to F. */
470 print_hard_reg_set (FILE *f
, HARD_REG_SET set
, bool new_line_p
)
474 for (start
= -1, i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
476 if (TEST_HARD_REG_BIT (set
, i
))
478 if (i
== 0 || ! TEST_HARD_REG_BIT (set
, i
- 1))
482 && (i
== FIRST_PSEUDO_REGISTER
- 1 || ! TEST_HARD_REG_BIT (set
, i
)))
485 fprintf (f
, " %d", start
);
486 else if (start
== i
- 2)
487 fprintf (f
, " %d %d", start
, start
+ 1);
489 fprintf (f
, " %d-%d", start
, i
- 1);
497 /* Print allocno hard register subforest given by ROOTS and its LEVEL
500 print_hard_regs_subforest (FILE *f
, allocno_hard_regs_node_t roots
,
504 allocno_hard_regs_node_t node
;
506 for (node
= roots
; node
!= NULL
; node
= node
->next
)
509 for (i
= 0; i
< level
* 2; i
++)
511 fprintf (f
, "%d:(", node
->preorder_num
);
512 print_hard_reg_set (f
, node
->hard_regs
->set
, false);
513 fprintf (f
, ")@" HOST_WIDEST_INT_PRINT_DEC
"\n", node
->hard_regs
->cost
);
514 print_hard_regs_subforest (f
, node
->first
, level
+ 1);
518 /* Print the allocno hard register forest to F. */
520 print_hard_regs_forest (FILE *f
)
522 fprintf (f
, " Hard reg set forest:\n");
523 print_hard_regs_subforest (f
, hard_regs_roots
, 1);
526 /* Print the allocno hard register forest to stderr. */
528 ira_debug_hard_regs_forest (void)
530 print_hard_regs_forest (stderr
);
533 /* Remove unused allocno hard registers nodes from forest given by its
536 remove_unused_allocno_hard_regs_nodes (allocno_hard_regs_node_t
*roots
)
538 allocno_hard_regs_node_t node
, prev
, next
, last
;
540 for (prev
= NULL
, node
= *roots
; node
!= NULL
; node
= next
)
545 remove_unused_allocno_hard_regs_nodes (&node
->first
);
550 for (last
= node
->first
;
551 last
!= NULL
&& last
->next
!= NULL
;
557 *roots
= node
->first
;
559 prev
->next
= node
->first
;
579 /* Set up fields preorder_num starting with START_NUM in all allocno
580 hard registers nodes in forest given by FIRST. Return biggest set
581 PREORDER_NUM increased by 1. */
583 enumerate_allocno_hard_regs_nodes (allocno_hard_regs_node_t first
,
584 allocno_hard_regs_node_t parent
,
587 allocno_hard_regs_node_t node
;
589 for (node
= first
; node
!= NULL
; node
= node
->next
)
591 node
->preorder_num
= start_num
++;
592 node
->parent
= parent
;
593 start_num
= enumerate_allocno_hard_regs_nodes (node
->first
, node
,
599 /* Number of allocno hard registers nodes in the forest. */
600 static int allocno_hard_regs_nodes_num
;
602 /* Table preorder number of allocno hard registers node in the forest
603 -> the allocno hard registers node. */
604 static allocno_hard_regs_node_t
*allocno_hard_regs_nodes
;
607 typedef struct allocno_hard_regs_subnode
*allocno_hard_regs_subnode_t
;
609 /* The structure is used to describes all subnodes (not only immediate
610 ones) in the mentioned above tree for given allocno hard register
611 node. The usage of such data accelerates calculation of
612 colorability of given allocno. */
613 struct allocno_hard_regs_subnode
615 /* The conflict size of conflicting allocnos whose hard register
616 sets are equal sets (plus supersets if given node is given
617 allocno hard registers node) of one in the given node. */
618 int left_conflict_size
;
619 /* The summary conflict size of conflicting allocnos whose hard
620 register sets are strict subsets of one in the given node.
621 Overall conflict size is
622 left_conflict_subnodes_size
623 + MIN (max_node_impact - left_conflict_subnodes_size,
626 short left_conflict_subnodes_size
;
627 short max_node_impact
;
630 /* Container for hard regs subnodes of all allocnos. */
631 static allocno_hard_regs_subnode_t allocno_hard_regs_subnodes
;
633 /* Table (preorder number of allocno hard registers node in the
634 forest, preorder number of allocno hard registers subnode) -> index
635 of the subnode relative to the node. -1 if it is not a
637 static int *allocno_hard_regs_subnode_index
;
639 /* Setup arrays ALLOCNO_HARD_REGS_NODES and
640 ALLOCNO_HARD_REGS_SUBNODE_INDEX. */
642 setup_allocno_hard_regs_subnode_index (allocno_hard_regs_node_t first
)
644 allocno_hard_regs_node_t node
, parent
;
647 for (node
= first
; node
!= NULL
; node
= node
->next
)
649 allocno_hard_regs_nodes
[node
->preorder_num
] = node
;
650 for (parent
= node
; parent
!= NULL
; parent
= parent
->parent
)
652 index
= parent
->preorder_num
* allocno_hard_regs_nodes_num
;
653 allocno_hard_regs_subnode_index
[index
+ node
->preorder_num
]
654 = node
->preorder_num
- parent
->preorder_num
;
656 setup_allocno_hard_regs_subnode_index (node
->first
);
660 /* Count all allocno hard registers nodes in tree ROOT. */
662 get_allocno_hard_regs_subnodes_num (allocno_hard_regs_node_t root
)
666 for (root
= root
->first
; root
!= NULL
; root
= root
->next
)
667 len
+= get_allocno_hard_regs_subnodes_num (root
);
671 /* Build the forest of allocno hard registers nodes and assign each
672 allocno a node from the forest. */
674 form_allocno_hard_regs_nodes_forest (void)
676 unsigned int i
, j
, size
, len
;
679 allocno_hard_regs_t hv
;
682 allocno_hard_regs_node_t node
, allocno_hard_regs_node
;
683 allocno_color_data_t allocno_data
;
686 init_allocno_hard_regs ();
687 hard_regs_roots
= NULL
;
688 hard_regs_node_vec
.create (100);
689 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
690 if (! TEST_HARD_REG_BIT (ira_no_alloc_regs
, i
))
692 CLEAR_HARD_REG_SET (temp
);
693 SET_HARD_REG_BIT (temp
, i
);
694 hv
= add_allocno_hard_regs (temp
, 0);
695 node
= create_new_allocno_hard_regs_node (hv
);
696 add_new_allocno_hard_regs_node_to_forest (&hard_regs_roots
, node
);
698 start
= allocno_hard_regs_vec
.length ();
699 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap
, 0, i
, bi
)
702 allocno_data
= ALLOCNO_COLOR_DATA (a
);
704 if (hard_reg_set_empty_p (allocno_data
->profitable_hard_regs
))
706 hv
= (add_allocno_hard_regs
707 (allocno_data
->profitable_hard_regs
,
708 ALLOCNO_MEMORY_COST (a
) - ALLOCNO_CLASS_COST (a
)));
710 SET_HARD_REG_SET (temp
);
711 AND_COMPL_HARD_REG_SET (temp
, ira_no_alloc_regs
);
712 add_allocno_hard_regs (temp
, 0);
713 qsort (allocno_hard_regs_vec
.address () + start
,
714 allocno_hard_regs_vec
.length () - start
,
715 sizeof (allocno_hard_regs_t
), allocno_hard_regs_compare
);
717 allocno_hard_regs_vec
.iterate (i
, &hv
);
720 add_allocno_hard_regs_to_forest (&hard_regs_roots
, hv
);
721 ira_assert (hard_regs_node_vec
.length () == 0);
723 /* We need to set up parent fields for right work of
724 first_common_ancestor_node. */
725 setup_allocno_hard_regs_nodes_parent (hard_regs_roots
, NULL
);
726 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap
, 0, i
, bi
)
729 allocno_data
= ALLOCNO_COLOR_DATA (a
);
730 if (hard_reg_set_empty_p (allocno_data
->profitable_hard_regs
))
732 hard_regs_node_vec
.truncate (0);
733 collect_allocno_hard_regs_cover (hard_regs_roots
,
734 allocno_data
->profitable_hard_regs
);
735 allocno_hard_regs_node
= NULL
;
736 for (j
= 0; hard_regs_node_vec
.iterate (j
, &node
); j
++)
737 allocno_hard_regs_node
740 : first_common_ancestor_node (node
, allocno_hard_regs_node
));
741 /* That is a temporary storage. */
742 allocno_hard_regs_node
->used_p
= true;
743 allocno_data
->hard_regs_node
= allocno_hard_regs_node
;
745 ira_assert (hard_regs_roots
->next
== NULL
);
746 hard_regs_roots
->used_p
= true;
747 remove_unused_allocno_hard_regs_nodes (&hard_regs_roots
);
748 allocno_hard_regs_nodes_num
749 = enumerate_allocno_hard_regs_nodes (hard_regs_roots
, NULL
, 0);
750 allocno_hard_regs_nodes
751 = ((allocno_hard_regs_node_t
*)
752 ira_allocate (allocno_hard_regs_nodes_num
753 * sizeof (allocno_hard_regs_node_t
)));
754 size
= allocno_hard_regs_nodes_num
* allocno_hard_regs_nodes_num
;
755 allocno_hard_regs_subnode_index
756 = (int *) ira_allocate (size
* sizeof (int));
757 for (i
= 0; i
< size
; i
++)
758 allocno_hard_regs_subnode_index
[i
] = -1;
759 setup_allocno_hard_regs_subnode_index (hard_regs_roots
);
761 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap
, 0, i
, bi
)
764 allocno_data
= ALLOCNO_COLOR_DATA (a
);
765 if (hard_reg_set_empty_p (allocno_data
->profitable_hard_regs
))
767 len
= get_allocno_hard_regs_subnodes_num (allocno_data
->hard_regs_node
);
768 allocno_data
->hard_regs_subnodes_start
= start
;
769 allocno_data
->hard_regs_subnodes_num
= len
;
772 allocno_hard_regs_subnodes
773 = ((allocno_hard_regs_subnode_t
)
774 ira_allocate (sizeof (struct allocno_hard_regs_subnode
) * start
));
775 hard_regs_node_vec
.release ();
778 /* Free tree of allocno hard registers nodes given by its ROOT. */
780 finish_allocno_hard_regs_nodes_tree (allocno_hard_regs_node_t root
)
782 allocno_hard_regs_node_t child
, next
;
784 for (child
= root
->first
; child
!= NULL
; child
= next
)
787 finish_allocno_hard_regs_nodes_tree (child
);
792 /* Finish work with the forest of allocno hard registers nodes. */
794 finish_allocno_hard_regs_nodes_forest (void)
796 allocno_hard_regs_node_t node
, next
;
798 ira_free (allocno_hard_regs_subnodes
);
799 for (node
= hard_regs_roots
; node
!= NULL
; node
= next
)
802 finish_allocno_hard_regs_nodes_tree (node
);
804 ira_free (allocno_hard_regs_nodes
);
805 ira_free (allocno_hard_regs_subnode_index
);
806 finish_allocno_hard_regs ();
809 /* Set up left conflict sizes and left conflict subnodes sizes of hard
810 registers subnodes of allocno A. Return TRUE if allocno A is
811 trivially colorable. */
813 setup_left_conflict_sizes_p (ira_allocno_t a
)
815 int i
, k
, nobj
, start
;
816 int conflict_size
, left_conflict_subnodes_size
, node_preorder_num
;
817 allocno_color_data_t data
;
818 HARD_REG_SET profitable_hard_regs
;
819 allocno_hard_regs_subnode_t subnodes
;
820 allocno_hard_regs_node_t node
;
821 HARD_REG_SET node_set
;
823 nobj
= ALLOCNO_NUM_OBJECTS (a
);
825 data
= ALLOCNO_COLOR_DATA (a
);
826 subnodes
= allocno_hard_regs_subnodes
+ data
->hard_regs_subnodes_start
;
827 COPY_HARD_REG_SET (profitable_hard_regs
, data
->profitable_hard_regs
);
828 node
= data
->hard_regs_node
;
829 node_preorder_num
= node
->preorder_num
;
830 COPY_HARD_REG_SET (node_set
, node
->hard_regs
->set
);
832 for (k
= 0; k
< nobj
; k
++)
834 ira_object_t obj
= ALLOCNO_OBJECT (a
, k
);
835 ira_object_t conflict_obj
;
836 ira_object_conflict_iterator oci
;
838 FOR_EACH_OBJECT_CONFLICT (obj
, conflict_obj
, oci
)
841 ira_allocno_t conflict_a
= OBJECT_ALLOCNO (conflict_obj
);
842 allocno_hard_regs_node_t conflict_node
, temp_node
;
843 HARD_REG_SET conflict_node_set
;
844 allocno_color_data_t conflict_data
;
846 conflict_data
= ALLOCNO_COLOR_DATA (conflict_a
);
847 if (! ALLOCNO_COLOR_DATA (conflict_a
)->in_graph_p
848 || ! hard_reg_set_intersect_p (profitable_hard_regs
,
850 ->profitable_hard_regs
))
852 conflict_node
= conflict_data
->hard_regs_node
;
853 COPY_HARD_REG_SET (conflict_node_set
, conflict_node
->hard_regs
->set
);
854 if (hard_reg_set_subset_p (node_set
, conflict_node_set
))
858 ira_assert (hard_reg_set_subset_p (conflict_node_set
, node_set
));
859 temp_node
= conflict_node
;
861 if (temp_node
->check
!= node_check_tick
)
863 temp_node
->check
= node_check_tick
;
864 temp_node
->conflict_size
= 0;
866 size
= (ira_reg_class_max_nregs
867 [ALLOCNO_CLASS (conflict_a
)][ALLOCNO_MODE (conflict_a
)]);
868 if (ALLOCNO_NUM_OBJECTS (conflict_a
) > 1)
869 /* We will deal with the subwords individually. */
871 temp_node
->conflict_size
+= size
;
874 for (i
= 0; i
< data
->hard_regs_subnodes_num
; i
++)
876 allocno_hard_regs_node_t temp_node
;
878 temp_node
= allocno_hard_regs_nodes
[i
+ node_preorder_num
];
879 ira_assert (temp_node
->preorder_num
== i
+ node_preorder_num
);
880 subnodes
[i
].left_conflict_size
= (temp_node
->check
!= node_check_tick
881 ? 0 : temp_node
->conflict_size
);
882 if (hard_reg_set_subset_p (temp_node
->hard_regs
->set
,
883 profitable_hard_regs
))
884 subnodes
[i
].max_node_impact
= temp_node
->hard_regs_num
;
887 HARD_REG_SET temp_set
;
888 int j
, n
, hard_regno
;
889 enum reg_class aclass
;
891 COPY_HARD_REG_SET (temp_set
, temp_node
->hard_regs
->set
);
892 AND_HARD_REG_SET (temp_set
, profitable_hard_regs
);
893 aclass
= ALLOCNO_CLASS (a
);
894 for (n
= 0, j
= ira_class_hard_regs_num
[aclass
] - 1; j
>= 0; j
--)
896 hard_regno
= ira_class_hard_regs
[aclass
][j
];
897 if (TEST_HARD_REG_BIT (temp_set
, hard_regno
))
900 subnodes
[i
].max_node_impact
= n
;
902 subnodes
[i
].left_conflict_subnodes_size
= 0;
904 start
= node_preorder_num
* allocno_hard_regs_nodes_num
;
905 for (i
= data
->hard_regs_subnodes_num
- 1; i
>= 0; i
--)
908 allocno_hard_regs_node_t parent
;
910 size
= (subnodes
[i
].left_conflict_subnodes_size
911 + MIN (subnodes
[i
].max_node_impact
912 - subnodes
[i
].left_conflict_subnodes_size
,
913 subnodes
[i
].left_conflict_size
));
914 parent
= allocno_hard_regs_nodes
[i
+ node_preorder_num
]->parent
;
918 = allocno_hard_regs_subnode_index
[start
+ parent
->preorder_num
];
921 subnodes
[parent_i
].left_conflict_subnodes_size
+= size
;
923 left_conflict_subnodes_size
= subnodes
[0].left_conflict_subnodes_size
;
925 += (left_conflict_subnodes_size
926 + MIN (subnodes
[0].max_node_impact
- left_conflict_subnodes_size
,
927 subnodes
[0].left_conflict_size
));
928 conflict_size
+= ira_reg_class_max_nregs
[ALLOCNO_CLASS (a
)][ALLOCNO_MODE (a
)];
929 data
->colorable_p
= conflict_size
<= data
->available_regs_num
;
930 return data
->colorable_p
;
933 /* Update left conflict sizes of hard registers subnodes of allocno A
934 after removing allocno REMOVED_A with SIZE from the conflict graph.
935 Return TRUE if A is trivially colorable. */
937 update_left_conflict_sizes_p (ira_allocno_t a
,
938 ira_allocno_t removed_a
, int size
)
940 int i
, conflict_size
, before_conflict_size
, diff
, start
;
941 int node_preorder_num
, parent_i
;
942 allocno_hard_regs_node_t node
, removed_node
, parent
;
943 allocno_hard_regs_subnode_t subnodes
;
944 allocno_color_data_t data
= ALLOCNO_COLOR_DATA (a
);
946 ira_assert (! data
->colorable_p
);
947 node
= data
->hard_regs_node
;
948 node_preorder_num
= node
->preorder_num
;
949 removed_node
= ALLOCNO_COLOR_DATA (removed_a
)->hard_regs_node
;
950 ira_assert (hard_reg_set_subset_p (removed_node
->hard_regs
->set
,
951 node
->hard_regs
->set
)
952 || hard_reg_set_subset_p (node
->hard_regs
->set
,
953 removed_node
->hard_regs
->set
));
954 start
= node_preorder_num
* allocno_hard_regs_nodes_num
;
955 i
= allocno_hard_regs_subnode_index
[start
+ removed_node
->preorder_num
];
958 subnodes
= allocno_hard_regs_subnodes
+ data
->hard_regs_subnodes_start
;
960 = (subnodes
[i
].left_conflict_subnodes_size
961 + MIN (subnodes
[i
].max_node_impact
962 - subnodes
[i
].left_conflict_subnodes_size
,
963 subnodes
[i
].left_conflict_size
));
964 subnodes
[i
].left_conflict_size
-= size
;
968 = (subnodes
[i
].left_conflict_subnodes_size
969 + MIN (subnodes
[i
].max_node_impact
970 - subnodes
[i
].left_conflict_subnodes_size
,
971 subnodes
[i
].left_conflict_size
));
972 if ((diff
= before_conflict_size
- conflict_size
) == 0)
974 ira_assert (conflict_size
< before_conflict_size
);
975 parent
= allocno_hard_regs_nodes
[i
+ node_preorder_num
]->parent
;
979 = allocno_hard_regs_subnode_index
[start
+ parent
->preorder_num
];
984 = (subnodes
[i
].left_conflict_subnodes_size
985 + MIN (subnodes
[i
].max_node_impact
986 - subnodes
[i
].left_conflict_subnodes_size
,
987 subnodes
[i
].left_conflict_size
));
988 subnodes
[i
].left_conflict_subnodes_size
-= diff
;
992 + ira_reg_class_max_nregs
[ALLOCNO_CLASS (a
)][ALLOCNO_MODE (a
)]
993 > data
->available_regs_num
))
995 data
->colorable_p
= true;
999 /* Return true if allocno A has empty profitable hard regs. */
1001 empty_profitable_hard_regs (ira_allocno_t a
)
1003 allocno_color_data_t data
= ALLOCNO_COLOR_DATA (a
);
1005 return hard_reg_set_empty_p (data
->profitable_hard_regs
);
1008 /* Set up profitable hard registers for each allocno being
1011 setup_profitable_hard_regs (void)
1014 int j
, k
, nobj
, hard_regno
, nregs
, class_size
;
1017 enum reg_class aclass
;
1018 enum machine_mode mode
;
1019 allocno_color_data_t data
;
1021 /* Initial set up from allocno classes and explicitly conflicting
1023 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap
, 0, i
, bi
)
1025 a
= ira_allocnos
[i
];
1026 if ((aclass
= ALLOCNO_CLASS (a
)) == NO_REGS
)
1028 data
= ALLOCNO_COLOR_DATA (a
);
1029 if (ALLOCNO_UPDATED_HARD_REG_COSTS (a
) == NULL
1030 && ALLOCNO_CLASS_COST (a
) > ALLOCNO_MEMORY_COST (a
))
1031 CLEAR_HARD_REG_SET (data
->profitable_hard_regs
);
1034 mode
= ALLOCNO_MODE (a
);
1035 COPY_HARD_REG_SET (data
->profitable_hard_regs
,
1036 ira_useful_class_mode_regs
[aclass
][mode
]);
1037 nobj
= ALLOCNO_NUM_OBJECTS (a
);
1038 for (k
= 0; k
< nobj
; k
++)
1040 ira_object_t obj
= ALLOCNO_OBJECT (a
, k
);
1042 AND_COMPL_HARD_REG_SET (data
->profitable_hard_regs
,
1043 OBJECT_TOTAL_CONFLICT_HARD_REGS (obj
));
1047 /* Exclude hard regs already assigned for conflicting objects. */
1048 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap
, 0, i
, bi
)
1050 a
= ira_allocnos
[i
];
1051 if ((aclass
= ALLOCNO_CLASS (a
)) == NO_REGS
1052 || ! ALLOCNO_ASSIGNED_P (a
)
1053 || (hard_regno
= ALLOCNO_HARD_REGNO (a
)) < 0)
1055 mode
= ALLOCNO_MODE (a
);
1056 nregs
= hard_regno_nregs
[hard_regno
][mode
];
1057 nobj
= ALLOCNO_NUM_OBJECTS (a
);
1058 for (k
= 0; k
< nobj
; k
++)
1060 ira_object_t obj
= ALLOCNO_OBJECT (a
, k
);
1061 ira_object_t conflict_obj
;
1062 ira_object_conflict_iterator oci
;
1064 FOR_EACH_OBJECT_CONFLICT (obj
, conflict_obj
, oci
)
1066 ira_allocno_t conflict_a
= OBJECT_ALLOCNO (conflict_obj
);
1068 /* We can process the conflict allocno repeatedly with
1070 if (nregs
== nobj
&& nregs
> 1)
1072 int num
= OBJECT_SUBWORD (conflict_obj
);
1074 if (REG_WORDS_BIG_ENDIAN
)
1076 (ALLOCNO_COLOR_DATA (conflict_a
)->profitable_hard_regs
,
1077 hard_regno
+ nobj
- num
- 1);
1080 (ALLOCNO_COLOR_DATA (conflict_a
)->profitable_hard_regs
,
1084 AND_COMPL_HARD_REG_SET
1085 (ALLOCNO_COLOR_DATA (conflict_a
)->profitable_hard_regs
,
1086 ira_reg_mode_hard_regset
[hard_regno
][mode
]);
1090 /* Exclude too costly hard regs. */
1091 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap
, 0, i
, bi
)
1093 int min_cost
= INT_MAX
;
1096 a
= ira_allocnos
[i
];
1097 if ((aclass
= ALLOCNO_CLASS (a
)) == NO_REGS
1098 || empty_profitable_hard_regs (a
))
1100 data
= ALLOCNO_COLOR_DATA (a
);
1101 mode
= ALLOCNO_MODE (a
);
1102 if ((costs
= ALLOCNO_UPDATED_HARD_REG_COSTS (a
)) != NULL
1103 || (costs
= ALLOCNO_HARD_REG_COSTS (a
)) != NULL
)
1105 class_size
= ira_class_hard_regs_num
[aclass
];
1106 for (j
= 0; j
< class_size
; j
++)
1108 hard_regno
= ira_class_hard_regs
[aclass
][j
];
1109 if (! TEST_HARD_REG_BIT (data
->profitable_hard_regs
,
1112 if (ALLOCNO_UPDATED_MEMORY_COST (a
) < costs
[j
])
1113 CLEAR_HARD_REG_BIT (data
->profitable_hard_regs
,
1115 else if (min_cost
> costs
[j
])
1116 min_cost
= costs
[j
];
1119 else if (ALLOCNO_UPDATED_MEMORY_COST (a
)
1120 < ALLOCNO_UPDATED_CLASS_COST (a
))
1121 CLEAR_HARD_REG_SET (data
->profitable_hard_regs
);
1122 if (ALLOCNO_UPDATED_CLASS_COST (a
) > min_cost
)
1123 ALLOCNO_UPDATED_CLASS_COST (a
) = min_cost
;
1129 /* This page contains functions used to choose hard registers for
1132 /* Pool for update cost records. */
1133 static alloc_pool update_cost_record_pool
;
1135 /* Initiate update cost records. */
1137 init_update_cost_records (void)
1139 update_cost_record_pool
1140 = create_alloc_pool ("update cost records",
1141 sizeof (struct update_cost_record
), 100);
1144 /* Return new update cost record with given params. */
1145 static struct update_cost_record
*
1146 get_update_cost_record (int hard_regno
, int divisor
,
1147 struct update_cost_record
*next
)
1149 struct update_cost_record
*record
;
1151 record
= (struct update_cost_record
*) pool_alloc (update_cost_record_pool
);
1152 record
->hard_regno
= hard_regno
;
1153 record
->divisor
= divisor
;
1154 record
->next
= next
;
1158 /* Free memory for all records in LIST. */
1160 free_update_cost_record_list (struct update_cost_record
*list
)
1162 struct update_cost_record
*next
;
1164 while (list
!= NULL
)
1167 pool_free (update_cost_record_pool
, list
);
1172 /* Free memory allocated for all update cost records. */
1174 finish_update_cost_records (void)
1176 free_alloc_pool (update_cost_record_pool
);
1179 /* Array whose element value is TRUE if the corresponding hard
1180 register was already allocated for an allocno. */
1181 static bool allocated_hardreg_p
[FIRST_PSEUDO_REGISTER
];
1183 /* Describes one element in a queue of allocnos whose costs need to be
1184 updated. Each allocno in the queue is known to have an allocno
1186 struct update_cost_queue_elem
1188 /* This element is in the queue iff CHECK == update_cost_check. */
1191 /* COST_HOP_DIVISOR**N, where N is the length of the shortest path
1192 connecting this allocno to the one being allocated. */
1195 /* Allocno from which we are chaning costs of connected allocnos.
1196 It is used not go back in graph of allocnos connected by
1200 /* The next allocno in the queue, or null if this is the last element. */
1204 /* The first element in a queue of allocnos whose copy costs need to be
1205 updated. Null if the queue is empty. */
1206 static ira_allocno_t update_cost_queue
;
1208 /* The last element in the queue described by update_cost_queue.
1209 Not valid if update_cost_queue is null. */
1210 static struct update_cost_queue_elem
*update_cost_queue_tail
;
1212 /* A pool of elements in the queue described by update_cost_queue.
1213 Elements are indexed by ALLOCNO_NUM. */
1214 static struct update_cost_queue_elem
*update_cost_queue_elems
;
1216 /* The current value of update_costs_from_copies call count. */
1217 static int update_cost_check
;
1219 /* Allocate and initialize data necessary for function
1220 update_costs_from_copies. */
1222 initiate_cost_update (void)
1226 size
= ira_allocnos_num
* sizeof (struct update_cost_queue_elem
);
1227 update_cost_queue_elems
1228 = (struct update_cost_queue_elem
*) ira_allocate (size
);
1229 memset (update_cost_queue_elems
, 0, size
);
1230 update_cost_check
= 0;
1231 init_update_cost_records ();
1234 /* Deallocate data used by function update_costs_from_copies. */
1236 finish_cost_update (void)
1238 ira_free (update_cost_queue_elems
);
1239 finish_update_cost_records ();
1242 /* When we traverse allocnos to update hard register costs, the cost
1243 divisor will be multiplied by the following macro value for each
1244 hop from given allocno to directly connected allocnos. */
1245 #define COST_HOP_DIVISOR 4
1247 /* Start a new cost-updating pass. */
1249 start_update_cost (void)
1251 update_cost_check
++;
1252 update_cost_queue
= NULL
;
1255 /* Add (ALLOCNO, FROM, DIVISOR) to the end of update_cost_queue, unless
1256 ALLOCNO is already in the queue, or has NO_REGS class. */
1258 queue_update_cost (ira_allocno_t allocno
, ira_allocno_t from
, int divisor
)
1260 struct update_cost_queue_elem
*elem
;
1262 elem
= &update_cost_queue_elems
[ALLOCNO_NUM (allocno
)];
1263 if (elem
->check
!= update_cost_check
1264 && ALLOCNO_CLASS (allocno
) != NO_REGS
)
1266 elem
->check
= update_cost_check
;
1268 elem
->divisor
= divisor
;
1270 if (update_cost_queue
== NULL
)
1271 update_cost_queue
= allocno
;
1273 update_cost_queue_tail
->next
= allocno
;
1274 update_cost_queue_tail
= elem
;
1278 /* Try to remove the first element from update_cost_queue. Return
1279 false if the queue was empty, otherwise make (*ALLOCNO, *FROM,
1280 *DIVISOR) describe the removed element. */
1282 get_next_update_cost (ira_allocno_t
*allocno
, ira_allocno_t
*from
, int *divisor
)
1284 struct update_cost_queue_elem
*elem
;
1286 if (update_cost_queue
== NULL
)
1289 *allocno
= update_cost_queue
;
1290 elem
= &update_cost_queue_elems
[ALLOCNO_NUM (*allocno
)];
1292 *divisor
= elem
->divisor
;
1293 update_cost_queue
= elem
->next
;
1297 /* Increase costs of HARD_REGNO by UPDATE_COST for ALLOCNO. Return
1298 true if we really modified the cost. */
1300 update_allocno_cost (ira_allocno_t allocno
, int hard_regno
, int update_cost
)
1303 enum reg_class aclass
= ALLOCNO_CLASS (allocno
);
1305 i
= ira_class_hard_reg_index
[aclass
][hard_regno
];
1308 ira_allocate_and_set_or_copy_costs
1309 (&ALLOCNO_UPDATED_HARD_REG_COSTS (allocno
), aclass
,
1310 ALLOCNO_UPDATED_CLASS_COST (allocno
),
1311 ALLOCNO_HARD_REG_COSTS (allocno
));
1312 ira_allocate_and_set_or_copy_costs
1313 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (allocno
),
1314 aclass
, 0, ALLOCNO_CONFLICT_HARD_REG_COSTS (allocno
));
1315 ALLOCNO_UPDATED_HARD_REG_COSTS (allocno
)[i
] += update_cost
;
1316 ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (allocno
)[i
] += update_cost
;
1320 /* Update (decrease if DECR_P) HARD_REGNO cost of allocnos connected
1321 by copies to ALLOCNO to increase chances to remove some copies as
1322 the result of subsequent assignment. Record cost updates if
1323 RECORD_P is true. */
1325 update_costs_from_allocno (ira_allocno_t allocno
, int hard_regno
,
1326 int divisor
, bool decr_p
, bool record_p
)
1328 int cost
, update_cost
;
1329 enum machine_mode mode
;
1330 enum reg_class rclass
, aclass
;
1331 ira_allocno_t another_allocno
, from
= NULL
;
1332 ira_copy_t cp
, next_cp
;
1334 rclass
= REGNO_REG_CLASS (hard_regno
);
1337 mode
= ALLOCNO_MODE (allocno
);
1338 ira_init_register_move_cost_if_necessary (mode
);
1339 for (cp
= ALLOCNO_COPIES (allocno
); cp
!= NULL
; cp
= next_cp
)
1341 if (cp
->first
== allocno
)
1343 next_cp
= cp
->next_first_allocno_copy
;
1344 another_allocno
= cp
->second
;
1346 else if (cp
->second
== allocno
)
1348 next_cp
= cp
->next_second_allocno_copy
;
1349 another_allocno
= cp
->first
;
1354 if (another_allocno
== from
)
1357 aclass
= ALLOCNO_CLASS (another_allocno
);
1358 if (! TEST_HARD_REG_BIT (reg_class_contents
[aclass
],
1360 || ALLOCNO_ASSIGNED_P (another_allocno
))
1363 cost
= (cp
->second
== allocno
1364 ? ira_register_move_cost
[mode
][rclass
][aclass
]
1365 : ira_register_move_cost
[mode
][aclass
][rclass
]);
1369 update_cost
= cp
->freq
* cost
/ divisor
;
1370 if (update_cost
== 0)
1373 if (! update_allocno_cost (another_allocno
, hard_regno
, update_cost
))
1375 queue_update_cost (another_allocno
, allocno
, divisor
* COST_HOP_DIVISOR
);
1376 if (record_p
&& ALLOCNO_COLOR_DATA (another_allocno
) != NULL
)
1377 ALLOCNO_COLOR_DATA (another_allocno
)->update_cost_records
1378 = get_update_cost_record (hard_regno
, divisor
,
1379 ALLOCNO_COLOR_DATA (another_allocno
)
1380 ->update_cost_records
);
1383 while (get_next_update_cost (&allocno
, &from
, &divisor
));
1386 /* Decrease preferred ALLOCNO hard register costs and costs of
1387 allocnos connected to ALLOCNO through copy. */
1389 update_costs_from_prefs (ira_allocno_t allocno
)
1393 start_update_cost ();
1394 for (pref
= ALLOCNO_PREFS (allocno
); pref
!= NULL
; pref
= pref
->next_pref
)
1395 update_costs_from_allocno (allocno
, pref
->hard_regno
,
1396 COST_HOP_DIVISOR
, true, true);
1399 /* Update (decrease if DECR_P) the cost of allocnos connected to
1400 ALLOCNO through copies to increase chances to remove some copies as
1401 the result of subsequent assignment. ALLOCNO was just assigned to
1402 a hard register. Record cost updates if RECORD_P is true. */
1404 update_costs_from_copies (ira_allocno_t allocno
, bool decr_p
, bool record_p
)
1408 hard_regno
= ALLOCNO_HARD_REGNO (allocno
);
1409 ira_assert (hard_regno
>= 0 && ALLOCNO_CLASS (allocno
) != NO_REGS
);
1410 start_update_cost ();
1411 update_costs_from_allocno (allocno
, hard_regno
, 1, decr_p
, record_p
);
1414 /* Restore costs of allocnos connected to ALLOCNO by copies as it was
1415 before updating costs of these allocnos from given allocno. This
1416 is a wise thing to do as if given allocno did not get an expected
1417 hard reg, using smaller cost of the hard reg for allocnos connected
1418 by copies to given allocno becomes actually misleading. Free all
1419 update cost records for ALLOCNO as we don't need them anymore. */
1421 restore_costs_from_copies (ira_allocno_t allocno
)
1423 struct update_cost_record
*records
, *curr
;
1425 if (ALLOCNO_COLOR_DATA (allocno
) == NULL
)
1427 records
= ALLOCNO_COLOR_DATA (allocno
)->update_cost_records
;
1428 start_update_cost ();
1429 for (curr
= records
; curr
!= NULL
; curr
= curr
->next
)
1430 update_costs_from_allocno (allocno
, curr
->hard_regno
,
1431 curr
->divisor
, true, false);
1432 free_update_cost_record_list (records
);
1433 ALLOCNO_COLOR_DATA (allocno
)->update_cost_records
= NULL
;
1436 /* This function updates COSTS (decrease if DECR_P) for hard_registers
1437 of ACLASS by conflict costs of the unassigned allocnos
1438 connected by copies with allocnos in update_cost_queue. This
1439 update increases chances to remove some copies. */
1441 update_conflict_hard_regno_costs (int *costs
, enum reg_class aclass
,
1444 int i
, cost
, class_size
, freq
, mult
, div
, divisor
;
1445 int index
, hard_regno
;
1446 int *conflict_costs
;
1448 enum reg_class another_aclass
;
1449 ira_allocno_t allocno
, another_allocno
, from
;
1450 ira_copy_t cp
, next_cp
;
1452 while (get_next_update_cost (&allocno
, &from
, &divisor
))
1453 for (cp
= ALLOCNO_COPIES (allocno
); cp
!= NULL
; cp
= next_cp
)
1455 if (cp
->first
== allocno
)
1457 next_cp
= cp
->next_first_allocno_copy
;
1458 another_allocno
= cp
->second
;
1460 else if (cp
->second
== allocno
)
1462 next_cp
= cp
->next_second_allocno_copy
;
1463 another_allocno
= cp
->first
;
1468 if (another_allocno
== from
)
1471 another_aclass
= ALLOCNO_CLASS (another_allocno
);
1472 if (! ira_reg_classes_intersect_p
[aclass
][another_aclass
]
1473 || ALLOCNO_ASSIGNED_P (another_allocno
)
1474 || ALLOCNO_COLOR_DATA (another_allocno
)->may_be_spilled_p
)
1476 class_size
= ira_class_hard_regs_num
[another_aclass
];
1477 ira_allocate_and_copy_costs
1478 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (another_allocno
),
1479 another_aclass
, ALLOCNO_CONFLICT_HARD_REG_COSTS (another_allocno
));
1481 = ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (another_allocno
);
1482 if (conflict_costs
== NULL
)
1487 freq
= ALLOCNO_FREQ (another_allocno
);
1490 div
= freq
* divisor
;
1492 for (i
= class_size
- 1; i
>= 0; i
--)
1494 hard_regno
= ira_class_hard_regs
[another_aclass
][i
];
1495 ira_assert (hard_regno
>= 0);
1496 index
= ira_class_hard_reg_index
[aclass
][hard_regno
];
1499 cost
= conflict_costs
[i
] * mult
/ div
;
1505 costs
[index
] += cost
;
1508 /* Probably 5 hops will be enough. */
1510 && divisor
<= (COST_HOP_DIVISOR
1513 * COST_HOP_DIVISOR
))
1514 queue_update_cost (another_allocno
, allocno
, divisor
* COST_HOP_DIVISOR
);
1518 /* Set up conflicting (through CONFLICT_REGS) for each object of
1519 allocno A and the start allocno profitable regs (through
1520 START_PROFITABLE_REGS). Remember that the start profitable regs
1521 exclude hard regs which can not hold value of mode of allocno A.
1522 This covers mostly cases when multi-register value should be
1525 get_conflict_and_start_profitable_regs (ira_allocno_t a
, bool retry_p
,
1526 HARD_REG_SET
*conflict_regs
,
1527 HARD_REG_SET
*start_profitable_regs
)
1532 nwords
= ALLOCNO_NUM_OBJECTS (a
);
1533 for (i
= 0; i
< nwords
; i
++)
1535 obj
= ALLOCNO_OBJECT (a
, i
);
1536 COPY_HARD_REG_SET (conflict_regs
[i
],
1537 OBJECT_TOTAL_CONFLICT_HARD_REGS (obj
));
1541 COPY_HARD_REG_SET (*start_profitable_regs
,
1542 reg_class_contents
[ALLOCNO_CLASS (a
)]);
1543 AND_COMPL_HARD_REG_SET (*start_profitable_regs
,
1544 ira_prohibited_class_mode_regs
1545 [ALLOCNO_CLASS (a
)][ALLOCNO_MODE (a
)]);
1548 COPY_HARD_REG_SET (*start_profitable_regs
,
1549 ALLOCNO_COLOR_DATA (a
)->profitable_hard_regs
);
1552 /* Return true if HARD_REGNO is ok for assigning to allocno A with
1553 PROFITABLE_REGS and whose objects have CONFLICT_REGS. */
1555 check_hard_reg_p (ira_allocno_t a
, int hard_regno
,
1556 HARD_REG_SET
*conflict_regs
, HARD_REG_SET profitable_regs
)
1558 int j
, nwords
, nregs
;
1559 enum reg_class aclass
;
1560 enum machine_mode mode
;
1562 aclass
= ALLOCNO_CLASS (a
);
1563 mode
= ALLOCNO_MODE (a
);
1564 if (TEST_HARD_REG_BIT (ira_prohibited_class_mode_regs
[aclass
][mode
],
1567 /* Checking only profitable hard regs. */
1568 if (! TEST_HARD_REG_BIT (profitable_regs
, hard_regno
))
1570 nregs
= hard_regno_nregs
[hard_regno
][mode
];
1571 nwords
= ALLOCNO_NUM_OBJECTS (a
);
1572 for (j
= 0; j
< nregs
; j
++)
1575 int set_to_test_start
= 0, set_to_test_end
= nwords
;
1577 if (nregs
== nwords
)
1579 if (REG_WORDS_BIG_ENDIAN
)
1580 set_to_test_start
= nwords
- j
- 1;
1582 set_to_test_start
= j
;
1583 set_to_test_end
= set_to_test_start
+ 1;
1585 for (k
= set_to_test_start
; k
< set_to_test_end
; k
++)
1586 if (TEST_HARD_REG_BIT (conflict_regs
[k
], hard_regno
+ j
))
1588 if (k
!= set_to_test_end
)
1593 #ifndef HONOR_REG_ALLOC_ORDER
1595 /* Return number of registers needed to be saved and restored at
1596 function prologue/epilogue if we allocate HARD_REGNO to hold value
1599 calculate_saved_nregs (int hard_regno
, enum machine_mode mode
)
1604 ira_assert (hard_regno
>= 0);
1605 for (i
= hard_regno_nregs
[hard_regno
][mode
] - 1; i
>= 0; i
--)
1606 if (!allocated_hardreg_p
[hard_regno
+ i
]
1607 && !TEST_HARD_REG_BIT (call_used_reg_set
, hard_regno
+ i
)
1608 && !LOCAL_REGNO (hard_regno
+ i
))
1614 /* Choose a hard register for allocno A. If RETRY_P is TRUE, it means
1615 that the function called from function
1616 `ira_reassign_conflict_allocnos' and `allocno_reload_assign'. In
1617 this case some allocno data are not defined or updated and we
1618 should not touch these data. The function returns true if we
1619 managed to assign a hard register to the allocno.
1621 To assign a hard register, first of all we calculate all conflict
1622 hard registers which can come from conflicting allocnos with
1623 already assigned hard registers. After that we find first free
1624 hard register with the minimal cost. During hard register cost
1625 calculation we take conflict hard register costs into account to
1626 give a chance for conflicting allocnos to get a better hard
1627 register in the future.
1629 If the best hard register cost is bigger than cost of memory usage
1630 for the allocno, we don't assign a hard register to given allocno
1633 If we assign a hard register to the allocno, we update costs of the
1634 hard register for allocnos connected by copies to improve a chance
1635 to coalesce insns represented by the copies when we assign hard
1636 registers to the allocnos connected by the copies. */
1638 assign_hard_reg (ira_allocno_t a
, bool retry_p
)
1640 HARD_REG_SET conflicting_regs
[2], profitable_hard_regs
;
1641 int i
, j
, hard_regno
, best_hard_regno
, class_size
;
1642 int cost
, mem_cost
, min_cost
, full_cost
, min_full_cost
, nwords
, word
;
1644 enum reg_class aclass
;
1645 enum machine_mode mode
;
1646 static int costs
[FIRST_PSEUDO_REGISTER
], full_costs
[FIRST_PSEUDO_REGISTER
];
1647 #ifndef HONOR_REG_ALLOC_ORDER
1649 enum reg_class rclass
;
1653 bool no_stack_reg_p
;
1656 ira_assert (! ALLOCNO_ASSIGNED_P (a
));
1657 get_conflict_and_start_profitable_regs (a
, retry_p
,
1659 &profitable_hard_regs
);
1660 aclass
= ALLOCNO_CLASS (a
);
1661 class_size
= ira_class_hard_regs_num
[aclass
];
1662 best_hard_regno
= -1;
1663 memset (full_costs
, 0, sizeof (int) * class_size
);
1665 memset (costs
, 0, sizeof (int) * class_size
);
1666 memset (full_costs
, 0, sizeof (int) * class_size
);
1668 no_stack_reg_p
= false;
1671 start_update_cost ();
1672 mem_cost
+= ALLOCNO_UPDATED_MEMORY_COST (a
);
1674 ira_allocate_and_copy_costs (&ALLOCNO_UPDATED_HARD_REG_COSTS (a
),
1675 aclass
, ALLOCNO_HARD_REG_COSTS (a
));
1676 a_costs
= ALLOCNO_UPDATED_HARD_REG_COSTS (a
);
1678 no_stack_reg_p
= no_stack_reg_p
|| ALLOCNO_TOTAL_NO_STACK_REG_P (a
);
1680 cost
= ALLOCNO_UPDATED_CLASS_COST (a
);
1681 for (i
= 0; i
< class_size
; i
++)
1682 if (a_costs
!= NULL
)
1684 costs
[i
] += a_costs
[i
];
1685 full_costs
[i
] += a_costs
[i
];
1690 full_costs
[i
] += cost
;
1692 nwords
= ALLOCNO_NUM_OBJECTS (a
);
1693 curr_allocno_process
++;
1694 for (word
= 0; word
< nwords
; word
++)
1696 ira_object_t conflict_obj
;
1697 ira_object_t obj
= ALLOCNO_OBJECT (a
, word
);
1698 ira_object_conflict_iterator oci
;
1700 /* Take preferences of conflicting allocnos into account. */
1701 FOR_EACH_OBJECT_CONFLICT (obj
, conflict_obj
, oci
)
1703 ira_allocno_t conflict_a
= OBJECT_ALLOCNO (conflict_obj
);
1704 enum reg_class conflict_aclass
;
1706 /* Reload can give another class so we need to check all
1709 && (!bitmap_bit_p (consideration_allocno_bitmap
,
1710 ALLOCNO_NUM (conflict_a
))
1711 || ((!ALLOCNO_ASSIGNED_P (conflict_a
)
1712 || ALLOCNO_HARD_REGNO (conflict_a
) < 0)
1713 && !(hard_reg_set_intersect_p
1714 (profitable_hard_regs
,
1716 (conflict_a
)->profitable_hard_regs
)))))
1718 conflict_aclass
= ALLOCNO_CLASS (conflict_a
);
1719 ira_assert (ira_reg_classes_intersect_p
1720 [aclass
][conflict_aclass
]);
1721 if (ALLOCNO_ASSIGNED_P (conflict_a
))
1723 hard_regno
= ALLOCNO_HARD_REGNO (conflict_a
);
1725 && (ira_hard_reg_set_intersection_p
1726 (hard_regno
, ALLOCNO_MODE (conflict_a
),
1727 reg_class_contents
[aclass
])))
1729 int n_objects
= ALLOCNO_NUM_OBJECTS (conflict_a
);
1732 mode
= ALLOCNO_MODE (conflict_a
);
1733 conflict_nregs
= hard_regno_nregs
[hard_regno
][mode
];
1734 if (conflict_nregs
== n_objects
&& conflict_nregs
> 1)
1736 int num
= OBJECT_SUBWORD (conflict_obj
);
1738 if (REG_WORDS_BIG_ENDIAN
)
1739 SET_HARD_REG_BIT (conflicting_regs
[word
],
1740 hard_regno
+ n_objects
- num
- 1);
1742 SET_HARD_REG_BIT (conflicting_regs
[word
],
1747 (conflicting_regs
[word
],
1748 ira_reg_mode_hard_regset
[hard_regno
][mode
]);
1749 if (hard_reg_set_subset_p (profitable_hard_regs
,
1750 conflicting_regs
[word
]))
1755 && ! ALLOCNO_COLOR_DATA (conflict_a
)->may_be_spilled_p
1756 /* Don't process the conflict allocno twice. */
1757 && (ALLOCNO_COLOR_DATA (conflict_a
)->last_process
1758 != curr_allocno_process
))
1760 int k
, *conflict_costs
;
1762 ALLOCNO_COLOR_DATA (conflict_a
)->last_process
1763 = curr_allocno_process
;
1764 ira_allocate_and_copy_costs
1765 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (conflict_a
),
1767 ALLOCNO_CONFLICT_HARD_REG_COSTS (conflict_a
));
1769 = ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (conflict_a
);
1770 if (conflict_costs
!= NULL
)
1771 for (j
= class_size
- 1; j
>= 0; j
--)
1773 hard_regno
= ira_class_hard_regs
[aclass
][j
];
1774 ira_assert (hard_regno
>= 0);
1775 k
= ira_class_hard_reg_index
[conflict_aclass
][hard_regno
];
1778 full_costs
[j
] -= conflict_costs
[k
];
1780 queue_update_cost (conflict_a
, NULL
, COST_HOP_DIVISOR
);
1786 /* Take into account preferences of allocnos connected by copies to
1787 the conflict allocnos. */
1788 update_conflict_hard_regno_costs (full_costs
, aclass
, true);
1790 /* Take preferences of allocnos connected by copies into
1794 start_update_cost ();
1795 queue_update_cost (a
, NULL
, COST_HOP_DIVISOR
);
1796 update_conflict_hard_regno_costs (full_costs
, aclass
, false);
1798 min_cost
= min_full_cost
= INT_MAX
;
1799 /* We don't care about giving callee saved registers to allocnos no
1800 living through calls because call clobbered registers are
1801 allocated first (it is usual practice to put them first in
1802 REG_ALLOC_ORDER). */
1803 mode
= ALLOCNO_MODE (a
);
1804 for (i
= 0; i
< class_size
; i
++)
1806 hard_regno
= ira_class_hard_regs
[aclass
][i
];
1809 && FIRST_STACK_REG
<= hard_regno
&& hard_regno
<= LAST_STACK_REG
)
1812 if (! check_hard_reg_p (a
, hard_regno
,
1813 conflicting_regs
, profitable_hard_regs
))
1816 full_cost
= full_costs
[i
];
1817 #ifndef HONOR_REG_ALLOC_ORDER
1818 if ((saved_nregs
= calculate_saved_nregs (hard_regno
, mode
)) != 0)
1819 /* We need to save/restore the hard register in
1820 epilogue/prologue. Therefore we increase the cost. */
1822 rclass
= REGNO_REG_CLASS (hard_regno
);
1823 add_cost
= ((ira_memory_move_cost
[mode
][rclass
][0]
1824 + ira_memory_move_cost
[mode
][rclass
][1])
1825 * saved_nregs
/ hard_regno_nregs
[hard_regno
][mode
] - 1);
1827 full_cost
+= add_cost
;
1830 if (min_cost
> cost
)
1832 if (min_full_cost
> full_cost
)
1834 min_full_cost
= full_cost
;
1835 best_hard_regno
= hard_regno
;
1836 ira_assert (hard_regno
>= 0);
1839 if (min_full_cost
> mem_cost
)
1841 if (! retry_p
&& internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
1842 fprintf (ira_dump_file
, "(memory is more profitable %d vs %d) ",
1843 mem_cost
, min_full_cost
);
1844 best_hard_regno
= -1;
1847 if (best_hard_regno
>= 0)
1849 for (i
= hard_regno_nregs
[best_hard_regno
][mode
] - 1; i
>= 0; i
--)
1850 allocated_hardreg_p
[best_hard_regno
+ i
] = true;
1853 restore_costs_from_copies (a
);
1854 ALLOCNO_HARD_REGNO (a
) = best_hard_regno
;
1855 ALLOCNO_ASSIGNED_P (a
) = true;
1856 if (best_hard_regno
>= 0)
1857 update_costs_from_copies (a
, true, ! retry_p
);
1858 ira_assert (ALLOCNO_CLASS (a
) == aclass
);
1859 /* We don't need updated costs anymore: */
1860 ira_free_allocno_updated_costs (a
);
1861 return best_hard_regno
>= 0;
1866 /* This page contains the allocator based on the Chaitin-Briggs algorithm. */
1868 /* Bucket of allocnos that can colored currently without spilling. */
1869 static ira_allocno_t colorable_allocno_bucket
;
1871 /* Bucket of allocnos that might be not colored currently without
1873 static ira_allocno_t uncolorable_allocno_bucket
;
1875 /* The current number of allocnos in the uncolorable_bucket. */
1876 static int uncolorable_allocnos_num
;
1878 /* Return the current spill priority of allocno A. The less the
1879 number, the more preferable the allocno for spilling. */
1881 allocno_spill_priority (ira_allocno_t a
)
1883 allocno_color_data_t data
= ALLOCNO_COLOR_DATA (a
);
1886 / (ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a
)
1887 * ira_reg_class_max_nregs
[ALLOCNO_CLASS (a
)][ALLOCNO_MODE (a
)]
1891 /* Add allocno A to bucket *BUCKET_PTR. A should be not in a bucket
1894 add_allocno_to_bucket (ira_allocno_t a
, ira_allocno_t
*bucket_ptr
)
1896 ira_allocno_t first_a
;
1897 allocno_color_data_t data
;
1899 if (bucket_ptr
== &uncolorable_allocno_bucket
1900 && ALLOCNO_CLASS (a
) != NO_REGS
)
1902 uncolorable_allocnos_num
++;
1903 ira_assert (uncolorable_allocnos_num
> 0);
1905 first_a
= *bucket_ptr
;
1906 data
= ALLOCNO_COLOR_DATA (a
);
1907 data
->next_bucket_allocno
= first_a
;
1908 data
->prev_bucket_allocno
= NULL
;
1909 if (first_a
!= NULL
)
1910 ALLOCNO_COLOR_DATA (first_a
)->prev_bucket_allocno
= a
;
1914 /* Compare two allocnos to define which allocno should be pushed first
1915 into the coloring stack. If the return is a negative number, the
1916 allocno given by the first parameter will be pushed first. In this
1917 case such allocno has less priority than the second one and the
1918 hard register will be assigned to it after assignment to the second
1919 one. As the result of such assignment order, the second allocno
1920 has a better chance to get the best hard register. */
1922 bucket_allocno_compare_func (const void *v1p
, const void *v2p
)
1924 ira_allocno_t a1
= *(const ira_allocno_t
*) v1p
;
1925 ira_allocno_t a2
= *(const ira_allocno_t
*) v2p
;
1926 int diff
, a1_freq
, a2_freq
, a1_num
, a2_num
;
1927 int cl1
= ALLOCNO_CLASS (a1
), cl2
= ALLOCNO_CLASS (a2
);
1929 /* Push pseudos requiring less hard registers first. It means that
1930 we will assign pseudos requiring more hard registers first
1931 avoiding creation small holes in free hard register file into
1932 which the pseudos requiring more hard registers can not fit. */
1933 if ((diff
= (ira_reg_class_max_nregs
[cl1
][ALLOCNO_MODE (a1
)]
1934 - ira_reg_class_max_nregs
[cl2
][ALLOCNO_MODE (a2
)])) != 0)
1936 a1_freq
= ALLOCNO_FREQ (a1
);
1937 a2_freq
= ALLOCNO_FREQ (a2
);
1938 if ((diff
= a1_freq
- a2_freq
) != 0)
1940 a1_num
= ALLOCNO_COLOR_DATA (a1
)->available_regs_num
;
1941 a2_num
= ALLOCNO_COLOR_DATA (a2
)->available_regs_num
;
1942 if ((diff
= a2_num
- a1_num
) != 0)
1944 return ALLOCNO_NUM (a2
) - ALLOCNO_NUM (a1
);
1947 /* Sort bucket *BUCKET_PTR and return the result through
1950 sort_bucket (ira_allocno_t
*bucket_ptr
,
1951 int (*compare_func
) (const void *, const void *))
1953 ira_allocno_t a
, head
;
1956 for (n
= 0, a
= *bucket_ptr
;
1958 a
= ALLOCNO_COLOR_DATA (a
)->next_bucket_allocno
)
1959 sorted_allocnos
[n
++] = a
;
1962 qsort (sorted_allocnos
, n
, sizeof (ira_allocno_t
), compare_func
);
1964 for (n
--; n
>= 0; n
--)
1966 a
= sorted_allocnos
[n
];
1967 ALLOCNO_COLOR_DATA (a
)->next_bucket_allocno
= head
;
1968 ALLOCNO_COLOR_DATA (a
)->prev_bucket_allocno
= NULL
;
1970 ALLOCNO_COLOR_DATA (head
)->prev_bucket_allocno
= a
;
1976 /* Add ALLOCNO to bucket *BUCKET_PTR maintaining the order according
1977 their priority. ALLOCNO should be not in a bucket before the
1980 add_allocno_to_ordered_bucket (ira_allocno_t allocno
,
1981 ira_allocno_t
*bucket_ptr
)
1983 ira_allocno_t before
, after
;
1985 if (bucket_ptr
== &uncolorable_allocno_bucket
1986 && ALLOCNO_CLASS (allocno
) != NO_REGS
)
1988 uncolorable_allocnos_num
++;
1989 ira_assert (uncolorable_allocnos_num
> 0);
1991 for (before
= *bucket_ptr
, after
= NULL
;
1994 before
= ALLOCNO_COLOR_DATA (before
)->next_bucket_allocno
)
1995 if (bucket_allocno_compare_func (&allocno
, &before
) < 0)
1997 ALLOCNO_COLOR_DATA (allocno
)->next_bucket_allocno
= before
;
1998 ALLOCNO_COLOR_DATA (allocno
)->prev_bucket_allocno
= after
;
2000 *bucket_ptr
= allocno
;
2002 ALLOCNO_COLOR_DATA (after
)->next_bucket_allocno
= allocno
;
2004 ALLOCNO_COLOR_DATA (before
)->prev_bucket_allocno
= allocno
;
2007 /* Delete ALLOCNO from bucket *BUCKET_PTR. It should be there before
2010 delete_allocno_from_bucket (ira_allocno_t allocno
, ira_allocno_t
*bucket_ptr
)
2012 ira_allocno_t prev_allocno
, next_allocno
;
2014 if (bucket_ptr
== &uncolorable_allocno_bucket
2015 && ALLOCNO_CLASS (allocno
) != NO_REGS
)
2017 uncolorable_allocnos_num
--;
2018 ira_assert (uncolorable_allocnos_num
>= 0);
2020 prev_allocno
= ALLOCNO_COLOR_DATA (allocno
)->prev_bucket_allocno
;
2021 next_allocno
= ALLOCNO_COLOR_DATA (allocno
)->next_bucket_allocno
;
2022 if (prev_allocno
!= NULL
)
2023 ALLOCNO_COLOR_DATA (prev_allocno
)->next_bucket_allocno
= next_allocno
;
2026 ira_assert (*bucket_ptr
== allocno
);
2027 *bucket_ptr
= next_allocno
;
2029 if (next_allocno
!= NULL
)
2030 ALLOCNO_COLOR_DATA (next_allocno
)->prev_bucket_allocno
= prev_allocno
;
2033 /* Put allocno A onto the coloring stack without removing it from its
2034 bucket. Pushing allocno to the coloring stack can result in moving
2035 conflicting allocnos from the uncolorable bucket to the colorable
2038 push_allocno_to_stack (ira_allocno_t a
)
2040 enum reg_class aclass
;
2041 allocno_color_data_t data
, conflict_data
;
2042 int size
, i
, n
= ALLOCNO_NUM_OBJECTS (a
);
2044 data
= ALLOCNO_COLOR_DATA (a
);
2045 data
->in_graph_p
= false;
2046 allocno_stack_vec
.safe_push (a
);
2047 aclass
= ALLOCNO_CLASS (a
);
2048 if (aclass
== NO_REGS
)
2050 size
= ira_reg_class_max_nregs
[aclass
][ALLOCNO_MODE (a
)];
2053 /* We will deal with the subwords individually. */
2054 gcc_assert (size
== ALLOCNO_NUM_OBJECTS (a
));
2057 for (i
= 0; i
< n
; i
++)
2059 ira_object_t obj
= ALLOCNO_OBJECT (a
, i
);
2060 ira_object_t conflict_obj
;
2061 ira_object_conflict_iterator oci
;
2063 FOR_EACH_OBJECT_CONFLICT (obj
, conflict_obj
, oci
)
2065 ira_allocno_t conflict_a
= OBJECT_ALLOCNO (conflict_obj
);
2067 conflict_data
= ALLOCNO_COLOR_DATA (conflict_a
);
2068 if (conflict_data
->colorable_p
2069 || ! conflict_data
->in_graph_p
2070 || ALLOCNO_ASSIGNED_P (conflict_a
)
2071 || !(hard_reg_set_intersect_p
2072 (ALLOCNO_COLOR_DATA (a
)->profitable_hard_regs
,
2073 conflict_data
->profitable_hard_regs
)))
2075 ira_assert (bitmap_bit_p (coloring_allocno_bitmap
,
2076 ALLOCNO_NUM (conflict_a
)));
2077 if (update_left_conflict_sizes_p (conflict_a
, a
, size
))
2079 delete_allocno_from_bucket
2080 (conflict_a
, &uncolorable_allocno_bucket
);
2081 add_allocno_to_ordered_bucket
2082 (conflict_a
, &colorable_allocno_bucket
);
2083 if (internal_flag_ira_verbose
> 4 && ira_dump_file
!= NULL
)
2085 fprintf (ira_dump_file
, " Making");
2086 ira_print_expanded_allocno (conflict_a
);
2087 fprintf (ira_dump_file
, " colorable\n");
2095 /* Put ALLOCNO onto the coloring stack and remove it from its bucket.
2096 The allocno is in the colorable bucket if COLORABLE_P is TRUE. */
2098 remove_allocno_from_bucket_and_push (ira_allocno_t allocno
, bool colorable_p
)
2101 delete_allocno_from_bucket (allocno
, &colorable_allocno_bucket
);
2103 delete_allocno_from_bucket (allocno
, &uncolorable_allocno_bucket
);
2104 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
2106 fprintf (ira_dump_file
, " Pushing");
2107 ira_print_expanded_allocno (allocno
);
2109 fprintf (ira_dump_file
, "(cost %d)\n",
2110 ALLOCNO_COLOR_DATA (allocno
)->temp
);
2112 fprintf (ira_dump_file
, "(potential spill: %spri=%d, cost=%d)\n",
2113 ALLOCNO_BAD_SPILL_P (allocno
) ? "bad spill, " : "",
2114 allocno_spill_priority (allocno
),
2115 ALLOCNO_COLOR_DATA (allocno
)->temp
);
2118 ALLOCNO_COLOR_DATA (allocno
)->may_be_spilled_p
= true;
2119 push_allocno_to_stack (allocno
);
2122 /* Put all allocnos from colorable bucket onto the coloring stack. */
2124 push_only_colorable (void)
2126 sort_bucket (&colorable_allocno_bucket
, bucket_allocno_compare_func
);
2127 for (;colorable_allocno_bucket
!= NULL
;)
2128 remove_allocno_from_bucket_and_push (colorable_allocno_bucket
, true);
2131 /* Return the frequency of exit edges (if EXIT_P) or entry from/to the
2132 loop given by its LOOP_NODE. */
2134 ira_loop_edge_freq (ira_loop_tree_node_t loop_node
, int regno
, bool exit_p
)
2141 ira_assert (current_loops
!= NULL
&& loop_node
->loop
!= NULL
2142 && (regno
< 0 || regno
>= FIRST_PSEUDO_REGISTER
));
2146 FOR_EACH_EDGE (e
, ei
, loop_node
->loop
->header
->preds
)
2147 if (e
->src
!= loop_node
->loop
->latch
2149 || (bitmap_bit_p (df_get_live_out (e
->src
), regno
)
2150 && bitmap_bit_p (df_get_live_in (e
->dest
), regno
))))
2151 freq
+= EDGE_FREQUENCY (e
);
2155 edges
= get_loop_exit_edges (loop_node
->loop
);
2156 FOR_EACH_VEC_ELT (edges
, i
, e
)
2158 || (bitmap_bit_p (df_get_live_out (e
->src
), regno
)
2159 && bitmap_bit_p (df_get_live_in (e
->dest
), regno
)))
2160 freq
+= EDGE_FREQUENCY (e
);
2164 return REG_FREQ_FROM_EDGE_FREQ (freq
);
2167 /* Calculate and return the cost of putting allocno A into memory. */
2169 calculate_allocno_spill_cost (ira_allocno_t a
)
2172 enum machine_mode mode
;
2173 enum reg_class rclass
;
2174 ira_allocno_t parent_allocno
;
2175 ira_loop_tree_node_t parent_node
, loop_node
;
2177 regno
= ALLOCNO_REGNO (a
);
2178 cost
= ALLOCNO_UPDATED_MEMORY_COST (a
) - ALLOCNO_UPDATED_CLASS_COST (a
);
2179 if (ALLOCNO_CAP (a
) != NULL
)
2181 loop_node
= ALLOCNO_LOOP_TREE_NODE (a
);
2182 if ((parent_node
= loop_node
->parent
) == NULL
)
2184 if ((parent_allocno
= parent_node
->regno_allocno_map
[regno
]) == NULL
)
2186 mode
= ALLOCNO_MODE (a
);
2187 rclass
= ALLOCNO_CLASS (a
);
2188 if (ALLOCNO_HARD_REGNO (parent_allocno
) < 0)
2189 cost
-= (ira_memory_move_cost
[mode
][rclass
][0]
2190 * ira_loop_edge_freq (loop_node
, regno
, true)
2191 + ira_memory_move_cost
[mode
][rclass
][1]
2192 * ira_loop_edge_freq (loop_node
, regno
, false));
2195 ira_init_register_move_cost_if_necessary (mode
);
2196 cost
+= ((ira_memory_move_cost
[mode
][rclass
][1]
2197 * ira_loop_edge_freq (loop_node
, regno
, true)
2198 + ira_memory_move_cost
[mode
][rclass
][0]
2199 * ira_loop_edge_freq (loop_node
, regno
, false))
2200 - (ira_register_move_cost
[mode
][rclass
][rclass
]
2201 * (ira_loop_edge_freq (loop_node
, regno
, false)
2202 + ira_loop_edge_freq (loop_node
, regno
, true))));
2207 /* Used for sorting allocnos for spilling. */
2209 allocno_spill_priority_compare (ira_allocno_t a1
, ira_allocno_t a2
)
2211 int pri1
, pri2
, diff
;
2213 if (ALLOCNO_BAD_SPILL_P (a1
) && ! ALLOCNO_BAD_SPILL_P (a2
))
2215 if (ALLOCNO_BAD_SPILL_P (a2
) && ! ALLOCNO_BAD_SPILL_P (a1
))
2217 pri1
= allocno_spill_priority (a1
);
2218 pri2
= allocno_spill_priority (a2
);
2219 if ((diff
= pri1
- pri2
) != 0)
2222 = ALLOCNO_COLOR_DATA (a1
)->temp
- ALLOCNO_COLOR_DATA (a2
)->temp
) != 0)
2224 return ALLOCNO_NUM (a1
) - ALLOCNO_NUM (a2
);
2227 /* Used for sorting allocnos for spilling. */
2229 allocno_spill_sort_compare (const void *v1p
, const void *v2p
)
2231 ira_allocno_t p1
= *(const ira_allocno_t
*) v1p
;
2232 ira_allocno_t p2
= *(const ira_allocno_t
*) v2p
;
2234 return allocno_spill_priority_compare (p1
, p2
);
2237 /* Push allocnos to the coloring stack. The order of allocnos in the
2238 stack defines the order for the subsequent coloring. */
2240 push_allocnos_to_stack (void)
2245 /* Calculate uncolorable allocno spill costs. */
2246 for (a
= uncolorable_allocno_bucket
;
2248 a
= ALLOCNO_COLOR_DATA (a
)->next_bucket_allocno
)
2249 if (ALLOCNO_CLASS (a
) != NO_REGS
)
2251 cost
= calculate_allocno_spill_cost (a
);
2252 /* ??? Remove cost of copies between the coalesced
2254 ALLOCNO_COLOR_DATA (a
)->temp
= cost
;
2256 sort_bucket (&uncolorable_allocno_bucket
, allocno_spill_sort_compare
);
2259 push_only_colorable ();
2260 a
= uncolorable_allocno_bucket
;
2263 remove_allocno_from_bucket_and_push (a
, false);
2265 ira_assert (colorable_allocno_bucket
== NULL
2266 && uncolorable_allocno_bucket
== NULL
);
2267 ira_assert (uncolorable_allocnos_num
== 0);
2270 /* Pop the coloring stack and assign hard registers to the popped
2273 pop_allocnos_from_stack (void)
2275 ira_allocno_t allocno
;
2276 enum reg_class aclass
;
2278 for (;allocno_stack_vec
.length () != 0;)
2280 allocno
= allocno_stack_vec
.pop ();
2281 aclass
= ALLOCNO_CLASS (allocno
);
2282 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
2284 fprintf (ira_dump_file
, " Popping");
2285 ira_print_expanded_allocno (allocno
);
2286 fprintf (ira_dump_file
, " -- ");
2288 if (aclass
== NO_REGS
)
2290 ALLOCNO_HARD_REGNO (allocno
) = -1;
2291 ALLOCNO_ASSIGNED_P (allocno
) = true;
2292 ira_assert (ALLOCNO_UPDATED_HARD_REG_COSTS (allocno
) == NULL
);
2294 (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (allocno
) == NULL
);
2295 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
2296 fprintf (ira_dump_file
, "assign memory\n");
2298 else if (assign_hard_reg (allocno
, false))
2300 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
2301 fprintf (ira_dump_file
, "assign reg %d\n",
2302 ALLOCNO_HARD_REGNO (allocno
));
2304 else if (ALLOCNO_ASSIGNED_P (allocno
))
2306 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
2307 fprintf (ira_dump_file
, "spill%s\n",
2308 ALLOCNO_COLOR_DATA (allocno
)->may_be_spilled_p
2311 ALLOCNO_COLOR_DATA (allocno
)->in_graph_p
= true;
2315 /* Set up number of available hard registers for allocno A. */
2317 setup_allocno_available_regs_num (ira_allocno_t a
)
2319 int i
, n
, hard_regno
, hard_regs_num
, nwords
;
2320 enum reg_class aclass
;
2321 allocno_color_data_t data
;
2323 aclass
= ALLOCNO_CLASS (a
);
2324 data
= ALLOCNO_COLOR_DATA (a
);
2325 data
->available_regs_num
= 0;
2326 if (aclass
== NO_REGS
)
2328 hard_regs_num
= ira_class_hard_regs_num
[aclass
];
2329 nwords
= ALLOCNO_NUM_OBJECTS (a
);
2330 for (n
= 0, i
= hard_regs_num
- 1; i
>= 0; i
--)
2332 hard_regno
= ira_class_hard_regs
[aclass
][i
];
2333 /* Checking only profitable hard regs. */
2334 if (TEST_HARD_REG_BIT (data
->profitable_hard_regs
, hard_regno
))
2337 data
->available_regs_num
= n
;
2338 if (internal_flag_ira_verbose
<= 2 || ira_dump_file
== NULL
)
2342 " Allocno a%dr%d of %s(%d) has %d avail. regs ",
2343 ALLOCNO_NUM (a
), ALLOCNO_REGNO (a
),
2344 reg_class_names
[aclass
], ira_class_hard_regs_num
[aclass
], n
);
2345 print_hard_reg_set (ira_dump_file
, data
->profitable_hard_regs
, false);
2346 fprintf (ira_dump_file
, ", %snode: ",
2347 hard_reg_set_equal_p (data
->profitable_hard_regs
,
2348 data
->hard_regs_node
->hard_regs
->set
)
2350 print_hard_reg_set (ira_dump_file
,
2351 data
->hard_regs_node
->hard_regs
->set
, false);
2352 for (i
= 0; i
< nwords
; i
++)
2354 ira_object_t obj
= ALLOCNO_OBJECT (a
, i
);
2359 fprintf (ira_dump_file
, ", ");
2360 fprintf (ira_dump_file
, " obj %d", i
);
2362 fprintf (ira_dump_file
, " (confl regs = ");
2363 print_hard_reg_set (ira_dump_file
, OBJECT_TOTAL_CONFLICT_HARD_REGS (obj
),
2365 fprintf (ira_dump_file
, ")");
2367 fprintf (ira_dump_file
, "\n");
2370 /* Put ALLOCNO in a bucket corresponding to its number and size of its
2371 conflicting allocnos and hard registers. */
2373 put_allocno_into_bucket (ira_allocno_t allocno
)
2375 ALLOCNO_COLOR_DATA (allocno
)->in_graph_p
= true;
2376 setup_allocno_available_regs_num (allocno
);
2377 if (setup_left_conflict_sizes_p (allocno
))
2378 add_allocno_to_bucket (allocno
, &colorable_allocno_bucket
);
2380 add_allocno_to_bucket (allocno
, &uncolorable_allocno_bucket
);
2383 /* Map: allocno number -> allocno priority. */
2384 static int *allocno_priorities
;
2386 /* Set up priorities for N allocnos in array
2387 CONSIDERATION_ALLOCNOS. */
2389 setup_allocno_priorities (ira_allocno_t
*consideration_allocnos
, int n
)
2391 int i
, length
, nrefs
, priority
, max_priority
, mult
;
2395 for (i
= 0; i
< n
; i
++)
2397 a
= consideration_allocnos
[i
];
2398 nrefs
= ALLOCNO_NREFS (a
);
2399 ira_assert (nrefs
>= 0);
2400 mult
= floor_log2 (ALLOCNO_NREFS (a
)) + 1;
2401 ira_assert (mult
>= 0);
2402 allocno_priorities
[ALLOCNO_NUM (a
)]
2405 * (ALLOCNO_MEMORY_COST (a
) - ALLOCNO_CLASS_COST (a
))
2406 * ira_reg_class_max_nregs
[ALLOCNO_CLASS (a
)][ALLOCNO_MODE (a
)]);
2408 priority
= -priority
;
2409 if (max_priority
< priority
)
2410 max_priority
= priority
;
2412 mult
= max_priority
== 0 ? 1 : INT_MAX
/ max_priority
;
2413 for (i
= 0; i
< n
; i
++)
2415 a
= consideration_allocnos
[i
];
2416 length
= ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a
);
2417 if (ALLOCNO_NUM_OBJECTS (a
) > 1)
2418 length
/= ALLOCNO_NUM_OBJECTS (a
);
2421 allocno_priorities
[ALLOCNO_NUM (a
)]
2422 = allocno_priorities
[ALLOCNO_NUM (a
)] * mult
/ length
;
2426 /* Sort allocnos according to the profit of usage of a hard register
2427 instead of memory for them. */
2429 allocno_cost_compare_func (const void *v1p
, const void *v2p
)
2431 ira_allocno_t p1
= *(const ira_allocno_t
*) v1p
;
2432 ira_allocno_t p2
= *(const ira_allocno_t
*) v2p
;
2435 c1
= ALLOCNO_UPDATED_MEMORY_COST (p1
) - ALLOCNO_UPDATED_CLASS_COST (p1
);
2436 c2
= ALLOCNO_UPDATED_MEMORY_COST (p2
) - ALLOCNO_UPDATED_CLASS_COST (p2
);
2440 /* If regs are equally good, sort by allocno numbers, so that the
2441 results of qsort leave nothing to chance. */
2442 return ALLOCNO_NUM (p1
) - ALLOCNO_NUM (p2
);
2445 /* We used Chaitin-Briggs coloring to assign as many pseudos as
2446 possible to hard registers. Let us try to improve allocation with
2447 cost point of view. This function improves the allocation by
2448 spilling some allocnos and assigning the freed hard registers to
2449 other allocnos if it decreases the overall allocation cost. */
2451 improve_allocation (void)
2454 int j
, k
, n
, hregno
, conflict_hregno
, base_cost
, class_size
, word
, nwords
;
2455 int check
, spill_cost
, min_cost
, nregs
, conflict_nregs
, r
, best
;
2457 enum reg_class aclass
;
2458 enum machine_mode mode
;
2460 int costs
[FIRST_PSEUDO_REGISTER
];
2461 HARD_REG_SET conflicting_regs
[2], profitable_hard_regs
;
2465 /* Clear counts used to process conflicting allocnos only once for
2467 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap
, 0, i
, bi
)
2468 ALLOCNO_COLOR_DATA (ira_allocnos
[i
])->temp
= 0;
2470 /* Process each allocno and try to assign a hard register to it by
2471 spilling some its conflicting allocnos. */
2472 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap
, 0, i
, bi
)
2474 a
= ira_allocnos
[i
];
2475 ALLOCNO_COLOR_DATA (a
)->temp
= 0;
2476 if (empty_profitable_hard_regs (a
))
2479 aclass
= ALLOCNO_CLASS (a
);
2480 allocno_costs
= ALLOCNO_UPDATED_HARD_REG_COSTS (a
);
2481 if (allocno_costs
== NULL
)
2482 allocno_costs
= ALLOCNO_HARD_REG_COSTS (a
);
2483 if ((hregno
= ALLOCNO_HARD_REGNO (a
)) < 0)
2484 base_cost
= ALLOCNO_UPDATED_MEMORY_COST (a
);
2485 else if (allocno_costs
== NULL
)
2486 /* It means that assigning a hard register is not profitable
2487 (we don't waste memory for hard register costs in this
2491 base_cost
= allocno_costs
[ira_class_hard_reg_index
[aclass
][hregno
]];
2493 get_conflict_and_start_profitable_regs (a
, false,
2495 &profitable_hard_regs
);
2496 class_size
= ira_class_hard_regs_num
[aclass
];
2497 /* Set up cost improvement for usage of each profitable hard
2498 register for allocno A. */
2499 for (j
= 0; j
< class_size
; j
++)
2501 hregno
= ira_class_hard_regs
[aclass
][j
];
2502 if (! check_hard_reg_p (a
, hregno
,
2503 conflicting_regs
, profitable_hard_regs
))
2505 ira_assert (ira_class_hard_reg_index
[aclass
][hregno
] == j
);
2506 k
= allocno_costs
== NULL
? 0 : j
;
2507 costs
[hregno
] = (allocno_costs
== NULL
2508 ? ALLOCNO_UPDATED_CLASS_COST (a
) : allocno_costs
[k
]);
2509 costs
[hregno
] -= base_cost
;
2510 if (costs
[hregno
] < 0)
2514 /* There is no chance to improve the allocation cost by
2515 assigning hard register to allocno A even without spilling
2516 conflicting allocnos. */
2518 mode
= ALLOCNO_MODE (a
);
2519 nwords
= ALLOCNO_NUM_OBJECTS (a
);
2520 /* Process each allocno conflicting with A and update the cost
2521 improvement for profitable hard registers of A. To use a
2522 hard register for A we need to spill some conflicting
2523 allocnos and that creates penalty for the cost
2525 for (word
= 0; word
< nwords
; word
++)
2527 ira_object_t conflict_obj
;
2528 ira_object_t obj
= ALLOCNO_OBJECT (a
, word
);
2529 ira_object_conflict_iterator oci
;
2531 FOR_EACH_OBJECT_CONFLICT (obj
, conflict_obj
, oci
)
2533 ira_allocno_t conflict_a
= OBJECT_ALLOCNO (conflict_obj
);
2535 if (ALLOCNO_COLOR_DATA (conflict_a
)->temp
== check
)
2536 /* We already processed this conflicting allocno
2537 because we processed earlier another object of the
2538 conflicting allocno. */
2540 ALLOCNO_COLOR_DATA (conflict_a
)->temp
= check
;
2541 if ((conflict_hregno
= ALLOCNO_HARD_REGNO (conflict_a
)) < 0)
2543 spill_cost
= ALLOCNO_UPDATED_MEMORY_COST (conflict_a
);
2544 k
= (ira_class_hard_reg_index
2545 [ALLOCNO_CLASS (conflict_a
)][conflict_hregno
]);
2546 ira_assert (k
>= 0);
2547 if ((allocno_costs
= ALLOCNO_UPDATED_HARD_REG_COSTS (conflict_a
))
2549 spill_cost
-= allocno_costs
[k
];
2550 else if ((allocno_costs
= ALLOCNO_HARD_REG_COSTS (conflict_a
))
2552 spill_cost
-= allocno_costs
[k
];
2554 spill_cost
-= ALLOCNO_UPDATED_CLASS_COST (conflict_a
);
2556 = hard_regno_nregs
[conflict_hregno
][ALLOCNO_MODE (conflict_a
)];
2557 for (r
= conflict_hregno
;
2558 r
>= 0 && r
+ hard_regno_nregs
[r
][mode
] > conflict_hregno
;
2560 if (check_hard_reg_p (a
, r
,
2561 conflicting_regs
, profitable_hard_regs
))
2562 costs
[r
] += spill_cost
;
2563 for (r
= conflict_hregno
+ 1;
2564 r
< conflict_hregno
+ conflict_nregs
;
2566 if (check_hard_reg_p (a
, r
,
2567 conflicting_regs
, profitable_hard_regs
))
2568 costs
[r
] += spill_cost
;
2573 /* Now we choose hard register for A which results in highest
2574 allocation cost improvement. */
2575 for (j
= 0; j
< class_size
; j
++)
2577 hregno
= ira_class_hard_regs
[aclass
][j
];
2578 if (check_hard_reg_p (a
, hregno
,
2579 conflicting_regs
, profitable_hard_regs
)
2580 && min_cost
> costs
[hregno
])
2583 min_cost
= costs
[hregno
];
2587 /* We are in a situation when assigning any hard register to A
2588 by spilling some conflicting allocnos does not improve the
2591 nregs
= hard_regno_nregs
[best
][mode
];
2592 /* Now spill conflicting allocnos which contain a hard register
2593 of A when we assign the best chosen hard register to it. */
2594 for (word
= 0; word
< nwords
; word
++)
2596 ira_object_t conflict_obj
;
2597 ira_object_t obj
= ALLOCNO_OBJECT (a
, word
);
2598 ira_object_conflict_iterator oci
;
2600 FOR_EACH_OBJECT_CONFLICT (obj
, conflict_obj
, oci
)
2602 ira_allocno_t conflict_a
= OBJECT_ALLOCNO (conflict_obj
);
2604 if ((conflict_hregno
= ALLOCNO_HARD_REGNO (conflict_a
)) < 0)
2607 = hard_regno_nregs
[conflict_hregno
][ALLOCNO_MODE (conflict_a
)];
2608 if (best
+ nregs
<= conflict_hregno
2609 || conflict_hregno
+ conflict_nregs
<= best
)
2610 /* No intersection. */
2612 ALLOCNO_HARD_REGNO (conflict_a
) = -1;
2613 sorted_allocnos
[n
++] = conflict_a
;
2614 if (internal_flag_ira_verbose
> 2 && ira_dump_file
!= NULL
)
2615 fprintf (ira_dump_file
, "Spilling a%dr%d for a%dr%d\n",
2616 ALLOCNO_NUM (conflict_a
), ALLOCNO_REGNO (conflict_a
),
2617 ALLOCNO_NUM (a
), ALLOCNO_REGNO (a
));
2620 /* Assign the best chosen hard register to A. */
2621 ALLOCNO_HARD_REGNO (a
) = best
;
2622 if (internal_flag_ira_verbose
> 2 && ira_dump_file
!= NULL
)
2623 fprintf (ira_dump_file
, "Assigning %d to a%dr%d\n",
2624 best
, ALLOCNO_NUM (a
), ALLOCNO_REGNO (a
));
2628 /* We spilled some allocnos to assign their hard registers to other
2629 allocnos. The spilled allocnos are now in array
2630 'sorted_allocnos'. There is still a possibility that some of the
2631 spilled allocnos can get hard registers. So let us try assign
2632 them hard registers again (just a reminder -- function
2633 'assign_hard_reg' assigns hard registers only if it is possible
2634 and profitable). We process the spilled allocnos with biggest
2635 benefit to get hard register first -- see function
2636 'allocno_cost_compare_func'. */
2637 qsort (sorted_allocnos
, n
, sizeof (ira_allocno_t
),
2638 allocno_cost_compare_func
);
2639 for (j
= 0; j
< n
; j
++)
2641 a
= sorted_allocnos
[j
];
2642 ALLOCNO_ASSIGNED_P (a
) = false;
2643 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
2645 fprintf (ira_dump_file
, " ");
2646 ira_print_expanded_allocno (a
);
2647 fprintf (ira_dump_file
, " -- ");
2649 if (assign_hard_reg (a
, false))
2651 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
2652 fprintf (ira_dump_file
, "assign hard reg %d\n",
2653 ALLOCNO_HARD_REGNO (a
));
2657 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
2658 fprintf (ira_dump_file
, "assign memory\n");
2663 /* Sort allocnos according to their priorities. */
2665 allocno_priority_compare_func (const void *v1p
, const void *v2p
)
2667 ira_allocno_t a1
= *(const ira_allocno_t
*) v1p
;
2668 ira_allocno_t a2
= *(const ira_allocno_t
*) v2p
;
2671 pri1
= allocno_priorities
[ALLOCNO_NUM (a1
)];
2672 pri2
= allocno_priorities
[ALLOCNO_NUM (a2
)];
2674 return SORTGT (pri2
, pri1
);
2676 /* If regs are equally good, sort by allocnos, so that the results of
2677 qsort leave nothing to chance. */
2678 return ALLOCNO_NUM (a1
) - ALLOCNO_NUM (a2
);
2681 /* Chaitin-Briggs coloring for allocnos in COLORING_ALLOCNO_BITMAP
2682 taking into account allocnos in CONSIDERATION_ALLOCNO_BITMAP. */
2684 color_allocnos (void)
2690 setup_profitable_hard_regs ();
2691 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap
, 0, i
, bi
)
2694 HARD_REG_SET conflict_hard_regs
;
2695 allocno_color_data_t data
;
2696 ira_pref_t pref
, next_pref
;
2698 a
= ira_allocnos
[i
];
2699 nr
= ALLOCNO_NUM_OBJECTS (a
);
2700 CLEAR_HARD_REG_SET (conflict_hard_regs
);
2701 for (l
= 0; l
< nr
; l
++)
2703 ira_object_t obj
= ALLOCNO_OBJECT (a
, l
);
2704 IOR_HARD_REG_SET (conflict_hard_regs
,
2705 OBJECT_CONFLICT_HARD_REGS (obj
));
2707 data
= ALLOCNO_COLOR_DATA (a
);
2708 for (pref
= ALLOCNO_PREFS (a
); pref
!= NULL
; pref
= next_pref
)
2710 next_pref
= pref
->next_pref
;
2711 if (! ira_hard_reg_in_set_p (pref
->hard_regno
,
2713 data
->profitable_hard_regs
))
2714 ira_remove_pref (pref
);
2717 if (flag_ira_algorithm
== IRA_ALGORITHM_PRIORITY
)
2720 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap
, 0, i
, bi
)
2722 a
= ira_allocnos
[i
];
2723 if (ALLOCNO_CLASS (a
) == NO_REGS
)
2725 ALLOCNO_HARD_REGNO (a
) = -1;
2726 ALLOCNO_ASSIGNED_P (a
) = true;
2727 ira_assert (ALLOCNO_UPDATED_HARD_REG_COSTS (a
) == NULL
);
2728 ira_assert (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a
) == NULL
);
2729 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
2731 fprintf (ira_dump_file
, " Spill");
2732 ira_print_expanded_allocno (a
);
2733 fprintf (ira_dump_file
, "\n");
2737 sorted_allocnos
[n
++] = a
;
2741 setup_allocno_priorities (sorted_allocnos
, n
);
2742 qsort (sorted_allocnos
, n
, sizeof (ira_allocno_t
),
2743 allocno_priority_compare_func
);
2744 for (i
= 0; i
< n
; i
++)
2746 a
= sorted_allocnos
[i
];
2747 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
2749 fprintf (ira_dump_file
, " ");
2750 ira_print_expanded_allocno (a
);
2751 fprintf (ira_dump_file
, " -- ");
2753 if (assign_hard_reg (a
, false))
2755 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
2756 fprintf (ira_dump_file
, "assign hard reg %d\n",
2757 ALLOCNO_HARD_REGNO (a
));
2761 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
2762 fprintf (ira_dump_file
, "assign memory\n");
2769 form_allocno_hard_regs_nodes_forest ();
2770 if (internal_flag_ira_verbose
> 2 && ira_dump_file
!= NULL
)
2771 print_hard_regs_forest (ira_dump_file
);
2772 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap
, 0, i
, bi
)
2774 a
= ira_allocnos
[i
];
2775 if (ALLOCNO_CLASS (a
) != NO_REGS
&& ! empty_profitable_hard_regs (a
))
2777 ALLOCNO_COLOR_DATA (a
)->in_graph_p
= true;
2778 update_costs_from_prefs (a
);
2782 ALLOCNO_HARD_REGNO (a
) = -1;
2783 ALLOCNO_ASSIGNED_P (a
) = true;
2784 /* We don't need updated costs anymore. */
2785 ira_free_allocno_updated_costs (a
);
2786 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
2788 fprintf (ira_dump_file
, " Spill");
2789 ira_print_expanded_allocno (a
);
2790 fprintf (ira_dump_file
, "\n");
2794 /* Put the allocnos into the corresponding buckets. */
2795 colorable_allocno_bucket
= NULL
;
2796 uncolorable_allocno_bucket
= NULL
;
2797 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap
, 0, i
, bi
)
2799 a
= ira_allocnos
[i
];
2800 if (ALLOCNO_COLOR_DATA (a
)->in_graph_p
)
2801 put_allocno_into_bucket (a
);
2803 push_allocnos_to_stack ();
2804 pop_allocnos_from_stack ();
2805 finish_allocno_hard_regs_nodes_forest ();
2807 improve_allocation ();
2812 /* Output information about the loop given by its LOOP_TREE_NODE. */
2814 print_loop_title (ira_loop_tree_node_t loop_tree_node
)
2818 ira_loop_tree_node_t subloop_node
, dest_loop_node
;
2822 if (loop_tree_node
->parent
== NULL
)
2823 fprintf (ira_dump_file
,
2824 "\n Loop 0 (parent -1, header bb%d, depth 0)\n bbs:",
2828 ira_assert (current_loops
!= NULL
&& loop_tree_node
->loop
!= NULL
);
2829 fprintf (ira_dump_file
,
2830 "\n Loop %d (parent %d, header bb%d, depth %d)\n bbs:",
2831 loop_tree_node
->loop_num
, loop_tree_node
->parent
->loop_num
,
2832 loop_tree_node
->loop
->header
->index
,
2833 loop_depth (loop_tree_node
->loop
));
2835 for (subloop_node
= loop_tree_node
->children
;
2836 subloop_node
!= NULL
;
2837 subloop_node
= subloop_node
->next
)
2838 if (subloop_node
->bb
!= NULL
)
2840 fprintf (ira_dump_file
, " %d", subloop_node
->bb
->index
);
2841 FOR_EACH_EDGE (e
, ei
, subloop_node
->bb
->succs
)
2842 if (e
->dest
!= EXIT_BLOCK_PTR
2843 && ((dest_loop_node
= IRA_BB_NODE (e
->dest
)->parent
)
2845 fprintf (ira_dump_file
, "(->%d:l%d)",
2846 e
->dest
->index
, dest_loop_node
->loop_num
);
2848 fprintf (ira_dump_file
, "\n all:");
2849 EXECUTE_IF_SET_IN_BITMAP (loop_tree_node
->all_allocnos
, 0, j
, bi
)
2850 fprintf (ira_dump_file
, " %dr%d", j
, ALLOCNO_REGNO (ira_allocnos
[j
]));
2851 fprintf (ira_dump_file
, "\n modified regnos:");
2852 EXECUTE_IF_SET_IN_BITMAP (loop_tree_node
->modified_regnos
, 0, j
, bi
)
2853 fprintf (ira_dump_file
, " %d", j
);
2854 fprintf (ira_dump_file
, "\n border:");
2855 EXECUTE_IF_SET_IN_BITMAP (loop_tree_node
->border_allocnos
, 0, j
, bi
)
2856 fprintf (ira_dump_file
, " %dr%d", j
, ALLOCNO_REGNO (ira_allocnos
[j
]));
2857 fprintf (ira_dump_file
, "\n Pressure:");
2858 for (j
= 0; (int) j
< ira_pressure_classes_num
; j
++)
2860 enum reg_class pclass
;
2862 pclass
= ira_pressure_classes
[j
];
2863 if (loop_tree_node
->reg_pressure
[pclass
] == 0)
2865 fprintf (ira_dump_file
, " %s=%d", reg_class_names
[pclass
],
2866 loop_tree_node
->reg_pressure
[pclass
]);
2868 fprintf (ira_dump_file
, "\n");
2871 /* Color the allocnos inside loop (in the extreme case it can be all
2872 of the function) given the corresponding LOOP_TREE_NODE. The
2873 function is called for each loop during top-down traverse of the
2876 color_pass (ira_loop_tree_node_t loop_tree_node
)
2878 int regno
, hard_regno
, index
= -1, n
;
2879 int cost
, exit_freq
, enter_freq
;
2882 enum machine_mode mode
;
2883 enum reg_class rclass
, aclass
, pclass
;
2884 ira_allocno_t a
, subloop_allocno
;
2885 ira_loop_tree_node_t subloop_node
;
2887 ira_assert (loop_tree_node
->bb
== NULL
);
2888 if (internal_flag_ira_verbose
> 1 && ira_dump_file
!= NULL
)
2889 print_loop_title (loop_tree_node
);
2891 bitmap_copy (coloring_allocno_bitmap
, loop_tree_node
->all_allocnos
);
2892 bitmap_copy (consideration_allocno_bitmap
, coloring_allocno_bitmap
);
2894 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap
, 0, j
, bi
)
2896 a
= ira_allocnos
[j
];
2898 if (! ALLOCNO_ASSIGNED_P (a
))
2900 bitmap_clear_bit (coloring_allocno_bitmap
, ALLOCNO_NUM (a
));
2903 = (allocno_color_data_t
) ira_allocate (sizeof (struct allocno_color_data
)
2905 memset (allocno_color_data
, 0, sizeof (struct allocno_color_data
) * n
);
2906 curr_allocno_process
= 0;
2908 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap
, 0, j
, bi
)
2910 a
= ira_allocnos
[j
];
2911 ALLOCNO_ADD_DATA (a
) = allocno_color_data
+ n
;
2914 /* Color all mentioned allocnos including transparent ones. */
2916 /* Process caps. They are processed just once. */
2917 if (flag_ira_region
== IRA_REGION_MIXED
2918 || flag_ira_region
== IRA_REGION_ALL
)
2919 EXECUTE_IF_SET_IN_BITMAP (loop_tree_node
->all_allocnos
, 0, j
, bi
)
2921 a
= ira_allocnos
[j
];
2922 if (ALLOCNO_CAP_MEMBER (a
) == NULL
)
2924 /* Remove from processing in the next loop. */
2925 bitmap_clear_bit (consideration_allocno_bitmap
, j
);
2926 rclass
= ALLOCNO_CLASS (a
);
2927 pclass
= ira_pressure_class_translate
[rclass
];
2928 if (flag_ira_region
== IRA_REGION_MIXED
2929 && (loop_tree_node
->reg_pressure
[pclass
]
2930 <= ira_class_hard_regs_num
[pclass
]))
2932 mode
= ALLOCNO_MODE (a
);
2933 hard_regno
= ALLOCNO_HARD_REGNO (a
);
2934 if (hard_regno
>= 0)
2936 index
= ira_class_hard_reg_index
[rclass
][hard_regno
];
2937 ira_assert (index
>= 0);
2939 regno
= ALLOCNO_REGNO (a
);
2940 subloop_allocno
= ALLOCNO_CAP_MEMBER (a
);
2941 subloop_node
= ALLOCNO_LOOP_TREE_NODE (subloop_allocno
);
2942 ira_assert (!ALLOCNO_ASSIGNED_P (subloop_allocno
));
2943 ALLOCNO_HARD_REGNO (subloop_allocno
) = hard_regno
;
2944 ALLOCNO_ASSIGNED_P (subloop_allocno
) = true;
2945 if (hard_regno
>= 0)
2946 update_costs_from_copies (subloop_allocno
, true, true);
2947 /* We don't need updated costs anymore: */
2948 ira_free_allocno_updated_costs (subloop_allocno
);
2951 /* Update costs of the corresponding allocnos (not caps) in the
2953 for (subloop_node
= loop_tree_node
->subloops
;
2954 subloop_node
!= NULL
;
2955 subloop_node
= subloop_node
->subloop_next
)
2957 ira_assert (subloop_node
->bb
== NULL
);
2958 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap
, 0, j
, bi
)
2960 a
= ira_allocnos
[j
];
2961 ira_assert (ALLOCNO_CAP_MEMBER (a
) == NULL
);
2962 mode
= ALLOCNO_MODE (a
);
2963 rclass
= ALLOCNO_CLASS (a
);
2964 pclass
= ira_pressure_class_translate
[rclass
];
2965 hard_regno
= ALLOCNO_HARD_REGNO (a
);
2966 /* Use hard register class here. ??? */
2967 if (hard_regno
>= 0)
2969 index
= ira_class_hard_reg_index
[rclass
][hard_regno
];
2970 ira_assert (index
>= 0);
2972 regno
= ALLOCNO_REGNO (a
);
2973 /* ??? conflict costs */
2974 subloop_allocno
= subloop_node
->regno_allocno_map
[regno
];
2975 if (subloop_allocno
== NULL
2976 || ALLOCNO_CAP (subloop_allocno
) != NULL
)
2978 ira_assert (ALLOCNO_CLASS (subloop_allocno
) == rclass
);
2979 ira_assert (bitmap_bit_p (subloop_node
->all_allocnos
,
2980 ALLOCNO_NUM (subloop_allocno
)));
2981 if ((flag_ira_region
== IRA_REGION_MIXED
)
2982 && (loop_tree_node
->reg_pressure
[pclass
]
2983 <= ira_class_hard_regs_num
[pclass
]))
2985 if (! ALLOCNO_ASSIGNED_P (subloop_allocno
))
2987 ALLOCNO_HARD_REGNO (subloop_allocno
) = hard_regno
;
2988 ALLOCNO_ASSIGNED_P (subloop_allocno
) = true;
2989 if (hard_regno
>= 0)
2990 update_costs_from_copies (subloop_allocno
, true, true);
2991 /* We don't need updated costs anymore: */
2992 ira_free_allocno_updated_costs (subloop_allocno
);
2996 exit_freq
= ira_loop_edge_freq (subloop_node
, regno
, true);
2997 enter_freq
= ira_loop_edge_freq (subloop_node
, regno
, false);
2998 ira_assert (regno
< ira_reg_equiv_len
);
2999 if (ira_equiv_no_lvalue_p (regno
))
3001 if (! ALLOCNO_ASSIGNED_P (subloop_allocno
))
3003 ALLOCNO_HARD_REGNO (subloop_allocno
) = hard_regno
;
3004 ALLOCNO_ASSIGNED_P (subloop_allocno
) = true;
3005 if (hard_regno
>= 0)
3006 update_costs_from_copies (subloop_allocno
, true, true);
3007 /* We don't need updated costs anymore: */
3008 ira_free_allocno_updated_costs (subloop_allocno
);
3011 else if (hard_regno
< 0)
3013 ALLOCNO_UPDATED_MEMORY_COST (subloop_allocno
)
3014 -= ((ira_memory_move_cost
[mode
][rclass
][1] * enter_freq
)
3015 + (ira_memory_move_cost
[mode
][rclass
][0] * exit_freq
));
3019 aclass
= ALLOCNO_CLASS (subloop_allocno
);
3020 ira_init_register_move_cost_if_necessary (mode
);
3021 cost
= (ira_register_move_cost
[mode
][rclass
][rclass
]
3022 * (exit_freq
+ enter_freq
));
3023 ira_allocate_and_set_or_copy_costs
3024 (&ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno
), aclass
,
3025 ALLOCNO_UPDATED_CLASS_COST (subloop_allocno
),
3026 ALLOCNO_HARD_REG_COSTS (subloop_allocno
));
3027 ira_allocate_and_set_or_copy_costs
3028 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (subloop_allocno
),
3029 aclass
, 0, ALLOCNO_CONFLICT_HARD_REG_COSTS (subloop_allocno
));
3030 ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno
)[index
] -= cost
;
3031 ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (subloop_allocno
)[index
]
3033 if (ALLOCNO_UPDATED_CLASS_COST (subloop_allocno
)
3034 > ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno
)[index
])
3035 ALLOCNO_UPDATED_CLASS_COST (subloop_allocno
)
3036 = ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno
)[index
];
3037 ALLOCNO_UPDATED_MEMORY_COST (subloop_allocno
)
3038 += (ira_memory_move_cost
[mode
][rclass
][0] * enter_freq
3039 + ira_memory_move_cost
[mode
][rclass
][1] * exit_freq
);
3043 ira_free (allocno_color_data
);
3044 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap
, 0, j
, bi
)
3046 a
= ira_allocnos
[j
];
3047 ALLOCNO_ADD_DATA (a
) = NULL
;
3051 /* Initialize the common data for coloring and calls functions to do
3052 Chaitin-Briggs and regional coloring. */
3056 coloring_allocno_bitmap
= ira_allocate_bitmap ();
3057 if (internal_flag_ira_verbose
> 0 && ira_dump_file
!= NULL
)
3058 fprintf (ira_dump_file
, "\n**** Allocnos coloring:\n\n");
3060 ira_traverse_loop_tree (false, ira_loop_tree_root
, color_pass
, NULL
);
3062 if (internal_flag_ira_verbose
> 1 && ira_dump_file
!= NULL
)
3063 ira_print_disposition (ira_dump_file
);
3065 ira_free_bitmap (coloring_allocno_bitmap
);
3070 /* Move spill/restore code, which are to be generated in ira-emit.c,
3071 to less frequent points (if it is profitable) by reassigning some
3072 allocnos (in loop with subloops containing in another loop) to
3073 memory which results in longer live-range where the corresponding
3074 pseudo-registers will be in memory. */
3076 move_spill_restore (void)
3078 int cost
, regno
, hard_regno
, hard_regno2
, index
;
3080 int enter_freq
, exit_freq
;
3081 enum machine_mode mode
;
3082 enum reg_class rclass
;
3083 ira_allocno_t a
, parent_allocno
, subloop_allocno
;
3084 ira_loop_tree_node_t parent
, loop_node
, subloop_node
;
3085 ira_allocno_iterator ai
;
3090 if (internal_flag_ira_verbose
> 0 && ira_dump_file
!= NULL
)
3091 fprintf (ira_dump_file
, "New iteration of spill/restore move\n");
3092 FOR_EACH_ALLOCNO (a
, ai
)
3094 regno
= ALLOCNO_REGNO (a
);
3095 loop_node
= ALLOCNO_LOOP_TREE_NODE (a
);
3096 if (ALLOCNO_CAP_MEMBER (a
) != NULL
3097 || ALLOCNO_CAP (a
) != NULL
3098 || (hard_regno
= ALLOCNO_HARD_REGNO (a
)) < 0
3099 || loop_node
->children
== NULL
3100 /* don't do the optimization because it can create
3101 copies and the reload pass can spill the allocno set
3102 by copy although the allocno will not get memory
3104 || ira_equiv_no_lvalue_p (regno
)
3105 || !bitmap_bit_p (loop_node
->border_allocnos
, ALLOCNO_NUM (a
)))
3107 mode
= ALLOCNO_MODE (a
);
3108 rclass
= ALLOCNO_CLASS (a
);
3109 index
= ira_class_hard_reg_index
[rclass
][hard_regno
];
3110 ira_assert (index
>= 0);
3111 cost
= (ALLOCNO_MEMORY_COST (a
)
3112 - (ALLOCNO_HARD_REG_COSTS (a
) == NULL
3113 ? ALLOCNO_CLASS_COST (a
)
3114 : ALLOCNO_HARD_REG_COSTS (a
)[index
]));
3115 ira_init_register_move_cost_if_necessary (mode
);
3116 for (subloop_node
= loop_node
->subloops
;
3117 subloop_node
!= NULL
;
3118 subloop_node
= subloop_node
->subloop_next
)
3120 ira_assert (subloop_node
->bb
== NULL
);
3121 subloop_allocno
= subloop_node
->regno_allocno_map
[regno
];
3122 if (subloop_allocno
== NULL
)
3124 ira_assert (rclass
== ALLOCNO_CLASS (subloop_allocno
));
3125 /* We have accumulated cost. To get the real cost of
3126 allocno usage in the loop we should subtract costs of
3127 the subloop allocnos. */
3128 cost
-= (ALLOCNO_MEMORY_COST (subloop_allocno
)
3129 - (ALLOCNO_HARD_REG_COSTS (subloop_allocno
) == NULL
3130 ? ALLOCNO_CLASS_COST (subloop_allocno
)
3131 : ALLOCNO_HARD_REG_COSTS (subloop_allocno
)[index
]));
3132 exit_freq
= ira_loop_edge_freq (subloop_node
, regno
, true);
3133 enter_freq
= ira_loop_edge_freq (subloop_node
, regno
, false);
3134 if ((hard_regno2
= ALLOCNO_HARD_REGNO (subloop_allocno
)) < 0)
3135 cost
-= (ira_memory_move_cost
[mode
][rclass
][0] * exit_freq
3136 + ira_memory_move_cost
[mode
][rclass
][1] * enter_freq
);
3140 += (ira_memory_move_cost
[mode
][rclass
][0] * exit_freq
3141 + ira_memory_move_cost
[mode
][rclass
][1] * enter_freq
);
3142 if (hard_regno2
!= hard_regno
)
3143 cost
-= (ira_register_move_cost
[mode
][rclass
][rclass
]
3144 * (exit_freq
+ enter_freq
));
3147 if ((parent
= loop_node
->parent
) != NULL
3148 && (parent_allocno
= parent
->regno_allocno_map
[regno
]) != NULL
)
3150 ira_assert (rclass
== ALLOCNO_CLASS (parent_allocno
));
3151 exit_freq
= ira_loop_edge_freq (loop_node
, regno
, true);
3152 enter_freq
= ira_loop_edge_freq (loop_node
, regno
, false);
3153 if ((hard_regno2
= ALLOCNO_HARD_REGNO (parent_allocno
)) < 0)
3154 cost
-= (ira_memory_move_cost
[mode
][rclass
][0] * exit_freq
3155 + ira_memory_move_cost
[mode
][rclass
][1] * enter_freq
);
3159 += (ira_memory_move_cost
[mode
][rclass
][1] * exit_freq
3160 + ira_memory_move_cost
[mode
][rclass
][0] * enter_freq
);
3161 if (hard_regno2
!= hard_regno
)
3162 cost
-= (ira_register_move_cost
[mode
][rclass
][rclass
]
3163 * (exit_freq
+ enter_freq
));
3168 ALLOCNO_HARD_REGNO (a
) = -1;
3169 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
3173 " Moving spill/restore for a%dr%d up from loop %d",
3174 ALLOCNO_NUM (a
), regno
, loop_node
->loop_num
);
3175 fprintf (ira_dump_file
, " - profit %d\n", -cost
);
3187 /* Update current hard reg costs and current conflict hard reg costs
3188 for allocno A. It is done by processing its copies containing
3189 other allocnos already assigned. */
3191 update_curr_costs (ira_allocno_t a
)
3193 int i
, hard_regno
, cost
;
3194 enum machine_mode mode
;
3195 enum reg_class aclass
, rclass
;
3196 ira_allocno_t another_a
;
3197 ira_copy_t cp
, next_cp
;
3199 ira_free_allocno_updated_costs (a
);
3200 ira_assert (! ALLOCNO_ASSIGNED_P (a
));
3201 aclass
= ALLOCNO_CLASS (a
);
3202 if (aclass
== NO_REGS
)
3204 mode
= ALLOCNO_MODE (a
);
3205 ira_init_register_move_cost_if_necessary (mode
);
3206 for (cp
= ALLOCNO_COPIES (a
); cp
!= NULL
; cp
= next_cp
)
3210 next_cp
= cp
->next_first_allocno_copy
;
3211 another_a
= cp
->second
;
3213 else if (cp
->second
== a
)
3215 next_cp
= cp
->next_second_allocno_copy
;
3216 another_a
= cp
->first
;
3220 if (! ira_reg_classes_intersect_p
[aclass
][ALLOCNO_CLASS (another_a
)]
3221 || ! ALLOCNO_ASSIGNED_P (another_a
)
3222 || (hard_regno
= ALLOCNO_HARD_REGNO (another_a
)) < 0)
3224 rclass
= REGNO_REG_CLASS (hard_regno
);
3225 i
= ira_class_hard_reg_index
[aclass
][hard_regno
];
3228 cost
= (cp
->first
== a
3229 ? ira_register_move_cost
[mode
][rclass
][aclass
]
3230 : ira_register_move_cost
[mode
][aclass
][rclass
]);
3231 ira_allocate_and_set_or_copy_costs
3232 (&ALLOCNO_UPDATED_HARD_REG_COSTS (a
), aclass
, ALLOCNO_CLASS_COST (a
),
3233 ALLOCNO_HARD_REG_COSTS (a
));
3234 ira_allocate_and_set_or_copy_costs
3235 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a
),
3236 aclass
, 0, ALLOCNO_CONFLICT_HARD_REG_COSTS (a
));
3237 ALLOCNO_UPDATED_HARD_REG_COSTS (a
)[i
] -= cp
->freq
* cost
;
3238 ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a
)[i
] -= cp
->freq
* cost
;
3242 /* Try to assign hard registers to the unassigned allocnos and
3243 allocnos conflicting with them or conflicting with allocnos whose
3244 regno >= START_REGNO. The function is called after ira_flattening,
3245 so more allocnos (including ones created in ira-emit.c) will have a
3246 chance to get a hard register. We use simple assignment algorithm
3247 based on priorities. */
3249 ira_reassign_conflict_allocnos (int start_regno
)
3251 int i
, allocnos_to_color_num
;
3253 enum reg_class aclass
;
3254 bitmap allocnos_to_color
;
3255 ira_allocno_iterator ai
;
3257 allocnos_to_color
= ira_allocate_bitmap ();
3258 allocnos_to_color_num
= 0;
3259 FOR_EACH_ALLOCNO (a
, ai
)
3261 int n
= ALLOCNO_NUM_OBJECTS (a
);
3263 if (! ALLOCNO_ASSIGNED_P (a
)
3264 && ! bitmap_bit_p (allocnos_to_color
, ALLOCNO_NUM (a
)))
3266 if (ALLOCNO_CLASS (a
) != NO_REGS
)
3267 sorted_allocnos
[allocnos_to_color_num
++] = a
;
3270 ALLOCNO_ASSIGNED_P (a
) = true;
3271 ALLOCNO_HARD_REGNO (a
) = -1;
3272 ira_assert (ALLOCNO_UPDATED_HARD_REG_COSTS (a
) == NULL
);
3273 ira_assert (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a
) == NULL
);
3275 bitmap_set_bit (allocnos_to_color
, ALLOCNO_NUM (a
));
3277 if (ALLOCNO_REGNO (a
) < start_regno
3278 || (aclass
= ALLOCNO_CLASS (a
)) == NO_REGS
)
3280 for (i
= 0; i
< n
; i
++)
3282 ira_object_t obj
= ALLOCNO_OBJECT (a
, i
);
3283 ira_object_t conflict_obj
;
3284 ira_object_conflict_iterator oci
;
3286 FOR_EACH_OBJECT_CONFLICT (obj
, conflict_obj
, oci
)
3288 ira_allocno_t conflict_a
= OBJECT_ALLOCNO (conflict_obj
);
3290 ira_assert (ira_reg_classes_intersect_p
3291 [aclass
][ALLOCNO_CLASS (conflict_a
)]);
3292 if (!bitmap_set_bit (allocnos_to_color
, ALLOCNO_NUM (conflict_a
)))
3294 sorted_allocnos
[allocnos_to_color_num
++] = conflict_a
;
3298 ira_free_bitmap (allocnos_to_color
);
3299 if (allocnos_to_color_num
> 1)
3301 setup_allocno_priorities (sorted_allocnos
, allocnos_to_color_num
);
3302 qsort (sorted_allocnos
, allocnos_to_color_num
, sizeof (ira_allocno_t
),
3303 allocno_priority_compare_func
);
3305 for (i
= 0; i
< allocnos_to_color_num
; i
++)
3307 a
= sorted_allocnos
[i
];
3308 ALLOCNO_ASSIGNED_P (a
) = false;
3309 update_curr_costs (a
);
3311 for (i
= 0; i
< allocnos_to_color_num
; i
++)
3313 a
= sorted_allocnos
[i
];
3314 if (assign_hard_reg (a
, true))
3316 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
3319 " Secondary allocation: assign hard reg %d to reg %d\n",
3320 ALLOCNO_HARD_REGNO (a
), ALLOCNO_REGNO (a
));
3327 /* This page contains functions used to find conflicts using allocno
3330 /* Return TRUE if live ranges of allocnos A1 and A2 intersect. It is
3331 used to find a conflict for new allocnos or allocnos with the
3332 different allocno classes. */
3334 allocnos_conflict_by_live_ranges_p (ira_allocno_t a1
, ira_allocno_t a2
)
3338 int n1
= ALLOCNO_NUM_OBJECTS (a1
);
3339 int n2
= ALLOCNO_NUM_OBJECTS (a2
);
3343 reg1
= regno_reg_rtx
[ALLOCNO_REGNO (a1
)];
3344 reg2
= regno_reg_rtx
[ALLOCNO_REGNO (a2
)];
3345 if (reg1
!= NULL
&& reg2
!= NULL
3346 && ORIGINAL_REGNO (reg1
) == ORIGINAL_REGNO (reg2
))
3349 for (i
= 0; i
< n1
; i
++)
3351 ira_object_t c1
= ALLOCNO_OBJECT (a1
, i
);
3353 for (j
= 0; j
< n2
; j
++)
3355 ira_object_t c2
= ALLOCNO_OBJECT (a2
, j
);
3357 if (ira_live_ranges_intersect_p (OBJECT_LIVE_RANGES (c1
),
3358 OBJECT_LIVE_RANGES (c2
)))
3365 #ifdef ENABLE_IRA_CHECKING
3367 /* Return TRUE if live ranges of pseudo-registers REGNO1 and REGNO2
3368 intersect. This should be used when there is only one region.
3369 Currently this is used during reload. */
3371 conflict_by_live_ranges_p (int regno1
, int regno2
)
3373 ira_allocno_t a1
, a2
;
3375 ira_assert (regno1
>= FIRST_PSEUDO_REGISTER
3376 && regno2
>= FIRST_PSEUDO_REGISTER
);
3377 /* Reg info caclulated by dataflow infrastructure can be different
3378 from one calculated by regclass. */
3379 if ((a1
= ira_loop_tree_root
->regno_allocno_map
[regno1
]) == NULL
3380 || (a2
= ira_loop_tree_root
->regno_allocno_map
[regno2
]) == NULL
)
3382 return allocnos_conflict_by_live_ranges_p (a1
, a2
);
3389 /* This page contains code to coalesce memory stack slots used by
3390 spilled allocnos. This results in smaller stack frame, better data
3391 locality, and in smaller code for some architectures like
3392 x86/x86_64 where insn size depends on address displacement value.
3393 On the other hand, it can worsen insn scheduling after the RA but
3394 in practice it is less important than smaller stack frames. */
3396 /* TRUE if we coalesced some allocnos. In other words, if we got
3397 loops formed by members first_coalesced_allocno and
3398 next_coalesced_allocno containing more one allocno. */
3399 static bool allocno_coalesced_p
;
3401 /* Bitmap used to prevent a repeated allocno processing because of
3403 static bitmap processed_coalesced_allocno_bitmap
;
3406 typedef struct coalesce_data
*coalesce_data_t
;
3408 /* To decrease footprint of ira_allocno structure we store all data
3409 needed only for coalescing in the following structure. */
3410 struct coalesce_data
3412 /* Coalesced allocnos form a cyclic list. One allocno given by
3413 FIRST represents all coalesced allocnos. The
3414 list is chained by NEXT. */
3415 ira_allocno_t first
;
3420 /* Container for storing allocno data concerning coalescing. */
3421 static coalesce_data_t allocno_coalesce_data
;
3423 /* Macro to access the data concerning coalescing. */
3424 #define ALLOCNO_COALESCE_DATA(a) ((coalesce_data_t) ALLOCNO_ADD_DATA (a))
3426 /* The function is used to sort allocnos according to their execution
3429 copy_freq_compare_func (const void *v1p
, const void *v2p
)
3431 ira_copy_t cp1
= *(const ira_copy_t
*) v1p
, cp2
= *(const ira_copy_t
*) v2p
;
3439 /* If freqencies are equal, sort by copies, so that the results of
3440 qsort leave nothing to chance. */
3441 return cp1
->num
- cp2
->num
;
3444 /* Merge two sets of coalesced allocnos given correspondingly by
3445 allocnos A1 and A2 (more accurately merging A2 set into A1
3448 merge_allocnos (ira_allocno_t a1
, ira_allocno_t a2
)
3450 ira_allocno_t a
, first
, last
, next
;
3452 first
= ALLOCNO_COALESCE_DATA (a1
)->first
;
3453 a
= ALLOCNO_COALESCE_DATA (a2
)->first
;
3456 for (last
= a2
, a
= ALLOCNO_COALESCE_DATA (a2
)->next
;;
3457 a
= ALLOCNO_COALESCE_DATA (a
)->next
)
3459 ALLOCNO_COALESCE_DATA (a
)->first
= first
;
3464 next
= allocno_coalesce_data
[ALLOCNO_NUM (first
)].next
;
3465 allocno_coalesce_data
[ALLOCNO_NUM (first
)].next
= a2
;
3466 allocno_coalesce_data
[ALLOCNO_NUM (last
)].next
= next
;
3469 /* Return TRUE if there are conflicting allocnos from two sets of
3470 coalesced allocnos given correspondingly by allocnos A1 and A2. We
3471 use live ranges to find conflicts because conflicts are represented
3472 only for allocnos of the same allocno class and during the reload
3473 pass we coalesce allocnos for sharing stack memory slots. */
3475 coalesced_allocno_conflict_p (ira_allocno_t a1
, ira_allocno_t a2
)
3477 ira_allocno_t a
, conflict_a
;
3479 if (allocno_coalesced_p
)
3481 bitmap_clear (processed_coalesced_allocno_bitmap
);
3482 for (a
= ALLOCNO_COALESCE_DATA (a1
)->next
;;
3483 a
= ALLOCNO_COALESCE_DATA (a
)->next
)
3485 bitmap_set_bit (processed_coalesced_allocno_bitmap
, ALLOCNO_NUM (a
));
3490 for (a
= ALLOCNO_COALESCE_DATA (a2
)->next
;;
3491 a
= ALLOCNO_COALESCE_DATA (a
)->next
)
3493 for (conflict_a
= ALLOCNO_COALESCE_DATA (a1
)->next
;;
3494 conflict_a
= ALLOCNO_COALESCE_DATA (conflict_a
)->next
)
3496 if (allocnos_conflict_by_live_ranges_p (a
, conflict_a
))
3498 if (conflict_a
== a1
)
3507 /* The major function for aggressive allocno coalescing. We coalesce
3508 only spilled allocnos. If some allocnos have been coalesced, we
3509 set up flag allocno_coalesced_p. */
3511 coalesce_allocnos (void)
3514 ira_copy_t cp
, next_cp
, *sorted_copies
;
3516 int i
, n
, cp_num
, regno
;
3519 sorted_copies
= (ira_copy_t
*) ira_allocate (ira_copies_num
3520 * sizeof (ira_copy_t
));
3522 /* Collect copies. */
3523 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap
, 0, j
, bi
)
3525 a
= ira_allocnos
[j
];
3526 regno
= ALLOCNO_REGNO (a
);
3527 if (! ALLOCNO_ASSIGNED_P (a
) || ALLOCNO_HARD_REGNO (a
) >= 0
3528 || ira_equiv_no_lvalue_p (regno
))
3530 for (cp
= ALLOCNO_COPIES (a
); cp
!= NULL
; cp
= next_cp
)
3534 next_cp
= cp
->next_first_allocno_copy
;
3535 regno
= ALLOCNO_REGNO (cp
->second
);
3536 /* For priority coloring we coalesce allocnos only with
3537 the same allocno class not with intersected allocno
3538 classes as it were possible. It is done for
3540 if ((cp
->insn
!= NULL
|| cp
->constraint_p
)
3541 && ALLOCNO_ASSIGNED_P (cp
->second
)
3542 && ALLOCNO_HARD_REGNO (cp
->second
) < 0
3543 && ! ira_equiv_no_lvalue_p (regno
))
3544 sorted_copies
[cp_num
++] = cp
;
3546 else if (cp
->second
== a
)
3547 next_cp
= cp
->next_second_allocno_copy
;
3552 qsort (sorted_copies
, cp_num
, sizeof (ira_copy_t
), copy_freq_compare_func
);
3553 /* Coalesced copies, most frequently executed first. */
3554 for (; cp_num
!= 0;)
3556 for (i
= 0; i
< cp_num
; i
++)
3558 cp
= sorted_copies
[i
];
3559 if (! coalesced_allocno_conflict_p (cp
->first
, cp
->second
))
3561 allocno_coalesced_p
= true;
3562 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
3565 " Coalescing copy %d:a%dr%d-a%dr%d (freq=%d)\n",
3566 cp
->num
, ALLOCNO_NUM (cp
->first
), ALLOCNO_REGNO (cp
->first
),
3567 ALLOCNO_NUM (cp
->second
), ALLOCNO_REGNO (cp
->second
),
3569 merge_allocnos (cp
->first
, cp
->second
);
3574 /* Collect the rest of copies. */
3575 for (n
= 0; i
< cp_num
; i
++)
3577 cp
= sorted_copies
[i
];
3578 if (allocno_coalesce_data
[ALLOCNO_NUM (cp
->first
)].first
3579 != allocno_coalesce_data
[ALLOCNO_NUM (cp
->second
)].first
)
3580 sorted_copies
[n
++] = cp
;
3584 ira_free (sorted_copies
);
3587 /* Usage cost and order number of coalesced allocno set to which
3588 given pseudo register belongs to. */
3589 static int *regno_coalesced_allocno_cost
;
3590 static int *regno_coalesced_allocno_num
;
3592 /* Sort pseudos according frequencies of coalesced allocno sets they
3593 belong to (putting most frequently ones first), and according to
3594 coalesced allocno set order numbers. */
3596 coalesced_pseudo_reg_freq_compare (const void *v1p
, const void *v2p
)
3598 const int regno1
= *(const int *) v1p
;
3599 const int regno2
= *(const int *) v2p
;
3602 if ((diff
= (regno_coalesced_allocno_cost
[regno2
]
3603 - regno_coalesced_allocno_cost
[regno1
])) != 0)
3605 if ((diff
= (regno_coalesced_allocno_num
[regno1
]
3606 - regno_coalesced_allocno_num
[regno2
])) != 0)
3608 return regno1
- regno2
;
3611 /* Widest width in which each pseudo reg is referred to (via subreg).
3612 It is used for sorting pseudo registers. */
3613 static unsigned int *regno_max_ref_width
;
3615 /* Redefine STACK_GROWS_DOWNWARD in terms of 0 or 1. */
3616 #ifdef STACK_GROWS_DOWNWARD
3617 # undef STACK_GROWS_DOWNWARD
3618 # define STACK_GROWS_DOWNWARD 1
3620 # define STACK_GROWS_DOWNWARD 0
3623 /* Sort pseudos according their slot numbers (putting ones with
3624 smaller numbers first, or last when the frame pointer is not
3627 coalesced_pseudo_reg_slot_compare (const void *v1p
, const void *v2p
)
3629 const int regno1
= *(const int *) v1p
;
3630 const int regno2
= *(const int *) v2p
;
3631 ira_allocno_t a1
= ira_regno_allocno_map
[regno1
];
3632 ira_allocno_t a2
= ira_regno_allocno_map
[regno2
];
3633 int diff
, slot_num1
, slot_num2
;
3634 int total_size1
, total_size2
;
3636 if (a1
== NULL
|| ALLOCNO_HARD_REGNO (a1
) >= 0)
3638 if (a2
== NULL
|| ALLOCNO_HARD_REGNO (a2
) >= 0)
3639 return regno1
- regno2
;
3642 else if (a2
== NULL
|| ALLOCNO_HARD_REGNO (a2
) >= 0)
3644 slot_num1
= -ALLOCNO_HARD_REGNO (a1
);
3645 slot_num2
= -ALLOCNO_HARD_REGNO (a2
);
3646 if ((diff
= slot_num1
- slot_num2
) != 0)
3647 return (frame_pointer_needed
3648 || !FRAME_GROWS_DOWNWARD
== STACK_GROWS_DOWNWARD
? diff
: -diff
);
3649 total_size1
= MAX (PSEUDO_REGNO_BYTES (regno1
),
3650 regno_max_ref_width
[regno1
]);
3651 total_size2
= MAX (PSEUDO_REGNO_BYTES (regno2
),
3652 regno_max_ref_width
[regno2
]);
3653 if ((diff
= total_size2
- total_size1
) != 0)
3655 return regno1
- regno2
;
3658 /* Setup REGNO_COALESCED_ALLOCNO_COST and REGNO_COALESCED_ALLOCNO_NUM
3659 for coalesced allocno sets containing allocnos with their regnos
3660 given in array PSEUDO_REGNOS of length N. */
3662 setup_coalesced_allocno_costs_and_nums (int *pseudo_regnos
, int n
)
3664 int i
, num
, regno
, cost
;
3665 ira_allocno_t allocno
, a
;
3667 for (num
= i
= 0; i
< n
; i
++)
3669 regno
= pseudo_regnos
[i
];
3670 allocno
= ira_regno_allocno_map
[regno
];
3671 if (allocno
== NULL
)
3673 regno_coalesced_allocno_cost
[regno
] = 0;
3674 regno_coalesced_allocno_num
[regno
] = ++num
;
3677 if (ALLOCNO_COALESCE_DATA (allocno
)->first
!= allocno
)
3680 for (cost
= 0, a
= ALLOCNO_COALESCE_DATA (allocno
)->next
;;
3681 a
= ALLOCNO_COALESCE_DATA (a
)->next
)
3683 cost
+= ALLOCNO_FREQ (a
);
3687 for (a
= ALLOCNO_COALESCE_DATA (allocno
)->next
;;
3688 a
= ALLOCNO_COALESCE_DATA (a
)->next
)
3690 regno_coalesced_allocno_num
[ALLOCNO_REGNO (a
)] = num
;
3691 regno_coalesced_allocno_cost
[ALLOCNO_REGNO (a
)] = cost
;
3698 /* Collect spilled allocnos representing coalesced allocno sets (the
3699 first coalesced allocno). The collected allocnos are returned
3700 through array SPILLED_COALESCED_ALLOCNOS. The function returns the
3701 number of the collected allocnos. The allocnos are given by their
3702 regnos in array PSEUDO_REGNOS of length N. */
3704 collect_spilled_coalesced_allocnos (int *pseudo_regnos
, int n
,
3705 ira_allocno_t
*spilled_coalesced_allocnos
)
3708 ira_allocno_t allocno
;
3710 for (num
= i
= 0; i
< n
; i
++)
3712 regno
= pseudo_regnos
[i
];
3713 allocno
= ira_regno_allocno_map
[regno
];
3714 if (allocno
== NULL
|| ALLOCNO_HARD_REGNO (allocno
) >= 0
3715 || ALLOCNO_COALESCE_DATA (allocno
)->first
!= allocno
)
3717 spilled_coalesced_allocnos
[num
++] = allocno
;
3722 /* Array of live ranges of size IRA_ALLOCNOS_NUM. Live range for
3723 given slot contains live ranges of coalesced allocnos assigned to
3725 static live_range_t
*slot_coalesced_allocnos_live_ranges
;
3727 /* Return TRUE if coalesced allocnos represented by ALLOCNO has live
3728 ranges intersected with live ranges of coalesced allocnos assigned
3729 to slot with number N. */
3731 slot_coalesced_allocno_live_ranges_intersect_p (ira_allocno_t allocno
, int n
)
3735 for (a
= ALLOCNO_COALESCE_DATA (allocno
)->next
;;
3736 a
= ALLOCNO_COALESCE_DATA (a
)->next
)
3739 int nr
= ALLOCNO_NUM_OBJECTS (a
);
3741 for (i
= 0; i
< nr
; i
++)
3743 ira_object_t obj
= ALLOCNO_OBJECT (a
, i
);
3745 if (ira_live_ranges_intersect_p
3746 (slot_coalesced_allocnos_live_ranges
[n
],
3747 OBJECT_LIVE_RANGES (obj
)))
3756 /* Update live ranges of slot to which coalesced allocnos represented
3757 by ALLOCNO were assigned. */
3759 setup_slot_coalesced_allocno_live_ranges (ira_allocno_t allocno
)
3765 n
= ALLOCNO_COALESCE_DATA (allocno
)->temp
;
3766 for (a
= ALLOCNO_COALESCE_DATA (allocno
)->next
;;
3767 a
= ALLOCNO_COALESCE_DATA (a
)->next
)
3769 int nr
= ALLOCNO_NUM_OBJECTS (a
);
3770 for (i
= 0; i
< nr
; i
++)
3772 ira_object_t obj
= ALLOCNO_OBJECT (a
, i
);
3774 r
= ira_copy_live_range_list (OBJECT_LIVE_RANGES (obj
));
3775 slot_coalesced_allocnos_live_ranges
[n
]
3776 = ira_merge_live_ranges
3777 (slot_coalesced_allocnos_live_ranges
[n
], r
);
3784 /* We have coalesced allocnos involving in copies. Coalesce allocnos
3785 further in order to share the same memory stack slot. Allocnos
3786 representing sets of allocnos coalesced before the call are given
3787 in array SPILLED_COALESCED_ALLOCNOS of length NUM. Return TRUE if
3788 some allocnos were coalesced in the function. */
3790 coalesce_spill_slots (ira_allocno_t
*spilled_coalesced_allocnos
, int num
)
3792 int i
, j
, n
, last_coalesced_allocno_num
;
3793 ira_allocno_t allocno
, a
;
3794 bool merged_p
= false;
3795 bitmap set_jump_crosses
= regstat_get_setjmp_crosses ();
3797 slot_coalesced_allocnos_live_ranges
3798 = (live_range_t
*) ira_allocate (sizeof (live_range_t
) * ira_allocnos_num
);
3799 memset (slot_coalesced_allocnos_live_ranges
, 0,
3800 sizeof (live_range_t
) * ira_allocnos_num
);
3801 last_coalesced_allocno_num
= 0;
3802 /* Coalesce non-conflicting spilled allocnos preferring most
3804 for (i
= 0; i
< num
; i
++)
3806 allocno
= spilled_coalesced_allocnos
[i
];
3807 if (ALLOCNO_COALESCE_DATA (allocno
)->first
!= allocno
3808 || bitmap_bit_p (set_jump_crosses
, ALLOCNO_REGNO (allocno
))
3809 || ira_equiv_no_lvalue_p (ALLOCNO_REGNO (allocno
)))
3811 for (j
= 0; j
< i
; j
++)
3813 a
= spilled_coalesced_allocnos
[j
];
3814 n
= ALLOCNO_COALESCE_DATA (a
)->temp
;
3815 if (ALLOCNO_COALESCE_DATA (a
)->first
== a
3816 && ! bitmap_bit_p (set_jump_crosses
, ALLOCNO_REGNO (a
))
3817 && ! ira_equiv_no_lvalue_p (ALLOCNO_REGNO (a
))
3818 && ! slot_coalesced_allocno_live_ranges_intersect_p (allocno
, n
))
3823 /* No coalescing: set up number for coalesced allocnos
3824 represented by ALLOCNO. */
3825 ALLOCNO_COALESCE_DATA (allocno
)->temp
= last_coalesced_allocno_num
++;
3826 setup_slot_coalesced_allocno_live_ranges (allocno
);
3830 allocno_coalesced_p
= true;
3832 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
3833 fprintf (ira_dump_file
,
3834 " Coalescing spilled allocnos a%dr%d->a%dr%d\n",
3835 ALLOCNO_NUM (allocno
), ALLOCNO_REGNO (allocno
),
3836 ALLOCNO_NUM (a
), ALLOCNO_REGNO (a
));
3837 ALLOCNO_COALESCE_DATA (allocno
)->temp
3838 = ALLOCNO_COALESCE_DATA (a
)->temp
;
3839 setup_slot_coalesced_allocno_live_ranges (allocno
);
3840 merge_allocnos (a
, allocno
);
3841 ira_assert (ALLOCNO_COALESCE_DATA (a
)->first
== a
);
3844 for (i
= 0; i
< ira_allocnos_num
; i
++)
3845 ira_finish_live_range_list (slot_coalesced_allocnos_live_ranges
[i
]);
3846 ira_free (slot_coalesced_allocnos_live_ranges
);
3850 /* Sort pseudo-register numbers in array PSEUDO_REGNOS of length N for
3851 subsequent assigning stack slots to them in the reload pass. To do
3852 this we coalesce spilled allocnos first to decrease the number of
3853 memory-memory move insns. This function is called by the
3856 ira_sort_regnos_for_alter_reg (int *pseudo_regnos
, int n
,
3857 unsigned int *reg_max_ref_width
)
3859 int max_regno
= max_reg_num ();
3860 int i
, regno
, num
, slot_num
;
3861 ira_allocno_t allocno
, a
;
3862 ira_allocno_iterator ai
;
3863 ira_allocno_t
*spilled_coalesced_allocnos
;
3865 /* Set up allocnos can be coalesced. */
3866 coloring_allocno_bitmap
= ira_allocate_bitmap ();
3867 for (i
= 0; i
< n
; i
++)
3869 regno
= pseudo_regnos
[i
];
3870 allocno
= ira_regno_allocno_map
[regno
];
3871 if (allocno
!= NULL
)
3872 bitmap_set_bit (coloring_allocno_bitmap
, ALLOCNO_NUM (allocno
));
3874 allocno_coalesced_p
= false;
3875 processed_coalesced_allocno_bitmap
= ira_allocate_bitmap ();
3876 allocno_coalesce_data
3877 = (coalesce_data_t
) ira_allocate (sizeof (struct coalesce_data
)
3878 * ira_allocnos_num
);
3879 /* Initialize coalesce data for allocnos. */
3880 FOR_EACH_ALLOCNO (a
, ai
)
3882 ALLOCNO_ADD_DATA (a
) = allocno_coalesce_data
+ ALLOCNO_NUM (a
);
3883 ALLOCNO_COALESCE_DATA (a
)->first
= a
;
3884 ALLOCNO_COALESCE_DATA (a
)->next
= a
;
3886 coalesce_allocnos ();
3887 ira_free_bitmap (coloring_allocno_bitmap
);
3888 regno_coalesced_allocno_cost
3889 = (int *) ira_allocate (max_regno
* sizeof (int));
3890 regno_coalesced_allocno_num
3891 = (int *) ira_allocate (max_regno
* sizeof (int));
3892 memset (regno_coalesced_allocno_num
, 0, max_regno
* sizeof (int));
3893 setup_coalesced_allocno_costs_and_nums (pseudo_regnos
, n
);
3894 /* Sort regnos according frequencies of the corresponding coalesced
3896 qsort (pseudo_regnos
, n
, sizeof (int), coalesced_pseudo_reg_freq_compare
);
3897 spilled_coalesced_allocnos
3898 = (ira_allocno_t
*) ira_allocate (ira_allocnos_num
3899 * sizeof (ira_allocno_t
));
3900 /* Collect allocnos representing the spilled coalesced allocno
3902 num
= collect_spilled_coalesced_allocnos (pseudo_regnos
, n
,
3903 spilled_coalesced_allocnos
);
3904 if (flag_ira_share_spill_slots
3905 && coalesce_spill_slots (spilled_coalesced_allocnos
, num
))
3907 setup_coalesced_allocno_costs_and_nums (pseudo_regnos
, n
);
3908 qsort (pseudo_regnos
, n
, sizeof (int),
3909 coalesced_pseudo_reg_freq_compare
);
3910 num
= collect_spilled_coalesced_allocnos (pseudo_regnos
, n
,
3911 spilled_coalesced_allocnos
);
3913 ira_free_bitmap (processed_coalesced_allocno_bitmap
);
3914 allocno_coalesced_p
= false;
3915 /* Assign stack slot numbers to spilled allocno sets, use smaller
3916 numbers for most frequently used coalesced allocnos. -1 is
3917 reserved for dynamic search of stack slots for pseudos spilled by
3920 for (i
= 0; i
< num
; i
++)
3922 allocno
= spilled_coalesced_allocnos
[i
];
3923 if (ALLOCNO_COALESCE_DATA (allocno
)->first
!= allocno
3924 || ALLOCNO_HARD_REGNO (allocno
) >= 0
3925 || ira_equiv_no_lvalue_p (ALLOCNO_REGNO (allocno
)))
3927 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
3928 fprintf (ira_dump_file
, " Slot %d (freq,size):", slot_num
);
3930 for (a
= ALLOCNO_COALESCE_DATA (allocno
)->next
;;
3931 a
= ALLOCNO_COALESCE_DATA (a
)->next
)
3933 ira_assert (ALLOCNO_HARD_REGNO (a
) < 0);
3934 ALLOCNO_HARD_REGNO (a
) = -slot_num
;
3935 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
3936 fprintf (ira_dump_file
, " a%dr%d(%d,%d)",
3937 ALLOCNO_NUM (a
), ALLOCNO_REGNO (a
), ALLOCNO_FREQ (a
),
3938 MAX (PSEUDO_REGNO_BYTES (ALLOCNO_REGNO (a
)),
3939 reg_max_ref_width
[ALLOCNO_REGNO (a
)]));
3944 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
3945 fprintf (ira_dump_file
, "\n");
3947 ira_spilled_reg_stack_slots_num
= slot_num
- 1;
3948 ira_free (spilled_coalesced_allocnos
);
3949 /* Sort regnos according the slot numbers. */
3950 regno_max_ref_width
= reg_max_ref_width
;
3951 qsort (pseudo_regnos
, n
, sizeof (int), coalesced_pseudo_reg_slot_compare
);
3952 FOR_EACH_ALLOCNO (a
, ai
)
3953 ALLOCNO_ADD_DATA (a
) = NULL
;
3954 ira_free (allocno_coalesce_data
);
3955 ira_free (regno_coalesced_allocno_num
);
3956 ira_free (regno_coalesced_allocno_cost
);
3961 /* This page contains code used by the reload pass to improve the
3964 /* The function is called from reload to mark changes in the
3965 allocation of REGNO made by the reload. Remember that reg_renumber
3966 reflects the change result. */
3968 ira_mark_allocation_change (int regno
)
3970 ira_allocno_t a
= ira_regno_allocno_map
[regno
];
3971 int old_hard_regno
, hard_regno
, cost
;
3972 enum reg_class aclass
= ALLOCNO_CLASS (a
);
3974 ira_assert (a
!= NULL
);
3975 hard_regno
= reg_renumber
[regno
];
3976 if ((old_hard_regno
= ALLOCNO_HARD_REGNO (a
)) == hard_regno
)
3978 if (old_hard_regno
< 0)
3979 cost
= -ALLOCNO_MEMORY_COST (a
);
3982 ira_assert (ira_class_hard_reg_index
[aclass
][old_hard_regno
] >= 0);
3983 cost
= -(ALLOCNO_HARD_REG_COSTS (a
) == NULL
3984 ? ALLOCNO_CLASS_COST (a
)
3985 : ALLOCNO_HARD_REG_COSTS (a
)
3986 [ira_class_hard_reg_index
[aclass
][old_hard_regno
]]);
3987 update_costs_from_copies (a
, false, false);
3989 ira_overall_cost
-= cost
;
3990 ALLOCNO_HARD_REGNO (a
) = hard_regno
;
3993 ALLOCNO_HARD_REGNO (a
) = -1;
3994 cost
+= ALLOCNO_MEMORY_COST (a
);
3996 else if (ira_class_hard_reg_index
[aclass
][hard_regno
] >= 0)
3998 cost
+= (ALLOCNO_HARD_REG_COSTS (a
) == NULL
3999 ? ALLOCNO_CLASS_COST (a
)
4000 : ALLOCNO_HARD_REG_COSTS (a
)
4001 [ira_class_hard_reg_index
[aclass
][hard_regno
]]);
4002 update_costs_from_copies (a
, true, false);
4005 /* Reload changed class of the allocno. */
4007 ira_overall_cost
+= cost
;
4010 /* This function is called when reload deletes memory-memory move. In
4011 this case we marks that the allocation of the corresponding
4012 allocnos should be not changed in future. Otherwise we risk to get
4015 ira_mark_memory_move_deletion (int dst_regno
, int src_regno
)
4017 ira_allocno_t dst
= ira_regno_allocno_map
[dst_regno
];
4018 ira_allocno_t src
= ira_regno_allocno_map
[src_regno
];
4020 ira_assert (dst
!= NULL
&& src
!= NULL
4021 && ALLOCNO_HARD_REGNO (dst
) < 0
4022 && ALLOCNO_HARD_REGNO (src
) < 0);
4023 ALLOCNO_DONT_REASSIGN_P (dst
) = true;
4024 ALLOCNO_DONT_REASSIGN_P (src
) = true;
4027 /* Try to assign a hard register (except for FORBIDDEN_REGS) to
4028 allocno A and return TRUE in the case of success. */
4030 allocno_reload_assign (ira_allocno_t a
, HARD_REG_SET forbidden_regs
)
4033 enum reg_class aclass
;
4034 int regno
= ALLOCNO_REGNO (a
);
4035 HARD_REG_SET saved
[2];
4038 n
= ALLOCNO_NUM_OBJECTS (a
);
4039 for (i
= 0; i
< n
; i
++)
4041 ira_object_t obj
= ALLOCNO_OBJECT (a
, i
);
4042 COPY_HARD_REG_SET (saved
[i
], OBJECT_TOTAL_CONFLICT_HARD_REGS (obj
));
4043 IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj
), forbidden_regs
);
4044 if (! flag_caller_saves
&& ALLOCNO_CALLS_CROSSED_NUM (a
) != 0)
4045 IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj
),
4048 ALLOCNO_ASSIGNED_P (a
) = false;
4049 aclass
= ALLOCNO_CLASS (a
);
4050 update_curr_costs (a
);
4051 assign_hard_reg (a
, true);
4052 hard_regno
= ALLOCNO_HARD_REGNO (a
);
4053 reg_renumber
[regno
] = hard_regno
;
4055 ALLOCNO_HARD_REGNO (a
) = -1;
4058 ira_assert (ira_class_hard_reg_index
[aclass
][hard_regno
] >= 0);
4060 -= (ALLOCNO_MEMORY_COST (a
)
4061 - (ALLOCNO_HARD_REG_COSTS (a
) == NULL
4062 ? ALLOCNO_CLASS_COST (a
)
4063 : ALLOCNO_HARD_REG_COSTS (a
)[ira_class_hard_reg_index
4064 [aclass
][hard_regno
]]));
4065 if (ALLOCNO_CALLS_CROSSED_NUM (a
) != 0
4066 && ira_hard_reg_set_intersection_p (hard_regno
, ALLOCNO_MODE (a
),
4069 ira_assert (flag_caller_saves
);
4070 caller_save_needed
= 1;
4074 /* If we found a hard register, modify the RTL for the pseudo
4075 register to show the hard register, and mark the pseudo register
4077 if (reg_renumber
[regno
] >= 0)
4079 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
4080 fprintf (ira_dump_file
, ": reassign to %d\n", reg_renumber
[regno
]);
4081 SET_REGNO (regno_reg_rtx
[regno
], reg_renumber
[regno
]);
4082 mark_home_live (regno
);
4084 else if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
4085 fprintf (ira_dump_file
, "\n");
4086 for (i
= 0; i
< n
; i
++)
4088 ira_object_t obj
= ALLOCNO_OBJECT (a
, i
);
4089 COPY_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj
), saved
[i
]);
4091 return reg_renumber
[regno
] >= 0;
4094 /* Sort pseudos according their usage frequencies (putting most
4095 frequently ones first). */
4097 pseudo_reg_compare (const void *v1p
, const void *v2p
)
4099 int regno1
= *(const int *) v1p
;
4100 int regno2
= *(const int *) v2p
;
4103 if ((diff
= REG_FREQ (regno2
) - REG_FREQ (regno1
)) != 0)
4105 return regno1
- regno2
;
4108 /* Try to allocate hard registers to SPILLED_PSEUDO_REGS (there are
4109 NUM of them) or spilled pseudos conflicting with pseudos in
4110 SPILLED_PSEUDO_REGS. Return TRUE and update SPILLED, if the
4111 allocation has been changed. The function doesn't use
4112 BAD_SPILL_REGS and hard registers in PSEUDO_FORBIDDEN_REGS and
4113 PSEUDO_PREVIOUS_REGS for the corresponding pseudos. The function
4114 is called by the reload pass at the end of each reload
4117 ira_reassign_pseudos (int *spilled_pseudo_regs
, int num
,
4118 HARD_REG_SET bad_spill_regs
,
4119 HARD_REG_SET
*pseudo_forbidden_regs
,
4120 HARD_REG_SET
*pseudo_previous_regs
,
4126 HARD_REG_SET forbidden_regs
;
4127 bitmap temp
= BITMAP_ALLOC (NULL
);
4129 /* Add pseudos which conflict with pseudos already in
4130 SPILLED_PSEUDO_REGS to SPILLED_PSEUDO_REGS. This is preferable
4131 to allocating in two steps as some of the conflicts might have
4132 a higher priority than the pseudos passed in SPILLED_PSEUDO_REGS. */
4133 for (i
= 0; i
< num
; i
++)
4134 bitmap_set_bit (temp
, spilled_pseudo_regs
[i
]);
4136 for (i
= 0, n
= num
; i
< n
; i
++)
4139 int regno
= spilled_pseudo_regs
[i
];
4140 bitmap_set_bit (temp
, regno
);
4142 a
= ira_regno_allocno_map
[regno
];
4143 nr
= ALLOCNO_NUM_OBJECTS (a
);
4144 for (j
= 0; j
< nr
; j
++)
4146 ira_object_t conflict_obj
;
4147 ira_object_t obj
= ALLOCNO_OBJECT (a
, j
);
4148 ira_object_conflict_iterator oci
;
4150 FOR_EACH_OBJECT_CONFLICT (obj
, conflict_obj
, oci
)
4152 ira_allocno_t conflict_a
= OBJECT_ALLOCNO (conflict_obj
);
4153 if (ALLOCNO_HARD_REGNO (conflict_a
) < 0
4154 && ! ALLOCNO_DONT_REASSIGN_P (conflict_a
)
4155 && bitmap_set_bit (temp
, ALLOCNO_REGNO (conflict_a
)))
4157 spilled_pseudo_regs
[num
++] = ALLOCNO_REGNO (conflict_a
);
4158 /* ?!? This seems wrong. */
4159 bitmap_set_bit (consideration_allocno_bitmap
,
4160 ALLOCNO_NUM (conflict_a
));
4167 qsort (spilled_pseudo_regs
, num
, sizeof (int), pseudo_reg_compare
);
4169 /* Try to assign hard registers to pseudos from
4170 SPILLED_PSEUDO_REGS. */
4171 for (i
= 0; i
< num
; i
++)
4173 regno
= spilled_pseudo_regs
[i
];
4174 COPY_HARD_REG_SET (forbidden_regs
, bad_spill_regs
);
4175 IOR_HARD_REG_SET (forbidden_regs
, pseudo_forbidden_regs
[regno
]);
4176 IOR_HARD_REG_SET (forbidden_regs
, pseudo_previous_regs
[regno
]);
4177 gcc_assert (reg_renumber
[regno
] < 0);
4178 a
= ira_regno_allocno_map
[regno
];
4179 ira_mark_allocation_change (regno
);
4180 ira_assert (reg_renumber
[regno
] < 0);
4181 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
4182 fprintf (ira_dump_file
,
4183 " Try Assign %d(a%d), cost=%d", regno
, ALLOCNO_NUM (a
),
4184 ALLOCNO_MEMORY_COST (a
)
4185 - ALLOCNO_CLASS_COST (a
));
4186 allocno_reload_assign (a
, forbidden_regs
);
4187 if (reg_renumber
[regno
] >= 0)
4189 CLEAR_REGNO_REG_SET (spilled
, regno
);
4197 /* The function is called by reload and returns already allocated
4198 stack slot (if any) for REGNO with given INHERENT_SIZE and
4199 TOTAL_SIZE. In the case of failure to find a slot which can be
4200 used for REGNO, the function returns NULL. */
4202 ira_reuse_stack_slot (int regno
, unsigned int inherent_size
,
4203 unsigned int total_size
)
4206 int slot_num
, best_slot_num
;
4207 int cost
, best_cost
;
4208 ira_copy_t cp
, next_cp
;
4209 ira_allocno_t another_allocno
, allocno
= ira_regno_allocno_map
[regno
];
4212 struct ira_spilled_reg_stack_slot
*slot
= NULL
;
4214 ira_assert (inherent_size
== PSEUDO_REGNO_BYTES (regno
)
4215 && inherent_size
<= total_size
4216 && ALLOCNO_HARD_REGNO (allocno
) < 0);
4217 if (! flag_ira_share_spill_slots
)
4219 slot_num
= -ALLOCNO_HARD_REGNO (allocno
) - 2;
4222 slot
= &ira_spilled_reg_stack_slots
[slot_num
];
4227 best_cost
= best_slot_num
= -1;
4229 /* It means that the pseudo was spilled in the reload pass, try
4232 slot_num
< ira_spilled_reg_stack_slots_num
;
4235 slot
= &ira_spilled_reg_stack_slots
[slot_num
];
4236 if (slot
->mem
== NULL_RTX
)
4238 if (slot
->width
< total_size
4239 || GET_MODE_SIZE (GET_MODE (slot
->mem
)) < inherent_size
)
4242 EXECUTE_IF_SET_IN_BITMAP (&slot
->spilled_regs
,
4243 FIRST_PSEUDO_REGISTER
, i
, bi
)
4245 another_allocno
= ira_regno_allocno_map
[i
];
4246 if (allocnos_conflict_by_live_ranges_p (allocno
,
4250 for (cost
= 0, cp
= ALLOCNO_COPIES (allocno
);
4254 if (cp
->first
== allocno
)
4256 next_cp
= cp
->next_first_allocno_copy
;
4257 another_allocno
= cp
->second
;
4259 else if (cp
->second
== allocno
)
4261 next_cp
= cp
->next_second_allocno_copy
;
4262 another_allocno
= cp
->first
;
4266 if (cp
->insn
== NULL_RTX
)
4268 if (bitmap_bit_p (&slot
->spilled_regs
,
4269 ALLOCNO_REGNO (another_allocno
)))
4272 if (cost
> best_cost
)
4275 best_slot_num
= slot_num
;
4282 slot_num
= best_slot_num
;
4283 slot
= &ira_spilled_reg_stack_slots
[slot_num
];
4284 SET_REGNO_REG_SET (&slot
->spilled_regs
, regno
);
4286 ALLOCNO_HARD_REGNO (allocno
) = -slot_num
- 2;
4291 ira_assert (slot
->width
>= total_size
);
4292 #ifdef ENABLE_IRA_CHECKING
4293 EXECUTE_IF_SET_IN_BITMAP (&slot
->spilled_regs
,
4294 FIRST_PSEUDO_REGISTER
, i
, bi
)
4296 ira_assert (! conflict_by_live_ranges_p (regno
, i
));
4299 SET_REGNO_REG_SET (&slot
->spilled_regs
, regno
);
4300 if (internal_flag_ira_verbose
> 3 && ira_dump_file
)
4302 fprintf (ira_dump_file
, " Assigning %d(freq=%d) slot %d of",
4303 regno
, REG_FREQ (regno
), slot_num
);
4304 EXECUTE_IF_SET_IN_BITMAP (&slot
->spilled_regs
,
4305 FIRST_PSEUDO_REGISTER
, i
, bi
)
4307 if ((unsigned) regno
!= i
)
4308 fprintf (ira_dump_file
, " %d", i
);
4310 fprintf (ira_dump_file
, "\n");
4316 /* This is called by reload every time a new stack slot X with
4317 TOTAL_SIZE was allocated for REGNO. We store this info for
4318 subsequent ira_reuse_stack_slot calls. */
4320 ira_mark_new_stack_slot (rtx x
, int regno
, unsigned int total_size
)
4322 struct ira_spilled_reg_stack_slot
*slot
;
4324 ira_allocno_t allocno
;
4326 ira_assert (PSEUDO_REGNO_BYTES (regno
) <= total_size
);
4327 allocno
= ira_regno_allocno_map
[regno
];
4328 slot_num
= -ALLOCNO_HARD_REGNO (allocno
) - 2;
4331 slot_num
= ira_spilled_reg_stack_slots_num
++;
4332 ALLOCNO_HARD_REGNO (allocno
) = -slot_num
- 2;
4334 slot
= &ira_spilled_reg_stack_slots
[slot_num
];
4335 INIT_REG_SET (&slot
->spilled_regs
);
4336 SET_REGNO_REG_SET (&slot
->spilled_regs
, regno
);
4338 slot
->width
= total_size
;
4339 if (internal_flag_ira_verbose
> 3 && ira_dump_file
)
4340 fprintf (ira_dump_file
, " Assigning %d(freq=%d) a new slot %d\n",
4341 regno
, REG_FREQ (regno
), slot_num
);
4345 /* Return spill cost for pseudo-registers whose numbers are in array
4346 REGNOS (with a negative number as an end marker) for reload with
4347 given IN and OUT for INSN. Return also number points (through
4348 EXCESS_PRESSURE_LIVE_LENGTH) where the pseudo-register lives and
4349 the register pressure is high, number of references of the
4350 pseudo-registers (through NREFS), number of callee-clobbered
4351 hard-registers occupied by the pseudo-registers (through
4352 CALL_USED_COUNT), and the first hard regno occupied by the
4353 pseudo-registers (through FIRST_HARD_REGNO). */
4355 calculate_spill_cost (int *regnos
, rtx in
, rtx out
, rtx insn
,
4356 int *excess_pressure_live_length
,
4357 int *nrefs
, int *call_used_count
, int *first_hard_regno
)
4359 int i
, cost
, regno
, hard_regno
, j
, count
, saved_cost
, nregs
;
4365 for (length
= count
= cost
= i
= 0;; i
++)
4370 *nrefs
+= REG_N_REFS (regno
);
4371 hard_regno
= reg_renumber
[regno
];
4372 ira_assert (hard_regno
>= 0);
4373 a
= ira_regno_allocno_map
[regno
];
4374 length
+= ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a
) / ALLOCNO_NUM_OBJECTS (a
);
4375 cost
+= ALLOCNO_MEMORY_COST (a
) - ALLOCNO_CLASS_COST (a
);
4376 nregs
= hard_regno_nregs
[hard_regno
][ALLOCNO_MODE (a
)];
4377 for (j
= 0; j
< nregs
; j
++)
4378 if (! TEST_HARD_REG_BIT (call_used_reg_set
, hard_regno
+ j
))
4382 in_p
= in
&& REG_P (in
) && (int) REGNO (in
) == hard_regno
;
4383 out_p
= out
&& REG_P (out
) && (int) REGNO (out
) == hard_regno
;
4385 && find_regno_note (insn
, REG_DEAD
, hard_regno
) != NULL_RTX
)
4389 saved_cost
+= ira_memory_move_cost
4390 [ALLOCNO_MODE (a
)][ALLOCNO_CLASS (a
)][1];
4393 += ira_memory_move_cost
4394 [ALLOCNO_MODE (a
)][ALLOCNO_CLASS (a
)][0];
4395 cost
-= REG_FREQ_FROM_BB (BLOCK_FOR_INSN (insn
)) * saved_cost
;
4398 *excess_pressure_live_length
= length
;
4399 *call_used_count
= count
;
4403 hard_regno
= reg_renumber
[regnos
[0]];
4405 *first_hard_regno
= hard_regno
;
4409 /* Return TRUE if spilling pseudo-registers whose numbers are in array
4410 REGNOS is better than spilling pseudo-registers with numbers in
4411 OTHER_REGNOS for reload with given IN and OUT for INSN. The
4412 function used by the reload pass to make better register spilling
4415 ira_better_spill_reload_regno_p (int *regnos
, int *other_regnos
,
4416 rtx in
, rtx out
, rtx insn
)
4418 int cost
, other_cost
;
4419 int length
, other_length
;
4420 int nrefs
, other_nrefs
;
4421 int call_used_count
, other_call_used_count
;
4422 int hard_regno
, other_hard_regno
;
4424 cost
= calculate_spill_cost (regnos
, in
, out
, insn
,
4425 &length
, &nrefs
, &call_used_count
, &hard_regno
);
4426 other_cost
= calculate_spill_cost (other_regnos
, in
, out
, insn
,
4427 &other_length
, &other_nrefs
,
4428 &other_call_used_count
,
4430 if (nrefs
== 0 && other_nrefs
!= 0)
4432 if (nrefs
!= 0 && other_nrefs
== 0)
4434 if (cost
!= other_cost
)
4435 return cost
< other_cost
;
4436 if (length
!= other_length
)
4437 return length
> other_length
;
4438 #ifdef REG_ALLOC_ORDER
4439 if (hard_regno
>= 0 && other_hard_regno
>= 0)
4440 return (inv_reg_alloc_order
[hard_regno
]
4441 < inv_reg_alloc_order
[other_hard_regno
]);
4443 if (call_used_count
!= other_call_used_count
)
4444 return call_used_count
> other_call_used_count
;
4451 /* Allocate and initialize data necessary for assign_hard_reg. */
4453 ira_initiate_assign (void)
4456 = (ira_allocno_t
*) ira_allocate (sizeof (ira_allocno_t
)
4457 * ira_allocnos_num
);
4458 consideration_allocno_bitmap
= ira_allocate_bitmap ();
4459 initiate_cost_update ();
4460 allocno_priorities
= (int *) ira_allocate (sizeof (int) * ira_allocnos_num
);
4463 /* Deallocate data used by assign_hard_reg. */
4465 ira_finish_assign (void)
4467 ira_free (sorted_allocnos
);
4468 ira_free_bitmap (consideration_allocno_bitmap
);
4469 finish_cost_update ();
4470 ira_free (allocno_priorities
);
4475 /* Entry function doing color-based register allocation. */
4479 allocno_stack_vec
.create (ira_allocnos_num
);
4480 memset (allocated_hardreg_p
, 0, sizeof (allocated_hardreg_p
));
4481 ira_initiate_assign ();
4483 ira_finish_assign ();
4484 allocno_stack_vec
.release ();
4485 move_spill_restore ();
4490 /* This page contains a simple register allocator without usage of
4491 allocno conflicts. This is used for fast allocation for -O0. */
4493 /* Do register allocation by not using allocno conflicts. It uses
4494 only allocno live ranges. The algorithm is close to Chow's
4495 priority coloring. */
4497 fast_allocation (void)
4499 int i
, j
, k
, num
, class_size
, hard_regno
;
4501 bool no_stack_reg_p
;
4503 enum reg_class aclass
;
4504 enum machine_mode mode
;
4506 ira_allocno_iterator ai
;
4508 HARD_REG_SET conflict_hard_regs
, *used_hard_regs
;
4510 sorted_allocnos
= (ira_allocno_t
*) ira_allocate (sizeof (ira_allocno_t
)
4511 * ira_allocnos_num
);
4513 FOR_EACH_ALLOCNO (a
, ai
)
4514 sorted_allocnos
[num
++] = a
;
4515 allocno_priorities
= (int *) ira_allocate (sizeof (int) * ira_allocnos_num
);
4516 setup_allocno_priorities (sorted_allocnos
, num
);
4517 used_hard_regs
= (HARD_REG_SET
*) ira_allocate (sizeof (HARD_REG_SET
)
4519 for (i
= 0; i
< ira_max_point
; i
++)
4520 CLEAR_HARD_REG_SET (used_hard_regs
[i
]);
4521 qsort (sorted_allocnos
, num
, sizeof (ira_allocno_t
),
4522 allocno_priority_compare_func
);
4523 for (i
= 0; i
< num
; i
++)
4527 a
= sorted_allocnos
[i
];
4528 nr
= ALLOCNO_NUM_OBJECTS (a
);
4529 CLEAR_HARD_REG_SET (conflict_hard_regs
);
4530 for (l
= 0; l
< nr
; l
++)
4532 ira_object_t obj
= ALLOCNO_OBJECT (a
, l
);
4533 IOR_HARD_REG_SET (conflict_hard_regs
,
4534 OBJECT_CONFLICT_HARD_REGS (obj
));
4535 for (r
= OBJECT_LIVE_RANGES (obj
); r
!= NULL
; r
= r
->next
)
4536 for (j
= r
->start
; j
<= r
->finish
; j
++)
4537 IOR_HARD_REG_SET (conflict_hard_regs
, used_hard_regs
[j
]);
4539 aclass
= ALLOCNO_CLASS (a
);
4540 ALLOCNO_ASSIGNED_P (a
) = true;
4541 ALLOCNO_HARD_REGNO (a
) = -1;
4542 if (hard_reg_set_subset_p (reg_class_contents
[aclass
],
4543 conflict_hard_regs
))
4545 mode
= ALLOCNO_MODE (a
);
4547 no_stack_reg_p
= ALLOCNO_NO_STACK_REG_P (a
);
4549 class_size
= ira_class_hard_regs_num
[aclass
];
4550 for (j
= 0; j
< class_size
; j
++)
4552 hard_regno
= ira_class_hard_regs
[aclass
][j
];
4554 if (no_stack_reg_p
&& FIRST_STACK_REG
<= hard_regno
4555 && hard_regno
<= LAST_STACK_REG
)
4558 if (ira_hard_reg_set_intersection_p (hard_regno
, mode
, conflict_hard_regs
)
4559 || (TEST_HARD_REG_BIT
4560 (ira_prohibited_class_mode_regs
[aclass
][mode
], hard_regno
)))
4562 ALLOCNO_HARD_REGNO (a
) = hard_regno
;
4563 for (l
= 0; l
< nr
; l
++)
4565 ira_object_t obj
= ALLOCNO_OBJECT (a
, l
);
4566 for (r
= OBJECT_LIVE_RANGES (obj
); r
!= NULL
; r
= r
->next
)
4567 for (k
= r
->start
; k
<= r
->finish
; k
++)
4568 IOR_HARD_REG_SET (used_hard_regs
[k
],
4569 ira_reg_mode_hard_regset
[hard_regno
][mode
]);
4574 ira_free (sorted_allocnos
);
4575 ira_free (used_hard_regs
);
4576 ira_free (allocno_priorities
);
4577 if (internal_flag_ira_verbose
> 1 && ira_dump_file
!= NULL
)
4578 ira_print_disposition (ira_dump_file
);
4583 /* Entry function doing coloring. */
4588 ira_allocno_iterator ai
;
4590 /* Setup updated costs. */
4591 FOR_EACH_ALLOCNO (a
, ai
)
4593 ALLOCNO_UPDATED_MEMORY_COST (a
) = ALLOCNO_MEMORY_COST (a
);
4594 ALLOCNO_UPDATED_CLASS_COST (a
) = ALLOCNO_CLASS_COST (a
);
4596 if (ira_conflicts_p
)