1 /* IRA allocation based on graph coloring.
2 Copyright (C) 2006-2016 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"
31 #include "insn-config.h"
38 typedef struct allocno_hard_regs
*allocno_hard_regs_t
;
40 /* The structure contains information about hard registers can be
41 assigned to allocnos. Usually it is allocno profitable hard
42 registers but in some cases this set can be a bit different. Major
43 reason of the difference is a requirement to use hard register sets
44 that form a tree or a forest (set of trees), i.e. hard register set
45 of a node should contain hard register sets of its subnodes. */
46 struct allocno_hard_regs
48 /* Hard registers can be assigned to an allocno. */
50 /* Overall (spilling) cost of all allocnos with given register
55 typedef struct allocno_hard_regs_node
*allocno_hard_regs_node_t
;
57 /* A node representing allocno hard registers. Such nodes form a
58 forest (set of trees). Each subnode of given node in the forest
59 refers for hard register set (usually allocno profitable hard
60 register set) which is a subset of one referred from given
62 struct allocno_hard_regs_node
64 /* Set up number of the node in preorder traversing of the forest. */
66 /* Used for different calculation like finding conflict size of an
69 /* Used for calculation of conflict size of an allocno. The
70 conflict size of the allocno is maximal number of given allocno
71 hard registers needed for allocation of the conflicting allocnos.
72 Given allocno is trivially colored if this number plus the number
73 of hard registers needed for given allocno is not greater than
74 the number of given allocno hard register set. */
76 /* The number of hard registers given by member hard_regs. */
78 /* The following member is used to form the final forest. */
80 /* Pointer to the corresponding profitable hard registers. */
81 allocno_hard_regs_t hard_regs
;
82 /* Parent, first subnode, previous and next node with the same
83 parent in the forest. */
84 allocno_hard_regs_node_t parent
, first
, prev
, next
;
87 /* Info about changing hard reg costs of an allocno. */
88 struct update_cost_record
90 /* Hard regno for which we changed the cost. */
92 /* Divisor used when we changed the cost of HARD_REGNO. */
94 /* Next record for given allocno. */
95 struct update_cost_record
*next
;
98 /* To decrease footprint of ira_allocno structure we store all data
99 needed only for coloring in the following structure. */
100 struct allocno_color_data
102 /* TRUE value means that the allocno was not removed yet from the
103 conflicting graph during coloring. */
104 unsigned int in_graph_p
: 1;
105 /* TRUE if it is put on the stack to make other allocnos
107 unsigned int may_be_spilled_p
: 1;
108 /* TRUE if the allocno is trivially colorable. */
109 unsigned int colorable_p
: 1;
110 /* Number of hard registers of the allocno class really
111 available for the allocno allocation. It is number of the
112 profitable hard regs. */
113 int available_regs_num
;
114 /* Allocnos in a bucket (used in coloring) chained by the following
116 ira_allocno_t next_bucket_allocno
;
117 ira_allocno_t prev_bucket_allocno
;
118 /* Used for temporary purposes. */
120 /* Used to exclude repeated processing. */
122 /* Profitable hard regs available for this pseudo allocation. It
123 means that the set excludes unavailable hard regs and hard regs
124 conflicting with given pseudo. They should be of the allocno
126 HARD_REG_SET profitable_hard_regs
;
127 /* The allocno hard registers node. */
128 allocno_hard_regs_node_t hard_regs_node
;
129 /* Array of structures allocno_hard_regs_subnode representing
130 given allocno hard registers node (the 1st element in the array)
131 and all its subnodes in the tree (forest) of allocno hard
132 register nodes (see comments above). */
133 int hard_regs_subnodes_start
;
134 /* The length of the previous array. */
135 int hard_regs_subnodes_num
;
136 /* Records about updating allocno hard reg costs from copies. If
137 the allocno did not get expected hard register, these records are
138 used to restore original hard reg costs of allocnos connected to
139 this allocno by copies. */
140 struct update_cost_record
*update_cost_records
;
141 /* Threads. We collect allocnos connected by copies into threads
142 and try to assign hard regs to allocnos by threads. */
143 /* Allocno representing all thread. */
144 ira_allocno_t first_thread_allocno
;
145 /* Allocnos in thread forms a cycle list through the following
147 ira_allocno_t next_thread_allocno
;
148 /* All thread frequency. Defined only for first thread allocno. */
153 typedef struct allocno_color_data
*allocno_color_data_t
;
155 /* Container for storing allocno data concerning coloring. */
156 static allocno_color_data_t allocno_color_data
;
158 /* Macro to access the data concerning coloring. */
159 #define ALLOCNO_COLOR_DATA(a) ((allocno_color_data_t) ALLOCNO_ADD_DATA (a))
161 /* Used for finding allocno colorability to exclude repeated allocno
162 processing and for updating preferencing to exclude repeated
163 allocno processing during assignment. */
164 static int curr_allocno_process
;
166 /* This file contains code for regional graph coloring, spill/restore
167 code placement optimization, and code helping the reload pass to do
170 /* Bitmap of allocnos which should be colored. */
171 static bitmap coloring_allocno_bitmap
;
173 /* Bitmap of allocnos which should be taken into account during
174 coloring. In general case it contains allocnos from
175 coloring_allocno_bitmap plus other already colored conflicting
177 static bitmap consideration_allocno_bitmap
;
179 /* All allocnos sorted according their priorities. */
180 static ira_allocno_t
*sorted_allocnos
;
182 /* Vec representing the stack of allocnos used during coloring. */
183 static vec
<ira_allocno_t
> allocno_stack_vec
;
185 /* Helper for qsort comparison callbacks - return a positive integer if
186 X > Y, or a negative value otherwise. Use a conditional expression
187 instead of a difference computation to insulate from possible overflow
188 issues, e.g. X - Y < 0 for some X > 0 and Y < 0. */
189 #define SORTGT(x,y) (((x) > (y)) ? 1 : -1)
193 /* Definition of vector of allocno hard registers. */
195 /* Vector of unique allocno hard registers. */
196 static vec
<allocno_hard_regs_t
> allocno_hard_regs_vec
;
198 struct allocno_hard_regs_hasher
: nofree_ptr_hash
<allocno_hard_regs
>
200 static inline hashval_t
hash (const allocno_hard_regs
*);
201 static inline bool equal (const allocno_hard_regs
*,
202 const allocno_hard_regs
*);
205 /* Returns hash value for allocno hard registers V. */
207 allocno_hard_regs_hasher::hash (const allocno_hard_regs
*hv
)
209 return iterative_hash (&hv
->set
, sizeof (HARD_REG_SET
), 0);
212 /* Compares allocno hard registers V1 and V2. */
214 allocno_hard_regs_hasher::equal (const allocno_hard_regs
*hv1
,
215 const allocno_hard_regs
*hv2
)
217 return hard_reg_set_equal_p (hv1
->set
, hv2
->set
);
220 /* Hash table of unique allocno hard registers. */
221 static hash_table
<allocno_hard_regs_hasher
> *allocno_hard_regs_htab
;
223 /* Return allocno hard registers in the hash table equal to HV. */
224 static allocno_hard_regs_t
225 find_hard_regs (allocno_hard_regs_t hv
)
227 return allocno_hard_regs_htab
->find (hv
);
230 /* Insert allocno hard registers HV in the hash table (if it is not
231 there yet) and return the value which in the table. */
232 static allocno_hard_regs_t
233 insert_hard_regs (allocno_hard_regs_t hv
)
235 allocno_hard_regs
**slot
= allocno_hard_regs_htab
->find_slot (hv
, INSERT
);
242 /* Initialize data concerning allocno hard registers. */
244 init_allocno_hard_regs (void)
246 allocno_hard_regs_vec
.create (200);
247 allocno_hard_regs_htab
248 = new hash_table
<allocno_hard_regs_hasher
> (200);
251 /* Add (or update info about) allocno hard registers with SET and
253 static allocno_hard_regs_t
254 add_allocno_hard_regs (HARD_REG_SET set
, int64_t cost
)
256 struct allocno_hard_regs temp
;
257 allocno_hard_regs_t hv
;
259 gcc_assert (! hard_reg_set_empty_p (set
));
260 COPY_HARD_REG_SET (temp
.set
, set
);
261 if ((hv
= find_hard_regs (&temp
)) != NULL
)
265 hv
= ((struct allocno_hard_regs
*)
266 ira_allocate (sizeof (struct allocno_hard_regs
)));
267 COPY_HARD_REG_SET (hv
->set
, set
);
269 allocno_hard_regs_vec
.safe_push (hv
);
270 insert_hard_regs (hv
);
275 /* Finalize data concerning allocno hard registers. */
277 finish_allocno_hard_regs (void)
280 allocno_hard_regs_t hv
;
283 allocno_hard_regs_vec
.iterate (i
, &hv
);
286 delete allocno_hard_regs_htab
;
287 allocno_hard_regs_htab
= NULL
;
288 allocno_hard_regs_vec
.release ();
291 /* Sort hard regs according to their frequency of usage. */
293 allocno_hard_regs_compare (const void *v1p
, const void *v2p
)
295 allocno_hard_regs_t hv1
= *(const allocno_hard_regs_t
*) v1p
;
296 allocno_hard_regs_t hv2
= *(const allocno_hard_regs_t
*) v2p
;
298 if (hv2
->cost
> hv1
->cost
)
300 else if (hv2
->cost
< hv1
->cost
)
308 /* Used for finding a common ancestor of two allocno hard registers
309 nodes in the forest. We use the current value of
310 'node_check_tick' to mark all nodes from one node to the top and
311 then walking up from another node until we find a marked node.
313 It is also used to figure out allocno colorability as a mark that
314 we already reset value of member 'conflict_size' for the forest
315 node corresponding to the processed allocno. */
316 static int node_check_tick
;
318 /* Roots of the forest containing hard register sets can be assigned
320 static allocno_hard_regs_node_t hard_regs_roots
;
322 /* Definition of vector of allocno hard register nodes. */
324 /* Vector used to create the forest. */
325 static vec
<allocno_hard_regs_node_t
> hard_regs_node_vec
;
327 /* Create and return allocno hard registers node containing allocno
328 hard registers HV. */
329 static allocno_hard_regs_node_t
330 create_new_allocno_hard_regs_node (allocno_hard_regs_t hv
)
332 allocno_hard_regs_node_t new_node
;
334 new_node
= ((struct allocno_hard_regs_node
*)
335 ira_allocate (sizeof (struct allocno_hard_regs_node
)));
337 new_node
->hard_regs
= hv
;
338 new_node
->hard_regs_num
= hard_reg_set_size (hv
->set
);
339 new_node
->first
= NULL
;
340 new_node
->used_p
= false;
344 /* Add allocno hard registers node NEW_NODE to the forest on its level
347 add_new_allocno_hard_regs_node_to_forest (allocno_hard_regs_node_t
*roots
,
348 allocno_hard_regs_node_t new_node
)
350 new_node
->next
= *roots
;
351 if (new_node
->next
!= NULL
)
352 new_node
->next
->prev
= new_node
;
353 new_node
->prev
= NULL
;
357 /* Add allocno hard registers HV (or its best approximation if it is
358 not possible) to the forest on its level given by ROOTS. */
360 add_allocno_hard_regs_to_forest (allocno_hard_regs_node_t
*roots
,
361 allocno_hard_regs_t hv
)
363 unsigned int i
, start
;
364 allocno_hard_regs_node_t node
, prev
, new_node
;
365 HARD_REG_SET temp_set
;
366 allocno_hard_regs_t hv2
;
368 start
= hard_regs_node_vec
.length ();
369 for (node
= *roots
; node
!= NULL
; node
= node
->next
)
371 if (hard_reg_set_equal_p (hv
->set
, node
->hard_regs
->set
))
373 if (hard_reg_set_subset_p (hv
->set
, node
->hard_regs
->set
))
375 add_allocno_hard_regs_to_forest (&node
->first
, hv
);
378 if (hard_reg_set_subset_p (node
->hard_regs
->set
, hv
->set
))
379 hard_regs_node_vec
.safe_push (node
);
380 else if (hard_reg_set_intersect_p (hv
->set
, node
->hard_regs
->set
))
382 COPY_HARD_REG_SET (temp_set
, hv
->set
);
383 AND_HARD_REG_SET (temp_set
, node
->hard_regs
->set
);
384 hv2
= add_allocno_hard_regs (temp_set
, hv
->cost
);
385 add_allocno_hard_regs_to_forest (&node
->first
, hv2
);
388 if (hard_regs_node_vec
.length ()
391 /* Create a new node which contains nodes in hard_regs_node_vec. */
392 CLEAR_HARD_REG_SET (temp_set
);
394 i
< hard_regs_node_vec
.length ();
397 node
= hard_regs_node_vec
[i
];
398 IOR_HARD_REG_SET (temp_set
, node
->hard_regs
->set
);
400 hv
= add_allocno_hard_regs (temp_set
, hv
->cost
);
401 new_node
= create_new_allocno_hard_regs_node (hv
);
404 i
< hard_regs_node_vec
.length ();
407 node
= hard_regs_node_vec
[i
];
408 if (node
->prev
== NULL
)
411 node
->prev
->next
= node
->next
;
412 if (node
->next
!= NULL
)
413 node
->next
->prev
= node
->prev
;
415 new_node
->first
= node
;
422 add_new_allocno_hard_regs_node_to_forest (roots
, new_node
);
424 hard_regs_node_vec
.truncate (start
);
427 /* Add allocno hard registers nodes starting with the forest level
428 given by FIRST which contains biggest set inside SET. */
430 collect_allocno_hard_regs_cover (allocno_hard_regs_node_t first
,
433 allocno_hard_regs_node_t node
;
435 ira_assert (first
!= NULL
);
436 for (node
= first
; node
!= NULL
; node
= node
->next
)
437 if (hard_reg_set_subset_p (node
->hard_regs
->set
, set
))
438 hard_regs_node_vec
.safe_push (node
);
439 else if (hard_reg_set_intersect_p (set
, node
->hard_regs
->set
))
440 collect_allocno_hard_regs_cover (node
->first
, set
);
443 /* Set up field parent as PARENT in all allocno hard registers nodes
444 in forest given by FIRST. */
446 setup_allocno_hard_regs_nodes_parent (allocno_hard_regs_node_t first
,
447 allocno_hard_regs_node_t parent
)
449 allocno_hard_regs_node_t node
;
451 for (node
= first
; node
!= NULL
; node
= node
->next
)
453 node
->parent
= parent
;
454 setup_allocno_hard_regs_nodes_parent (node
->first
, node
);
458 /* Return allocno hard registers node which is a first common ancestor
459 node of FIRST and SECOND in the forest. */
460 static allocno_hard_regs_node_t
461 first_common_ancestor_node (allocno_hard_regs_node_t first
,
462 allocno_hard_regs_node_t second
)
464 allocno_hard_regs_node_t node
;
467 for (node
= first
; node
!= NULL
; node
= node
->parent
)
468 node
->check
= node_check_tick
;
469 for (node
= second
; node
!= NULL
; node
= node
->parent
)
470 if (node
->check
== node_check_tick
)
472 return first_common_ancestor_node (second
, first
);
475 /* Print hard reg set SET to F. */
477 print_hard_reg_set (FILE *f
, HARD_REG_SET set
, bool new_line_p
)
481 for (start
= -1, i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
483 if (TEST_HARD_REG_BIT (set
, i
))
485 if (i
== 0 || ! TEST_HARD_REG_BIT (set
, i
- 1))
489 && (i
== FIRST_PSEUDO_REGISTER
- 1 || ! TEST_HARD_REG_BIT (set
, i
)))
492 fprintf (f
, " %d", start
);
493 else if (start
== i
- 2)
494 fprintf (f
, " %d %d", start
, start
+ 1);
496 fprintf (f
, " %d-%d", start
, i
- 1);
504 /* Print allocno hard register subforest given by ROOTS and its LEVEL
507 print_hard_regs_subforest (FILE *f
, allocno_hard_regs_node_t roots
,
511 allocno_hard_regs_node_t node
;
513 for (node
= roots
; node
!= NULL
; node
= node
->next
)
516 for (i
= 0; i
< level
* 2; i
++)
518 fprintf (f
, "%d:(", node
->preorder_num
);
519 print_hard_reg_set (f
, node
->hard_regs
->set
, false);
520 fprintf (f
, ")@%" PRId64
"\n", node
->hard_regs
->cost
);
521 print_hard_regs_subforest (f
, node
->first
, level
+ 1);
525 /* Print the allocno hard register forest to F. */
527 print_hard_regs_forest (FILE *f
)
529 fprintf (f
, " Hard reg set forest:\n");
530 print_hard_regs_subforest (f
, hard_regs_roots
, 1);
533 /* Print the allocno hard register forest to stderr. */
535 ira_debug_hard_regs_forest (void)
537 print_hard_regs_forest (stderr
);
540 /* Remove unused allocno hard registers nodes from forest given by its
543 remove_unused_allocno_hard_regs_nodes (allocno_hard_regs_node_t
*roots
)
545 allocno_hard_regs_node_t node
, prev
, next
, last
;
547 for (prev
= NULL
, node
= *roots
; node
!= NULL
; node
= next
)
552 remove_unused_allocno_hard_regs_nodes (&node
->first
);
557 for (last
= node
->first
;
558 last
!= NULL
&& last
->next
!= NULL
;
564 *roots
= node
->first
;
566 prev
->next
= node
->first
;
586 /* Set up fields preorder_num starting with START_NUM in all allocno
587 hard registers nodes in forest given by FIRST. Return biggest set
588 PREORDER_NUM increased by 1. */
590 enumerate_allocno_hard_regs_nodes (allocno_hard_regs_node_t first
,
591 allocno_hard_regs_node_t parent
,
594 allocno_hard_regs_node_t node
;
596 for (node
= first
; node
!= NULL
; node
= node
->next
)
598 node
->preorder_num
= start_num
++;
599 node
->parent
= parent
;
600 start_num
= enumerate_allocno_hard_regs_nodes (node
->first
, node
,
606 /* Number of allocno hard registers nodes in the forest. */
607 static int allocno_hard_regs_nodes_num
;
609 /* Table preorder number of allocno hard registers node in the forest
610 -> the allocno hard registers node. */
611 static allocno_hard_regs_node_t
*allocno_hard_regs_nodes
;
614 typedef struct allocno_hard_regs_subnode
*allocno_hard_regs_subnode_t
;
616 /* The structure is used to describes all subnodes (not only immediate
617 ones) in the mentioned above tree for given allocno hard register
618 node. The usage of such data accelerates calculation of
619 colorability of given allocno. */
620 struct allocno_hard_regs_subnode
622 /* The conflict size of conflicting allocnos whose hard register
623 sets are equal sets (plus supersets if given node is given
624 allocno hard registers node) of one in the given node. */
625 int left_conflict_size
;
626 /* The summary conflict size of conflicting allocnos whose hard
627 register sets are strict subsets of one in the given node.
628 Overall conflict size is
629 left_conflict_subnodes_size
630 + MIN (max_node_impact - left_conflict_subnodes_size,
633 short left_conflict_subnodes_size
;
634 short max_node_impact
;
637 /* Container for hard regs subnodes of all allocnos. */
638 static allocno_hard_regs_subnode_t allocno_hard_regs_subnodes
;
640 /* Table (preorder number of allocno hard registers node in the
641 forest, preorder number of allocno hard registers subnode) -> index
642 of the subnode relative to the node. -1 if it is not a
644 static int *allocno_hard_regs_subnode_index
;
646 /* Setup arrays ALLOCNO_HARD_REGS_NODES and
647 ALLOCNO_HARD_REGS_SUBNODE_INDEX. */
649 setup_allocno_hard_regs_subnode_index (allocno_hard_regs_node_t first
)
651 allocno_hard_regs_node_t node
, parent
;
654 for (node
= first
; node
!= NULL
; node
= node
->next
)
656 allocno_hard_regs_nodes
[node
->preorder_num
] = node
;
657 for (parent
= node
; parent
!= NULL
; parent
= parent
->parent
)
659 index
= parent
->preorder_num
* allocno_hard_regs_nodes_num
;
660 allocno_hard_regs_subnode_index
[index
+ node
->preorder_num
]
661 = node
->preorder_num
- parent
->preorder_num
;
663 setup_allocno_hard_regs_subnode_index (node
->first
);
667 /* Count all allocno hard registers nodes in tree ROOT. */
669 get_allocno_hard_regs_subnodes_num (allocno_hard_regs_node_t root
)
673 for (root
= root
->first
; root
!= NULL
; root
= root
->next
)
674 len
+= get_allocno_hard_regs_subnodes_num (root
);
678 /* Build the forest of allocno hard registers nodes and assign each
679 allocno a node from the forest. */
681 form_allocno_hard_regs_nodes_forest (void)
683 unsigned int i
, j
, size
, len
;
686 allocno_hard_regs_t hv
;
689 allocno_hard_regs_node_t node
, allocno_hard_regs_node
;
690 allocno_color_data_t allocno_data
;
693 init_allocno_hard_regs ();
694 hard_regs_roots
= NULL
;
695 hard_regs_node_vec
.create (100);
696 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
697 if (! TEST_HARD_REG_BIT (ira_no_alloc_regs
, i
))
699 CLEAR_HARD_REG_SET (temp
);
700 SET_HARD_REG_BIT (temp
, i
);
701 hv
= add_allocno_hard_regs (temp
, 0);
702 node
= create_new_allocno_hard_regs_node (hv
);
703 add_new_allocno_hard_regs_node_to_forest (&hard_regs_roots
, node
);
705 start
= allocno_hard_regs_vec
.length ();
706 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap
, 0, i
, bi
)
709 allocno_data
= ALLOCNO_COLOR_DATA (a
);
711 if (hard_reg_set_empty_p (allocno_data
->profitable_hard_regs
))
713 hv
= (add_allocno_hard_regs
714 (allocno_data
->profitable_hard_regs
,
715 ALLOCNO_MEMORY_COST (a
) - ALLOCNO_CLASS_COST (a
)));
717 SET_HARD_REG_SET (temp
);
718 AND_COMPL_HARD_REG_SET (temp
, ira_no_alloc_regs
);
719 add_allocno_hard_regs (temp
, 0);
720 qsort (allocno_hard_regs_vec
.address () + start
,
721 allocno_hard_regs_vec
.length () - start
,
722 sizeof (allocno_hard_regs_t
), allocno_hard_regs_compare
);
724 allocno_hard_regs_vec
.iterate (i
, &hv
);
727 add_allocno_hard_regs_to_forest (&hard_regs_roots
, hv
);
728 ira_assert (hard_regs_node_vec
.length () == 0);
730 /* We need to set up parent fields for right work of
731 first_common_ancestor_node. */
732 setup_allocno_hard_regs_nodes_parent (hard_regs_roots
, NULL
);
733 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap
, 0, i
, bi
)
736 allocno_data
= ALLOCNO_COLOR_DATA (a
);
737 if (hard_reg_set_empty_p (allocno_data
->profitable_hard_regs
))
739 hard_regs_node_vec
.truncate (0);
740 collect_allocno_hard_regs_cover (hard_regs_roots
,
741 allocno_data
->profitable_hard_regs
);
742 allocno_hard_regs_node
= NULL
;
743 for (j
= 0; hard_regs_node_vec
.iterate (j
, &node
); j
++)
744 allocno_hard_regs_node
747 : first_common_ancestor_node (node
, allocno_hard_regs_node
));
748 /* That is a temporary storage. */
749 allocno_hard_regs_node
->used_p
= true;
750 allocno_data
->hard_regs_node
= allocno_hard_regs_node
;
752 ira_assert (hard_regs_roots
->next
== NULL
);
753 hard_regs_roots
->used_p
= true;
754 remove_unused_allocno_hard_regs_nodes (&hard_regs_roots
);
755 allocno_hard_regs_nodes_num
756 = enumerate_allocno_hard_regs_nodes (hard_regs_roots
, NULL
, 0);
757 allocno_hard_regs_nodes
758 = ((allocno_hard_regs_node_t
*)
759 ira_allocate (allocno_hard_regs_nodes_num
760 * sizeof (allocno_hard_regs_node_t
)));
761 size
= allocno_hard_regs_nodes_num
* allocno_hard_regs_nodes_num
;
762 allocno_hard_regs_subnode_index
763 = (int *) ira_allocate (size
* sizeof (int));
764 for (i
= 0; i
< size
; i
++)
765 allocno_hard_regs_subnode_index
[i
] = -1;
766 setup_allocno_hard_regs_subnode_index (hard_regs_roots
);
768 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap
, 0, i
, bi
)
771 allocno_data
= ALLOCNO_COLOR_DATA (a
);
772 if (hard_reg_set_empty_p (allocno_data
->profitable_hard_regs
))
774 len
= get_allocno_hard_regs_subnodes_num (allocno_data
->hard_regs_node
);
775 allocno_data
->hard_regs_subnodes_start
= start
;
776 allocno_data
->hard_regs_subnodes_num
= len
;
779 allocno_hard_regs_subnodes
780 = ((allocno_hard_regs_subnode_t
)
781 ira_allocate (sizeof (struct allocno_hard_regs_subnode
) * start
));
782 hard_regs_node_vec
.release ();
785 /* Free tree of allocno hard registers nodes given by its ROOT. */
787 finish_allocno_hard_regs_nodes_tree (allocno_hard_regs_node_t root
)
789 allocno_hard_regs_node_t child
, next
;
791 for (child
= root
->first
; child
!= NULL
; child
= next
)
794 finish_allocno_hard_regs_nodes_tree (child
);
799 /* Finish work with the forest of allocno hard registers nodes. */
801 finish_allocno_hard_regs_nodes_forest (void)
803 allocno_hard_regs_node_t node
, next
;
805 ira_free (allocno_hard_regs_subnodes
);
806 for (node
= hard_regs_roots
; node
!= NULL
; node
= next
)
809 finish_allocno_hard_regs_nodes_tree (node
);
811 ira_free (allocno_hard_regs_nodes
);
812 ira_free (allocno_hard_regs_subnode_index
);
813 finish_allocno_hard_regs ();
816 /* Set up left conflict sizes and left conflict subnodes sizes of hard
817 registers subnodes of allocno A. Return TRUE if allocno A is
818 trivially colorable. */
820 setup_left_conflict_sizes_p (ira_allocno_t a
)
822 int i
, k
, nobj
, start
;
823 int conflict_size
, left_conflict_subnodes_size
, node_preorder_num
;
824 allocno_color_data_t data
;
825 HARD_REG_SET profitable_hard_regs
;
826 allocno_hard_regs_subnode_t subnodes
;
827 allocno_hard_regs_node_t node
;
828 HARD_REG_SET node_set
;
830 nobj
= ALLOCNO_NUM_OBJECTS (a
);
831 data
= ALLOCNO_COLOR_DATA (a
);
832 subnodes
= allocno_hard_regs_subnodes
+ data
->hard_regs_subnodes_start
;
833 COPY_HARD_REG_SET (profitable_hard_regs
, data
->profitable_hard_regs
);
834 node
= data
->hard_regs_node
;
835 node_preorder_num
= node
->preorder_num
;
836 COPY_HARD_REG_SET (node_set
, node
->hard_regs
->set
);
838 for (k
= 0; k
< nobj
; k
++)
840 ira_object_t obj
= ALLOCNO_OBJECT (a
, k
);
841 ira_object_t conflict_obj
;
842 ira_object_conflict_iterator oci
;
844 FOR_EACH_OBJECT_CONFLICT (obj
, conflict_obj
, oci
)
847 ira_allocno_t conflict_a
= OBJECT_ALLOCNO (conflict_obj
);
848 allocno_hard_regs_node_t conflict_node
, temp_node
;
849 HARD_REG_SET conflict_node_set
;
850 allocno_color_data_t conflict_data
;
852 conflict_data
= ALLOCNO_COLOR_DATA (conflict_a
);
853 if (! ALLOCNO_COLOR_DATA (conflict_a
)->in_graph_p
854 || ! hard_reg_set_intersect_p (profitable_hard_regs
,
856 ->profitable_hard_regs
))
858 conflict_node
= conflict_data
->hard_regs_node
;
859 COPY_HARD_REG_SET (conflict_node_set
, conflict_node
->hard_regs
->set
);
860 if (hard_reg_set_subset_p (node_set
, conflict_node_set
))
864 ira_assert (hard_reg_set_subset_p (conflict_node_set
, node_set
));
865 temp_node
= conflict_node
;
867 if (temp_node
->check
!= node_check_tick
)
869 temp_node
->check
= node_check_tick
;
870 temp_node
->conflict_size
= 0;
872 size
= (ira_reg_class_max_nregs
873 [ALLOCNO_CLASS (conflict_a
)][ALLOCNO_MODE (conflict_a
)]);
874 if (ALLOCNO_NUM_OBJECTS (conflict_a
) > 1)
875 /* We will deal with the subwords individually. */
877 temp_node
->conflict_size
+= size
;
880 for (i
= 0; i
< data
->hard_regs_subnodes_num
; i
++)
882 allocno_hard_regs_node_t temp_node
;
884 temp_node
= allocno_hard_regs_nodes
[i
+ node_preorder_num
];
885 ira_assert (temp_node
->preorder_num
== i
+ node_preorder_num
);
886 subnodes
[i
].left_conflict_size
= (temp_node
->check
!= node_check_tick
887 ? 0 : temp_node
->conflict_size
);
888 if (hard_reg_set_subset_p (temp_node
->hard_regs
->set
,
889 profitable_hard_regs
))
890 subnodes
[i
].max_node_impact
= temp_node
->hard_regs_num
;
893 HARD_REG_SET temp_set
;
894 int j
, n
, hard_regno
;
895 enum reg_class aclass
;
897 COPY_HARD_REG_SET (temp_set
, temp_node
->hard_regs
->set
);
898 AND_HARD_REG_SET (temp_set
, profitable_hard_regs
);
899 aclass
= ALLOCNO_CLASS (a
);
900 for (n
= 0, j
= ira_class_hard_regs_num
[aclass
] - 1; j
>= 0; j
--)
902 hard_regno
= ira_class_hard_regs
[aclass
][j
];
903 if (TEST_HARD_REG_BIT (temp_set
, hard_regno
))
906 subnodes
[i
].max_node_impact
= n
;
908 subnodes
[i
].left_conflict_subnodes_size
= 0;
910 start
= node_preorder_num
* allocno_hard_regs_nodes_num
;
911 for (i
= data
->hard_regs_subnodes_num
- 1; i
> 0; i
--)
914 allocno_hard_regs_node_t parent
;
916 size
= (subnodes
[i
].left_conflict_subnodes_size
917 + MIN (subnodes
[i
].max_node_impact
918 - subnodes
[i
].left_conflict_subnodes_size
,
919 subnodes
[i
].left_conflict_size
));
920 parent
= allocno_hard_regs_nodes
[i
+ node_preorder_num
]->parent
;
921 gcc_checking_assert(parent
);
923 = allocno_hard_regs_subnode_index
[start
+ parent
->preorder_num
];
924 gcc_checking_assert(parent_i
>= 0);
925 subnodes
[parent_i
].left_conflict_subnodes_size
+= size
;
927 left_conflict_subnodes_size
= subnodes
[0].left_conflict_subnodes_size
;
929 = (left_conflict_subnodes_size
930 + MIN (subnodes
[0].max_node_impact
- left_conflict_subnodes_size
,
931 subnodes
[0].left_conflict_size
));
932 conflict_size
+= ira_reg_class_max_nregs
[ALLOCNO_CLASS (a
)][ALLOCNO_MODE (a
)];
933 data
->colorable_p
= conflict_size
<= data
->available_regs_num
;
934 return data
->colorable_p
;
937 /* Update left conflict sizes of hard registers subnodes of allocno A
938 after removing allocno REMOVED_A with SIZE from the conflict graph.
939 Return TRUE if A is trivially colorable. */
941 update_left_conflict_sizes_p (ira_allocno_t a
,
942 ira_allocno_t removed_a
, int size
)
944 int i
, conflict_size
, before_conflict_size
, diff
, start
;
945 int node_preorder_num
, parent_i
;
946 allocno_hard_regs_node_t node
, removed_node
, parent
;
947 allocno_hard_regs_subnode_t subnodes
;
948 allocno_color_data_t data
= ALLOCNO_COLOR_DATA (a
);
950 ira_assert (! data
->colorable_p
);
951 node
= data
->hard_regs_node
;
952 node_preorder_num
= node
->preorder_num
;
953 removed_node
= ALLOCNO_COLOR_DATA (removed_a
)->hard_regs_node
;
954 ira_assert (hard_reg_set_subset_p (removed_node
->hard_regs
->set
,
955 node
->hard_regs
->set
)
956 || hard_reg_set_subset_p (node
->hard_regs
->set
,
957 removed_node
->hard_regs
->set
));
958 start
= node_preorder_num
* allocno_hard_regs_nodes_num
;
959 i
= allocno_hard_regs_subnode_index
[start
+ removed_node
->preorder_num
];
962 subnodes
= allocno_hard_regs_subnodes
+ data
->hard_regs_subnodes_start
;
964 = (subnodes
[i
].left_conflict_subnodes_size
965 + MIN (subnodes
[i
].max_node_impact
966 - subnodes
[i
].left_conflict_subnodes_size
,
967 subnodes
[i
].left_conflict_size
));
968 subnodes
[i
].left_conflict_size
-= size
;
972 = (subnodes
[i
].left_conflict_subnodes_size
973 + MIN (subnodes
[i
].max_node_impact
974 - subnodes
[i
].left_conflict_subnodes_size
,
975 subnodes
[i
].left_conflict_size
));
976 if ((diff
= before_conflict_size
- conflict_size
) == 0)
978 ira_assert (conflict_size
< before_conflict_size
);
979 parent
= allocno_hard_regs_nodes
[i
+ node_preorder_num
]->parent
;
983 = allocno_hard_regs_subnode_index
[start
+ parent
->preorder_num
];
988 = (subnodes
[i
].left_conflict_subnodes_size
989 + MIN (subnodes
[i
].max_node_impact
990 - subnodes
[i
].left_conflict_subnodes_size
,
991 subnodes
[i
].left_conflict_size
));
992 subnodes
[i
].left_conflict_subnodes_size
-= diff
;
996 + ira_reg_class_max_nregs
[ALLOCNO_CLASS (a
)][ALLOCNO_MODE (a
)]
997 > data
->available_regs_num
))
999 data
->colorable_p
= true;
1003 /* Return true if allocno A has empty profitable hard regs. */
1005 empty_profitable_hard_regs (ira_allocno_t a
)
1007 allocno_color_data_t data
= ALLOCNO_COLOR_DATA (a
);
1009 return hard_reg_set_empty_p (data
->profitable_hard_regs
);
1012 /* Set up profitable hard registers for each allocno being
1015 setup_profitable_hard_regs (void)
1018 int j
, k
, nobj
, hard_regno
, nregs
, class_size
;
1021 enum reg_class aclass
;
1023 allocno_color_data_t data
;
1025 /* Initial set up from allocno classes and explicitly conflicting
1027 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap
, 0, i
, bi
)
1029 a
= ira_allocnos
[i
];
1030 if ((aclass
= ALLOCNO_CLASS (a
)) == NO_REGS
)
1032 data
= ALLOCNO_COLOR_DATA (a
);
1033 if (ALLOCNO_UPDATED_HARD_REG_COSTS (a
) == NULL
1034 && ALLOCNO_CLASS_COST (a
) > ALLOCNO_MEMORY_COST (a
)
1035 /* Do not empty profitable regs for static chain pointer
1036 pseudo when non-local goto is used. */
1037 && ! non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a
)))
1038 CLEAR_HARD_REG_SET (data
->profitable_hard_regs
);
1041 mode
= ALLOCNO_MODE (a
);
1042 COPY_HARD_REG_SET (data
->profitable_hard_regs
,
1043 ira_useful_class_mode_regs
[aclass
][mode
]);
1044 nobj
= ALLOCNO_NUM_OBJECTS (a
);
1045 for (k
= 0; k
< nobj
; k
++)
1047 ira_object_t obj
= ALLOCNO_OBJECT (a
, k
);
1049 AND_COMPL_HARD_REG_SET (data
->profitable_hard_regs
,
1050 OBJECT_TOTAL_CONFLICT_HARD_REGS (obj
));
1054 /* Exclude hard regs already assigned for conflicting objects. */
1055 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap
, 0, i
, bi
)
1057 a
= ira_allocnos
[i
];
1058 if ((aclass
= ALLOCNO_CLASS (a
)) == NO_REGS
1059 || ! ALLOCNO_ASSIGNED_P (a
)
1060 || (hard_regno
= ALLOCNO_HARD_REGNO (a
)) < 0)
1062 mode
= ALLOCNO_MODE (a
);
1063 nregs
= hard_regno_nregs
[hard_regno
][mode
];
1064 nobj
= ALLOCNO_NUM_OBJECTS (a
);
1065 for (k
= 0; k
< nobj
; k
++)
1067 ira_object_t obj
= ALLOCNO_OBJECT (a
, k
);
1068 ira_object_t conflict_obj
;
1069 ira_object_conflict_iterator oci
;
1071 FOR_EACH_OBJECT_CONFLICT (obj
, conflict_obj
, oci
)
1073 ira_allocno_t conflict_a
= OBJECT_ALLOCNO (conflict_obj
);
1075 /* We can process the conflict allocno repeatedly with
1077 if (nregs
== nobj
&& nregs
> 1)
1079 int num
= OBJECT_SUBWORD (conflict_obj
);
1081 if (REG_WORDS_BIG_ENDIAN
)
1083 (ALLOCNO_COLOR_DATA (conflict_a
)->profitable_hard_regs
,
1084 hard_regno
+ nobj
- num
- 1);
1087 (ALLOCNO_COLOR_DATA (conflict_a
)->profitable_hard_regs
,
1091 AND_COMPL_HARD_REG_SET
1092 (ALLOCNO_COLOR_DATA (conflict_a
)->profitable_hard_regs
,
1093 ira_reg_mode_hard_regset
[hard_regno
][mode
]);
1097 /* Exclude too costly hard regs. */
1098 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap
, 0, i
, bi
)
1100 int min_cost
= INT_MAX
;
1103 a
= ira_allocnos
[i
];
1104 if ((aclass
= ALLOCNO_CLASS (a
)) == NO_REGS
1105 || empty_profitable_hard_regs (a
))
1107 data
= ALLOCNO_COLOR_DATA (a
);
1108 mode
= ALLOCNO_MODE (a
);
1109 if ((costs
= ALLOCNO_UPDATED_HARD_REG_COSTS (a
)) != NULL
1110 || (costs
= ALLOCNO_HARD_REG_COSTS (a
)) != NULL
)
1112 class_size
= ira_class_hard_regs_num
[aclass
];
1113 for (j
= 0; j
< class_size
; j
++)
1115 hard_regno
= ira_class_hard_regs
[aclass
][j
];
1116 if (! TEST_HARD_REG_BIT (data
->profitable_hard_regs
,
1119 if (ALLOCNO_UPDATED_MEMORY_COST (a
) < costs
[j
]
1120 /* Do not remove HARD_REGNO for static chain pointer
1121 pseudo when non-local goto is used. */
1122 && ! non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a
)))
1123 CLEAR_HARD_REG_BIT (data
->profitable_hard_regs
,
1125 else if (min_cost
> costs
[j
])
1126 min_cost
= costs
[j
];
1129 else if (ALLOCNO_UPDATED_MEMORY_COST (a
)
1130 < ALLOCNO_UPDATED_CLASS_COST (a
)
1131 /* Do not empty profitable regs for static chain
1132 pointer pseudo when non-local goto is used. */
1133 && ! non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a
)))
1134 CLEAR_HARD_REG_SET (data
->profitable_hard_regs
);
1135 if (ALLOCNO_UPDATED_CLASS_COST (a
) > min_cost
)
1136 ALLOCNO_UPDATED_CLASS_COST (a
) = min_cost
;
1142 /* This page contains functions used to choose hard registers for
1145 /* Pool for update cost records. */
1146 static object_allocator
<update_cost_record
> update_cost_record_pool
1147 ("update cost records");
1149 /* Return new update cost record with given params. */
1150 static struct update_cost_record
*
1151 get_update_cost_record (int hard_regno
, int divisor
,
1152 struct update_cost_record
*next
)
1154 struct update_cost_record
*record
;
1156 record
= update_cost_record_pool
.allocate ();
1157 record
->hard_regno
= hard_regno
;
1158 record
->divisor
= divisor
;
1159 record
->next
= next
;
1163 /* Free memory for all records in LIST. */
1165 free_update_cost_record_list (struct update_cost_record
*list
)
1167 struct update_cost_record
*next
;
1169 while (list
!= NULL
)
1172 update_cost_record_pool
.remove (list
);
1177 /* Free memory allocated for all update cost records. */
1179 finish_update_cost_records (void)
1181 update_cost_record_pool
.release ();
1184 /* Array whose element value is TRUE if the corresponding hard
1185 register was already allocated for an allocno. */
1186 static bool allocated_hardreg_p
[FIRST_PSEUDO_REGISTER
];
1188 /* Describes one element in a queue of allocnos whose costs need to be
1189 updated. Each allocno in the queue is known to have an allocno
1191 struct update_cost_queue_elem
1193 /* This element is in the queue iff CHECK == update_cost_check. */
1196 /* COST_HOP_DIVISOR**N, where N is the length of the shortest path
1197 connecting this allocno to the one being allocated. */
1200 /* Allocno from which we are chaining costs of connected allocnos.
1201 It is used not go back in graph of allocnos connected by
1205 /* The next allocno in the queue, or null if this is the last element. */
1209 /* The first element in a queue of allocnos whose copy costs need to be
1210 updated. Null if the queue is empty. */
1211 static ira_allocno_t update_cost_queue
;
1213 /* The last element in the queue described by update_cost_queue.
1214 Not valid if update_cost_queue is null. */
1215 static struct update_cost_queue_elem
*update_cost_queue_tail
;
1217 /* A pool of elements in the queue described by update_cost_queue.
1218 Elements are indexed by ALLOCNO_NUM. */
1219 static struct update_cost_queue_elem
*update_cost_queue_elems
;
1221 /* The current value of update_costs_from_copies call count. */
1222 static int update_cost_check
;
1224 /* Allocate and initialize data necessary for function
1225 update_costs_from_copies. */
1227 initiate_cost_update (void)
1231 size
= ira_allocnos_num
* sizeof (struct update_cost_queue_elem
);
1232 update_cost_queue_elems
1233 = (struct update_cost_queue_elem
*) ira_allocate (size
);
1234 memset (update_cost_queue_elems
, 0, size
);
1235 update_cost_check
= 0;
1238 /* Deallocate data used by function update_costs_from_copies. */
1240 finish_cost_update (void)
1242 ira_free (update_cost_queue_elems
);
1243 finish_update_cost_records ();
1246 /* When we traverse allocnos to update hard register costs, the cost
1247 divisor will be multiplied by the following macro value for each
1248 hop from given allocno to directly connected allocnos. */
1249 #define COST_HOP_DIVISOR 4
1251 /* Start a new cost-updating pass. */
1253 start_update_cost (void)
1255 update_cost_check
++;
1256 update_cost_queue
= NULL
;
1259 /* Add (ALLOCNO, FROM, DIVISOR) to the end of update_cost_queue, unless
1260 ALLOCNO is already in the queue, or has NO_REGS class. */
1262 queue_update_cost (ira_allocno_t allocno
, ira_allocno_t from
, int divisor
)
1264 struct update_cost_queue_elem
*elem
;
1266 elem
= &update_cost_queue_elems
[ALLOCNO_NUM (allocno
)];
1267 if (elem
->check
!= update_cost_check
1268 && ALLOCNO_CLASS (allocno
) != NO_REGS
)
1270 elem
->check
= update_cost_check
;
1272 elem
->divisor
= divisor
;
1274 if (update_cost_queue
== NULL
)
1275 update_cost_queue
= allocno
;
1277 update_cost_queue_tail
->next
= allocno
;
1278 update_cost_queue_tail
= elem
;
1282 /* Try to remove the first element from update_cost_queue. Return
1283 false if the queue was empty, otherwise make (*ALLOCNO, *FROM,
1284 *DIVISOR) describe the removed element. */
1286 get_next_update_cost (ira_allocno_t
*allocno
, ira_allocno_t
*from
, int *divisor
)
1288 struct update_cost_queue_elem
*elem
;
1290 if (update_cost_queue
== NULL
)
1293 *allocno
= update_cost_queue
;
1294 elem
= &update_cost_queue_elems
[ALLOCNO_NUM (*allocno
)];
1296 *divisor
= elem
->divisor
;
1297 update_cost_queue
= elem
->next
;
1301 /* Increase costs of HARD_REGNO by UPDATE_COST and conflict cost by
1302 UPDATE_CONFLICT_COST for ALLOCNO. Return true if we really
1303 modified the cost. */
1305 update_allocno_cost (ira_allocno_t allocno
, int hard_regno
,
1306 int update_cost
, int update_conflict_cost
)
1309 enum reg_class aclass
= ALLOCNO_CLASS (allocno
);
1311 i
= ira_class_hard_reg_index
[aclass
][hard_regno
];
1314 ira_allocate_and_set_or_copy_costs
1315 (&ALLOCNO_UPDATED_HARD_REG_COSTS (allocno
), aclass
,
1316 ALLOCNO_UPDATED_CLASS_COST (allocno
),
1317 ALLOCNO_HARD_REG_COSTS (allocno
));
1318 ira_allocate_and_set_or_copy_costs
1319 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (allocno
),
1320 aclass
, 0, ALLOCNO_CONFLICT_HARD_REG_COSTS (allocno
));
1321 ALLOCNO_UPDATED_HARD_REG_COSTS (allocno
)[i
] += update_cost
;
1322 ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (allocno
)[i
] += update_conflict_cost
;
1326 /* Update (decrease if DECR_P) HARD_REGNO cost of allocnos connected
1327 by copies to ALLOCNO to increase chances to remove some copies as
1328 the result of subsequent assignment. Record cost updates if
1329 RECORD_P is true. */
1331 update_costs_from_allocno (ira_allocno_t allocno
, int hard_regno
,
1332 int divisor
, bool decr_p
, bool record_p
)
1334 int cost
, update_cost
, update_conflict_cost
;
1336 enum reg_class rclass
, aclass
;
1337 ira_allocno_t another_allocno
, from
= NULL
;
1338 ira_copy_t cp
, next_cp
;
1340 rclass
= REGNO_REG_CLASS (hard_regno
);
1343 mode
= ALLOCNO_MODE (allocno
);
1344 ira_init_register_move_cost_if_necessary (mode
);
1345 for (cp
= ALLOCNO_COPIES (allocno
); cp
!= NULL
; cp
= next_cp
)
1347 if (cp
->first
== allocno
)
1349 next_cp
= cp
->next_first_allocno_copy
;
1350 another_allocno
= cp
->second
;
1352 else if (cp
->second
== allocno
)
1354 next_cp
= cp
->next_second_allocno_copy
;
1355 another_allocno
= cp
->first
;
1360 if (another_allocno
== from
)
1363 aclass
= ALLOCNO_CLASS (another_allocno
);
1364 if (! TEST_HARD_REG_BIT (reg_class_contents
[aclass
],
1366 || ALLOCNO_ASSIGNED_P (another_allocno
))
1369 cost
= (cp
->second
== allocno
1370 ? ira_register_move_cost
[mode
][rclass
][aclass
]
1371 : ira_register_move_cost
[mode
][aclass
][rclass
]);
1375 update_conflict_cost
= update_cost
= cp
->freq
* cost
/ divisor
;
1377 if (ALLOCNO_COLOR_DATA (another_allocno
) != NULL
1378 && (ALLOCNO_COLOR_DATA (allocno
)->first_thread_allocno
1379 != ALLOCNO_COLOR_DATA (another_allocno
)->first_thread_allocno
))
1380 /* Decrease conflict cost of ANOTHER_ALLOCNO if it is not
1381 in the same allocation thread. */
1382 update_conflict_cost
/= COST_HOP_DIVISOR
;
1384 if (update_cost
== 0)
1387 if (! update_allocno_cost (another_allocno
, hard_regno
,
1388 update_cost
, update_conflict_cost
))
1390 queue_update_cost (another_allocno
, allocno
, divisor
* COST_HOP_DIVISOR
);
1391 if (record_p
&& ALLOCNO_COLOR_DATA (another_allocno
) != NULL
)
1392 ALLOCNO_COLOR_DATA (another_allocno
)->update_cost_records
1393 = get_update_cost_record (hard_regno
, divisor
,
1394 ALLOCNO_COLOR_DATA (another_allocno
)
1395 ->update_cost_records
);
1398 while (get_next_update_cost (&allocno
, &from
, &divisor
));
1401 /* Decrease preferred ALLOCNO hard register costs and costs of
1402 allocnos connected to ALLOCNO through copy. */
1404 update_costs_from_prefs (ira_allocno_t allocno
)
1408 start_update_cost ();
1409 for (pref
= ALLOCNO_PREFS (allocno
); pref
!= NULL
; pref
= pref
->next_pref
)
1410 update_costs_from_allocno (allocno
, pref
->hard_regno
,
1411 COST_HOP_DIVISOR
, true, true);
1414 /* Update (decrease if DECR_P) the cost of allocnos connected to
1415 ALLOCNO through copies to increase chances to remove some copies as
1416 the result of subsequent assignment. ALLOCNO was just assigned to
1417 a hard register. Record cost updates if RECORD_P is true. */
1419 update_costs_from_copies (ira_allocno_t allocno
, bool decr_p
, bool record_p
)
1423 hard_regno
= ALLOCNO_HARD_REGNO (allocno
);
1424 ira_assert (hard_regno
>= 0 && ALLOCNO_CLASS (allocno
) != NO_REGS
);
1425 start_update_cost ();
1426 update_costs_from_allocno (allocno
, hard_regno
, 1, decr_p
, record_p
);
1429 /* Restore costs of allocnos connected to ALLOCNO by copies as it was
1430 before updating costs of these allocnos from given allocno. This
1431 is a wise thing to do as if given allocno did not get an expected
1432 hard reg, using smaller cost of the hard reg for allocnos connected
1433 by copies to given allocno becomes actually misleading. Free all
1434 update cost records for ALLOCNO as we don't need them anymore. */
1436 restore_costs_from_copies (ira_allocno_t allocno
)
1438 struct update_cost_record
*records
, *curr
;
1440 if (ALLOCNO_COLOR_DATA (allocno
) == NULL
)
1442 records
= ALLOCNO_COLOR_DATA (allocno
)->update_cost_records
;
1443 start_update_cost ();
1444 for (curr
= records
; curr
!= NULL
; curr
= curr
->next
)
1445 update_costs_from_allocno (allocno
, curr
->hard_regno
,
1446 curr
->divisor
, true, false);
1447 free_update_cost_record_list (records
);
1448 ALLOCNO_COLOR_DATA (allocno
)->update_cost_records
= NULL
;
1451 /* This function updates COSTS (decrease if DECR_P) for hard_registers
1452 of ACLASS by conflict costs of the unassigned allocnos
1453 connected by copies with allocnos in update_cost_queue. This
1454 update increases chances to remove some copies. */
1456 update_conflict_hard_regno_costs (int *costs
, enum reg_class aclass
,
1459 int i
, cost
, class_size
, freq
, mult
, div
, divisor
;
1460 int index
, hard_regno
;
1461 int *conflict_costs
;
1463 enum reg_class another_aclass
;
1464 ira_allocno_t allocno
, another_allocno
, from
;
1465 ira_copy_t cp
, next_cp
;
1467 while (get_next_update_cost (&allocno
, &from
, &divisor
))
1468 for (cp
= ALLOCNO_COPIES (allocno
); cp
!= NULL
; cp
= next_cp
)
1470 if (cp
->first
== allocno
)
1472 next_cp
= cp
->next_first_allocno_copy
;
1473 another_allocno
= cp
->second
;
1475 else if (cp
->second
== allocno
)
1477 next_cp
= cp
->next_second_allocno_copy
;
1478 another_allocno
= cp
->first
;
1483 if (another_allocno
== from
)
1486 another_aclass
= ALLOCNO_CLASS (another_allocno
);
1487 if (! ira_reg_classes_intersect_p
[aclass
][another_aclass
]
1488 || ALLOCNO_ASSIGNED_P (another_allocno
)
1489 || ALLOCNO_COLOR_DATA (another_allocno
)->may_be_spilled_p
)
1491 class_size
= ira_class_hard_regs_num
[another_aclass
];
1492 ira_allocate_and_copy_costs
1493 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (another_allocno
),
1494 another_aclass
, ALLOCNO_CONFLICT_HARD_REG_COSTS (another_allocno
));
1496 = ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (another_allocno
);
1497 if (conflict_costs
== NULL
)
1502 freq
= ALLOCNO_FREQ (another_allocno
);
1505 div
= freq
* divisor
;
1507 for (i
= class_size
- 1; i
>= 0; i
--)
1509 hard_regno
= ira_class_hard_regs
[another_aclass
][i
];
1510 ira_assert (hard_regno
>= 0);
1511 index
= ira_class_hard_reg_index
[aclass
][hard_regno
];
1514 cost
= (int) ((unsigned) conflict_costs
[i
] * mult
) / div
;
1520 costs
[index
] += cost
;
1523 /* Probably 5 hops will be enough. */
1525 && divisor
<= (COST_HOP_DIVISOR
1528 * COST_HOP_DIVISOR
))
1529 queue_update_cost (another_allocno
, allocno
, divisor
* COST_HOP_DIVISOR
);
1533 /* Set up conflicting (through CONFLICT_REGS) for each object of
1534 allocno A and the start allocno profitable regs (through
1535 START_PROFITABLE_REGS). Remember that the start profitable regs
1536 exclude hard regs which can not hold value of mode of allocno A.
1537 This covers mostly cases when multi-register value should be
1540 get_conflict_and_start_profitable_regs (ira_allocno_t a
, bool retry_p
,
1541 HARD_REG_SET
*conflict_regs
,
1542 HARD_REG_SET
*start_profitable_regs
)
1547 nwords
= ALLOCNO_NUM_OBJECTS (a
);
1548 for (i
= 0; i
< nwords
; i
++)
1550 obj
= ALLOCNO_OBJECT (a
, i
);
1551 COPY_HARD_REG_SET (conflict_regs
[i
],
1552 OBJECT_TOTAL_CONFLICT_HARD_REGS (obj
));
1556 COPY_HARD_REG_SET (*start_profitable_regs
,
1557 reg_class_contents
[ALLOCNO_CLASS (a
)]);
1558 AND_COMPL_HARD_REG_SET (*start_profitable_regs
,
1559 ira_prohibited_class_mode_regs
1560 [ALLOCNO_CLASS (a
)][ALLOCNO_MODE (a
)]);
1563 COPY_HARD_REG_SET (*start_profitable_regs
,
1564 ALLOCNO_COLOR_DATA (a
)->profitable_hard_regs
);
1567 /* Return true if HARD_REGNO is ok for assigning to allocno A with
1568 PROFITABLE_REGS and whose objects have CONFLICT_REGS. */
1570 check_hard_reg_p (ira_allocno_t a
, int hard_regno
,
1571 HARD_REG_SET
*conflict_regs
, HARD_REG_SET profitable_regs
)
1573 int j
, nwords
, nregs
;
1574 enum reg_class aclass
;
1577 aclass
= ALLOCNO_CLASS (a
);
1578 mode
= ALLOCNO_MODE (a
);
1579 if (TEST_HARD_REG_BIT (ira_prohibited_class_mode_regs
[aclass
][mode
],
1582 /* Checking only profitable hard regs. */
1583 if (! TEST_HARD_REG_BIT (profitable_regs
, hard_regno
))
1585 nregs
= hard_regno_nregs
[hard_regno
][mode
];
1586 nwords
= ALLOCNO_NUM_OBJECTS (a
);
1587 for (j
= 0; j
< nregs
; j
++)
1590 int set_to_test_start
= 0, set_to_test_end
= nwords
;
1592 if (nregs
== nwords
)
1594 if (REG_WORDS_BIG_ENDIAN
)
1595 set_to_test_start
= nwords
- j
- 1;
1597 set_to_test_start
= j
;
1598 set_to_test_end
= set_to_test_start
+ 1;
1600 for (k
= set_to_test_start
; k
< set_to_test_end
; k
++)
1601 if (TEST_HARD_REG_BIT (conflict_regs
[k
], hard_regno
+ j
))
1603 if (k
!= set_to_test_end
)
1609 /* Return number of registers needed to be saved and restored at
1610 function prologue/epilogue if we allocate HARD_REGNO to hold value
1613 calculate_saved_nregs (int hard_regno
, machine_mode mode
)
1618 ira_assert (hard_regno
>= 0);
1619 for (i
= hard_regno_nregs
[hard_regno
][mode
] - 1; i
>= 0; i
--)
1620 if (!allocated_hardreg_p
[hard_regno
+ i
]
1621 && !TEST_HARD_REG_BIT (call_used_reg_set
, hard_regno
+ i
)
1622 && !LOCAL_REGNO (hard_regno
+ i
))
1627 /* Choose a hard register for allocno A. If RETRY_P is TRUE, it means
1628 that the function called from function
1629 `ira_reassign_conflict_allocnos' and `allocno_reload_assign'. In
1630 this case some allocno data are not defined or updated and we
1631 should not touch these data. The function returns true if we
1632 managed to assign a hard register to the allocno.
1634 To assign a hard register, first of all we calculate all conflict
1635 hard registers which can come from conflicting allocnos with
1636 already assigned hard registers. After that we find first free
1637 hard register with the minimal cost. During hard register cost
1638 calculation we take conflict hard register costs into account to
1639 give a chance for conflicting allocnos to get a better hard
1640 register in the future.
1642 If the best hard register cost is bigger than cost of memory usage
1643 for the allocno, we don't assign a hard register to given allocno
1646 If we assign a hard register to the allocno, we update costs of the
1647 hard register for allocnos connected by copies to improve a chance
1648 to coalesce insns represented by the copies when we assign hard
1649 registers to the allocnos connected by the copies. */
1651 assign_hard_reg (ira_allocno_t a
, bool retry_p
)
1653 HARD_REG_SET conflicting_regs
[2], profitable_hard_regs
;
1654 int i
, j
, hard_regno
, best_hard_regno
, class_size
;
1655 int cost
, mem_cost
, min_cost
, full_cost
, min_full_cost
, nwords
, word
;
1657 enum reg_class aclass
;
1659 static int costs
[FIRST_PSEUDO_REGISTER
], full_costs
[FIRST_PSEUDO_REGISTER
];
1661 enum reg_class rclass
;
1664 bool no_stack_reg_p
;
1667 ira_assert (! ALLOCNO_ASSIGNED_P (a
));
1668 get_conflict_and_start_profitable_regs (a
, retry_p
,
1670 &profitable_hard_regs
);
1671 aclass
= ALLOCNO_CLASS (a
);
1672 class_size
= ira_class_hard_regs_num
[aclass
];
1673 best_hard_regno
= -1;
1674 memset (full_costs
, 0, sizeof (int) * class_size
);
1676 memset (costs
, 0, sizeof (int) * class_size
);
1677 memset (full_costs
, 0, sizeof (int) * class_size
);
1679 no_stack_reg_p
= false;
1682 start_update_cost ();
1683 mem_cost
+= ALLOCNO_UPDATED_MEMORY_COST (a
);
1685 ira_allocate_and_copy_costs (&ALLOCNO_UPDATED_HARD_REG_COSTS (a
),
1686 aclass
, ALLOCNO_HARD_REG_COSTS (a
));
1687 a_costs
= ALLOCNO_UPDATED_HARD_REG_COSTS (a
);
1689 no_stack_reg_p
= no_stack_reg_p
|| ALLOCNO_TOTAL_NO_STACK_REG_P (a
);
1691 cost
= ALLOCNO_UPDATED_CLASS_COST (a
);
1692 for (i
= 0; i
< class_size
; i
++)
1693 if (a_costs
!= NULL
)
1695 costs
[i
] += a_costs
[i
];
1696 full_costs
[i
] += a_costs
[i
];
1701 full_costs
[i
] += cost
;
1703 nwords
= ALLOCNO_NUM_OBJECTS (a
);
1704 curr_allocno_process
++;
1705 for (word
= 0; word
< nwords
; word
++)
1707 ira_object_t conflict_obj
;
1708 ira_object_t obj
= ALLOCNO_OBJECT (a
, word
);
1709 ira_object_conflict_iterator oci
;
1711 /* Take preferences of conflicting allocnos into account. */
1712 FOR_EACH_OBJECT_CONFLICT (obj
, conflict_obj
, oci
)
1714 ira_allocno_t conflict_a
= OBJECT_ALLOCNO (conflict_obj
);
1715 enum reg_class conflict_aclass
;
1716 allocno_color_data_t data
= ALLOCNO_COLOR_DATA (conflict_a
);
1718 /* Reload can give another class so we need to check all
1721 && ((!ALLOCNO_ASSIGNED_P (conflict_a
)
1722 || ALLOCNO_HARD_REGNO (conflict_a
) < 0)
1723 && !(hard_reg_set_intersect_p
1724 (profitable_hard_regs
,
1726 (conflict_a
)->profitable_hard_regs
))))
1728 /* All conflict allocnos are in consideration bitmap
1729 when retry_p is false. It might change in future and
1730 if it happens the assert will be broken. It means
1731 the code should be modified for the new
1733 ira_assert (bitmap_bit_p (consideration_allocno_bitmap
,
1734 ALLOCNO_NUM (conflict_a
)));
1737 conflict_aclass
= ALLOCNO_CLASS (conflict_a
);
1738 ira_assert (ira_reg_classes_intersect_p
1739 [aclass
][conflict_aclass
]);
1740 if (ALLOCNO_ASSIGNED_P (conflict_a
))
1742 hard_regno
= ALLOCNO_HARD_REGNO (conflict_a
);
1744 && (ira_hard_reg_set_intersection_p
1745 (hard_regno
, ALLOCNO_MODE (conflict_a
),
1746 reg_class_contents
[aclass
])))
1748 int n_objects
= ALLOCNO_NUM_OBJECTS (conflict_a
);
1751 mode
= ALLOCNO_MODE (conflict_a
);
1752 conflict_nregs
= hard_regno_nregs
[hard_regno
][mode
];
1753 if (conflict_nregs
== n_objects
&& conflict_nregs
> 1)
1755 int num
= OBJECT_SUBWORD (conflict_obj
);
1757 if (REG_WORDS_BIG_ENDIAN
)
1758 SET_HARD_REG_BIT (conflicting_regs
[word
],
1759 hard_regno
+ n_objects
- num
- 1);
1761 SET_HARD_REG_BIT (conflicting_regs
[word
],
1766 (conflicting_regs
[word
],
1767 ira_reg_mode_hard_regset
[hard_regno
][mode
]);
1768 if (hard_reg_set_subset_p (profitable_hard_regs
,
1769 conflicting_regs
[word
]))
1774 && ! ALLOCNO_COLOR_DATA (conflict_a
)->may_be_spilled_p
1775 /* Don't process the conflict allocno twice. */
1776 && (ALLOCNO_COLOR_DATA (conflict_a
)->last_process
1777 != curr_allocno_process
))
1779 int k
, *conflict_costs
;
1781 ALLOCNO_COLOR_DATA (conflict_a
)->last_process
1782 = curr_allocno_process
;
1783 ira_allocate_and_copy_costs
1784 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (conflict_a
),
1786 ALLOCNO_CONFLICT_HARD_REG_COSTS (conflict_a
));
1788 = ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (conflict_a
);
1789 if (conflict_costs
!= NULL
)
1790 for (j
= class_size
- 1; j
>= 0; j
--)
1792 hard_regno
= ira_class_hard_regs
[aclass
][j
];
1793 ira_assert (hard_regno
>= 0);
1794 k
= ira_class_hard_reg_index
[conflict_aclass
][hard_regno
];
1796 /* If HARD_REGNO is not available for CONFLICT_A,
1797 the conflict would be ignored, since HARD_REGNO
1798 will never be assigned to CONFLICT_A. */
1799 || !TEST_HARD_REG_BIT (data
->profitable_hard_regs
,
1802 full_costs
[j
] -= conflict_costs
[k
];
1804 queue_update_cost (conflict_a
, NULL
, COST_HOP_DIVISOR
);
1810 /* Take into account preferences of allocnos connected by copies to
1811 the conflict allocnos. */
1812 update_conflict_hard_regno_costs (full_costs
, aclass
, true);
1814 /* Take preferences of allocnos connected by copies into
1818 start_update_cost ();
1819 queue_update_cost (a
, NULL
, COST_HOP_DIVISOR
);
1820 update_conflict_hard_regno_costs (full_costs
, aclass
, false);
1822 min_cost
= min_full_cost
= INT_MAX
;
1823 /* We don't care about giving callee saved registers to allocnos no
1824 living through calls because call clobbered registers are
1825 allocated first (it is usual practice to put them first in
1826 REG_ALLOC_ORDER). */
1827 mode
= ALLOCNO_MODE (a
);
1828 for (i
= 0; i
< class_size
; i
++)
1830 hard_regno
= ira_class_hard_regs
[aclass
][i
];
1833 && FIRST_STACK_REG
<= hard_regno
&& hard_regno
<= LAST_STACK_REG
)
1836 if (! check_hard_reg_p (a
, hard_regno
,
1837 conflicting_regs
, profitable_hard_regs
))
1840 full_cost
= full_costs
[i
];
1841 if (!HONOR_REG_ALLOC_ORDER
)
1843 if ((saved_nregs
= calculate_saved_nregs (hard_regno
, mode
)) != 0)
1844 /* We need to save/restore the hard register in
1845 epilogue/prologue. Therefore we increase the cost. */
1847 rclass
= REGNO_REG_CLASS (hard_regno
);
1848 add_cost
= ((ira_memory_move_cost
[mode
][rclass
][0]
1849 + ira_memory_move_cost
[mode
][rclass
][1])
1850 * saved_nregs
/ hard_regno_nregs
[hard_regno
][mode
] - 1);
1852 full_cost
+= add_cost
;
1855 if (min_cost
> cost
)
1857 if (min_full_cost
> full_cost
)
1859 min_full_cost
= full_cost
;
1860 best_hard_regno
= hard_regno
;
1861 ira_assert (hard_regno
>= 0);
1864 if (min_full_cost
> mem_cost
1865 /* Do not spill static chain pointer pseudo when non-local goto
1867 && ! non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a
)))
1869 if (! retry_p
&& internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
1870 fprintf (ira_dump_file
, "(memory is more profitable %d vs %d) ",
1871 mem_cost
, min_full_cost
);
1872 best_hard_regno
= -1;
1875 if (best_hard_regno
>= 0)
1877 for (i
= hard_regno_nregs
[best_hard_regno
][mode
] - 1; i
>= 0; i
--)
1878 allocated_hardreg_p
[best_hard_regno
+ i
] = true;
1881 restore_costs_from_copies (a
);
1882 ALLOCNO_HARD_REGNO (a
) = best_hard_regno
;
1883 ALLOCNO_ASSIGNED_P (a
) = true;
1884 if (best_hard_regno
>= 0)
1885 update_costs_from_copies (a
, true, ! retry_p
);
1886 ira_assert (ALLOCNO_CLASS (a
) == aclass
);
1887 /* We don't need updated costs anymore. */
1888 ira_free_allocno_updated_costs (a
);
1889 return best_hard_regno
>= 0;
1894 /* An array used to sort copies. */
1895 static ira_copy_t
*sorted_copies
;
1897 /* Return TRUE if live ranges of allocnos A1 and A2 intersect. It is
1898 used to find a conflict for new allocnos or allocnos with the
1899 different allocno classes. */
1901 allocnos_conflict_by_live_ranges_p (ira_allocno_t a1
, ira_allocno_t a2
)
1905 int n1
= ALLOCNO_NUM_OBJECTS (a1
);
1906 int n2
= ALLOCNO_NUM_OBJECTS (a2
);
1910 reg1
= regno_reg_rtx
[ALLOCNO_REGNO (a1
)];
1911 reg2
= regno_reg_rtx
[ALLOCNO_REGNO (a2
)];
1912 if (reg1
!= NULL
&& reg2
!= NULL
1913 && ORIGINAL_REGNO (reg1
) == ORIGINAL_REGNO (reg2
))
1916 for (i
= 0; i
< n1
; i
++)
1918 ira_object_t c1
= ALLOCNO_OBJECT (a1
, i
);
1920 for (j
= 0; j
< n2
; j
++)
1922 ira_object_t c2
= ALLOCNO_OBJECT (a2
, j
);
1924 if (ira_live_ranges_intersect_p (OBJECT_LIVE_RANGES (c1
),
1925 OBJECT_LIVE_RANGES (c2
)))
1932 /* The function is used to sort copies according to their execution
1935 copy_freq_compare_func (const void *v1p
, const void *v2p
)
1937 ira_copy_t cp1
= *(const ira_copy_t
*) v1p
, cp2
= *(const ira_copy_t
*) v2p
;
1945 /* If frequencies are equal, sort by copies, so that the results of
1946 qsort leave nothing to chance. */
1947 return cp1
->num
- cp2
->num
;
1952 /* Return true if any allocno from thread of A1 conflicts with any
1953 allocno from thread A2. */
1955 allocno_thread_conflict_p (ira_allocno_t a1
, ira_allocno_t a2
)
1957 ira_allocno_t a
, conflict_a
;
1959 for (a
= ALLOCNO_COLOR_DATA (a2
)->next_thread_allocno
;;
1960 a
= ALLOCNO_COLOR_DATA (a
)->next_thread_allocno
)
1962 for (conflict_a
= ALLOCNO_COLOR_DATA (a1
)->next_thread_allocno
;;
1963 conflict_a
= ALLOCNO_COLOR_DATA (conflict_a
)->next_thread_allocno
)
1965 if (allocnos_conflict_by_live_ranges_p (a
, conflict_a
))
1967 if (conflict_a
== a1
)
1976 /* Merge two threads given correspondingly by their first allocnos T1
1977 and T2 (more accurately merging T2 into T1). */
1979 merge_threads (ira_allocno_t t1
, ira_allocno_t t2
)
1981 ira_allocno_t a
, next
, last
;
1983 gcc_assert (t1
!= t2
1984 && ALLOCNO_COLOR_DATA (t1
)->first_thread_allocno
== t1
1985 && ALLOCNO_COLOR_DATA (t2
)->first_thread_allocno
== t2
);
1986 for (last
= t2
, a
= ALLOCNO_COLOR_DATA (t2
)->next_thread_allocno
;;
1987 a
= ALLOCNO_COLOR_DATA (a
)->next_thread_allocno
)
1989 ALLOCNO_COLOR_DATA (a
)->first_thread_allocno
= t1
;
1994 next
= ALLOCNO_COLOR_DATA (t1
)->next_thread_allocno
;
1995 ALLOCNO_COLOR_DATA (t1
)->next_thread_allocno
= t2
;
1996 ALLOCNO_COLOR_DATA (last
)->next_thread_allocno
= next
;
1997 ALLOCNO_COLOR_DATA (t1
)->thread_freq
+= ALLOCNO_COLOR_DATA (t2
)->thread_freq
;
2000 /* Create threads by processing CP_NUM copies from sorted copies. We
2001 process the most expensive copies first. */
2003 form_threads_from_copies (int cp_num
)
2005 ira_allocno_t a
, thread1
, thread2
;
2009 qsort (sorted_copies
, cp_num
, sizeof (ira_copy_t
), copy_freq_compare_func
);
2010 /* Form threads processing copies, most frequently executed
2012 for (; cp_num
!= 0;)
2014 for (i
= 0; i
< cp_num
; i
++)
2016 cp
= sorted_copies
[i
];
2017 thread1
= ALLOCNO_COLOR_DATA (cp
->first
)->first_thread_allocno
;
2018 thread2
= ALLOCNO_COLOR_DATA (cp
->second
)->first_thread_allocno
;
2019 if (thread1
== thread2
)
2021 if (! allocno_thread_conflict_p (thread1
, thread2
))
2023 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
2026 " Forming thread by copy %d:a%dr%d-a%dr%d (freq=%d):\n",
2027 cp
->num
, ALLOCNO_NUM (cp
->first
), ALLOCNO_REGNO (cp
->first
),
2028 ALLOCNO_NUM (cp
->second
), ALLOCNO_REGNO (cp
->second
),
2030 merge_threads (thread1
, thread2
);
2031 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
2033 thread1
= ALLOCNO_COLOR_DATA (thread1
)->first_thread_allocno
;
2034 fprintf (ira_dump_file
, " Result (freq=%d): a%dr%d(%d)",
2035 ALLOCNO_COLOR_DATA (thread1
)->thread_freq
,
2036 ALLOCNO_NUM (thread1
), ALLOCNO_REGNO (thread1
),
2037 ALLOCNO_FREQ (thread1
));
2038 for (a
= ALLOCNO_COLOR_DATA (thread1
)->next_thread_allocno
;
2040 a
= ALLOCNO_COLOR_DATA (a
)->next_thread_allocno
)
2041 fprintf (ira_dump_file
, " a%dr%d(%d)",
2042 ALLOCNO_NUM (a
), ALLOCNO_REGNO (a
),
2044 fprintf (ira_dump_file
, "\n");
2050 /* Collect the rest of copies. */
2051 for (n
= 0; i
< cp_num
; i
++)
2053 cp
= sorted_copies
[i
];
2054 if (ALLOCNO_COLOR_DATA (cp
->first
)->first_thread_allocno
2055 != ALLOCNO_COLOR_DATA (cp
->second
)->first_thread_allocno
)
2056 sorted_copies
[n
++] = cp
;
2062 /* Create threads by processing copies of all alocnos from BUCKET. We
2063 process the most expensive copies first. */
2065 form_threads_from_bucket (ira_allocno_t bucket
)
2068 ira_copy_t cp
, next_cp
;
2071 for (a
= bucket
; a
!= NULL
; a
= ALLOCNO_COLOR_DATA (a
)->next_bucket_allocno
)
2073 for (cp
= ALLOCNO_COPIES (a
); cp
!= NULL
; cp
= next_cp
)
2077 next_cp
= cp
->next_first_allocno_copy
;
2078 sorted_copies
[cp_num
++] = cp
;
2080 else if (cp
->second
== a
)
2081 next_cp
= cp
->next_second_allocno_copy
;
2086 form_threads_from_copies (cp_num
);
2089 /* Create threads by processing copies of colorable allocno A. We
2090 process most expensive copies first. */
2092 form_threads_from_colorable_allocno (ira_allocno_t a
)
2094 ira_allocno_t another_a
;
2095 ira_copy_t cp
, next_cp
;
2098 for (cp
= ALLOCNO_COPIES (a
); cp
!= NULL
; cp
= next_cp
)
2102 next_cp
= cp
->next_first_allocno_copy
;
2103 another_a
= cp
->second
;
2105 else if (cp
->second
== a
)
2107 next_cp
= cp
->next_second_allocno_copy
;
2108 another_a
= cp
->first
;
2112 if ((! ALLOCNO_COLOR_DATA (another_a
)->in_graph_p
2113 && !ALLOCNO_COLOR_DATA (another_a
)->may_be_spilled_p
)
2114 || ALLOCNO_COLOR_DATA (another_a
)->colorable_p
)
2115 sorted_copies
[cp_num
++] = cp
;
2117 form_threads_from_copies (cp_num
);
2120 /* Form initial threads which contain only one allocno. */
2122 init_allocno_threads (void)
2128 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap
, 0, j
, bi
)
2130 a
= ira_allocnos
[j
];
2131 /* Set up initial thread data: */
2132 ALLOCNO_COLOR_DATA (a
)->first_thread_allocno
2133 = ALLOCNO_COLOR_DATA (a
)->next_thread_allocno
= a
;
2134 ALLOCNO_COLOR_DATA (a
)->thread_freq
= ALLOCNO_FREQ (a
);
2140 /* This page contains the allocator based on the Chaitin-Briggs algorithm. */
2142 /* Bucket of allocnos that can colored currently without spilling. */
2143 static ira_allocno_t colorable_allocno_bucket
;
2145 /* Bucket of allocnos that might be not colored currently without
2147 static ira_allocno_t uncolorable_allocno_bucket
;
2149 /* The current number of allocnos in the uncolorable_bucket. */
2150 static int uncolorable_allocnos_num
;
2152 /* Return the current spill priority of allocno A. The less the
2153 number, the more preferable the allocno for spilling. */
2155 allocno_spill_priority (ira_allocno_t a
)
2157 allocno_color_data_t data
= ALLOCNO_COLOR_DATA (a
);
2160 / (ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a
)
2161 * ira_reg_class_max_nregs
[ALLOCNO_CLASS (a
)][ALLOCNO_MODE (a
)]
2165 /* Add allocno A to bucket *BUCKET_PTR. A should be not in a bucket
2168 add_allocno_to_bucket (ira_allocno_t a
, ira_allocno_t
*bucket_ptr
)
2170 ira_allocno_t first_a
;
2171 allocno_color_data_t data
;
2173 if (bucket_ptr
== &uncolorable_allocno_bucket
2174 && ALLOCNO_CLASS (a
) != NO_REGS
)
2176 uncolorable_allocnos_num
++;
2177 ira_assert (uncolorable_allocnos_num
> 0);
2179 first_a
= *bucket_ptr
;
2180 data
= ALLOCNO_COLOR_DATA (a
);
2181 data
->next_bucket_allocno
= first_a
;
2182 data
->prev_bucket_allocno
= NULL
;
2183 if (first_a
!= NULL
)
2184 ALLOCNO_COLOR_DATA (first_a
)->prev_bucket_allocno
= a
;
2188 /* Compare two allocnos to define which allocno should be pushed first
2189 into the coloring stack. If the return is a negative number, the
2190 allocno given by the first parameter will be pushed first. In this
2191 case such allocno has less priority than the second one and the
2192 hard register will be assigned to it after assignment to the second
2193 one. As the result of such assignment order, the second allocno
2194 has a better chance to get the best hard register. */
2196 bucket_allocno_compare_func (const void *v1p
, const void *v2p
)
2198 ira_allocno_t a1
= *(const ira_allocno_t
*) v1p
;
2199 ira_allocno_t a2
= *(const ira_allocno_t
*) v2p
;
2200 int diff
, freq1
, freq2
, a1_num
, a2_num
;
2201 ira_allocno_t t1
= ALLOCNO_COLOR_DATA (a1
)->first_thread_allocno
;
2202 ira_allocno_t t2
= ALLOCNO_COLOR_DATA (a2
)->first_thread_allocno
;
2203 int cl1
= ALLOCNO_CLASS (a1
), cl2
= ALLOCNO_CLASS (a2
);
2205 freq1
= ALLOCNO_COLOR_DATA (t1
)->thread_freq
;
2206 freq2
= ALLOCNO_COLOR_DATA (t2
)->thread_freq
;
2207 if ((diff
= freq1
- freq2
) != 0)
2210 if ((diff
= ALLOCNO_NUM (t2
) - ALLOCNO_NUM (t1
)) != 0)
2213 /* Push pseudos requiring less hard registers first. It means that
2214 we will assign pseudos requiring more hard registers first
2215 avoiding creation small holes in free hard register file into
2216 which the pseudos requiring more hard registers can not fit. */
2217 if ((diff
= (ira_reg_class_max_nregs
[cl1
][ALLOCNO_MODE (a1
)]
2218 - ira_reg_class_max_nregs
[cl2
][ALLOCNO_MODE (a2
)])) != 0)
2221 freq1
= ALLOCNO_FREQ (a1
);
2222 freq2
= ALLOCNO_FREQ (a2
);
2223 if ((diff
= freq1
- freq2
) != 0)
2226 a1_num
= ALLOCNO_COLOR_DATA (a1
)->available_regs_num
;
2227 a2_num
= ALLOCNO_COLOR_DATA (a2
)->available_regs_num
;
2228 if ((diff
= a2_num
- a1_num
) != 0)
2230 return ALLOCNO_NUM (a2
) - ALLOCNO_NUM (a1
);
2233 /* Sort bucket *BUCKET_PTR and return the result through
2236 sort_bucket (ira_allocno_t
*bucket_ptr
,
2237 int (*compare_func
) (const void *, const void *))
2239 ira_allocno_t a
, head
;
2242 for (n
= 0, a
= *bucket_ptr
;
2244 a
= ALLOCNO_COLOR_DATA (a
)->next_bucket_allocno
)
2245 sorted_allocnos
[n
++] = a
;
2248 qsort (sorted_allocnos
, n
, sizeof (ira_allocno_t
), compare_func
);
2250 for (n
--; n
>= 0; n
--)
2252 a
= sorted_allocnos
[n
];
2253 ALLOCNO_COLOR_DATA (a
)->next_bucket_allocno
= head
;
2254 ALLOCNO_COLOR_DATA (a
)->prev_bucket_allocno
= NULL
;
2256 ALLOCNO_COLOR_DATA (head
)->prev_bucket_allocno
= a
;
2262 /* Add ALLOCNO to colorable bucket maintaining the order according
2263 their priority. ALLOCNO should be not in a bucket before the
2266 add_allocno_to_ordered_colorable_bucket (ira_allocno_t allocno
)
2268 ira_allocno_t before
, after
;
2270 form_threads_from_colorable_allocno (allocno
);
2271 for (before
= colorable_allocno_bucket
, after
= NULL
;
2274 before
= ALLOCNO_COLOR_DATA (before
)->next_bucket_allocno
)
2275 if (bucket_allocno_compare_func (&allocno
, &before
) < 0)
2277 ALLOCNO_COLOR_DATA (allocno
)->next_bucket_allocno
= before
;
2278 ALLOCNO_COLOR_DATA (allocno
)->prev_bucket_allocno
= after
;
2280 colorable_allocno_bucket
= allocno
;
2282 ALLOCNO_COLOR_DATA (after
)->next_bucket_allocno
= allocno
;
2284 ALLOCNO_COLOR_DATA (before
)->prev_bucket_allocno
= allocno
;
2287 /* Delete ALLOCNO from bucket *BUCKET_PTR. It should be there before
2290 delete_allocno_from_bucket (ira_allocno_t allocno
, ira_allocno_t
*bucket_ptr
)
2292 ira_allocno_t prev_allocno
, next_allocno
;
2294 if (bucket_ptr
== &uncolorable_allocno_bucket
2295 && ALLOCNO_CLASS (allocno
) != NO_REGS
)
2297 uncolorable_allocnos_num
--;
2298 ira_assert (uncolorable_allocnos_num
>= 0);
2300 prev_allocno
= ALLOCNO_COLOR_DATA (allocno
)->prev_bucket_allocno
;
2301 next_allocno
= ALLOCNO_COLOR_DATA (allocno
)->next_bucket_allocno
;
2302 if (prev_allocno
!= NULL
)
2303 ALLOCNO_COLOR_DATA (prev_allocno
)->next_bucket_allocno
= next_allocno
;
2306 ira_assert (*bucket_ptr
== allocno
);
2307 *bucket_ptr
= next_allocno
;
2309 if (next_allocno
!= NULL
)
2310 ALLOCNO_COLOR_DATA (next_allocno
)->prev_bucket_allocno
= prev_allocno
;
2313 /* Put allocno A onto the coloring stack without removing it from its
2314 bucket. Pushing allocno to the coloring stack can result in moving
2315 conflicting allocnos from the uncolorable bucket to the colorable
2318 push_allocno_to_stack (ira_allocno_t a
)
2320 enum reg_class aclass
;
2321 allocno_color_data_t data
, conflict_data
;
2322 int size
, i
, n
= ALLOCNO_NUM_OBJECTS (a
);
2324 data
= ALLOCNO_COLOR_DATA (a
);
2325 data
->in_graph_p
= false;
2326 allocno_stack_vec
.safe_push (a
);
2327 aclass
= ALLOCNO_CLASS (a
);
2328 if (aclass
== NO_REGS
)
2330 size
= ira_reg_class_max_nregs
[aclass
][ALLOCNO_MODE (a
)];
2333 /* We will deal with the subwords individually. */
2334 gcc_assert (size
== ALLOCNO_NUM_OBJECTS (a
));
2337 for (i
= 0; i
< n
; i
++)
2339 ira_object_t obj
= ALLOCNO_OBJECT (a
, i
);
2340 ira_object_t conflict_obj
;
2341 ira_object_conflict_iterator oci
;
2343 FOR_EACH_OBJECT_CONFLICT (obj
, conflict_obj
, oci
)
2345 ira_allocno_t conflict_a
= OBJECT_ALLOCNO (conflict_obj
);
2347 conflict_data
= ALLOCNO_COLOR_DATA (conflict_a
);
2348 if (conflict_data
->colorable_p
2349 || ! conflict_data
->in_graph_p
2350 || ALLOCNO_ASSIGNED_P (conflict_a
)
2351 || !(hard_reg_set_intersect_p
2352 (ALLOCNO_COLOR_DATA (a
)->profitable_hard_regs
,
2353 conflict_data
->profitable_hard_regs
)))
2355 ira_assert (bitmap_bit_p (coloring_allocno_bitmap
,
2356 ALLOCNO_NUM (conflict_a
)));
2357 if (update_left_conflict_sizes_p (conflict_a
, a
, size
))
2359 delete_allocno_from_bucket
2360 (conflict_a
, &uncolorable_allocno_bucket
);
2361 add_allocno_to_ordered_colorable_bucket (conflict_a
);
2362 if (internal_flag_ira_verbose
> 4 && ira_dump_file
!= NULL
)
2364 fprintf (ira_dump_file
, " Making");
2365 ira_print_expanded_allocno (conflict_a
);
2366 fprintf (ira_dump_file
, " colorable\n");
2374 /* Put ALLOCNO onto the coloring stack and remove it from its bucket.
2375 The allocno is in the colorable bucket if COLORABLE_P is TRUE. */
2377 remove_allocno_from_bucket_and_push (ira_allocno_t allocno
, bool colorable_p
)
2380 delete_allocno_from_bucket (allocno
, &colorable_allocno_bucket
);
2382 delete_allocno_from_bucket (allocno
, &uncolorable_allocno_bucket
);
2383 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
2385 fprintf (ira_dump_file
, " Pushing");
2386 ira_print_expanded_allocno (allocno
);
2388 fprintf (ira_dump_file
, "(cost %d)\n",
2389 ALLOCNO_COLOR_DATA (allocno
)->temp
);
2391 fprintf (ira_dump_file
, "(potential spill: %spri=%d, cost=%d)\n",
2392 ALLOCNO_BAD_SPILL_P (allocno
) ? "bad spill, " : "",
2393 allocno_spill_priority (allocno
),
2394 ALLOCNO_COLOR_DATA (allocno
)->temp
);
2397 ALLOCNO_COLOR_DATA (allocno
)->may_be_spilled_p
= true;
2398 push_allocno_to_stack (allocno
);
2401 /* Put all allocnos from colorable bucket onto the coloring stack. */
2403 push_only_colorable (void)
2405 form_threads_from_bucket (colorable_allocno_bucket
);
2406 sort_bucket (&colorable_allocno_bucket
, bucket_allocno_compare_func
);
2407 for (;colorable_allocno_bucket
!= NULL
;)
2408 remove_allocno_from_bucket_and_push (colorable_allocno_bucket
, true);
2411 /* Return the frequency of exit edges (if EXIT_P) or entry from/to the
2412 loop given by its LOOP_NODE. */
2414 ira_loop_edge_freq (ira_loop_tree_node_t loop_node
, int regno
, bool exit_p
)
2421 ira_assert (current_loops
!= NULL
&& loop_node
->loop
!= NULL
2422 && (regno
< 0 || regno
>= FIRST_PSEUDO_REGISTER
));
2426 FOR_EACH_EDGE (e
, ei
, loop_node
->loop
->header
->preds
)
2427 if (e
->src
!= loop_node
->loop
->latch
2429 || (bitmap_bit_p (df_get_live_out (e
->src
), regno
)
2430 && bitmap_bit_p (df_get_live_in (e
->dest
), regno
))))
2431 freq
+= EDGE_FREQUENCY (e
);
2435 edges
= get_loop_exit_edges (loop_node
->loop
);
2436 FOR_EACH_VEC_ELT (edges
, i
, e
)
2438 || (bitmap_bit_p (df_get_live_out (e
->src
), regno
)
2439 && bitmap_bit_p (df_get_live_in (e
->dest
), regno
)))
2440 freq
+= EDGE_FREQUENCY (e
);
2444 return REG_FREQ_FROM_EDGE_FREQ (freq
);
2447 /* Calculate and return the cost of putting allocno A into memory. */
2449 calculate_allocno_spill_cost (ira_allocno_t a
)
2453 enum reg_class rclass
;
2454 ira_allocno_t parent_allocno
;
2455 ira_loop_tree_node_t parent_node
, loop_node
;
2457 regno
= ALLOCNO_REGNO (a
);
2458 cost
= ALLOCNO_UPDATED_MEMORY_COST (a
) - ALLOCNO_UPDATED_CLASS_COST (a
);
2459 if (ALLOCNO_CAP (a
) != NULL
)
2461 loop_node
= ALLOCNO_LOOP_TREE_NODE (a
);
2462 if ((parent_node
= loop_node
->parent
) == NULL
)
2464 if ((parent_allocno
= parent_node
->regno_allocno_map
[regno
]) == NULL
)
2466 mode
= ALLOCNO_MODE (a
);
2467 rclass
= ALLOCNO_CLASS (a
);
2468 if (ALLOCNO_HARD_REGNO (parent_allocno
) < 0)
2469 cost
-= (ira_memory_move_cost
[mode
][rclass
][0]
2470 * ira_loop_edge_freq (loop_node
, regno
, true)
2471 + ira_memory_move_cost
[mode
][rclass
][1]
2472 * ira_loop_edge_freq (loop_node
, regno
, false));
2475 ira_init_register_move_cost_if_necessary (mode
);
2476 cost
+= ((ira_memory_move_cost
[mode
][rclass
][1]
2477 * ira_loop_edge_freq (loop_node
, regno
, true)
2478 + ira_memory_move_cost
[mode
][rclass
][0]
2479 * ira_loop_edge_freq (loop_node
, regno
, false))
2480 - (ira_register_move_cost
[mode
][rclass
][rclass
]
2481 * (ira_loop_edge_freq (loop_node
, regno
, false)
2482 + ira_loop_edge_freq (loop_node
, regno
, true))));
2487 /* Used for sorting allocnos for spilling. */
2489 allocno_spill_priority_compare (ira_allocno_t a1
, ira_allocno_t a2
)
2491 int pri1
, pri2
, diff
;
2493 /* Avoid spilling static chain pointer pseudo when non-local goto is
2495 if (non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a1
)))
2497 else if (non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a2
)))
2499 if (ALLOCNO_BAD_SPILL_P (a1
) && ! ALLOCNO_BAD_SPILL_P (a2
))
2501 if (ALLOCNO_BAD_SPILL_P (a2
) && ! ALLOCNO_BAD_SPILL_P (a1
))
2503 pri1
= allocno_spill_priority (a1
);
2504 pri2
= allocno_spill_priority (a2
);
2505 if ((diff
= pri1
- pri2
) != 0)
2508 = ALLOCNO_COLOR_DATA (a1
)->temp
- ALLOCNO_COLOR_DATA (a2
)->temp
) != 0)
2510 return ALLOCNO_NUM (a1
) - ALLOCNO_NUM (a2
);
2513 /* Used for sorting allocnos for spilling. */
2515 allocno_spill_sort_compare (const void *v1p
, const void *v2p
)
2517 ira_allocno_t p1
= *(const ira_allocno_t
*) v1p
;
2518 ira_allocno_t p2
= *(const ira_allocno_t
*) v2p
;
2520 return allocno_spill_priority_compare (p1
, p2
);
2523 /* Push allocnos to the coloring stack. The order of allocnos in the
2524 stack defines the order for the subsequent coloring. */
2526 push_allocnos_to_stack (void)
2531 /* Calculate uncolorable allocno spill costs. */
2532 for (a
= uncolorable_allocno_bucket
;
2534 a
= ALLOCNO_COLOR_DATA (a
)->next_bucket_allocno
)
2535 if (ALLOCNO_CLASS (a
) != NO_REGS
)
2537 cost
= calculate_allocno_spill_cost (a
);
2538 /* ??? Remove cost of copies between the coalesced
2540 ALLOCNO_COLOR_DATA (a
)->temp
= cost
;
2542 sort_bucket (&uncolorable_allocno_bucket
, allocno_spill_sort_compare
);
2545 push_only_colorable ();
2546 a
= uncolorable_allocno_bucket
;
2549 remove_allocno_from_bucket_and_push (a
, false);
2551 ira_assert (colorable_allocno_bucket
== NULL
2552 && uncolorable_allocno_bucket
== NULL
);
2553 ira_assert (uncolorable_allocnos_num
== 0);
2556 /* Pop the coloring stack and assign hard registers to the popped
2559 pop_allocnos_from_stack (void)
2561 ira_allocno_t allocno
;
2562 enum reg_class aclass
;
2564 for (;allocno_stack_vec
.length () != 0;)
2566 allocno
= allocno_stack_vec
.pop ();
2567 aclass
= ALLOCNO_CLASS (allocno
);
2568 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
2570 fprintf (ira_dump_file
, " Popping");
2571 ira_print_expanded_allocno (allocno
);
2572 fprintf (ira_dump_file
, " -- ");
2574 if (aclass
== NO_REGS
)
2576 ALLOCNO_HARD_REGNO (allocno
) = -1;
2577 ALLOCNO_ASSIGNED_P (allocno
) = true;
2578 ira_assert (ALLOCNO_UPDATED_HARD_REG_COSTS (allocno
) == NULL
);
2580 (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (allocno
) == NULL
);
2581 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
2582 fprintf (ira_dump_file
, "assign memory\n");
2584 else if (assign_hard_reg (allocno
, false))
2586 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
2587 fprintf (ira_dump_file
, "assign reg %d\n",
2588 ALLOCNO_HARD_REGNO (allocno
));
2590 else if (ALLOCNO_ASSIGNED_P (allocno
))
2592 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
2593 fprintf (ira_dump_file
, "spill%s\n",
2594 ALLOCNO_COLOR_DATA (allocno
)->may_be_spilled_p
2597 ALLOCNO_COLOR_DATA (allocno
)->in_graph_p
= true;
2601 /* Set up number of available hard registers for allocno A. */
2603 setup_allocno_available_regs_num (ira_allocno_t a
)
2605 int i
, n
, hard_regno
, hard_regs_num
, nwords
;
2606 enum reg_class aclass
;
2607 allocno_color_data_t data
;
2609 aclass
= ALLOCNO_CLASS (a
);
2610 data
= ALLOCNO_COLOR_DATA (a
);
2611 data
->available_regs_num
= 0;
2612 if (aclass
== NO_REGS
)
2614 hard_regs_num
= ira_class_hard_regs_num
[aclass
];
2615 nwords
= ALLOCNO_NUM_OBJECTS (a
);
2616 for (n
= 0, i
= hard_regs_num
- 1; i
>= 0; i
--)
2618 hard_regno
= ira_class_hard_regs
[aclass
][i
];
2619 /* Checking only profitable hard regs. */
2620 if (TEST_HARD_REG_BIT (data
->profitable_hard_regs
, hard_regno
))
2623 data
->available_regs_num
= n
;
2624 if (internal_flag_ira_verbose
<= 2 || ira_dump_file
== NULL
)
2628 " Allocno a%dr%d of %s(%d) has %d avail. regs ",
2629 ALLOCNO_NUM (a
), ALLOCNO_REGNO (a
),
2630 reg_class_names
[aclass
], ira_class_hard_regs_num
[aclass
], n
);
2631 print_hard_reg_set (ira_dump_file
, data
->profitable_hard_regs
, false);
2632 fprintf (ira_dump_file
, ", %snode: ",
2633 hard_reg_set_equal_p (data
->profitable_hard_regs
,
2634 data
->hard_regs_node
->hard_regs
->set
)
2636 print_hard_reg_set (ira_dump_file
,
2637 data
->hard_regs_node
->hard_regs
->set
, false);
2638 for (i
= 0; i
< nwords
; i
++)
2640 ira_object_t obj
= ALLOCNO_OBJECT (a
, i
);
2645 fprintf (ira_dump_file
, ", ");
2646 fprintf (ira_dump_file
, " obj %d", i
);
2648 fprintf (ira_dump_file
, " (confl regs = ");
2649 print_hard_reg_set (ira_dump_file
, OBJECT_TOTAL_CONFLICT_HARD_REGS (obj
),
2651 fprintf (ira_dump_file
, ")");
2653 fprintf (ira_dump_file
, "\n");
2656 /* Put ALLOCNO in a bucket corresponding to its number and size of its
2657 conflicting allocnos and hard registers. */
2659 put_allocno_into_bucket (ira_allocno_t allocno
)
2661 ALLOCNO_COLOR_DATA (allocno
)->in_graph_p
= true;
2662 setup_allocno_available_regs_num (allocno
);
2663 if (setup_left_conflict_sizes_p (allocno
))
2664 add_allocno_to_bucket (allocno
, &colorable_allocno_bucket
);
2666 add_allocno_to_bucket (allocno
, &uncolorable_allocno_bucket
);
2669 /* Map: allocno number -> allocno priority. */
2670 static int *allocno_priorities
;
2672 /* Set up priorities for N allocnos in array
2673 CONSIDERATION_ALLOCNOS. */
2675 setup_allocno_priorities (ira_allocno_t
*consideration_allocnos
, int n
)
2677 int i
, length
, nrefs
, priority
, max_priority
, mult
;
2681 for (i
= 0; i
< n
; i
++)
2683 a
= consideration_allocnos
[i
];
2684 nrefs
= ALLOCNO_NREFS (a
);
2685 ira_assert (nrefs
>= 0);
2686 mult
= floor_log2 (ALLOCNO_NREFS (a
)) + 1;
2687 ira_assert (mult
>= 0);
2688 allocno_priorities
[ALLOCNO_NUM (a
)]
2691 * (ALLOCNO_MEMORY_COST (a
) - ALLOCNO_CLASS_COST (a
))
2692 * ira_reg_class_max_nregs
[ALLOCNO_CLASS (a
)][ALLOCNO_MODE (a
)]);
2694 priority
= -priority
;
2695 if (max_priority
< priority
)
2696 max_priority
= priority
;
2698 mult
= max_priority
== 0 ? 1 : INT_MAX
/ max_priority
;
2699 for (i
= 0; i
< n
; i
++)
2701 a
= consideration_allocnos
[i
];
2702 length
= ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a
);
2703 if (ALLOCNO_NUM_OBJECTS (a
) > 1)
2704 length
/= ALLOCNO_NUM_OBJECTS (a
);
2707 allocno_priorities
[ALLOCNO_NUM (a
)]
2708 = allocno_priorities
[ALLOCNO_NUM (a
)] * mult
/ length
;
2712 /* Sort allocnos according to the profit of usage of a hard register
2713 instead of memory for them. */
2715 allocno_cost_compare_func (const void *v1p
, const void *v2p
)
2717 ira_allocno_t p1
= *(const ira_allocno_t
*) v1p
;
2718 ira_allocno_t p2
= *(const ira_allocno_t
*) v2p
;
2721 c1
= ALLOCNO_UPDATED_MEMORY_COST (p1
) - ALLOCNO_UPDATED_CLASS_COST (p1
);
2722 c2
= ALLOCNO_UPDATED_MEMORY_COST (p2
) - ALLOCNO_UPDATED_CLASS_COST (p2
);
2726 /* If regs are equally good, sort by allocno numbers, so that the
2727 results of qsort leave nothing to chance. */
2728 return ALLOCNO_NUM (p1
) - ALLOCNO_NUM (p2
);
2731 /* We used Chaitin-Briggs coloring to assign as many pseudos as
2732 possible to hard registers. Let us try to improve allocation with
2733 cost point of view. This function improves the allocation by
2734 spilling some allocnos and assigning the freed hard registers to
2735 other allocnos if it decreases the overall allocation cost. */
2737 improve_allocation (void)
2740 int j
, k
, n
, hregno
, conflict_hregno
, base_cost
, class_size
, word
, nwords
;
2741 int check
, spill_cost
, min_cost
, nregs
, conflict_nregs
, r
, best
;
2743 enum reg_class aclass
;
2746 int costs
[FIRST_PSEUDO_REGISTER
];
2747 HARD_REG_SET conflicting_regs
[2], profitable_hard_regs
;
2751 /* Don't bother to optimize the code with static chain pointer and
2752 non-local goto in order not to spill the chain pointer
2754 if (cfun
->static_chain_decl
&& crtl
->has_nonlocal_goto
)
2756 /* Clear counts used to process conflicting allocnos only once for
2758 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap
, 0, i
, bi
)
2759 ALLOCNO_COLOR_DATA (ira_allocnos
[i
])->temp
= 0;
2761 /* Process each allocno and try to assign a hard register to it by
2762 spilling some its conflicting allocnos. */
2763 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap
, 0, i
, bi
)
2765 a
= ira_allocnos
[i
];
2766 ALLOCNO_COLOR_DATA (a
)->temp
= 0;
2767 if (empty_profitable_hard_regs (a
))
2770 aclass
= ALLOCNO_CLASS (a
);
2771 allocno_costs
= ALLOCNO_UPDATED_HARD_REG_COSTS (a
);
2772 if (allocno_costs
== NULL
)
2773 allocno_costs
= ALLOCNO_HARD_REG_COSTS (a
);
2774 if ((hregno
= ALLOCNO_HARD_REGNO (a
)) < 0)
2775 base_cost
= ALLOCNO_UPDATED_MEMORY_COST (a
);
2776 else if (allocno_costs
== NULL
)
2777 /* It means that assigning a hard register is not profitable
2778 (we don't waste memory for hard register costs in this
2782 base_cost
= allocno_costs
[ira_class_hard_reg_index
[aclass
][hregno
]];
2784 get_conflict_and_start_profitable_regs (a
, false,
2786 &profitable_hard_regs
);
2787 class_size
= ira_class_hard_regs_num
[aclass
];
2788 /* Set up cost improvement for usage of each profitable hard
2789 register for allocno A. */
2790 for (j
= 0; j
< class_size
; j
++)
2792 hregno
= ira_class_hard_regs
[aclass
][j
];
2793 if (! check_hard_reg_p (a
, hregno
,
2794 conflicting_regs
, profitable_hard_regs
))
2796 ira_assert (ira_class_hard_reg_index
[aclass
][hregno
] == j
);
2797 k
= allocno_costs
== NULL
? 0 : j
;
2798 costs
[hregno
] = (allocno_costs
== NULL
2799 ? ALLOCNO_UPDATED_CLASS_COST (a
) : allocno_costs
[k
]);
2800 costs
[hregno
] -= base_cost
;
2801 if (costs
[hregno
] < 0)
2805 /* There is no chance to improve the allocation cost by
2806 assigning hard register to allocno A even without spilling
2807 conflicting allocnos. */
2809 mode
= ALLOCNO_MODE (a
);
2810 nwords
= ALLOCNO_NUM_OBJECTS (a
);
2811 /* Process each allocno conflicting with A and update the cost
2812 improvement for profitable hard registers of A. To use a
2813 hard register for A we need to spill some conflicting
2814 allocnos and that creates penalty for the cost
2816 for (word
= 0; word
< nwords
; word
++)
2818 ira_object_t conflict_obj
;
2819 ira_object_t obj
= ALLOCNO_OBJECT (a
, word
);
2820 ira_object_conflict_iterator oci
;
2822 FOR_EACH_OBJECT_CONFLICT (obj
, conflict_obj
, oci
)
2824 ira_allocno_t conflict_a
= OBJECT_ALLOCNO (conflict_obj
);
2826 if (ALLOCNO_COLOR_DATA (conflict_a
)->temp
== check
)
2827 /* We already processed this conflicting allocno
2828 because we processed earlier another object of the
2829 conflicting allocno. */
2831 ALLOCNO_COLOR_DATA (conflict_a
)->temp
= check
;
2832 if ((conflict_hregno
= ALLOCNO_HARD_REGNO (conflict_a
)) < 0)
2834 spill_cost
= ALLOCNO_UPDATED_MEMORY_COST (conflict_a
);
2835 k
= (ira_class_hard_reg_index
2836 [ALLOCNO_CLASS (conflict_a
)][conflict_hregno
]);
2837 ira_assert (k
>= 0);
2838 if ((allocno_costs
= ALLOCNO_UPDATED_HARD_REG_COSTS (conflict_a
))
2840 spill_cost
-= allocno_costs
[k
];
2841 else if ((allocno_costs
= ALLOCNO_HARD_REG_COSTS (conflict_a
))
2843 spill_cost
-= allocno_costs
[k
];
2845 spill_cost
-= ALLOCNO_UPDATED_CLASS_COST (conflict_a
);
2847 = hard_regno_nregs
[conflict_hregno
][ALLOCNO_MODE (conflict_a
)];
2848 for (r
= conflict_hregno
;
2849 r
>= 0 && r
+ hard_regno_nregs
[r
][mode
] > conflict_hregno
;
2851 if (check_hard_reg_p (a
, r
,
2852 conflicting_regs
, profitable_hard_regs
))
2853 costs
[r
] += spill_cost
;
2854 for (r
= conflict_hregno
+ 1;
2855 r
< conflict_hregno
+ conflict_nregs
;
2857 if (check_hard_reg_p (a
, r
,
2858 conflicting_regs
, profitable_hard_regs
))
2859 costs
[r
] += spill_cost
;
2864 /* Now we choose hard register for A which results in highest
2865 allocation cost improvement. */
2866 for (j
= 0; j
< class_size
; j
++)
2868 hregno
= ira_class_hard_regs
[aclass
][j
];
2869 if (check_hard_reg_p (a
, hregno
,
2870 conflicting_regs
, profitable_hard_regs
)
2871 && min_cost
> costs
[hregno
])
2874 min_cost
= costs
[hregno
];
2878 /* We are in a situation when assigning any hard register to A
2879 by spilling some conflicting allocnos does not improve the
2882 nregs
= hard_regno_nregs
[best
][mode
];
2883 /* Now spill conflicting allocnos which contain a hard register
2884 of A when we assign the best chosen hard register to it. */
2885 for (word
= 0; word
< nwords
; word
++)
2887 ira_object_t conflict_obj
;
2888 ira_object_t obj
= ALLOCNO_OBJECT (a
, word
);
2889 ira_object_conflict_iterator oci
;
2891 FOR_EACH_OBJECT_CONFLICT (obj
, conflict_obj
, oci
)
2893 ira_allocno_t conflict_a
= OBJECT_ALLOCNO (conflict_obj
);
2895 if ((conflict_hregno
= ALLOCNO_HARD_REGNO (conflict_a
)) < 0)
2898 = hard_regno_nregs
[conflict_hregno
][ALLOCNO_MODE (conflict_a
)];
2899 if (best
+ nregs
<= conflict_hregno
2900 || conflict_hregno
+ conflict_nregs
<= best
)
2901 /* No intersection. */
2903 ALLOCNO_HARD_REGNO (conflict_a
) = -1;
2904 sorted_allocnos
[n
++] = conflict_a
;
2905 if (internal_flag_ira_verbose
> 2 && ira_dump_file
!= NULL
)
2906 fprintf (ira_dump_file
, "Spilling a%dr%d for a%dr%d\n",
2907 ALLOCNO_NUM (conflict_a
), ALLOCNO_REGNO (conflict_a
),
2908 ALLOCNO_NUM (a
), ALLOCNO_REGNO (a
));
2911 /* Assign the best chosen hard register to A. */
2912 ALLOCNO_HARD_REGNO (a
) = best
;
2913 if (internal_flag_ira_verbose
> 2 && ira_dump_file
!= NULL
)
2914 fprintf (ira_dump_file
, "Assigning %d to a%dr%d\n",
2915 best
, ALLOCNO_NUM (a
), ALLOCNO_REGNO (a
));
2919 /* We spilled some allocnos to assign their hard registers to other
2920 allocnos. The spilled allocnos are now in array
2921 'sorted_allocnos'. There is still a possibility that some of the
2922 spilled allocnos can get hard registers. So let us try assign
2923 them hard registers again (just a reminder -- function
2924 'assign_hard_reg' assigns hard registers only if it is possible
2925 and profitable). We process the spilled allocnos with biggest
2926 benefit to get hard register first -- see function
2927 'allocno_cost_compare_func'. */
2928 qsort (sorted_allocnos
, n
, sizeof (ira_allocno_t
),
2929 allocno_cost_compare_func
);
2930 for (j
= 0; j
< n
; j
++)
2932 a
= sorted_allocnos
[j
];
2933 ALLOCNO_ASSIGNED_P (a
) = false;
2934 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
2936 fprintf (ira_dump_file
, " ");
2937 ira_print_expanded_allocno (a
);
2938 fprintf (ira_dump_file
, " -- ");
2940 if (assign_hard_reg (a
, false))
2942 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
2943 fprintf (ira_dump_file
, "assign hard reg %d\n",
2944 ALLOCNO_HARD_REGNO (a
));
2948 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
2949 fprintf (ira_dump_file
, "assign memory\n");
2954 /* Sort allocnos according to their priorities. */
2956 allocno_priority_compare_func (const void *v1p
, const void *v2p
)
2958 ira_allocno_t a1
= *(const ira_allocno_t
*) v1p
;
2959 ira_allocno_t a2
= *(const ira_allocno_t
*) v2p
;
2962 /* Assign hard reg to static chain pointer pseudo first when
2963 non-local goto is used. */
2964 if (non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a1
)))
2966 else if (non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a2
)))
2968 pri1
= allocno_priorities
[ALLOCNO_NUM (a1
)];
2969 pri2
= allocno_priorities
[ALLOCNO_NUM (a2
)];
2971 return SORTGT (pri2
, pri1
);
2973 /* If regs are equally good, sort by allocnos, so that the results of
2974 qsort leave nothing to chance. */
2975 return ALLOCNO_NUM (a1
) - ALLOCNO_NUM (a2
);
2978 /* Chaitin-Briggs coloring for allocnos in COLORING_ALLOCNO_BITMAP
2979 taking into account allocnos in CONSIDERATION_ALLOCNO_BITMAP. */
2981 color_allocnos (void)
2987 setup_profitable_hard_regs ();
2988 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap
, 0, i
, bi
)
2991 HARD_REG_SET conflict_hard_regs
;
2992 allocno_color_data_t data
;
2993 ira_pref_t pref
, next_pref
;
2995 a
= ira_allocnos
[i
];
2996 nr
= ALLOCNO_NUM_OBJECTS (a
);
2997 CLEAR_HARD_REG_SET (conflict_hard_regs
);
2998 for (l
= 0; l
< nr
; l
++)
3000 ira_object_t obj
= ALLOCNO_OBJECT (a
, l
);
3001 IOR_HARD_REG_SET (conflict_hard_regs
,
3002 OBJECT_CONFLICT_HARD_REGS (obj
));
3004 data
= ALLOCNO_COLOR_DATA (a
);
3005 for (pref
= ALLOCNO_PREFS (a
); pref
!= NULL
; pref
= next_pref
)
3007 next_pref
= pref
->next_pref
;
3008 if (! ira_hard_reg_in_set_p (pref
->hard_regno
,
3010 data
->profitable_hard_regs
))
3011 ira_remove_pref (pref
);
3014 if (flag_ira_algorithm
== IRA_ALGORITHM_PRIORITY
)
3017 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap
, 0, i
, bi
)
3019 a
= ira_allocnos
[i
];
3020 if (ALLOCNO_CLASS (a
) == NO_REGS
)
3022 ALLOCNO_HARD_REGNO (a
) = -1;
3023 ALLOCNO_ASSIGNED_P (a
) = true;
3024 ira_assert (ALLOCNO_UPDATED_HARD_REG_COSTS (a
) == NULL
);
3025 ira_assert (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a
) == NULL
);
3026 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
3028 fprintf (ira_dump_file
, " Spill");
3029 ira_print_expanded_allocno (a
);
3030 fprintf (ira_dump_file
, "\n");
3034 sorted_allocnos
[n
++] = a
;
3038 setup_allocno_priorities (sorted_allocnos
, n
);
3039 qsort (sorted_allocnos
, n
, sizeof (ira_allocno_t
),
3040 allocno_priority_compare_func
);
3041 for (i
= 0; i
< n
; i
++)
3043 a
= sorted_allocnos
[i
];
3044 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
3046 fprintf (ira_dump_file
, " ");
3047 ira_print_expanded_allocno (a
);
3048 fprintf (ira_dump_file
, " -- ");
3050 if (assign_hard_reg (a
, false))
3052 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
3053 fprintf (ira_dump_file
, "assign hard reg %d\n",
3054 ALLOCNO_HARD_REGNO (a
));
3058 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
3059 fprintf (ira_dump_file
, "assign memory\n");
3066 form_allocno_hard_regs_nodes_forest ();
3067 if (internal_flag_ira_verbose
> 2 && ira_dump_file
!= NULL
)
3068 print_hard_regs_forest (ira_dump_file
);
3069 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap
, 0, i
, bi
)
3071 a
= ira_allocnos
[i
];
3072 if (ALLOCNO_CLASS (a
) != NO_REGS
&& ! empty_profitable_hard_regs (a
))
3074 ALLOCNO_COLOR_DATA (a
)->in_graph_p
= true;
3075 update_costs_from_prefs (a
);
3079 ALLOCNO_HARD_REGNO (a
) = -1;
3080 ALLOCNO_ASSIGNED_P (a
) = true;
3081 /* We don't need updated costs anymore. */
3082 ira_free_allocno_updated_costs (a
);
3083 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
3085 fprintf (ira_dump_file
, " Spill");
3086 ira_print_expanded_allocno (a
);
3087 fprintf (ira_dump_file
, "\n");
3091 /* Put the allocnos into the corresponding buckets. */
3092 colorable_allocno_bucket
= NULL
;
3093 uncolorable_allocno_bucket
= NULL
;
3094 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap
, 0, i
, bi
)
3096 a
= ira_allocnos
[i
];
3097 if (ALLOCNO_COLOR_DATA (a
)->in_graph_p
)
3098 put_allocno_into_bucket (a
);
3100 push_allocnos_to_stack ();
3101 pop_allocnos_from_stack ();
3102 finish_allocno_hard_regs_nodes_forest ();
3104 improve_allocation ();
3109 /* Output information about the loop given by its LOOP_TREE_NODE. */
3111 print_loop_title (ira_loop_tree_node_t loop_tree_node
)
3115 ira_loop_tree_node_t subloop_node
, dest_loop_node
;
3119 if (loop_tree_node
->parent
== NULL
)
3120 fprintf (ira_dump_file
,
3121 "\n Loop 0 (parent -1, header bb%d, depth 0)\n bbs:",
3125 ira_assert (current_loops
!= NULL
&& loop_tree_node
->loop
!= NULL
);
3126 fprintf (ira_dump_file
,
3127 "\n Loop %d (parent %d, header bb%d, depth %d)\n bbs:",
3128 loop_tree_node
->loop_num
, loop_tree_node
->parent
->loop_num
,
3129 loop_tree_node
->loop
->header
->index
,
3130 loop_depth (loop_tree_node
->loop
));
3132 for (subloop_node
= loop_tree_node
->children
;
3133 subloop_node
!= NULL
;
3134 subloop_node
= subloop_node
->next
)
3135 if (subloop_node
->bb
!= NULL
)
3137 fprintf (ira_dump_file
, " %d", subloop_node
->bb
->index
);
3138 FOR_EACH_EDGE (e
, ei
, subloop_node
->bb
->succs
)
3139 if (e
->dest
!= EXIT_BLOCK_PTR_FOR_FN (cfun
)
3140 && ((dest_loop_node
= IRA_BB_NODE (e
->dest
)->parent
)
3142 fprintf (ira_dump_file
, "(->%d:l%d)",
3143 e
->dest
->index
, dest_loop_node
->loop_num
);
3145 fprintf (ira_dump_file
, "\n all:");
3146 EXECUTE_IF_SET_IN_BITMAP (loop_tree_node
->all_allocnos
, 0, j
, bi
)
3147 fprintf (ira_dump_file
, " %dr%d", j
, ALLOCNO_REGNO (ira_allocnos
[j
]));
3148 fprintf (ira_dump_file
, "\n modified regnos:");
3149 EXECUTE_IF_SET_IN_BITMAP (loop_tree_node
->modified_regnos
, 0, j
, bi
)
3150 fprintf (ira_dump_file
, " %d", j
);
3151 fprintf (ira_dump_file
, "\n border:");
3152 EXECUTE_IF_SET_IN_BITMAP (loop_tree_node
->border_allocnos
, 0, j
, bi
)
3153 fprintf (ira_dump_file
, " %dr%d", j
, ALLOCNO_REGNO (ira_allocnos
[j
]));
3154 fprintf (ira_dump_file
, "\n Pressure:");
3155 for (j
= 0; (int) j
< ira_pressure_classes_num
; j
++)
3157 enum reg_class pclass
;
3159 pclass
= ira_pressure_classes
[j
];
3160 if (loop_tree_node
->reg_pressure
[pclass
] == 0)
3162 fprintf (ira_dump_file
, " %s=%d", reg_class_names
[pclass
],
3163 loop_tree_node
->reg_pressure
[pclass
]);
3165 fprintf (ira_dump_file
, "\n");
3168 /* Color the allocnos inside loop (in the extreme case it can be all
3169 of the function) given the corresponding LOOP_TREE_NODE. The
3170 function is called for each loop during top-down traverse of the
3173 color_pass (ira_loop_tree_node_t loop_tree_node
)
3175 int regno
, hard_regno
, index
= -1, n
;
3176 int cost
, exit_freq
, enter_freq
;
3180 enum reg_class rclass
, aclass
, pclass
;
3181 ira_allocno_t a
, subloop_allocno
;
3182 ira_loop_tree_node_t subloop_node
;
3184 ira_assert (loop_tree_node
->bb
== NULL
);
3185 if (internal_flag_ira_verbose
> 1 && ira_dump_file
!= NULL
)
3186 print_loop_title (loop_tree_node
);
3188 bitmap_copy (coloring_allocno_bitmap
, loop_tree_node
->all_allocnos
);
3189 bitmap_copy (consideration_allocno_bitmap
, coloring_allocno_bitmap
);
3191 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap
, 0, j
, bi
)
3193 a
= ira_allocnos
[j
];
3195 if (! ALLOCNO_ASSIGNED_P (a
))
3197 bitmap_clear_bit (coloring_allocno_bitmap
, ALLOCNO_NUM (a
));
3200 = (allocno_color_data_t
) ira_allocate (sizeof (struct allocno_color_data
)
3202 memset (allocno_color_data
, 0, sizeof (struct allocno_color_data
) * n
);
3203 curr_allocno_process
= 0;
3205 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap
, 0, j
, bi
)
3207 a
= ira_allocnos
[j
];
3208 ALLOCNO_ADD_DATA (a
) = allocno_color_data
+ n
;
3211 init_allocno_threads ();
3212 /* Color all mentioned allocnos including transparent ones. */
3214 /* Process caps. They are processed just once. */
3215 if (flag_ira_region
== IRA_REGION_MIXED
3216 || flag_ira_region
== IRA_REGION_ALL
)
3217 EXECUTE_IF_SET_IN_BITMAP (loop_tree_node
->all_allocnos
, 0, j
, bi
)
3219 a
= ira_allocnos
[j
];
3220 if (ALLOCNO_CAP_MEMBER (a
) == NULL
)
3222 /* Remove from processing in the next loop. */
3223 bitmap_clear_bit (consideration_allocno_bitmap
, j
);
3224 rclass
= ALLOCNO_CLASS (a
);
3225 pclass
= ira_pressure_class_translate
[rclass
];
3226 if (flag_ira_region
== IRA_REGION_MIXED
3227 && (loop_tree_node
->reg_pressure
[pclass
]
3228 <= ira_class_hard_regs_num
[pclass
]))
3230 mode
= ALLOCNO_MODE (a
);
3231 hard_regno
= ALLOCNO_HARD_REGNO (a
);
3232 if (hard_regno
>= 0)
3234 index
= ira_class_hard_reg_index
[rclass
][hard_regno
];
3235 ira_assert (index
>= 0);
3237 regno
= ALLOCNO_REGNO (a
);
3238 subloop_allocno
= ALLOCNO_CAP_MEMBER (a
);
3239 subloop_node
= ALLOCNO_LOOP_TREE_NODE (subloop_allocno
);
3240 ira_assert (!ALLOCNO_ASSIGNED_P (subloop_allocno
));
3241 ALLOCNO_HARD_REGNO (subloop_allocno
) = hard_regno
;
3242 ALLOCNO_ASSIGNED_P (subloop_allocno
) = true;
3243 if (hard_regno
>= 0)
3244 update_costs_from_copies (subloop_allocno
, true, true);
3245 /* We don't need updated costs anymore. */
3246 ira_free_allocno_updated_costs (subloop_allocno
);
3249 /* Update costs of the corresponding allocnos (not caps) in the
3251 for (subloop_node
= loop_tree_node
->subloops
;
3252 subloop_node
!= NULL
;
3253 subloop_node
= subloop_node
->subloop_next
)
3255 ira_assert (subloop_node
->bb
== NULL
);
3256 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap
, 0, j
, bi
)
3258 a
= ira_allocnos
[j
];
3259 ira_assert (ALLOCNO_CAP_MEMBER (a
) == NULL
);
3260 mode
= ALLOCNO_MODE (a
);
3261 rclass
= ALLOCNO_CLASS (a
);
3262 pclass
= ira_pressure_class_translate
[rclass
];
3263 hard_regno
= ALLOCNO_HARD_REGNO (a
);
3264 /* Use hard register class here. ??? */
3265 if (hard_regno
>= 0)
3267 index
= ira_class_hard_reg_index
[rclass
][hard_regno
];
3268 ira_assert (index
>= 0);
3270 regno
= ALLOCNO_REGNO (a
);
3271 /* ??? conflict costs */
3272 subloop_allocno
= subloop_node
->regno_allocno_map
[regno
];
3273 if (subloop_allocno
== NULL
3274 || ALLOCNO_CAP (subloop_allocno
) != NULL
)
3276 ira_assert (ALLOCNO_CLASS (subloop_allocno
) == rclass
);
3277 ira_assert (bitmap_bit_p (subloop_node
->all_allocnos
,
3278 ALLOCNO_NUM (subloop_allocno
)));
3279 if ((flag_ira_region
== IRA_REGION_MIXED
3280 && (loop_tree_node
->reg_pressure
[pclass
]
3281 <= ira_class_hard_regs_num
[pclass
]))
3282 || (pic_offset_table_rtx
!= NULL
3283 && regno
== (int) REGNO (pic_offset_table_rtx
))
3284 /* Avoid overlapped multi-registers. Moves between them
3285 might result in wrong code generation. */
3287 && ira_reg_class_max_nregs
[pclass
][mode
] > 1))
3289 if (! ALLOCNO_ASSIGNED_P (subloop_allocno
))
3291 ALLOCNO_HARD_REGNO (subloop_allocno
) = hard_regno
;
3292 ALLOCNO_ASSIGNED_P (subloop_allocno
) = true;
3293 if (hard_regno
>= 0)
3294 update_costs_from_copies (subloop_allocno
, true, true);
3295 /* We don't need updated costs anymore. */
3296 ira_free_allocno_updated_costs (subloop_allocno
);
3300 exit_freq
= ira_loop_edge_freq (subloop_node
, regno
, true);
3301 enter_freq
= ira_loop_edge_freq (subloop_node
, regno
, false);
3302 ira_assert (regno
< ira_reg_equiv_len
);
3303 if (ira_equiv_no_lvalue_p (regno
))
3305 if (! ALLOCNO_ASSIGNED_P (subloop_allocno
))
3307 ALLOCNO_HARD_REGNO (subloop_allocno
) = hard_regno
;
3308 ALLOCNO_ASSIGNED_P (subloop_allocno
) = true;
3309 if (hard_regno
>= 0)
3310 update_costs_from_copies (subloop_allocno
, true, true);
3311 /* We don't need updated costs anymore. */
3312 ira_free_allocno_updated_costs (subloop_allocno
);
3315 else if (hard_regno
< 0)
3317 ALLOCNO_UPDATED_MEMORY_COST (subloop_allocno
)
3318 -= ((ira_memory_move_cost
[mode
][rclass
][1] * enter_freq
)
3319 + (ira_memory_move_cost
[mode
][rclass
][0] * exit_freq
));
3323 aclass
= ALLOCNO_CLASS (subloop_allocno
);
3324 ira_init_register_move_cost_if_necessary (mode
);
3325 cost
= (ira_register_move_cost
[mode
][rclass
][rclass
]
3326 * (exit_freq
+ enter_freq
));
3327 ira_allocate_and_set_or_copy_costs
3328 (&ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno
), aclass
,
3329 ALLOCNO_UPDATED_CLASS_COST (subloop_allocno
),
3330 ALLOCNO_HARD_REG_COSTS (subloop_allocno
));
3331 ira_allocate_and_set_or_copy_costs
3332 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (subloop_allocno
),
3333 aclass
, 0, ALLOCNO_CONFLICT_HARD_REG_COSTS (subloop_allocno
));
3334 ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno
)[index
] -= cost
;
3335 ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (subloop_allocno
)[index
]
3337 if (ALLOCNO_UPDATED_CLASS_COST (subloop_allocno
)
3338 > ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno
)[index
])
3339 ALLOCNO_UPDATED_CLASS_COST (subloop_allocno
)
3340 = ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno
)[index
];
3341 ALLOCNO_UPDATED_MEMORY_COST (subloop_allocno
)
3342 += (ira_memory_move_cost
[mode
][rclass
][0] * enter_freq
3343 + ira_memory_move_cost
[mode
][rclass
][1] * exit_freq
);
3347 ira_free (allocno_color_data
);
3348 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap
, 0, j
, bi
)
3350 a
= ira_allocnos
[j
];
3351 ALLOCNO_ADD_DATA (a
) = NULL
;
3355 /* Initialize the common data for coloring and calls functions to do
3356 Chaitin-Briggs and regional coloring. */
3360 coloring_allocno_bitmap
= ira_allocate_bitmap ();
3361 if (internal_flag_ira_verbose
> 0 && ira_dump_file
!= NULL
)
3362 fprintf (ira_dump_file
, "\n**** Allocnos coloring:\n\n");
3364 ira_traverse_loop_tree (false, ira_loop_tree_root
, color_pass
, NULL
);
3366 if (internal_flag_ira_verbose
> 1 && ira_dump_file
!= NULL
)
3367 ira_print_disposition (ira_dump_file
);
3369 ira_free_bitmap (coloring_allocno_bitmap
);
3374 /* Move spill/restore code, which are to be generated in ira-emit.c,
3375 to less frequent points (if it is profitable) by reassigning some
3376 allocnos (in loop with subloops containing in another loop) to
3377 memory which results in longer live-range where the corresponding
3378 pseudo-registers will be in memory. */
3380 move_spill_restore (void)
3382 int cost
, regno
, hard_regno
, hard_regno2
, index
;
3384 int enter_freq
, exit_freq
;
3386 enum reg_class rclass
;
3387 ira_allocno_t a
, parent_allocno
, subloop_allocno
;
3388 ira_loop_tree_node_t parent
, loop_node
, subloop_node
;
3389 ira_allocno_iterator ai
;
3394 if (internal_flag_ira_verbose
> 0 && ira_dump_file
!= NULL
)
3395 fprintf (ira_dump_file
, "New iteration of spill/restore move\n");
3396 FOR_EACH_ALLOCNO (a
, ai
)
3398 regno
= ALLOCNO_REGNO (a
);
3399 loop_node
= ALLOCNO_LOOP_TREE_NODE (a
);
3400 if (ALLOCNO_CAP_MEMBER (a
) != NULL
3401 || ALLOCNO_CAP (a
) != NULL
3402 || (hard_regno
= ALLOCNO_HARD_REGNO (a
)) < 0
3403 || loop_node
->children
== NULL
3404 /* don't do the optimization because it can create
3405 copies and the reload pass can spill the allocno set
3406 by copy although the allocno will not get memory
3408 || ira_equiv_no_lvalue_p (regno
)
3409 || !bitmap_bit_p (loop_node
->border_allocnos
, ALLOCNO_NUM (a
))
3410 /* Do not spill static chain pointer pseudo when
3411 non-local goto is used. */
3412 || non_spilled_static_chain_regno_p (regno
))
3414 mode
= ALLOCNO_MODE (a
);
3415 rclass
= ALLOCNO_CLASS (a
);
3416 index
= ira_class_hard_reg_index
[rclass
][hard_regno
];
3417 ira_assert (index
>= 0);
3418 cost
= (ALLOCNO_MEMORY_COST (a
)
3419 - (ALLOCNO_HARD_REG_COSTS (a
) == NULL
3420 ? ALLOCNO_CLASS_COST (a
)
3421 : ALLOCNO_HARD_REG_COSTS (a
)[index
]));
3422 ira_init_register_move_cost_if_necessary (mode
);
3423 for (subloop_node
= loop_node
->subloops
;
3424 subloop_node
!= NULL
;
3425 subloop_node
= subloop_node
->subloop_next
)
3427 ira_assert (subloop_node
->bb
== NULL
);
3428 subloop_allocno
= subloop_node
->regno_allocno_map
[regno
];
3429 if (subloop_allocno
== NULL
)
3431 ira_assert (rclass
== ALLOCNO_CLASS (subloop_allocno
));
3432 /* We have accumulated cost. To get the real cost of
3433 allocno usage in the loop we should subtract costs of
3434 the subloop allocnos. */
3435 cost
-= (ALLOCNO_MEMORY_COST (subloop_allocno
)
3436 - (ALLOCNO_HARD_REG_COSTS (subloop_allocno
) == NULL
3437 ? ALLOCNO_CLASS_COST (subloop_allocno
)
3438 : ALLOCNO_HARD_REG_COSTS (subloop_allocno
)[index
]));
3439 exit_freq
= ira_loop_edge_freq (subloop_node
, regno
, true);
3440 enter_freq
= ira_loop_edge_freq (subloop_node
, regno
, false);
3441 if ((hard_regno2
= ALLOCNO_HARD_REGNO (subloop_allocno
)) < 0)
3442 cost
-= (ira_memory_move_cost
[mode
][rclass
][0] * exit_freq
3443 + ira_memory_move_cost
[mode
][rclass
][1] * enter_freq
);
3447 += (ira_memory_move_cost
[mode
][rclass
][0] * exit_freq
3448 + ira_memory_move_cost
[mode
][rclass
][1] * enter_freq
);
3449 if (hard_regno2
!= hard_regno
)
3450 cost
-= (ira_register_move_cost
[mode
][rclass
][rclass
]
3451 * (exit_freq
+ enter_freq
));
3454 if ((parent
= loop_node
->parent
) != NULL
3455 && (parent_allocno
= parent
->regno_allocno_map
[regno
]) != NULL
)
3457 ira_assert (rclass
== ALLOCNO_CLASS (parent_allocno
));
3458 exit_freq
= ira_loop_edge_freq (loop_node
, regno
, true);
3459 enter_freq
= ira_loop_edge_freq (loop_node
, regno
, false);
3460 if ((hard_regno2
= ALLOCNO_HARD_REGNO (parent_allocno
)) < 0)
3461 cost
-= (ira_memory_move_cost
[mode
][rclass
][0] * exit_freq
3462 + ira_memory_move_cost
[mode
][rclass
][1] * enter_freq
);
3466 += (ira_memory_move_cost
[mode
][rclass
][1] * exit_freq
3467 + ira_memory_move_cost
[mode
][rclass
][0] * enter_freq
);
3468 if (hard_regno2
!= hard_regno
)
3469 cost
-= (ira_register_move_cost
[mode
][rclass
][rclass
]
3470 * (exit_freq
+ enter_freq
));
3475 ALLOCNO_HARD_REGNO (a
) = -1;
3476 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
3480 " Moving spill/restore for a%dr%d up from loop %d",
3481 ALLOCNO_NUM (a
), regno
, loop_node
->loop_num
);
3482 fprintf (ira_dump_file
, " - profit %d\n", -cost
);
3494 /* Update current hard reg costs and current conflict hard reg costs
3495 for allocno A. It is done by processing its copies containing
3496 other allocnos already assigned. */
3498 update_curr_costs (ira_allocno_t a
)
3500 int i
, hard_regno
, cost
;
3502 enum reg_class aclass
, rclass
;
3503 ira_allocno_t another_a
;
3504 ira_copy_t cp
, next_cp
;
3506 ira_free_allocno_updated_costs (a
);
3507 ira_assert (! ALLOCNO_ASSIGNED_P (a
));
3508 aclass
= ALLOCNO_CLASS (a
);
3509 if (aclass
== NO_REGS
)
3511 mode
= ALLOCNO_MODE (a
);
3512 ira_init_register_move_cost_if_necessary (mode
);
3513 for (cp
= ALLOCNO_COPIES (a
); cp
!= NULL
; cp
= next_cp
)
3517 next_cp
= cp
->next_first_allocno_copy
;
3518 another_a
= cp
->second
;
3520 else if (cp
->second
== a
)
3522 next_cp
= cp
->next_second_allocno_copy
;
3523 another_a
= cp
->first
;
3527 if (! ira_reg_classes_intersect_p
[aclass
][ALLOCNO_CLASS (another_a
)]
3528 || ! ALLOCNO_ASSIGNED_P (another_a
)
3529 || (hard_regno
= ALLOCNO_HARD_REGNO (another_a
)) < 0)
3531 rclass
= REGNO_REG_CLASS (hard_regno
);
3532 i
= ira_class_hard_reg_index
[aclass
][hard_regno
];
3535 cost
= (cp
->first
== a
3536 ? ira_register_move_cost
[mode
][rclass
][aclass
]
3537 : ira_register_move_cost
[mode
][aclass
][rclass
]);
3538 ira_allocate_and_set_or_copy_costs
3539 (&ALLOCNO_UPDATED_HARD_REG_COSTS (a
), aclass
, ALLOCNO_CLASS_COST (a
),
3540 ALLOCNO_HARD_REG_COSTS (a
));
3541 ira_allocate_and_set_or_copy_costs
3542 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a
),
3543 aclass
, 0, ALLOCNO_CONFLICT_HARD_REG_COSTS (a
));
3544 ALLOCNO_UPDATED_HARD_REG_COSTS (a
)[i
] -= cp
->freq
* cost
;
3545 ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a
)[i
] -= cp
->freq
* cost
;
3549 /* Try to assign hard registers to the unassigned allocnos and
3550 allocnos conflicting with them or conflicting with allocnos whose
3551 regno >= START_REGNO. The function is called after ira_flattening,
3552 so more allocnos (including ones created in ira-emit.c) will have a
3553 chance to get a hard register. We use simple assignment algorithm
3554 based on priorities. */
3556 ira_reassign_conflict_allocnos (int start_regno
)
3558 int i
, allocnos_to_color_num
;
3560 enum reg_class aclass
;
3561 bitmap allocnos_to_color
;
3562 ira_allocno_iterator ai
;
3564 allocnos_to_color
= ira_allocate_bitmap ();
3565 allocnos_to_color_num
= 0;
3566 FOR_EACH_ALLOCNO (a
, ai
)
3568 int n
= ALLOCNO_NUM_OBJECTS (a
);
3570 if (! ALLOCNO_ASSIGNED_P (a
)
3571 && ! bitmap_bit_p (allocnos_to_color
, ALLOCNO_NUM (a
)))
3573 if (ALLOCNO_CLASS (a
) != NO_REGS
)
3574 sorted_allocnos
[allocnos_to_color_num
++] = a
;
3577 ALLOCNO_ASSIGNED_P (a
) = true;
3578 ALLOCNO_HARD_REGNO (a
) = -1;
3579 ira_assert (ALLOCNO_UPDATED_HARD_REG_COSTS (a
) == NULL
);
3580 ira_assert (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a
) == NULL
);
3582 bitmap_set_bit (allocnos_to_color
, ALLOCNO_NUM (a
));
3584 if (ALLOCNO_REGNO (a
) < start_regno
3585 || (aclass
= ALLOCNO_CLASS (a
)) == NO_REGS
)
3587 for (i
= 0; i
< n
; i
++)
3589 ira_object_t obj
= ALLOCNO_OBJECT (a
, i
);
3590 ira_object_t conflict_obj
;
3591 ira_object_conflict_iterator oci
;
3593 FOR_EACH_OBJECT_CONFLICT (obj
, conflict_obj
, oci
)
3595 ira_allocno_t conflict_a
= OBJECT_ALLOCNO (conflict_obj
);
3597 ira_assert (ira_reg_classes_intersect_p
3598 [aclass
][ALLOCNO_CLASS (conflict_a
)]);
3599 if (!bitmap_set_bit (allocnos_to_color
, ALLOCNO_NUM (conflict_a
)))
3601 sorted_allocnos
[allocnos_to_color_num
++] = conflict_a
;
3605 ira_free_bitmap (allocnos_to_color
);
3606 if (allocnos_to_color_num
> 1)
3608 setup_allocno_priorities (sorted_allocnos
, allocnos_to_color_num
);
3609 qsort (sorted_allocnos
, allocnos_to_color_num
, sizeof (ira_allocno_t
),
3610 allocno_priority_compare_func
);
3612 for (i
= 0; i
< allocnos_to_color_num
; i
++)
3614 a
= sorted_allocnos
[i
];
3615 ALLOCNO_ASSIGNED_P (a
) = false;
3616 update_curr_costs (a
);
3618 for (i
= 0; i
< allocnos_to_color_num
; i
++)
3620 a
= sorted_allocnos
[i
];
3621 if (assign_hard_reg (a
, true))
3623 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
3626 " Secondary allocation: assign hard reg %d to reg %d\n",
3627 ALLOCNO_HARD_REGNO (a
), ALLOCNO_REGNO (a
));
3634 /* This page contains functions used to find conflicts using allocno
3637 #ifdef ENABLE_IRA_CHECKING
3639 /* Return TRUE if live ranges of pseudo-registers REGNO1 and REGNO2
3640 intersect. This should be used when there is only one region.
3641 Currently this is used during reload. */
3643 conflict_by_live_ranges_p (int regno1
, int regno2
)
3645 ira_allocno_t a1
, a2
;
3647 ira_assert (regno1
>= FIRST_PSEUDO_REGISTER
3648 && regno2
>= FIRST_PSEUDO_REGISTER
);
3649 /* Reg info calculated by dataflow infrastructure can be different
3650 from one calculated by regclass. */
3651 if ((a1
= ira_loop_tree_root
->regno_allocno_map
[regno1
]) == NULL
3652 || (a2
= ira_loop_tree_root
->regno_allocno_map
[regno2
]) == NULL
)
3654 return allocnos_conflict_by_live_ranges_p (a1
, a2
);
3661 /* This page contains code to coalesce memory stack slots used by
3662 spilled allocnos. This results in smaller stack frame, better data
3663 locality, and in smaller code for some architectures like
3664 x86/x86_64 where insn size depends on address displacement value.
3665 On the other hand, it can worsen insn scheduling after the RA but
3666 in practice it is less important than smaller stack frames. */
3668 /* TRUE if we coalesced some allocnos. In other words, if we got
3669 loops formed by members first_coalesced_allocno and
3670 next_coalesced_allocno containing more one allocno. */
3671 static bool allocno_coalesced_p
;
3673 /* Bitmap used to prevent a repeated allocno processing because of
3675 static bitmap processed_coalesced_allocno_bitmap
;
3678 typedef struct coalesce_data
*coalesce_data_t
;
3680 /* To decrease footprint of ira_allocno structure we store all data
3681 needed only for coalescing in the following structure. */
3682 struct coalesce_data
3684 /* Coalesced allocnos form a cyclic list. One allocno given by
3685 FIRST represents all coalesced allocnos. The
3686 list is chained by NEXT. */
3687 ira_allocno_t first
;
3692 /* Container for storing allocno data concerning coalescing. */
3693 static coalesce_data_t allocno_coalesce_data
;
3695 /* Macro to access the data concerning coalescing. */
3696 #define ALLOCNO_COALESCE_DATA(a) ((coalesce_data_t) ALLOCNO_ADD_DATA (a))
3698 /* Merge two sets of coalesced allocnos given correspondingly by
3699 allocnos A1 and A2 (more accurately merging A2 set into A1
3702 merge_allocnos (ira_allocno_t a1
, ira_allocno_t a2
)
3704 ira_allocno_t a
, first
, last
, next
;
3706 first
= ALLOCNO_COALESCE_DATA (a1
)->first
;
3707 a
= ALLOCNO_COALESCE_DATA (a2
)->first
;
3710 for (last
= a2
, a
= ALLOCNO_COALESCE_DATA (a2
)->next
;;
3711 a
= ALLOCNO_COALESCE_DATA (a
)->next
)
3713 ALLOCNO_COALESCE_DATA (a
)->first
= first
;
3718 next
= allocno_coalesce_data
[ALLOCNO_NUM (first
)].next
;
3719 allocno_coalesce_data
[ALLOCNO_NUM (first
)].next
= a2
;
3720 allocno_coalesce_data
[ALLOCNO_NUM (last
)].next
= next
;
3723 /* Return TRUE if there are conflicting allocnos from two sets of
3724 coalesced allocnos given correspondingly by allocnos A1 and A2. We
3725 use live ranges to find conflicts because conflicts are represented
3726 only for allocnos of the same allocno class and during the reload
3727 pass we coalesce allocnos for sharing stack memory slots. */
3729 coalesced_allocno_conflict_p (ira_allocno_t a1
, ira_allocno_t a2
)
3731 ira_allocno_t a
, conflict_a
;
3733 if (allocno_coalesced_p
)
3735 bitmap_clear (processed_coalesced_allocno_bitmap
);
3736 for (a
= ALLOCNO_COALESCE_DATA (a1
)->next
;;
3737 a
= ALLOCNO_COALESCE_DATA (a
)->next
)
3739 bitmap_set_bit (processed_coalesced_allocno_bitmap
, ALLOCNO_NUM (a
));
3744 for (a
= ALLOCNO_COALESCE_DATA (a2
)->next
;;
3745 a
= ALLOCNO_COALESCE_DATA (a
)->next
)
3747 for (conflict_a
= ALLOCNO_COALESCE_DATA (a1
)->next
;;
3748 conflict_a
= ALLOCNO_COALESCE_DATA (conflict_a
)->next
)
3750 if (allocnos_conflict_by_live_ranges_p (a
, conflict_a
))
3752 if (conflict_a
== a1
)
3761 /* The major function for aggressive allocno coalescing. We coalesce
3762 only spilled allocnos. If some allocnos have been coalesced, we
3763 set up flag allocno_coalesced_p. */
3765 coalesce_allocnos (void)
3768 ira_copy_t cp
, next_cp
;
3770 int i
, n
, cp_num
, regno
;
3774 /* Collect copies. */
3775 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap
, 0, j
, bi
)
3777 a
= ira_allocnos
[j
];
3778 regno
= ALLOCNO_REGNO (a
);
3779 if (! ALLOCNO_ASSIGNED_P (a
) || ALLOCNO_HARD_REGNO (a
) >= 0
3780 || ira_equiv_no_lvalue_p (regno
))
3782 for (cp
= ALLOCNO_COPIES (a
); cp
!= NULL
; cp
= next_cp
)
3786 next_cp
= cp
->next_first_allocno_copy
;
3787 regno
= ALLOCNO_REGNO (cp
->second
);
3788 /* For priority coloring we coalesce allocnos only with
3789 the same allocno class not with intersected allocno
3790 classes as it were possible. It is done for
3792 if ((cp
->insn
!= NULL
|| cp
->constraint_p
)
3793 && ALLOCNO_ASSIGNED_P (cp
->second
)
3794 && ALLOCNO_HARD_REGNO (cp
->second
) < 0
3795 && ! ira_equiv_no_lvalue_p (regno
))
3796 sorted_copies
[cp_num
++] = cp
;
3798 else if (cp
->second
== a
)
3799 next_cp
= cp
->next_second_allocno_copy
;
3804 qsort (sorted_copies
, cp_num
, sizeof (ira_copy_t
), copy_freq_compare_func
);
3805 /* Coalesced copies, most frequently executed first. */
3806 for (; cp_num
!= 0;)
3808 for (i
= 0; i
< cp_num
; i
++)
3810 cp
= sorted_copies
[i
];
3811 if (! coalesced_allocno_conflict_p (cp
->first
, cp
->second
))
3813 allocno_coalesced_p
= true;
3814 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
3817 " Coalescing copy %d:a%dr%d-a%dr%d (freq=%d)\n",
3818 cp
->num
, ALLOCNO_NUM (cp
->first
), ALLOCNO_REGNO (cp
->first
),
3819 ALLOCNO_NUM (cp
->second
), ALLOCNO_REGNO (cp
->second
),
3821 merge_allocnos (cp
->first
, cp
->second
);
3826 /* Collect the rest of copies. */
3827 for (n
= 0; i
< cp_num
; i
++)
3829 cp
= sorted_copies
[i
];
3830 if (allocno_coalesce_data
[ALLOCNO_NUM (cp
->first
)].first
3831 != allocno_coalesce_data
[ALLOCNO_NUM (cp
->second
)].first
)
3832 sorted_copies
[n
++] = cp
;
3838 /* Usage cost and order number of coalesced allocno set to which
3839 given pseudo register belongs to. */
3840 static int *regno_coalesced_allocno_cost
;
3841 static int *regno_coalesced_allocno_num
;
3843 /* Sort pseudos according frequencies of coalesced allocno sets they
3844 belong to (putting most frequently ones first), and according to
3845 coalesced allocno set order numbers. */
3847 coalesced_pseudo_reg_freq_compare (const void *v1p
, const void *v2p
)
3849 const int regno1
= *(const int *) v1p
;
3850 const int regno2
= *(const int *) v2p
;
3853 if ((diff
= (regno_coalesced_allocno_cost
[regno2
]
3854 - regno_coalesced_allocno_cost
[regno1
])) != 0)
3856 if ((diff
= (regno_coalesced_allocno_num
[regno1
]
3857 - regno_coalesced_allocno_num
[regno2
])) != 0)
3859 return regno1
- regno2
;
3862 /* Widest width in which each pseudo reg is referred to (via subreg).
3863 It is used for sorting pseudo registers. */
3864 static unsigned int *regno_max_ref_width
;
3866 /* Sort pseudos according their slot numbers (putting ones with
3867 smaller numbers first, or last when the frame pointer is not
3870 coalesced_pseudo_reg_slot_compare (const void *v1p
, const void *v2p
)
3872 const int regno1
= *(const int *) v1p
;
3873 const int regno2
= *(const int *) v2p
;
3874 ira_allocno_t a1
= ira_regno_allocno_map
[regno1
];
3875 ira_allocno_t a2
= ira_regno_allocno_map
[regno2
];
3876 int diff
, slot_num1
, slot_num2
;
3877 int total_size1
, total_size2
;
3879 if (a1
== NULL
|| ALLOCNO_HARD_REGNO (a1
) >= 0)
3881 if (a2
== NULL
|| ALLOCNO_HARD_REGNO (a2
) >= 0)
3882 return regno1
- regno2
;
3885 else if (a2
== NULL
|| ALLOCNO_HARD_REGNO (a2
) >= 0)
3887 slot_num1
= -ALLOCNO_HARD_REGNO (a1
);
3888 slot_num2
= -ALLOCNO_HARD_REGNO (a2
);
3889 if ((diff
= slot_num1
- slot_num2
) != 0)
3890 return (frame_pointer_needed
3891 || (!FRAME_GROWS_DOWNWARD
) == STACK_GROWS_DOWNWARD
? diff
: -diff
);
3892 total_size1
= MAX (PSEUDO_REGNO_BYTES (regno1
),
3893 regno_max_ref_width
[regno1
]);
3894 total_size2
= MAX (PSEUDO_REGNO_BYTES (regno2
),
3895 regno_max_ref_width
[regno2
]);
3896 if ((diff
= total_size2
- total_size1
) != 0)
3898 return regno1
- regno2
;
3901 /* Setup REGNO_COALESCED_ALLOCNO_COST and REGNO_COALESCED_ALLOCNO_NUM
3902 for coalesced allocno sets containing allocnos with their regnos
3903 given in array PSEUDO_REGNOS of length N. */
3905 setup_coalesced_allocno_costs_and_nums (int *pseudo_regnos
, int n
)
3907 int i
, num
, regno
, cost
;
3908 ira_allocno_t allocno
, a
;
3910 for (num
= i
= 0; i
< n
; i
++)
3912 regno
= pseudo_regnos
[i
];
3913 allocno
= ira_regno_allocno_map
[regno
];
3914 if (allocno
== NULL
)
3916 regno_coalesced_allocno_cost
[regno
] = 0;
3917 regno_coalesced_allocno_num
[regno
] = ++num
;
3920 if (ALLOCNO_COALESCE_DATA (allocno
)->first
!= allocno
)
3923 for (cost
= 0, a
= ALLOCNO_COALESCE_DATA (allocno
)->next
;;
3924 a
= ALLOCNO_COALESCE_DATA (a
)->next
)
3926 cost
+= ALLOCNO_FREQ (a
);
3930 for (a
= ALLOCNO_COALESCE_DATA (allocno
)->next
;;
3931 a
= ALLOCNO_COALESCE_DATA (a
)->next
)
3933 regno_coalesced_allocno_num
[ALLOCNO_REGNO (a
)] = num
;
3934 regno_coalesced_allocno_cost
[ALLOCNO_REGNO (a
)] = cost
;
3941 /* Collect spilled allocnos representing coalesced allocno sets (the
3942 first coalesced allocno). The collected allocnos are returned
3943 through array SPILLED_COALESCED_ALLOCNOS. The function returns the
3944 number of the collected allocnos. The allocnos are given by their
3945 regnos in array PSEUDO_REGNOS of length N. */
3947 collect_spilled_coalesced_allocnos (int *pseudo_regnos
, int n
,
3948 ira_allocno_t
*spilled_coalesced_allocnos
)
3951 ira_allocno_t allocno
;
3953 for (num
= i
= 0; i
< n
; i
++)
3955 regno
= pseudo_regnos
[i
];
3956 allocno
= ira_regno_allocno_map
[regno
];
3957 if (allocno
== NULL
|| ALLOCNO_HARD_REGNO (allocno
) >= 0
3958 || ALLOCNO_COALESCE_DATA (allocno
)->first
!= allocno
)
3960 spilled_coalesced_allocnos
[num
++] = allocno
;
3965 /* Array of live ranges of size IRA_ALLOCNOS_NUM. Live range for
3966 given slot contains live ranges of coalesced allocnos assigned to
3968 static live_range_t
*slot_coalesced_allocnos_live_ranges
;
3970 /* Return TRUE if coalesced allocnos represented by ALLOCNO has live
3971 ranges intersected with live ranges of coalesced allocnos assigned
3972 to slot with number N. */
3974 slot_coalesced_allocno_live_ranges_intersect_p (ira_allocno_t allocno
, int n
)
3978 for (a
= ALLOCNO_COALESCE_DATA (allocno
)->next
;;
3979 a
= ALLOCNO_COALESCE_DATA (a
)->next
)
3982 int nr
= ALLOCNO_NUM_OBJECTS (a
);
3984 for (i
= 0; i
< nr
; i
++)
3986 ira_object_t obj
= ALLOCNO_OBJECT (a
, i
);
3988 if (ira_live_ranges_intersect_p
3989 (slot_coalesced_allocnos_live_ranges
[n
],
3990 OBJECT_LIVE_RANGES (obj
)))
3999 /* Update live ranges of slot to which coalesced allocnos represented
4000 by ALLOCNO were assigned. */
4002 setup_slot_coalesced_allocno_live_ranges (ira_allocno_t allocno
)
4008 n
= ALLOCNO_COALESCE_DATA (allocno
)->temp
;
4009 for (a
= ALLOCNO_COALESCE_DATA (allocno
)->next
;;
4010 a
= ALLOCNO_COALESCE_DATA (a
)->next
)
4012 int nr
= ALLOCNO_NUM_OBJECTS (a
);
4013 for (i
= 0; i
< nr
; i
++)
4015 ira_object_t obj
= ALLOCNO_OBJECT (a
, i
);
4017 r
= ira_copy_live_range_list (OBJECT_LIVE_RANGES (obj
));
4018 slot_coalesced_allocnos_live_ranges
[n
]
4019 = ira_merge_live_ranges
4020 (slot_coalesced_allocnos_live_ranges
[n
], r
);
4027 /* We have coalesced allocnos involving in copies. Coalesce allocnos
4028 further in order to share the same memory stack slot. Allocnos
4029 representing sets of allocnos coalesced before the call are given
4030 in array SPILLED_COALESCED_ALLOCNOS of length NUM. Return TRUE if
4031 some allocnos were coalesced in the function. */
4033 coalesce_spill_slots (ira_allocno_t
*spilled_coalesced_allocnos
, int num
)
4035 int i
, j
, n
, last_coalesced_allocno_num
;
4036 ira_allocno_t allocno
, a
;
4037 bool merged_p
= false;
4038 bitmap set_jump_crosses
= regstat_get_setjmp_crosses ();
4040 slot_coalesced_allocnos_live_ranges
4041 = (live_range_t
*) ira_allocate (sizeof (live_range_t
) * ira_allocnos_num
);
4042 memset (slot_coalesced_allocnos_live_ranges
, 0,
4043 sizeof (live_range_t
) * ira_allocnos_num
);
4044 last_coalesced_allocno_num
= 0;
4045 /* Coalesce non-conflicting spilled allocnos preferring most
4047 for (i
= 0; i
< num
; i
++)
4049 allocno
= spilled_coalesced_allocnos
[i
];
4050 if (ALLOCNO_COALESCE_DATA (allocno
)->first
!= allocno
4051 || bitmap_bit_p (set_jump_crosses
, ALLOCNO_REGNO (allocno
))
4052 || ira_equiv_no_lvalue_p (ALLOCNO_REGNO (allocno
)))
4054 for (j
= 0; j
< i
; j
++)
4056 a
= spilled_coalesced_allocnos
[j
];
4057 n
= ALLOCNO_COALESCE_DATA (a
)->temp
;
4058 if (ALLOCNO_COALESCE_DATA (a
)->first
== a
4059 && ! bitmap_bit_p (set_jump_crosses
, ALLOCNO_REGNO (a
))
4060 && ! ira_equiv_no_lvalue_p (ALLOCNO_REGNO (a
))
4061 && ! slot_coalesced_allocno_live_ranges_intersect_p (allocno
, n
))
4066 /* No coalescing: set up number for coalesced allocnos
4067 represented by ALLOCNO. */
4068 ALLOCNO_COALESCE_DATA (allocno
)->temp
= last_coalesced_allocno_num
++;
4069 setup_slot_coalesced_allocno_live_ranges (allocno
);
4073 allocno_coalesced_p
= true;
4075 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
4076 fprintf (ira_dump_file
,
4077 " Coalescing spilled allocnos a%dr%d->a%dr%d\n",
4078 ALLOCNO_NUM (allocno
), ALLOCNO_REGNO (allocno
),
4079 ALLOCNO_NUM (a
), ALLOCNO_REGNO (a
));
4080 ALLOCNO_COALESCE_DATA (allocno
)->temp
4081 = ALLOCNO_COALESCE_DATA (a
)->temp
;
4082 setup_slot_coalesced_allocno_live_ranges (allocno
);
4083 merge_allocnos (a
, allocno
);
4084 ira_assert (ALLOCNO_COALESCE_DATA (a
)->first
== a
);
4087 for (i
= 0; i
< ira_allocnos_num
; i
++)
4088 ira_finish_live_range_list (slot_coalesced_allocnos_live_ranges
[i
]);
4089 ira_free (slot_coalesced_allocnos_live_ranges
);
4093 /* Sort pseudo-register numbers in array PSEUDO_REGNOS of length N for
4094 subsequent assigning stack slots to them in the reload pass. To do
4095 this we coalesce spilled allocnos first to decrease the number of
4096 memory-memory move insns. This function is called by the
4099 ira_sort_regnos_for_alter_reg (int *pseudo_regnos
, int n
,
4100 unsigned int *reg_max_ref_width
)
4102 int max_regno
= max_reg_num ();
4103 int i
, regno
, num
, slot_num
;
4104 ira_allocno_t allocno
, a
;
4105 ira_allocno_iterator ai
;
4106 ira_allocno_t
*spilled_coalesced_allocnos
;
4108 ira_assert (! ira_use_lra_p
);
4110 /* Set up allocnos can be coalesced. */
4111 coloring_allocno_bitmap
= ira_allocate_bitmap ();
4112 for (i
= 0; i
< n
; i
++)
4114 regno
= pseudo_regnos
[i
];
4115 allocno
= ira_regno_allocno_map
[regno
];
4116 if (allocno
!= NULL
)
4117 bitmap_set_bit (coloring_allocno_bitmap
, ALLOCNO_NUM (allocno
));
4119 allocno_coalesced_p
= false;
4120 processed_coalesced_allocno_bitmap
= ira_allocate_bitmap ();
4121 allocno_coalesce_data
4122 = (coalesce_data_t
) ira_allocate (sizeof (struct coalesce_data
)
4123 * ira_allocnos_num
);
4124 /* Initialize coalesce data for allocnos. */
4125 FOR_EACH_ALLOCNO (a
, ai
)
4127 ALLOCNO_ADD_DATA (a
) = allocno_coalesce_data
+ ALLOCNO_NUM (a
);
4128 ALLOCNO_COALESCE_DATA (a
)->first
= a
;
4129 ALLOCNO_COALESCE_DATA (a
)->next
= a
;
4131 coalesce_allocnos ();
4132 ira_free_bitmap (coloring_allocno_bitmap
);
4133 regno_coalesced_allocno_cost
4134 = (int *) ira_allocate (max_regno
* sizeof (int));
4135 regno_coalesced_allocno_num
4136 = (int *) ira_allocate (max_regno
* sizeof (int));
4137 memset (regno_coalesced_allocno_num
, 0, max_regno
* sizeof (int));
4138 setup_coalesced_allocno_costs_and_nums (pseudo_regnos
, n
);
4139 /* Sort regnos according frequencies of the corresponding coalesced
4141 qsort (pseudo_regnos
, n
, sizeof (int), coalesced_pseudo_reg_freq_compare
);
4142 spilled_coalesced_allocnos
4143 = (ira_allocno_t
*) ira_allocate (ira_allocnos_num
4144 * sizeof (ira_allocno_t
));
4145 /* Collect allocnos representing the spilled coalesced allocno
4147 num
= collect_spilled_coalesced_allocnos (pseudo_regnos
, n
,
4148 spilled_coalesced_allocnos
);
4149 if (flag_ira_share_spill_slots
4150 && coalesce_spill_slots (spilled_coalesced_allocnos
, num
))
4152 setup_coalesced_allocno_costs_and_nums (pseudo_regnos
, n
);
4153 qsort (pseudo_regnos
, n
, sizeof (int),
4154 coalesced_pseudo_reg_freq_compare
);
4155 num
= collect_spilled_coalesced_allocnos (pseudo_regnos
, n
,
4156 spilled_coalesced_allocnos
);
4158 ira_free_bitmap (processed_coalesced_allocno_bitmap
);
4159 allocno_coalesced_p
= false;
4160 /* Assign stack slot numbers to spilled allocno sets, use smaller
4161 numbers for most frequently used coalesced allocnos. -1 is
4162 reserved for dynamic search of stack slots for pseudos spilled by
4165 for (i
= 0; i
< num
; i
++)
4167 allocno
= spilled_coalesced_allocnos
[i
];
4168 if (ALLOCNO_COALESCE_DATA (allocno
)->first
!= allocno
4169 || ALLOCNO_HARD_REGNO (allocno
) >= 0
4170 || ira_equiv_no_lvalue_p (ALLOCNO_REGNO (allocno
)))
4172 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
4173 fprintf (ira_dump_file
, " Slot %d (freq,size):", slot_num
);
4175 for (a
= ALLOCNO_COALESCE_DATA (allocno
)->next
;;
4176 a
= ALLOCNO_COALESCE_DATA (a
)->next
)
4178 ira_assert (ALLOCNO_HARD_REGNO (a
) < 0);
4179 ALLOCNO_HARD_REGNO (a
) = -slot_num
;
4180 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
4181 fprintf (ira_dump_file
, " a%dr%d(%d,%d)",
4182 ALLOCNO_NUM (a
), ALLOCNO_REGNO (a
), ALLOCNO_FREQ (a
),
4183 MAX (PSEUDO_REGNO_BYTES (ALLOCNO_REGNO (a
)),
4184 reg_max_ref_width
[ALLOCNO_REGNO (a
)]));
4189 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
4190 fprintf (ira_dump_file
, "\n");
4192 ira_spilled_reg_stack_slots_num
= slot_num
- 1;
4193 ira_free (spilled_coalesced_allocnos
);
4194 /* Sort regnos according the slot numbers. */
4195 regno_max_ref_width
= reg_max_ref_width
;
4196 qsort (pseudo_regnos
, n
, sizeof (int), coalesced_pseudo_reg_slot_compare
);
4197 FOR_EACH_ALLOCNO (a
, ai
)
4198 ALLOCNO_ADD_DATA (a
) = NULL
;
4199 ira_free (allocno_coalesce_data
);
4200 ira_free (regno_coalesced_allocno_num
);
4201 ira_free (regno_coalesced_allocno_cost
);
4206 /* This page contains code used by the reload pass to improve the
4209 /* The function is called from reload to mark changes in the
4210 allocation of REGNO made by the reload. Remember that reg_renumber
4211 reflects the change result. */
4213 ira_mark_allocation_change (int regno
)
4215 ira_allocno_t a
= ira_regno_allocno_map
[regno
];
4216 int old_hard_regno
, hard_regno
, cost
;
4217 enum reg_class aclass
= ALLOCNO_CLASS (a
);
4219 ira_assert (a
!= NULL
);
4220 hard_regno
= reg_renumber
[regno
];
4221 if ((old_hard_regno
= ALLOCNO_HARD_REGNO (a
)) == hard_regno
)
4223 if (old_hard_regno
< 0)
4224 cost
= -ALLOCNO_MEMORY_COST (a
);
4227 ira_assert (ira_class_hard_reg_index
[aclass
][old_hard_regno
] >= 0);
4228 cost
= -(ALLOCNO_HARD_REG_COSTS (a
) == NULL
4229 ? ALLOCNO_CLASS_COST (a
)
4230 : ALLOCNO_HARD_REG_COSTS (a
)
4231 [ira_class_hard_reg_index
[aclass
][old_hard_regno
]]);
4232 update_costs_from_copies (a
, false, false);
4234 ira_overall_cost
-= cost
;
4235 ALLOCNO_HARD_REGNO (a
) = hard_regno
;
4238 ALLOCNO_HARD_REGNO (a
) = -1;
4239 cost
+= ALLOCNO_MEMORY_COST (a
);
4241 else if (ira_class_hard_reg_index
[aclass
][hard_regno
] >= 0)
4243 cost
+= (ALLOCNO_HARD_REG_COSTS (a
) == NULL
4244 ? ALLOCNO_CLASS_COST (a
)
4245 : ALLOCNO_HARD_REG_COSTS (a
)
4246 [ira_class_hard_reg_index
[aclass
][hard_regno
]]);
4247 update_costs_from_copies (a
, true, false);
4250 /* Reload changed class of the allocno. */
4252 ira_overall_cost
+= cost
;
4255 /* This function is called when reload deletes memory-memory move. In
4256 this case we marks that the allocation of the corresponding
4257 allocnos should be not changed in future. Otherwise we risk to get
4260 ira_mark_memory_move_deletion (int dst_regno
, int src_regno
)
4262 ira_allocno_t dst
= ira_regno_allocno_map
[dst_regno
];
4263 ira_allocno_t src
= ira_regno_allocno_map
[src_regno
];
4265 ira_assert (dst
!= NULL
&& src
!= NULL
4266 && ALLOCNO_HARD_REGNO (dst
) < 0
4267 && ALLOCNO_HARD_REGNO (src
) < 0);
4268 ALLOCNO_DONT_REASSIGN_P (dst
) = true;
4269 ALLOCNO_DONT_REASSIGN_P (src
) = true;
4272 /* Try to assign a hard register (except for FORBIDDEN_REGS) to
4273 allocno A and return TRUE in the case of success. */
4275 allocno_reload_assign (ira_allocno_t a
, HARD_REG_SET forbidden_regs
)
4278 enum reg_class aclass
;
4279 int regno
= ALLOCNO_REGNO (a
);
4280 HARD_REG_SET saved
[2];
4283 n
= ALLOCNO_NUM_OBJECTS (a
);
4284 for (i
= 0; i
< n
; i
++)
4286 ira_object_t obj
= ALLOCNO_OBJECT (a
, i
);
4287 COPY_HARD_REG_SET (saved
[i
], OBJECT_TOTAL_CONFLICT_HARD_REGS (obj
));
4288 IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj
), forbidden_regs
);
4289 if (! flag_caller_saves
&& ALLOCNO_CALLS_CROSSED_NUM (a
) != 0)
4290 IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj
),
4293 ALLOCNO_ASSIGNED_P (a
) = false;
4294 aclass
= ALLOCNO_CLASS (a
);
4295 update_curr_costs (a
);
4296 assign_hard_reg (a
, true);
4297 hard_regno
= ALLOCNO_HARD_REGNO (a
);
4298 reg_renumber
[regno
] = hard_regno
;
4300 ALLOCNO_HARD_REGNO (a
) = -1;
4303 ira_assert (ira_class_hard_reg_index
[aclass
][hard_regno
] >= 0);
4305 -= (ALLOCNO_MEMORY_COST (a
)
4306 - (ALLOCNO_HARD_REG_COSTS (a
) == NULL
4307 ? ALLOCNO_CLASS_COST (a
)
4308 : ALLOCNO_HARD_REG_COSTS (a
)[ira_class_hard_reg_index
4309 [aclass
][hard_regno
]]));
4310 if (ALLOCNO_CALLS_CROSSED_NUM (a
) != 0
4311 && ira_hard_reg_set_intersection_p (hard_regno
, ALLOCNO_MODE (a
),
4314 ira_assert (flag_caller_saves
);
4315 caller_save_needed
= 1;
4319 /* If we found a hard register, modify the RTL for the pseudo
4320 register to show the hard register, and mark the pseudo register
4322 if (reg_renumber
[regno
] >= 0)
4324 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
4325 fprintf (ira_dump_file
, ": reassign to %d\n", reg_renumber
[regno
]);
4326 SET_REGNO (regno_reg_rtx
[regno
], reg_renumber
[regno
]);
4327 mark_home_live (regno
);
4329 else if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
4330 fprintf (ira_dump_file
, "\n");
4331 for (i
= 0; i
< n
; i
++)
4333 ira_object_t obj
= ALLOCNO_OBJECT (a
, i
);
4334 COPY_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj
), saved
[i
]);
4336 return reg_renumber
[regno
] >= 0;
4339 /* Sort pseudos according their usage frequencies (putting most
4340 frequently ones first). */
4342 pseudo_reg_compare (const void *v1p
, const void *v2p
)
4344 int regno1
= *(const int *) v1p
;
4345 int regno2
= *(const int *) v2p
;
4348 if ((diff
= REG_FREQ (regno2
) - REG_FREQ (regno1
)) != 0)
4350 return regno1
- regno2
;
4353 /* Try to allocate hard registers to SPILLED_PSEUDO_REGS (there are
4354 NUM of them) or spilled pseudos conflicting with pseudos in
4355 SPILLED_PSEUDO_REGS. Return TRUE and update SPILLED, if the
4356 allocation has been changed. The function doesn't use
4357 BAD_SPILL_REGS and hard registers in PSEUDO_FORBIDDEN_REGS and
4358 PSEUDO_PREVIOUS_REGS for the corresponding pseudos. The function
4359 is called by the reload pass at the end of each reload
4362 ira_reassign_pseudos (int *spilled_pseudo_regs
, int num
,
4363 HARD_REG_SET bad_spill_regs
,
4364 HARD_REG_SET
*pseudo_forbidden_regs
,
4365 HARD_REG_SET
*pseudo_previous_regs
,
4371 HARD_REG_SET forbidden_regs
;
4372 bitmap temp
= BITMAP_ALLOC (NULL
);
4374 /* Add pseudos which conflict with pseudos already in
4375 SPILLED_PSEUDO_REGS to SPILLED_PSEUDO_REGS. This is preferable
4376 to allocating in two steps as some of the conflicts might have
4377 a higher priority than the pseudos passed in SPILLED_PSEUDO_REGS. */
4378 for (i
= 0; i
< num
; i
++)
4379 bitmap_set_bit (temp
, spilled_pseudo_regs
[i
]);
4381 for (i
= 0, n
= num
; i
< n
; i
++)
4384 int regno
= spilled_pseudo_regs
[i
];
4385 bitmap_set_bit (temp
, regno
);
4387 a
= ira_regno_allocno_map
[regno
];
4388 nr
= ALLOCNO_NUM_OBJECTS (a
);
4389 for (j
= 0; j
< nr
; j
++)
4391 ira_object_t conflict_obj
;
4392 ira_object_t obj
= ALLOCNO_OBJECT (a
, j
);
4393 ira_object_conflict_iterator oci
;
4395 FOR_EACH_OBJECT_CONFLICT (obj
, conflict_obj
, oci
)
4397 ira_allocno_t conflict_a
= OBJECT_ALLOCNO (conflict_obj
);
4398 if (ALLOCNO_HARD_REGNO (conflict_a
) < 0
4399 && ! ALLOCNO_DONT_REASSIGN_P (conflict_a
)
4400 && bitmap_set_bit (temp
, ALLOCNO_REGNO (conflict_a
)))
4402 spilled_pseudo_regs
[num
++] = ALLOCNO_REGNO (conflict_a
);
4403 /* ?!? This seems wrong. */
4404 bitmap_set_bit (consideration_allocno_bitmap
,
4405 ALLOCNO_NUM (conflict_a
));
4412 qsort (spilled_pseudo_regs
, num
, sizeof (int), pseudo_reg_compare
);
4414 /* Try to assign hard registers to pseudos from
4415 SPILLED_PSEUDO_REGS. */
4416 for (i
= 0; i
< num
; i
++)
4418 regno
= spilled_pseudo_regs
[i
];
4419 COPY_HARD_REG_SET (forbidden_regs
, bad_spill_regs
);
4420 IOR_HARD_REG_SET (forbidden_regs
, pseudo_forbidden_regs
[regno
]);
4421 IOR_HARD_REG_SET (forbidden_regs
, pseudo_previous_regs
[regno
]);
4422 gcc_assert (reg_renumber
[regno
] < 0);
4423 a
= ira_regno_allocno_map
[regno
];
4424 ira_mark_allocation_change (regno
);
4425 ira_assert (reg_renumber
[regno
] < 0);
4426 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
4427 fprintf (ira_dump_file
,
4428 " Try Assign %d(a%d), cost=%d", regno
, ALLOCNO_NUM (a
),
4429 ALLOCNO_MEMORY_COST (a
)
4430 - ALLOCNO_CLASS_COST (a
));
4431 allocno_reload_assign (a
, forbidden_regs
);
4432 if (reg_renumber
[regno
] >= 0)
4434 CLEAR_REGNO_REG_SET (spilled
, regno
);
4442 /* The function is called by reload and returns already allocated
4443 stack slot (if any) for REGNO with given INHERENT_SIZE and
4444 TOTAL_SIZE. In the case of failure to find a slot which can be
4445 used for REGNO, the function returns NULL. */
4447 ira_reuse_stack_slot (int regno
, unsigned int inherent_size
,
4448 unsigned int total_size
)
4451 int slot_num
, best_slot_num
;
4452 int cost
, best_cost
;
4453 ira_copy_t cp
, next_cp
;
4454 ira_allocno_t another_allocno
, allocno
= ira_regno_allocno_map
[regno
];
4457 struct ira_spilled_reg_stack_slot
*slot
= NULL
;
4459 ira_assert (! ira_use_lra_p
);
4461 ira_assert (inherent_size
== PSEUDO_REGNO_BYTES (regno
)
4462 && inherent_size
<= total_size
4463 && ALLOCNO_HARD_REGNO (allocno
) < 0);
4464 if (! flag_ira_share_spill_slots
)
4466 slot_num
= -ALLOCNO_HARD_REGNO (allocno
) - 2;
4469 slot
= &ira_spilled_reg_stack_slots
[slot_num
];
4474 best_cost
= best_slot_num
= -1;
4476 /* It means that the pseudo was spilled in the reload pass, try
4479 slot_num
< ira_spilled_reg_stack_slots_num
;
4482 slot
= &ira_spilled_reg_stack_slots
[slot_num
];
4483 if (slot
->mem
== NULL_RTX
)
4485 if (slot
->width
< total_size
4486 || GET_MODE_SIZE (GET_MODE (slot
->mem
)) < inherent_size
)
4489 EXECUTE_IF_SET_IN_BITMAP (&slot
->spilled_regs
,
4490 FIRST_PSEUDO_REGISTER
, i
, bi
)
4492 another_allocno
= ira_regno_allocno_map
[i
];
4493 if (allocnos_conflict_by_live_ranges_p (allocno
,
4497 for (cost
= 0, cp
= ALLOCNO_COPIES (allocno
);
4501 if (cp
->first
== allocno
)
4503 next_cp
= cp
->next_first_allocno_copy
;
4504 another_allocno
= cp
->second
;
4506 else if (cp
->second
== allocno
)
4508 next_cp
= cp
->next_second_allocno_copy
;
4509 another_allocno
= cp
->first
;
4513 if (cp
->insn
== NULL_RTX
)
4515 if (bitmap_bit_p (&slot
->spilled_regs
,
4516 ALLOCNO_REGNO (another_allocno
)))
4519 if (cost
> best_cost
)
4522 best_slot_num
= slot_num
;
4529 slot_num
= best_slot_num
;
4530 slot
= &ira_spilled_reg_stack_slots
[slot_num
];
4531 SET_REGNO_REG_SET (&slot
->spilled_regs
, regno
);
4533 ALLOCNO_HARD_REGNO (allocno
) = -slot_num
- 2;
4538 ira_assert (slot
->width
>= total_size
);
4539 #ifdef ENABLE_IRA_CHECKING
4540 EXECUTE_IF_SET_IN_BITMAP (&slot
->spilled_regs
,
4541 FIRST_PSEUDO_REGISTER
, i
, bi
)
4543 ira_assert (! conflict_by_live_ranges_p (regno
, i
));
4546 SET_REGNO_REG_SET (&slot
->spilled_regs
, regno
);
4547 if (internal_flag_ira_verbose
> 3 && ira_dump_file
)
4549 fprintf (ira_dump_file
, " Assigning %d(freq=%d) slot %d of",
4550 regno
, REG_FREQ (regno
), slot_num
);
4551 EXECUTE_IF_SET_IN_BITMAP (&slot
->spilled_regs
,
4552 FIRST_PSEUDO_REGISTER
, i
, bi
)
4554 if ((unsigned) regno
!= i
)
4555 fprintf (ira_dump_file
, " %d", i
);
4557 fprintf (ira_dump_file
, "\n");
4563 /* This is called by reload every time a new stack slot X with
4564 TOTAL_SIZE was allocated for REGNO. We store this info for
4565 subsequent ira_reuse_stack_slot calls. */
4567 ira_mark_new_stack_slot (rtx x
, int regno
, unsigned int total_size
)
4569 struct ira_spilled_reg_stack_slot
*slot
;
4571 ira_allocno_t allocno
;
4573 ira_assert (! ira_use_lra_p
);
4575 ira_assert (PSEUDO_REGNO_BYTES (regno
) <= total_size
);
4576 allocno
= ira_regno_allocno_map
[regno
];
4577 slot_num
= -ALLOCNO_HARD_REGNO (allocno
) - 2;
4580 slot_num
= ira_spilled_reg_stack_slots_num
++;
4581 ALLOCNO_HARD_REGNO (allocno
) = -slot_num
- 2;
4583 slot
= &ira_spilled_reg_stack_slots
[slot_num
];
4584 INIT_REG_SET (&slot
->spilled_regs
);
4585 SET_REGNO_REG_SET (&slot
->spilled_regs
, regno
);
4587 slot
->width
= total_size
;
4588 if (internal_flag_ira_verbose
> 3 && ira_dump_file
)
4589 fprintf (ira_dump_file
, " Assigning %d(freq=%d) a new slot %d\n",
4590 regno
, REG_FREQ (regno
), slot_num
);
4594 /* Return spill cost for pseudo-registers whose numbers are in array
4595 REGNOS (with a negative number as an end marker) for reload with
4596 given IN and OUT for INSN. Return also number points (through
4597 EXCESS_PRESSURE_LIVE_LENGTH) where the pseudo-register lives and
4598 the register pressure is high, number of references of the
4599 pseudo-registers (through NREFS), number of callee-clobbered
4600 hard-registers occupied by the pseudo-registers (through
4601 CALL_USED_COUNT), and the first hard regno occupied by the
4602 pseudo-registers (through FIRST_HARD_REGNO). */
4604 calculate_spill_cost (int *regnos
, rtx in
, rtx out
, rtx_insn
*insn
,
4605 int *excess_pressure_live_length
,
4606 int *nrefs
, int *call_used_count
, int *first_hard_regno
)
4608 int i
, cost
, regno
, hard_regno
, j
, count
, saved_cost
, nregs
;
4614 for (length
= count
= cost
= i
= 0;; i
++)
4619 *nrefs
+= REG_N_REFS (regno
);
4620 hard_regno
= reg_renumber
[regno
];
4621 ira_assert (hard_regno
>= 0);
4622 a
= ira_regno_allocno_map
[regno
];
4623 length
+= ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a
) / ALLOCNO_NUM_OBJECTS (a
);
4624 cost
+= ALLOCNO_MEMORY_COST (a
) - ALLOCNO_CLASS_COST (a
);
4625 nregs
= hard_regno_nregs
[hard_regno
][ALLOCNO_MODE (a
)];
4626 for (j
= 0; j
< nregs
; j
++)
4627 if (! TEST_HARD_REG_BIT (call_used_reg_set
, hard_regno
+ j
))
4631 in_p
= in
&& REG_P (in
) && (int) REGNO (in
) == hard_regno
;
4632 out_p
= out
&& REG_P (out
) && (int) REGNO (out
) == hard_regno
;
4634 && find_regno_note (insn
, REG_DEAD
, hard_regno
) != NULL_RTX
)
4638 saved_cost
+= ira_memory_move_cost
4639 [ALLOCNO_MODE (a
)][ALLOCNO_CLASS (a
)][1];
4642 += ira_memory_move_cost
4643 [ALLOCNO_MODE (a
)][ALLOCNO_CLASS (a
)][0];
4644 cost
-= REG_FREQ_FROM_BB (BLOCK_FOR_INSN (insn
)) * saved_cost
;
4647 *excess_pressure_live_length
= length
;
4648 *call_used_count
= count
;
4652 hard_regno
= reg_renumber
[regnos
[0]];
4654 *first_hard_regno
= hard_regno
;
4658 /* Return TRUE if spilling pseudo-registers whose numbers are in array
4659 REGNOS is better than spilling pseudo-registers with numbers in
4660 OTHER_REGNOS for reload with given IN and OUT for INSN. The
4661 function used by the reload pass to make better register spilling
4664 ira_better_spill_reload_regno_p (int *regnos
, int *other_regnos
,
4665 rtx in
, rtx out
, rtx_insn
*insn
)
4667 int cost
, other_cost
;
4668 int length
, other_length
;
4669 int nrefs
, other_nrefs
;
4670 int call_used_count
, other_call_used_count
;
4671 int hard_regno
, other_hard_regno
;
4673 cost
= calculate_spill_cost (regnos
, in
, out
, insn
,
4674 &length
, &nrefs
, &call_used_count
, &hard_regno
);
4675 other_cost
= calculate_spill_cost (other_regnos
, in
, out
, insn
,
4676 &other_length
, &other_nrefs
,
4677 &other_call_used_count
,
4679 if (nrefs
== 0 && other_nrefs
!= 0)
4681 if (nrefs
!= 0 && other_nrefs
== 0)
4683 if (cost
!= other_cost
)
4684 return cost
< other_cost
;
4685 if (length
!= other_length
)
4686 return length
> other_length
;
4687 #ifdef REG_ALLOC_ORDER
4688 if (hard_regno
>= 0 && other_hard_regno
>= 0)
4689 return (inv_reg_alloc_order
[hard_regno
]
4690 < inv_reg_alloc_order
[other_hard_regno
]);
4692 if (call_used_count
!= other_call_used_count
)
4693 return call_used_count
> other_call_used_count
;
4700 /* Allocate and initialize data necessary for assign_hard_reg. */
4702 ira_initiate_assign (void)
4705 = (ira_allocno_t
*) ira_allocate (sizeof (ira_allocno_t
)
4706 * ira_allocnos_num
);
4707 consideration_allocno_bitmap
= ira_allocate_bitmap ();
4708 initiate_cost_update ();
4709 allocno_priorities
= (int *) ira_allocate (sizeof (int) * ira_allocnos_num
);
4710 sorted_copies
= (ira_copy_t
*) ira_allocate (ira_copies_num
4711 * sizeof (ira_copy_t
));
4714 /* Deallocate data used by assign_hard_reg. */
4716 ira_finish_assign (void)
4718 ira_free (sorted_allocnos
);
4719 ira_free_bitmap (consideration_allocno_bitmap
);
4720 finish_cost_update ();
4721 ira_free (allocno_priorities
);
4722 ira_free (sorted_copies
);
4727 /* Entry function doing color-based register allocation. */
4731 allocno_stack_vec
.create (ira_allocnos_num
);
4732 memset (allocated_hardreg_p
, 0, sizeof (allocated_hardreg_p
));
4733 ira_initiate_assign ();
4735 ira_finish_assign ();
4736 allocno_stack_vec
.release ();
4737 move_spill_restore ();
4742 /* This page contains a simple register allocator without usage of
4743 allocno conflicts. This is used for fast allocation for -O0. */
4745 /* Do register allocation by not using allocno conflicts. It uses
4746 only allocno live ranges. The algorithm is close to Chow's
4747 priority coloring. */
4749 fast_allocation (void)
4751 int i
, j
, k
, num
, class_size
, hard_regno
;
4753 bool no_stack_reg_p
;
4755 enum reg_class aclass
;
4758 ira_allocno_iterator ai
;
4760 HARD_REG_SET conflict_hard_regs
, *used_hard_regs
;
4762 sorted_allocnos
= (ira_allocno_t
*) ira_allocate (sizeof (ira_allocno_t
)
4763 * ira_allocnos_num
);
4765 FOR_EACH_ALLOCNO (a
, ai
)
4766 sorted_allocnos
[num
++] = a
;
4767 allocno_priorities
= (int *) ira_allocate (sizeof (int) * ira_allocnos_num
);
4768 setup_allocno_priorities (sorted_allocnos
, num
);
4769 used_hard_regs
= (HARD_REG_SET
*) ira_allocate (sizeof (HARD_REG_SET
)
4771 for (i
= 0; i
< ira_max_point
; i
++)
4772 CLEAR_HARD_REG_SET (used_hard_regs
[i
]);
4773 qsort (sorted_allocnos
, num
, sizeof (ira_allocno_t
),
4774 allocno_priority_compare_func
);
4775 for (i
= 0; i
< num
; i
++)
4779 a
= sorted_allocnos
[i
];
4780 nr
= ALLOCNO_NUM_OBJECTS (a
);
4781 CLEAR_HARD_REG_SET (conflict_hard_regs
);
4782 for (l
= 0; l
< nr
; l
++)
4784 ira_object_t obj
= ALLOCNO_OBJECT (a
, l
);
4785 IOR_HARD_REG_SET (conflict_hard_regs
,
4786 OBJECT_CONFLICT_HARD_REGS (obj
));
4787 for (r
= OBJECT_LIVE_RANGES (obj
); r
!= NULL
; r
= r
->next
)
4788 for (j
= r
->start
; j
<= r
->finish
; j
++)
4789 IOR_HARD_REG_SET (conflict_hard_regs
, used_hard_regs
[j
]);
4791 aclass
= ALLOCNO_CLASS (a
);
4792 ALLOCNO_ASSIGNED_P (a
) = true;
4793 ALLOCNO_HARD_REGNO (a
) = -1;
4794 if (hard_reg_set_subset_p (reg_class_contents
[aclass
],
4795 conflict_hard_regs
))
4797 mode
= ALLOCNO_MODE (a
);
4799 no_stack_reg_p
= ALLOCNO_NO_STACK_REG_P (a
);
4801 class_size
= ira_class_hard_regs_num
[aclass
];
4802 for (j
= 0; j
< class_size
; j
++)
4804 hard_regno
= ira_class_hard_regs
[aclass
][j
];
4806 if (no_stack_reg_p
&& FIRST_STACK_REG
<= hard_regno
4807 && hard_regno
<= LAST_STACK_REG
)
4810 if (ira_hard_reg_set_intersection_p (hard_regno
, mode
, conflict_hard_regs
)
4811 || (TEST_HARD_REG_BIT
4812 (ira_prohibited_class_mode_regs
[aclass
][mode
], hard_regno
)))
4814 ALLOCNO_HARD_REGNO (a
) = hard_regno
;
4815 for (l
= 0; l
< nr
; l
++)
4817 ira_object_t obj
= ALLOCNO_OBJECT (a
, l
);
4818 for (r
= OBJECT_LIVE_RANGES (obj
); r
!= NULL
; r
= r
->next
)
4819 for (k
= r
->start
; k
<= r
->finish
; k
++)
4820 IOR_HARD_REG_SET (used_hard_regs
[k
],
4821 ira_reg_mode_hard_regset
[hard_regno
][mode
]);
4826 ira_free (sorted_allocnos
);
4827 ira_free (used_hard_regs
);
4828 ira_free (allocno_priorities
);
4829 if (internal_flag_ira_verbose
> 1 && ira_dump_file
!= NULL
)
4830 ira_print_disposition (ira_dump_file
);
4835 /* Entry function doing coloring. */
4840 ira_allocno_iterator ai
;
4842 /* Setup updated costs. */
4843 FOR_EACH_ALLOCNO (a
, ai
)
4845 ALLOCNO_UPDATED_MEMORY_COST (a
) = ALLOCNO_MEMORY_COST (a
);
4846 ALLOCNO_UPDATED_CLASS_COST (a
) = ALLOCNO_CLASS_COST (a
);
4848 if (ira_conflicts_p
)