1 /* IRA allocation based on graph coloring.
2 Copyright (C) 2006-2019 Free Software Foundation, Inc.
3 Contributed by Vladimir Makarov <vmakarov@redhat.com>.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
23 #include "coretypes.h"
32 #include "insn-config.h"
39 typedef struct allocno_hard_regs
*allocno_hard_regs_t
;
41 /* The structure contains information about hard registers can be
42 assigned to allocnos. Usually it is allocno profitable hard
43 registers but in some cases this set can be a bit different. Major
44 reason of the difference is a requirement to use hard register sets
45 that form a tree or a forest (set of trees), i.e. hard register set
46 of a node should contain hard register sets of its subnodes. */
47 struct allocno_hard_regs
49 /* Hard registers can be assigned to an allocno. */
51 /* Overall (spilling) cost of all allocnos with given register
56 typedef struct allocno_hard_regs_node
*allocno_hard_regs_node_t
;
58 /* A node representing allocno hard registers. Such nodes form a
59 forest (set of trees). Each subnode of given node in the forest
60 refers for hard register set (usually allocno profitable hard
61 register set) which is a subset of one referred from given
63 struct allocno_hard_regs_node
65 /* Set up number of the node in preorder traversing of the forest. */
67 /* Used for different calculation like finding conflict size of an
70 /* Used for calculation of conflict size of an allocno. The
71 conflict size of the allocno is maximal number of given allocno
72 hard registers needed for allocation of the conflicting allocnos.
73 Given allocno is trivially colored if this number plus the number
74 of hard registers needed for given allocno is not greater than
75 the number of given allocno hard register set. */
77 /* The number of hard registers given by member hard_regs. */
79 /* The following member is used to form the final forest. */
81 /* Pointer to the corresponding profitable hard registers. */
82 allocno_hard_regs_t hard_regs
;
83 /* Parent, first subnode, previous and next node with the same
84 parent in the forest. */
85 allocno_hard_regs_node_t parent
, first
, prev
, next
;
88 /* Info about changing hard reg costs of an allocno. */
89 struct update_cost_record
91 /* Hard regno for which we changed the cost. */
93 /* Divisor used when we changed the cost of HARD_REGNO. */
95 /* Next record for given allocno. */
96 struct update_cost_record
*next
;
99 /* To decrease footprint of ira_allocno structure we store all data
100 needed only for coloring in the following structure. */
101 struct allocno_color_data
103 /* TRUE value means that the allocno was not removed yet from the
104 conflicting graph during coloring. */
105 unsigned int in_graph_p
: 1;
106 /* TRUE if it is put on the stack to make other allocnos
108 unsigned int may_be_spilled_p
: 1;
109 /* TRUE if the allocno is trivially colorable. */
110 unsigned int colorable_p
: 1;
111 /* Number of hard registers of the allocno class really
112 available for the allocno allocation. It is number of the
113 profitable hard regs. */
114 int available_regs_num
;
115 /* Sum of frequencies of hard register preferences of all
116 conflicting allocnos which are not the coloring stack yet. */
117 int conflict_allocno_hard_prefs
;
118 /* Allocnos in a bucket (used in coloring) chained by the following
120 ira_allocno_t next_bucket_allocno
;
121 ira_allocno_t prev_bucket_allocno
;
122 /* Used for temporary purposes. */
124 /* Used to exclude repeated processing. */
126 /* Profitable hard regs available for this pseudo allocation. It
127 means that the set excludes unavailable hard regs and hard regs
128 conflicting with given pseudo. They should be of the allocno
130 HARD_REG_SET profitable_hard_regs
;
131 /* The allocno hard registers node. */
132 allocno_hard_regs_node_t hard_regs_node
;
133 /* Array of structures allocno_hard_regs_subnode representing
134 given allocno hard registers node (the 1st element in the array)
135 and all its subnodes in the tree (forest) of allocno hard
136 register nodes (see comments above). */
137 int hard_regs_subnodes_start
;
138 /* The length of the previous array. */
139 int hard_regs_subnodes_num
;
140 /* Records about updating allocno hard reg costs from copies. If
141 the allocno did not get expected hard register, these records are
142 used to restore original hard reg costs of allocnos connected to
143 this allocno by copies. */
144 struct update_cost_record
*update_cost_records
;
145 /* Threads. We collect allocnos connected by copies into threads
146 and try to assign hard regs to allocnos by threads. */
147 /* Allocno representing all thread. */
148 ira_allocno_t first_thread_allocno
;
149 /* Allocnos in thread forms a cycle list through the following
151 ira_allocno_t next_thread_allocno
;
152 /* All thread frequency. Defined only for first thread allocno. */
157 typedef struct allocno_color_data
*allocno_color_data_t
;
159 /* Container for storing allocno data concerning coloring. */
160 static allocno_color_data_t allocno_color_data
;
162 /* Macro to access the data concerning coloring. */
163 #define ALLOCNO_COLOR_DATA(a) ((allocno_color_data_t) ALLOCNO_ADD_DATA (a))
165 /* Used for finding allocno colorability to exclude repeated allocno
166 processing and for updating preferencing to exclude repeated
167 allocno processing during assignment. */
168 static int curr_allocno_process
;
170 /* This file contains code for regional graph coloring, spill/restore
171 code placement optimization, and code helping the reload pass to do
174 /* Bitmap of allocnos which should be colored. */
175 static bitmap coloring_allocno_bitmap
;
177 /* Bitmap of allocnos which should be taken into account during
178 coloring. In general case it contains allocnos from
179 coloring_allocno_bitmap plus other already colored conflicting
181 static bitmap consideration_allocno_bitmap
;
183 /* All allocnos sorted according their priorities. */
184 static ira_allocno_t
*sorted_allocnos
;
186 /* Vec representing the stack of allocnos used during coloring. */
187 static vec
<ira_allocno_t
> allocno_stack_vec
;
189 /* Helper for qsort comparison callbacks - return a positive integer if
190 X > Y, or a negative value otherwise. Use a conditional expression
191 instead of a difference computation to insulate from possible overflow
192 issues, e.g. X - Y < 0 for some X > 0 and Y < 0. */
193 #define SORTGT(x,y) (((x) > (y)) ? 1 : -1)
197 /* Definition of vector of allocno hard registers. */
199 /* Vector of unique allocno hard registers. */
200 static vec
<allocno_hard_regs_t
> allocno_hard_regs_vec
;
202 struct allocno_hard_regs_hasher
: nofree_ptr_hash
<allocno_hard_regs
>
204 static inline hashval_t
hash (const allocno_hard_regs
*);
205 static inline bool equal (const allocno_hard_regs
*,
206 const allocno_hard_regs
*);
209 /* Returns hash value for allocno hard registers V. */
211 allocno_hard_regs_hasher::hash (const allocno_hard_regs
*hv
)
213 return iterative_hash (&hv
->set
, sizeof (HARD_REG_SET
), 0);
216 /* Compares allocno hard registers V1 and V2. */
218 allocno_hard_regs_hasher::equal (const allocno_hard_regs
*hv1
,
219 const allocno_hard_regs
*hv2
)
221 return hard_reg_set_equal_p (hv1
->set
, hv2
->set
);
224 /* Hash table of unique allocno hard registers. */
225 static hash_table
<allocno_hard_regs_hasher
> *allocno_hard_regs_htab
;
227 /* Return allocno hard registers in the hash table equal to HV. */
228 static allocno_hard_regs_t
229 find_hard_regs (allocno_hard_regs_t hv
)
231 return allocno_hard_regs_htab
->find (hv
);
234 /* Insert allocno hard registers HV in the hash table (if it is not
235 there yet) and return the value which in the table. */
236 static allocno_hard_regs_t
237 insert_hard_regs (allocno_hard_regs_t hv
)
239 allocno_hard_regs
**slot
= allocno_hard_regs_htab
->find_slot (hv
, INSERT
);
246 /* Initialize data concerning allocno hard registers. */
248 init_allocno_hard_regs (void)
250 allocno_hard_regs_vec
.create (200);
251 allocno_hard_regs_htab
252 = new hash_table
<allocno_hard_regs_hasher
> (200);
255 /* Add (or update info about) allocno hard registers with SET and
257 static allocno_hard_regs_t
258 add_allocno_hard_regs (HARD_REG_SET set
, int64_t cost
)
260 struct allocno_hard_regs temp
;
261 allocno_hard_regs_t hv
;
263 gcc_assert (! hard_reg_set_empty_p (set
));
264 COPY_HARD_REG_SET (temp
.set
, set
);
265 if ((hv
= find_hard_regs (&temp
)) != NULL
)
269 hv
= ((struct allocno_hard_regs
*)
270 ira_allocate (sizeof (struct allocno_hard_regs
)));
271 COPY_HARD_REG_SET (hv
->set
, set
);
273 allocno_hard_regs_vec
.safe_push (hv
);
274 insert_hard_regs (hv
);
279 /* Finalize data concerning allocno hard registers. */
281 finish_allocno_hard_regs (void)
284 allocno_hard_regs_t hv
;
287 allocno_hard_regs_vec
.iterate (i
, &hv
);
290 delete allocno_hard_regs_htab
;
291 allocno_hard_regs_htab
= NULL
;
292 allocno_hard_regs_vec
.release ();
295 /* Sort hard regs according to their frequency of usage. */
297 allocno_hard_regs_compare (const void *v1p
, const void *v2p
)
299 allocno_hard_regs_t hv1
= *(const allocno_hard_regs_t
*) v1p
;
300 allocno_hard_regs_t hv2
= *(const allocno_hard_regs_t
*) v2p
;
302 if (hv2
->cost
> hv1
->cost
)
304 else if (hv2
->cost
< hv1
->cost
)
306 return SORTGT (allocno_hard_regs_hasher::hash(hv2
), allocno_hard_regs_hasher::hash(hv1
));
311 /* Used for finding a common ancestor of two allocno hard registers
312 nodes in the forest. We use the current value of
313 'node_check_tick' to mark all nodes from one node to the top and
314 then walking up from another node until we find a marked node.
316 It is also used to figure out allocno colorability as a mark that
317 we already reset value of member 'conflict_size' for the forest
318 node corresponding to the processed allocno. */
319 static int node_check_tick
;
321 /* Roots of the forest containing hard register sets can be assigned
323 static allocno_hard_regs_node_t hard_regs_roots
;
325 /* Definition of vector of allocno hard register nodes. */
327 /* Vector used to create the forest. */
328 static vec
<allocno_hard_regs_node_t
> hard_regs_node_vec
;
330 /* Create and return allocno hard registers node containing allocno
331 hard registers HV. */
332 static allocno_hard_regs_node_t
333 create_new_allocno_hard_regs_node (allocno_hard_regs_t hv
)
335 allocno_hard_regs_node_t new_node
;
337 new_node
= ((struct allocno_hard_regs_node
*)
338 ira_allocate (sizeof (struct allocno_hard_regs_node
)));
340 new_node
->hard_regs
= hv
;
341 new_node
->hard_regs_num
= hard_reg_set_size (hv
->set
);
342 new_node
->first
= NULL
;
343 new_node
->used_p
= false;
347 /* Add allocno hard registers node NEW_NODE to the forest on its level
350 add_new_allocno_hard_regs_node_to_forest (allocno_hard_regs_node_t
*roots
,
351 allocno_hard_regs_node_t new_node
)
353 new_node
->next
= *roots
;
354 if (new_node
->next
!= NULL
)
355 new_node
->next
->prev
= new_node
;
356 new_node
->prev
= NULL
;
360 /* Add allocno hard registers HV (or its best approximation if it is
361 not possible) to the forest on its level given by ROOTS. */
363 add_allocno_hard_regs_to_forest (allocno_hard_regs_node_t
*roots
,
364 allocno_hard_regs_t hv
)
366 unsigned int i
, start
;
367 allocno_hard_regs_node_t node
, prev
, new_node
;
368 HARD_REG_SET temp_set
;
369 allocno_hard_regs_t hv2
;
371 start
= hard_regs_node_vec
.length ();
372 for (node
= *roots
; node
!= NULL
; node
= node
->next
)
374 if (hard_reg_set_equal_p (hv
->set
, node
->hard_regs
->set
))
376 if (hard_reg_set_subset_p (hv
->set
, node
->hard_regs
->set
))
378 add_allocno_hard_regs_to_forest (&node
->first
, hv
);
381 if (hard_reg_set_subset_p (node
->hard_regs
->set
, hv
->set
))
382 hard_regs_node_vec
.safe_push (node
);
383 else if (hard_reg_set_intersect_p (hv
->set
, node
->hard_regs
->set
))
385 COPY_HARD_REG_SET (temp_set
, hv
->set
);
386 AND_HARD_REG_SET (temp_set
, node
->hard_regs
->set
);
387 hv2
= add_allocno_hard_regs (temp_set
, hv
->cost
);
388 add_allocno_hard_regs_to_forest (&node
->first
, hv2
);
391 if (hard_regs_node_vec
.length ()
394 /* Create a new node which contains nodes in hard_regs_node_vec. */
395 CLEAR_HARD_REG_SET (temp_set
);
397 i
< hard_regs_node_vec
.length ();
400 node
= hard_regs_node_vec
[i
];
401 IOR_HARD_REG_SET (temp_set
, node
->hard_regs
->set
);
403 hv
= add_allocno_hard_regs (temp_set
, hv
->cost
);
404 new_node
= create_new_allocno_hard_regs_node (hv
);
407 i
< hard_regs_node_vec
.length ();
410 node
= hard_regs_node_vec
[i
];
411 if (node
->prev
== NULL
)
414 node
->prev
->next
= node
->next
;
415 if (node
->next
!= NULL
)
416 node
->next
->prev
= node
->prev
;
418 new_node
->first
= node
;
425 add_new_allocno_hard_regs_node_to_forest (roots
, new_node
);
427 hard_regs_node_vec
.truncate (start
);
430 /* Add allocno hard registers nodes starting with the forest level
431 given by FIRST which contains biggest set inside SET. */
433 collect_allocno_hard_regs_cover (allocno_hard_regs_node_t first
,
436 allocno_hard_regs_node_t node
;
438 ira_assert (first
!= NULL
);
439 for (node
= first
; node
!= NULL
; node
= node
->next
)
440 if (hard_reg_set_subset_p (node
->hard_regs
->set
, set
))
441 hard_regs_node_vec
.safe_push (node
);
442 else if (hard_reg_set_intersect_p (set
, node
->hard_regs
->set
))
443 collect_allocno_hard_regs_cover (node
->first
, set
);
446 /* Set up field parent as PARENT in all allocno hard registers nodes
447 in forest given by FIRST. */
449 setup_allocno_hard_regs_nodes_parent (allocno_hard_regs_node_t first
,
450 allocno_hard_regs_node_t parent
)
452 allocno_hard_regs_node_t node
;
454 for (node
= first
; node
!= NULL
; node
= node
->next
)
456 node
->parent
= parent
;
457 setup_allocno_hard_regs_nodes_parent (node
->first
, node
);
461 /* Return allocno hard registers node which is a first common ancestor
462 node of FIRST and SECOND in the forest. */
463 static allocno_hard_regs_node_t
464 first_common_ancestor_node (allocno_hard_regs_node_t first
,
465 allocno_hard_regs_node_t second
)
467 allocno_hard_regs_node_t node
;
470 for (node
= first
; node
!= NULL
; node
= node
->parent
)
471 node
->check
= node_check_tick
;
472 for (node
= second
; node
!= NULL
; node
= node
->parent
)
473 if (node
->check
== node_check_tick
)
475 return first_common_ancestor_node (second
, first
);
478 /* Print hard reg set SET to F. */
480 print_hard_reg_set (FILE *f
, HARD_REG_SET set
, bool new_line_p
)
484 for (start
= -1, i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
486 if (TEST_HARD_REG_BIT (set
, i
))
488 if (i
== 0 || ! TEST_HARD_REG_BIT (set
, i
- 1))
492 && (i
== FIRST_PSEUDO_REGISTER
- 1 || ! TEST_HARD_REG_BIT (set
, i
)))
495 fprintf (f
, " %d", start
);
496 else if (start
== i
- 2)
497 fprintf (f
, " %d %d", start
, start
+ 1);
499 fprintf (f
, " %d-%d", start
, i
- 1);
507 /* Print allocno hard register subforest given by ROOTS and its LEVEL
510 print_hard_regs_subforest (FILE *f
, allocno_hard_regs_node_t roots
,
514 allocno_hard_regs_node_t node
;
516 for (node
= roots
; node
!= NULL
; node
= node
->next
)
519 for (i
= 0; i
< level
* 2; i
++)
521 fprintf (f
, "%d:(", node
->preorder_num
);
522 print_hard_reg_set (f
, node
->hard_regs
->set
, false);
523 fprintf (f
, ")@%" PRId64
"\n", node
->hard_regs
->cost
);
524 print_hard_regs_subforest (f
, node
->first
, level
+ 1);
528 /* Print the allocno hard register forest to F. */
530 print_hard_regs_forest (FILE *f
)
532 fprintf (f
, " Hard reg set forest:\n");
533 print_hard_regs_subforest (f
, hard_regs_roots
, 1);
536 /* Print the allocno hard register forest to stderr. */
538 ira_debug_hard_regs_forest (void)
540 print_hard_regs_forest (stderr
);
543 /* Remove unused allocno hard registers nodes from forest given by its
546 remove_unused_allocno_hard_regs_nodes (allocno_hard_regs_node_t
*roots
)
548 allocno_hard_regs_node_t node
, prev
, next
, last
;
550 for (prev
= NULL
, node
= *roots
; node
!= NULL
; node
= next
)
555 remove_unused_allocno_hard_regs_nodes (&node
->first
);
560 for (last
= node
->first
;
561 last
!= NULL
&& last
->next
!= NULL
;
567 *roots
= node
->first
;
569 prev
->next
= node
->first
;
589 /* Set up fields preorder_num starting with START_NUM in all allocno
590 hard registers nodes in forest given by FIRST. Return biggest set
591 PREORDER_NUM increased by 1. */
593 enumerate_allocno_hard_regs_nodes (allocno_hard_regs_node_t first
,
594 allocno_hard_regs_node_t parent
,
597 allocno_hard_regs_node_t node
;
599 for (node
= first
; node
!= NULL
; node
= node
->next
)
601 node
->preorder_num
= start_num
++;
602 node
->parent
= parent
;
603 start_num
= enumerate_allocno_hard_regs_nodes (node
->first
, node
,
609 /* Number of allocno hard registers nodes in the forest. */
610 static int allocno_hard_regs_nodes_num
;
612 /* Table preorder number of allocno hard registers node in the forest
613 -> the allocno hard registers node. */
614 static allocno_hard_regs_node_t
*allocno_hard_regs_nodes
;
617 typedef struct allocno_hard_regs_subnode
*allocno_hard_regs_subnode_t
;
619 /* The structure is used to describes all subnodes (not only immediate
620 ones) in the mentioned above tree for given allocno hard register
621 node. The usage of such data accelerates calculation of
622 colorability of given allocno. */
623 struct allocno_hard_regs_subnode
625 /* The conflict size of conflicting allocnos whose hard register
626 sets are equal sets (plus supersets if given node is given
627 allocno hard registers node) of one in the given node. */
628 int left_conflict_size
;
629 /* The summary conflict size of conflicting allocnos whose hard
630 register sets are strict subsets of one in the given node.
631 Overall conflict size is
632 left_conflict_subnodes_size
633 + MIN (max_node_impact - left_conflict_subnodes_size,
636 short left_conflict_subnodes_size
;
637 short max_node_impact
;
640 /* Container for hard regs subnodes of all allocnos. */
641 static allocno_hard_regs_subnode_t allocno_hard_regs_subnodes
;
643 /* Table (preorder number of allocno hard registers node in the
644 forest, preorder number of allocno hard registers subnode) -> index
645 of the subnode relative to the node. -1 if it is not a
647 static int *allocno_hard_regs_subnode_index
;
649 /* Setup arrays ALLOCNO_HARD_REGS_NODES and
650 ALLOCNO_HARD_REGS_SUBNODE_INDEX. */
652 setup_allocno_hard_regs_subnode_index (allocno_hard_regs_node_t first
)
654 allocno_hard_regs_node_t node
, parent
;
657 for (node
= first
; node
!= NULL
; node
= node
->next
)
659 allocno_hard_regs_nodes
[node
->preorder_num
] = node
;
660 for (parent
= node
; parent
!= NULL
; parent
= parent
->parent
)
662 index
= parent
->preorder_num
* allocno_hard_regs_nodes_num
;
663 allocno_hard_regs_subnode_index
[index
+ node
->preorder_num
]
664 = node
->preorder_num
- parent
->preorder_num
;
666 setup_allocno_hard_regs_subnode_index (node
->first
);
670 /* Count all allocno hard registers nodes in tree ROOT. */
672 get_allocno_hard_regs_subnodes_num (allocno_hard_regs_node_t root
)
676 for (root
= root
->first
; root
!= NULL
; root
= root
->next
)
677 len
+= get_allocno_hard_regs_subnodes_num (root
);
681 /* Build the forest of allocno hard registers nodes and assign each
682 allocno a node from the forest. */
684 form_allocno_hard_regs_nodes_forest (void)
686 unsigned int i
, j
, size
, len
;
689 allocno_hard_regs_t hv
;
692 allocno_hard_regs_node_t node
, allocno_hard_regs_node
;
693 allocno_color_data_t allocno_data
;
696 init_allocno_hard_regs ();
697 hard_regs_roots
= NULL
;
698 hard_regs_node_vec
.create (100);
699 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
700 if (! TEST_HARD_REG_BIT (ira_no_alloc_regs
, i
))
702 CLEAR_HARD_REG_SET (temp
);
703 SET_HARD_REG_BIT (temp
, i
);
704 hv
= add_allocno_hard_regs (temp
, 0);
705 node
= create_new_allocno_hard_regs_node (hv
);
706 add_new_allocno_hard_regs_node_to_forest (&hard_regs_roots
, node
);
708 start
= allocno_hard_regs_vec
.length ();
709 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap
, 0, i
, bi
)
712 allocno_data
= ALLOCNO_COLOR_DATA (a
);
714 if (hard_reg_set_empty_p (allocno_data
->profitable_hard_regs
))
716 hv
= (add_allocno_hard_regs
717 (allocno_data
->profitable_hard_regs
,
718 ALLOCNO_MEMORY_COST (a
) - ALLOCNO_CLASS_COST (a
)));
720 SET_HARD_REG_SET (temp
);
721 AND_COMPL_HARD_REG_SET (temp
, ira_no_alloc_regs
);
722 add_allocno_hard_regs (temp
, 0);
723 qsort (allocno_hard_regs_vec
.address () + start
,
724 allocno_hard_regs_vec
.length () - start
,
725 sizeof (allocno_hard_regs_t
), allocno_hard_regs_compare
);
727 allocno_hard_regs_vec
.iterate (i
, &hv
);
730 add_allocno_hard_regs_to_forest (&hard_regs_roots
, hv
);
731 ira_assert (hard_regs_node_vec
.length () == 0);
733 /* We need to set up parent fields for right work of
734 first_common_ancestor_node. */
735 setup_allocno_hard_regs_nodes_parent (hard_regs_roots
, NULL
);
736 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap
, 0, i
, bi
)
739 allocno_data
= ALLOCNO_COLOR_DATA (a
);
740 if (hard_reg_set_empty_p (allocno_data
->profitable_hard_regs
))
742 hard_regs_node_vec
.truncate (0);
743 collect_allocno_hard_regs_cover (hard_regs_roots
,
744 allocno_data
->profitable_hard_regs
);
745 allocno_hard_regs_node
= NULL
;
746 for (j
= 0; hard_regs_node_vec
.iterate (j
, &node
); j
++)
747 allocno_hard_regs_node
750 : first_common_ancestor_node (node
, allocno_hard_regs_node
));
751 /* That is a temporary storage. */
752 allocno_hard_regs_node
->used_p
= true;
753 allocno_data
->hard_regs_node
= allocno_hard_regs_node
;
755 ira_assert (hard_regs_roots
->next
== NULL
);
756 hard_regs_roots
->used_p
= true;
757 remove_unused_allocno_hard_regs_nodes (&hard_regs_roots
);
758 allocno_hard_regs_nodes_num
759 = enumerate_allocno_hard_regs_nodes (hard_regs_roots
, NULL
, 0);
760 allocno_hard_regs_nodes
761 = ((allocno_hard_regs_node_t
*)
762 ira_allocate (allocno_hard_regs_nodes_num
763 * sizeof (allocno_hard_regs_node_t
)));
764 size
= allocno_hard_regs_nodes_num
* allocno_hard_regs_nodes_num
;
765 allocno_hard_regs_subnode_index
766 = (int *) ira_allocate (size
* sizeof (int));
767 for (i
= 0; i
< size
; i
++)
768 allocno_hard_regs_subnode_index
[i
] = -1;
769 setup_allocno_hard_regs_subnode_index (hard_regs_roots
);
771 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap
, 0, i
, bi
)
774 allocno_data
= ALLOCNO_COLOR_DATA (a
);
775 if (hard_reg_set_empty_p (allocno_data
->profitable_hard_regs
))
777 len
= get_allocno_hard_regs_subnodes_num (allocno_data
->hard_regs_node
);
778 allocno_data
->hard_regs_subnodes_start
= start
;
779 allocno_data
->hard_regs_subnodes_num
= len
;
782 allocno_hard_regs_subnodes
783 = ((allocno_hard_regs_subnode_t
)
784 ira_allocate (sizeof (struct allocno_hard_regs_subnode
) * start
));
785 hard_regs_node_vec
.release ();
788 /* Free tree of allocno hard registers nodes given by its ROOT. */
790 finish_allocno_hard_regs_nodes_tree (allocno_hard_regs_node_t root
)
792 allocno_hard_regs_node_t child
, next
;
794 for (child
= root
->first
; child
!= NULL
; child
= next
)
797 finish_allocno_hard_regs_nodes_tree (child
);
802 /* Finish work with the forest of allocno hard registers nodes. */
804 finish_allocno_hard_regs_nodes_forest (void)
806 allocno_hard_regs_node_t node
, next
;
808 ira_free (allocno_hard_regs_subnodes
);
809 for (node
= hard_regs_roots
; node
!= NULL
; node
= next
)
812 finish_allocno_hard_regs_nodes_tree (node
);
814 ira_free (allocno_hard_regs_nodes
);
815 ira_free (allocno_hard_regs_subnode_index
);
816 finish_allocno_hard_regs ();
819 /* Set up left conflict sizes and left conflict subnodes sizes of hard
820 registers subnodes of allocno A. Return TRUE if allocno A is
821 trivially colorable. */
823 setup_left_conflict_sizes_p (ira_allocno_t a
)
825 int i
, k
, nobj
, start
;
826 int conflict_size
, left_conflict_subnodes_size
, node_preorder_num
;
827 allocno_color_data_t data
;
828 HARD_REG_SET profitable_hard_regs
;
829 allocno_hard_regs_subnode_t subnodes
;
830 allocno_hard_regs_node_t node
;
831 HARD_REG_SET node_set
;
833 nobj
= ALLOCNO_NUM_OBJECTS (a
);
834 data
= ALLOCNO_COLOR_DATA (a
);
835 subnodes
= allocno_hard_regs_subnodes
+ data
->hard_regs_subnodes_start
;
836 COPY_HARD_REG_SET (profitable_hard_regs
, data
->profitable_hard_regs
);
837 node
= data
->hard_regs_node
;
838 node_preorder_num
= node
->preorder_num
;
839 COPY_HARD_REG_SET (node_set
, node
->hard_regs
->set
);
841 for (k
= 0; k
< nobj
; k
++)
843 ira_object_t obj
= ALLOCNO_OBJECT (a
, k
);
844 ira_object_t conflict_obj
;
845 ira_object_conflict_iterator oci
;
847 FOR_EACH_OBJECT_CONFLICT (obj
, conflict_obj
, oci
)
850 ira_allocno_t conflict_a
= OBJECT_ALLOCNO (conflict_obj
);
851 allocno_hard_regs_node_t conflict_node
, temp_node
;
852 HARD_REG_SET conflict_node_set
;
853 allocno_color_data_t conflict_data
;
855 conflict_data
= ALLOCNO_COLOR_DATA (conflict_a
);
856 if (! ALLOCNO_COLOR_DATA (conflict_a
)->in_graph_p
857 || ! hard_reg_set_intersect_p (profitable_hard_regs
,
859 ->profitable_hard_regs
))
861 conflict_node
= conflict_data
->hard_regs_node
;
862 COPY_HARD_REG_SET (conflict_node_set
, conflict_node
->hard_regs
->set
);
863 if (hard_reg_set_subset_p (node_set
, conflict_node_set
))
867 ira_assert (hard_reg_set_subset_p (conflict_node_set
, node_set
));
868 temp_node
= conflict_node
;
870 if (temp_node
->check
!= node_check_tick
)
872 temp_node
->check
= node_check_tick
;
873 temp_node
->conflict_size
= 0;
875 size
= (ira_reg_class_max_nregs
876 [ALLOCNO_CLASS (conflict_a
)][ALLOCNO_MODE (conflict_a
)]);
877 if (ALLOCNO_NUM_OBJECTS (conflict_a
) > 1)
878 /* We will deal with the subwords individually. */
880 temp_node
->conflict_size
+= size
;
883 for (i
= 0; i
< data
->hard_regs_subnodes_num
; i
++)
885 allocno_hard_regs_node_t temp_node
;
887 temp_node
= allocno_hard_regs_nodes
[i
+ node_preorder_num
];
888 ira_assert (temp_node
->preorder_num
== i
+ node_preorder_num
);
889 subnodes
[i
].left_conflict_size
= (temp_node
->check
!= node_check_tick
890 ? 0 : temp_node
->conflict_size
);
891 if (hard_reg_set_subset_p (temp_node
->hard_regs
->set
,
892 profitable_hard_regs
))
893 subnodes
[i
].max_node_impact
= temp_node
->hard_regs_num
;
896 HARD_REG_SET temp_set
;
897 int j
, n
, hard_regno
;
898 enum reg_class aclass
;
900 COPY_HARD_REG_SET (temp_set
, temp_node
->hard_regs
->set
);
901 AND_HARD_REG_SET (temp_set
, profitable_hard_regs
);
902 aclass
= ALLOCNO_CLASS (a
);
903 for (n
= 0, j
= ira_class_hard_regs_num
[aclass
] - 1; j
>= 0; j
--)
905 hard_regno
= ira_class_hard_regs
[aclass
][j
];
906 if (TEST_HARD_REG_BIT (temp_set
, hard_regno
))
909 subnodes
[i
].max_node_impact
= n
;
911 subnodes
[i
].left_conflict_subnodes_size
= 0;
913 start
= node_preorder_num
* allocno_hard_regs_nodes_num
;
914 for (i
= data
->hard_regs_subnodes_num
- 1; i
> 0; i
--)
917 allocno_hard_regs_node_t parent
;
919 size
= (subnodes
[i
].left_conflict_subnodes_size
920 + MIN (subnodes
[i
].max_node_impact
921 - subnodes
[i
].left_conflict_subnodes_size
,
922 subnodes
[i
].left_conflict_size
));
923 parent
= allocno_hard_regs_nodes
[i
+ node_preorder_num
]->parent
;
924 gcc_checking_assert(parent
);
926 = allocno_hard_regs_subnode_index
[start
+ parent
->preorder_num
];
927 gcc_checking_assert(parent_i
>= 0);
928 subnodes
[parent_i
].left_conflict_subnodes_size
+= size
;
930 left_conflict_subnodes_size
= subnodes
[0].left_conflict_subnodes_size
;
932 = (left_conflict_subnodes_size
933 + MIN (subnodes
[0].max_node_impact
- left_conflict_subnodes_size
,
934 subnodes
[0].left_conflict_size
));
935 conflict_size
+= ira_reg_class_max_nregs
[ALLOCNO_CLASS (a
)][ALLOCNO_MODE (a
)];
936 data
->colorable_p
= conflict_size
<= data
->available_regs_num
;
937 return data
->colorable_p
;
940 /* Update left conflict sizes of hard registers subnodes of allocno A
941 after removing allocno REMOVED_A with SIZE from the conflict graph.
942 Return TRUE if A is trivially colorable. */
944 update_left_conflict_sizes_p (ira_allocno_t a
,
945 ira_allocno_t removed_a
, int size
)
947 int i
, conflict_size
, before_conflict_size
, diff
, start
;
948 int node_preorder_num
, parent_i
;
949 allocno_hard_regs_node_t node
, removed_node
, parent
;
950 allocno_hard_regs_subnode_t subnodes
;
951 allocno_color_data_t data
= ALLOCNO_COLOR_DATA (a
);
953 ira_assert (! data
->colorable_p
);
954 node
= data
->hard_regs_node
;
955 node_preorder_num
= node
->preorder_num
;
956 removed_node
= ALLOCNO_COLOR_DATA (removed_a
)->hard_regs_node
;
957 ira_assert (hard_reg_set_subset_p (removed_node
->hard_regs
->set
,
958 node
->hard_regs
->set
)
959 || hard_reg_set_subset_p (node
->hard_regs
->set
,
960 removed_node
->hard_regs
->set
));
961 start
= node_preorder_num
* allocno_hard_regs_nodes_num
;
962 i
= allocno_hard_regs_subnode_index
[start
+ removed_node
->preorder_num
];
965 subnodes
= allocno_hard_regs_subnodes
+ data
->hard_regs_subnodes_start
;
967 = (subnodes
[i
].left_conflict_subnodes_size
968 + MIN (subnodes
[i
].max_node_impact
969 - subnodes
[i
].left_conflict_subnodes_size
,
970 subnodes
[i
].left_conflict_size
));
971 subnodes
[i
].left_conflict_size
-= size
;
975 = (subnodes
[i
].left_conflict_subnodes_size
976 + MIN (subnodes
[i
].max_node_impact
977 - subnodes
[i
].left_conflict_subnodes_size
,
978 subnodes
[i
].left_conflict_size
));
979 if ((diff
= before_conflict_size
- conflict_size
) == 0)
981 ira_assert (conflict_size
< before_conflict_size
);
982 parent
= allocno_hard_regs_nodes
[i
+ node_preorder_num
]->parent
;
986 = allocno_hard_regs_subnode_index
[start
+ parent
->preorder_num
];
991 = (subnodes
[i
].left_conflict_subnodes_size
992 + MIN (subnodes
[i
].max_node_impact
993 - subnodes
[i
].left_conflict_subnodes_size
,
994 subnodes
[i
].left_conflict_size
));
995 subnodes
[i
].left_conflict_subnodes_size
-= diff
;
999 + ira_reg_class_max_nregs
[ALLOCNO_CLASS (a
)][ALLOCNO_MODE (a
)]
1000 > data
->available_regs_num
))
1002 data
->colorable_p
= true;
1006 /* Return true if allocno A has empty profitable hard regs. */
1008 empty_profitable_hard_regs (ira_allocno_t a
)
1010 allocno_color_data_t data
= ALLOCNO_COLOR_DATA (a
);
1012 return hard_reg_set_empty_p (data
->profitable_hard_regs
);
1015 /* Set up profitable hard registers for each allocno being
1018 setup_profitable_hard_regs (void)
1021 int j
, k
, nobj
, hard_regno
, nregs
, class_size
;
1024 enum reg_class aclass
;
1026 allocno_color_data_t data
;
1028 /* Initial set up from allocno classes and explicitly conflicting
1030 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap
, 0, i
, bi
)
1032 a
= ira_allocnos
[i
];
1033 if ((aclass
= ALLOCNO_CLASS (a
)) == NO_REGS
)
1035 data
= ALLOCNO_COLOR_DATA (a
);
1036 if (ALLOCNO_UPDATED_HARD_REG_COSTS (a
) == NULL
1037 && ALLOCNO_CLASS_COST (a
) > ALLOCNO_MEMORY_COST (a
)
1038 /* Do not empty profitable regs for static chain pointer
1039 pseudo when non-local goto is used. */
1040 && ! non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a
)))
1041 CLEAR_HARD_REG_SET (data
->profitable_hard_regs
);
1044 mode
= ALLOCNO_MODE (a
);
1045 COPY_HARD_REG_SET (data
->profitable_hard_regs
,
1046 ira_useful_class_mode_regs
[aclass
][mode
]);
1047 nobj
= ALLOCNO_NUM_OBJECTS (a
);
1048 for (k
= 0; k
< nobj
; k
++)
1050 ira_object_t obj
= ALLOCNO_OBJECT (a
, k
);
1052 AND_COMPL_HARD_REG_SET (data
->profitable_hard_regs
,
1053 OBJECT_TOTAL_CONFLICT_HARD_REGS (obj
));
1057 /* Exclude hard regs already assigned for conflicting objects. */
1058 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap
, 0, i
, bi
)
1060 a
= ira_allocnos
[i
];
1061 if ((aclass
= ALLOCNO_CLASS (a
)) == NO_REGS
1062 || ! ALLOCNO_ASSIGNED_P (a
)
1063 || (hard_regno
= ALLOCNO_HARD_REGNO (a
)) < 0)
1065 mode
= ALLOCNO_MODE (a
);
1066 nregs
= hard_regno_nregs (hard_regno
, mode
);
1067 nobj
= ALLOCNO_NUM_OBJECTS (a
);
1068 for (k
= 0; k
< nobj
; k
++)
1070 ira_object_t obj
= ALLOCNO_OBJECT (a
, k
);
1071 ira_object_t conflict_obj
;
1072 ira_object_conflict_iterator oci
;
1074 FOR_EACH_OBJECT_CONFLICT (obj
, conflict_obj
, oci
)
1076 ira_allocno_t conflict_a
= OBJECT_ALLOCNO (conflict_obj
);
1078 /* We can process the conflict allocno repeatedly with
1080 if (nregs
== nobj
&& nregs
> 1)
1082 int num
= OBJECT_SUBWORD (conflict_obj
);
1084 if (REG_WORDS_BIG_ENDIAN
)
1086 (ALLOCNO_COLOR_DATA (conflict_a
)->profitable_hard_regs
,
1087 hard_regno
+ nobj
- num
- 1);
1090 (ALLOCNO_COLOR_DATA (conflict_a
)->profitable_hard_regs
,
1094 AND_COMPL_HARD_REG_SET
1095 (ALLOCNO_COLOR_DATA (conflict_a
)->profitable_hard_regs
,
1096 ira_reg_mode_hard_regset
[hard_regno
][mode
]);
1100 /* Exclude too costly hard regs. */
1101 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap
, 0, i
, bi
)
1103 int min_cost
= INT_MAX
;
1106 a
= ira_allocnos
[i
];
1107 if ((aclass
= ALLOCNO_CLASS (a
)) == NO_REGS
1108 || empty_profitable_hard_regs (a
))
1110 data
= ALLOCNO_COLOR_DATA (a
);
1111 mode
= ALLOCNO_MODE (a
);
1112 if ((costs
= ALLOCNO_UPDATED_HARD_REG_COSTS (a
)) != NULL
1113 || (costs
= ALLOCNO_HARD_REG_COSTS (a
)) != NULL
)
1115 class_size
= ira_class_hard_regs_num
[aclass
];
1116 for (j
= 0; j
< class_size
; j
++)
1118 hard_regno
= ira_class_hard_regs
[aclass
][j
];
1119 if (! TEST_HARD_REG_BIT (data
->profitable_hard_regs
,
1122 if (ALLOCNO_UPDATED_MEMORY_COST (a
) < costs
[j
]
1123 /* Do not remove HARD_REGNO for static chain pointer
1124 pseudo when non-local goto is used. */
1125 && ! non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a
)))
1126 CLEAR_HARD_REG_BIT (data
->profitable_hard_regs
,
1128 else if (min_cost
> costs
[j
])
1129 min_cost
= costs
[j
];
1132 else if (ALLOCNO_UPDATED_MEMORY_COST (a
)
1133 < ALLOCNO_UPDATED_CLASS_COST (a
)
1134 /* Do not empty profitable regs for static chain
1135 pointer pseudo when non-local goto is used. */
1136 && ! non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a
)))
1137 CLEAR_HARD_REG_SET (data
->profitable_hard_regs
);
1138 if (ALLOCNO_UPDATED_CLASS_COST (a
) > min_cost
)
1139 ALLOCNO_UPDATED_CLASS_COST (a
) = min_cost
;
1145 /* This page contains functions used to choose hard registers for
1148 /* Pool for update cost records. */
1149 static object_allocator
<update_cost_record
> update_cost_record_pool
1150 ("update cost records");
1152 /* Return new update cost record with given params. */
1153 static struct update_cost_record
*
1154 get_update_cost_record (int hard_regno
, int divisor
,
1155 struct update_cost_record
*next
)
1157 struct update_cost_record
*record
;
1159 record
= update_cost_record_pool
.allocate ();
1160 record
->hard_regno
= hard_regno
;
1161 record
->divisor
= divisor
;
1162 record
->next
= next
;
1166 /* Free memory for all records in LIST. */
1168 free_update_cost_record_list (struct update_cost_record
*list
)
1170 struct update_cost_record
*next
;
1172 while (list
!= NULL
)
1175 update_cost_record_pool
.remove (list
);
1180 /* Free memory allocated for all update cost records. */
1182 finish_update_cost_records (void)
1184 update_cost_record_pool
.release ();
1187 /* Array whose element value is TRUE if the corresponding hard
1188 register was already allocated for an allocno. */
1189 static bool allocated_hardreg_p
[FIRST_PSEUDO_REGISTER
];
1191 /* Describes one element in a queue of allocnos whose costs need to be
1192 updated. Each allocno in the queue is known to have an allocno
1194 struct update_cost_queue_elem
1196 /* This element is in the queue iff CHECK == update_cost_check. */
1199 /* COST_HOP_DIVISOR**N, where N is the length of the shortest path
1200 connecting this allocno to the one being allocated. */
1203 /* Allocno from which we are chaining costs of connected allocnos.
1204 It is used not go back in graph of allocnos connected by
1208 /* The next allocno in the queue, or null if this is the last element. */
1212 /* The first element in a queue of allocnos whose copy costs need to be
1213 updated. Null if the queue is empty. */
1214 static ira_allocno_t update_cost_queue
;
1216 /* The last element in the queue described by update_cost_queue.
1217 Not valid if update_cost_queue is null. */
1218 static struct update_cost_queue_elem
*update_cost_queue_tail
;
1220 /* A pool of elements in the queue described by update_cost_queue.
1221 Elements are indexed by ALLOCNO_NUM. */
1222 static struct update_cost_queue_elem
*update_cost_queue_elems
;
1224 /* The current value of update_costs_from_copies call count. */
1225 static int update_cost_check
;
1227 /* Allocate and initialize data necessary for function
1228 update_costs_from_copies. */
1230 initiate_cost_update (void)
1234 size
= ira_allocnos_num
* sizeof (struct update_cost_queue_elem
);
1235 update_cost_queue_elems
1236 = (struct update_cost_queue_elem
*) ira_allocate (size
);
1237 memset (update_cost_queue_elems
, 0, size
);
1238 update_cost_check
= 0;
1241 /* Deallocate data used by function update_costs_from_copies. */
1243 finish_cost_update (void)
1245 ira_free (update_cost_queue_elems
);
1246 finish_update_cost_records ();
1249 /* When we traverse allocnos to update hard register costs, the cost
1250 divisor will be multiplied by the following macro value for each
1251 hop from given allocno to directly connected allocnos. */
1252 #define COST_HOP_DIVISOR 4
1254 /* Start a new cost-updating pass. */
1256 start_update_cost (void)
1258 update_cost_check
++;
1259 update_cost_queue
= NULL
;
1262 /* Add (ALLOCNO, FROM, DIVISOR) to the end of update_cost_queue, unless
1263 ALLOCNO is already in the queue, or has NO_REGS class. */
1265 queue_update_cost (ira_allocno_t allocno
, ira_allocno_t from
, int divisor
)
1267 struct update_cost_queue_elem
*elem
;
1269 elem
= &update_cost_queue_elems
[ALLOCNO_NUM (allocno
)];
1270 if (elem
->check
!= update_cost_check
1271 && ALLOCNO_CLASS (allocno
) != NO_REGS
)
1273 elem
->check
= update_cost_check
;
1275 elem
->divisor
= divisor
;
1277 if (update_cost_queue
== NULL
)
1278 update_cost_queue
= allocno
;
1280 update_cost_queue_tail
->next
= allocno
;
1281 update_cost_queue_tail
= elem
;
1285 /* Try to remove the first element from update_cost_queue. Return
1286 false if the queue was empty, otherwise make (*ALLOCNO, *FROM,
1287 *DIVISOR) describe the removed element. */
1289 get_next_update_cost (ira_allocno_t
*allocno
, ira_allocno_t
*from
, int *divisor
)
1291 struct update_cost_queue_elem
*elem
;
1293 if (update_cost_queue
== NULL
)
1296 *allocno
= update_cost_queue
;
1297 elem
= &update_cost_queue_elems
[ALLOCNO_NUM (*allocno
)];
1299 *divisor
= elem
->divisor
;
1300 update_cost_queue
= elem
->next
;
1304 /* Increase costs of HARD_REGNO by UPDATE_COST and conflict cost by
1305 UPDATE_CONFLICT_COST for ALLOCNO. Return true if we really
1306 modified the cost. */
1308 update_allocno_cost (ira_allocno_t allocno
, int hard_regno
,
1309 int update_cost
, int update_conflict_cost
)
1312 enum reg_class aclass
= ALLOCNO_CLASS (allocno
);
1314 i
= ira_class_hard_reg_index
[aclass
][hard_regno
];
1317 ira_allocate_and_set_or_copy_costs
1318 (&ALLOCNO_UPDATED_HARD_REG_COSTS (allocno
), aclass
,
1319 ALLOCNO_UPDATED_CLASS_COST (allocno
),
1320 ALLOCNO_HARD_REG_COSTS (allocno
));
1321 ira_allocate_and_set_or_copy_costs
1322 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (allocno
),
1323 aclass
, 0, ALLOCNO_CONFLICT_HARD_REG_COSTS (allocno
));
1324 ALLOCNO_UPDATED_HARD_REG_COSTS (allocno
)[i
] += update_cost
;
1325 ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (allocno
)[i
] += update_conflict_cost
;
1329 /* Update (decrease if DECR_P) HARD_REGNO cost of allocnos connected
1330 by copies to ALLOCNO to increase chances to remove some copies as
1331 the result of subsequent assignment. Record cost updates if
1332 RECORD_P is true. */
1334 update_costs_from_allocno (ira_allocno_t allocno
, int hard_regno
,
1335 int divisor
, bool decr_p
, bool record_p
)
1337 int cost
, update_cost
, update_conflict_cost
;
1339 enum reg_class rclass
, aclass
;
1340 ira_allocno_t another_allocno
, from
= NULL
;
1341 ira_copy_t cp
, next_cp
;
1343 rclass
= REGNO_REG_CLASS (hard_regno
);
1346 mode
= ALLOCNO_MODE (allocno
);
1347 ira_init_register_move_cost_if_necessary (mode
);
1348 for (cp
= ALLOCNO_COPIES (allocno
); cp
!= NULL
; cp
= next_cp
)
1350 if (cp
->first
== allocno
)
1352 next_cp
= cp
->next_first_allocno_copy
;
1353 another_allocno
= cp
->second
;
1355 else if (cp
->second
== allocno
)
1357 next_cp
= cp
->next_second_allocno_copy
;
1358 another_allocno
= cp
->first
;
1363 if (another_allocno
== from
)
1366 aclass
= ALLOCNO_CLASS (another_allocno
);
1367 if (! TEST_HARD_REG_BIT (reg_class_contents
[aclass
],
1369 || ALLOCNO_ASSIGNED_P (another_allocno
))
1372 /* If we have different modes use the smallest one. It is
1373 a sub-register move. It is hard to predict what LRA
1374 will reload (the pseudo or its sub-register) but LRA
1375 will try to minimize the data movement. Also for some
1376 register classes bigger modes might be invalid,
1377 e.g. DImode for AREG on x86. For such cases the
1378 register move cost will be maximal. */
1379 mode
= narrower_subreg_mode (mode
, ALLOCNO_MODE (cp
->second
));
1381 cost
= (cp
->second
== allocno
1382 ? ira_register_move_cost
[mode
][rclass
][aclass
]
1383 : ira_register_move_cost
[mode
][aclass
][rclass
]);
1387 update_conflict_cost
= update_cost
= cp
->freq
* cost
/ divisor
;
1389 if (ALLOCNO_COLOR_DATA (another_allocno
) != NULL
1390 && (ALLOCNO_COLOR_DATA (allocno
)->first_thread_allocno
1391 != ALLOCNO_COLOR_DATA (another_allocno
)->first_thread_allocno
))
1392 /* Decrease conflict cost of ANOTHER_ALLOCNO if it is not
1393 in the same allocation thread. */
1394 update_conflict_cost
/= COST_HOP_DIVISOR
;
1396 if (update_cost
== 0)
1399 if (! update_allocno_cost (another_allocno
, hard_regno
,
1400 update_cost
, update_conflict_cost
))
1402 queue_update_cost (another_allocno
, allocno
, divisor
* COST_HOP_DIVISOR
);
1403 if (record_p
&& ALLOCNO_COLOR_DATA (another_allocno
) != NULL
)
1404 ALLOCNO_COLOR_DATA (another_allocno
)->update_cost_records
1405 = get_update_cost_record (hard_regno
, divisor
,
1406 ALLOCNO_COLOR_DATA (another_allocno
)
1407 ->update_cost_records
);
1410 while (get_next_update_cost (&allocno
, &from
, &divisor
));
1413 /* Decrease preferred ALLOCNO hard register costs and costs of
1414 allocnos connected to ALLOCNO through copy. */
1416 update_costs_from_prefs (ira_allocno_t allocno
)
1420 start_update_cost ();
1421 for (pref
= ALLOCNO_PREFS (allocno
); pref
!= NULL
; pref
= pref
->next_pref
)
1422 update_costs_from_allocno (allocno
, pref
->hard_regno
,
1423 COST_HOP_DIVISOR
, true, true);
1426 /* Update (decrease if DECR_P) the cost of allocnos connected to
1427 ALLOCNO through copies to increase chances to remove some copies as
1428 the result of subsequent assignment. ALLOCNO was just assigned to
1429 a hard register. Record cost updates if RECORD_P is true. */
1431 update_costs_from_copies (ira_allocno_t allocno
, bool decr_p
, bool record_p
)
1435 hard_regno
= ALLOCNO_HARD_REGNO (allocno
);
1436 ira_assert (hard_regno
>= 0 && ALLOCNO_CLASS (allocno
) != NO_REGS
);
1437 start_update_cost ();
1438 update_costs_from_allocno (allocno
, hard_regno
, 1, decr_p
, record_p
);
1441 /* Update conflict_allocno_hard_prefs of allocnos conflicting with
1444 update_conflict_allocno_hard_prefs (ira_allocno_t allocno
)
1446 int l
, nr
= ALLOCNO_NUM_OBJECTS (allocno
);
1448 for (l
= 0; l
< nr
; l
++)
1450 ira_object_t conflict_obj
, obj
= ALLOCNO_OBJECT (allocno
, l
);
1451 ira_object_conflict_iterator oci
;
1453 FOR_EACH_OBJECT_CONFLICT (obj
, conflict_obj
, oci
)
1455 ira_allocno_t conflict_a
= OBJECT_ALLOCNO (conflict_obj
);
1456 allocno_color_data_t conflict_data
= ALLOCNO_COLOR_DATA (conflict_a
);
1459 if (!(hard_reg_set_intersect_p
1460 (ALLOCNO_COLOR_DATA (allocno
)->profitable_hard_regs
,
1461 conflict_data
->profitable_hard_regs
)))
1463 for (pref
= ALLOCNO_PREFS (allocno
);
1465 pref
= pref
->next_pref
)
1466 conflict_data
->conflict_allocno_hard_prefs
+= pref
->freq
;
1471 /* Restore costs of allocnos connected to ALLOCNO by copies as it was
1472 before updating costs of these allocnos from given allocno. This
1473 is a wise thing to do as if given allocno did not get an expected
1474 hard reg, using smaller cost of the hard reg for allocnos connected
1475 by copies to given allocno becomes actually misleading. Free all
1476 update cost records for ALLOCNO as we don't need them anymore. */
1478 restore_costs_from_copies (ira_allocno_t allocno
)
1480 struct update_cost_record
*records
, *curr
;
1482 if (ALLOCNO_COLOR_DATA (allocno
) == NULL
)
1484 records
= ALLOCNO_COLOR_DATA (allocno
)->update_cost_records
;
1485 start_update_cost ();
1486 for (curr
= records
; curr
!= NULL
; curr
= curr
->next
)
1487 update_costs_from_allocno (allocno
, curr
->hard_regno
,
1488 curr
->divisor
, true, false);
1489 free_update_cost_record_list (records
);
1490 ALLOCNO_COLOR_DATA (allocno
)->update_cost_records
= NULL
;
1493 /* This function updates COSTS (decrease if DECR_P) for hard_registers
1494 of ACLASS by conflict costs of the unassigned allocnos
1495 connected by copies with allocnos in update_cost_queue. This
1496 update increases chances to remove some copies. */
1498 update_conflict_hard_regno_costs (int *costs
, enum reg_class aclass
,
1501 int i
, cost
, class_size
, freq
, mult
, div
, divisor
;
1502 int index
, hard_regno
;
1503 int *conflict_costs
;
1505 enum reg_class another_aclass
;
1506 ira_allocno_t allocno
, another_allocno
, from
;
1507 ira_copy_t cp
, next_cp
;
1509 while (get_next_update_cost (&allocno
, &from
, &divisor
))
1510 for (cp
= ALLOCNO_COPIES (allocno
); cp
!= NULL
; cp
= next_cp
)
1512 if (cp
->first
== allocno
)
1514 next_cp
= cp
->next_first_allocno_copy
;
1515 another_allocno
= cp
->second
;
1517 else if (cp
->second
== allocno
)
1519 next_cp
= cp
->next_second_allocno_copy
;
1520 another_allocno
= cp
->first
;
1525 if (another_allocno
== from
)
1528 another_aclass
= ALLOCNO_CLASS (another_allocno
);
1529 if (! ira_reg_classes_intersect_p
[aclass
][another_aclass
]
1530 || ALLOCNO_ASSIGNED_P (another_allocno
)
1531 || ALLOCNO_COLOR_DATA (another_allocno
)->may_be_spilled_p
)
1533 class_size
= ira_class_hard_regs_num
[another_aclass
];
1534 ira_allocate_and_copy_costs
1535 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (another_allocno
),
1536 another_aclass
, ALLOCNO_CONFLICT_HARD_REG_COSTS (another_allocno
));
1538 = ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (another_allocno
);
1539 if (conflict_costs
== NULL
)
1544 freq
= ALLOCNO_FREQ (another_allocno
);
1547 div
= freq
* divisor
;
1549 for (i
= class_size
- 1; i
>= 0; i
--)
1551 hard_regno
= ira_class_hard_regs
[another_aclass
][i
];
1552 ira_assert (hard_regno
>= 0);
1553 index
= ira_class_hard_reg_index
[aclass
][hard_regno
];
1556 cost
= (int) (((int64_t) conflict_costs
[i
] * mult
) / div
);
1562 costs
[index
] += cost
;
1565 /* Probably 5 hops will be enough. */
1567 && divisor
<= (COST_HOP_DIVISOR
1570 * COST_HOP_DIVISOR
))
1571 queue_update_cost (another_allocno
, allocno
, divisor
* COST_HOP_DIVISOR
);
1575 /* Set up conflicting (through CONFLICT_REGS) for each object of
1576 allocno A and the start allocno profitable regs (through
1577 START_PROFITABLE_REGS). Remember that the start profitable regs
1578 exclude hard regs which cannot hold value of mode of allocno A.
1579 This covers mostly cases when multi-register value should be
1582 get_conflict_and_start_profitable_regs (ira_allocno_t a
, bool retry_p
,
1583 HARD_REG_SET
*conflict_regs
,
1584 HARD_REG_SET
*start_profitable_regs
)
1589 nwords
= ALLOCNO_NUM_OBJECTS (a
);
1590 for (i
= 0; i
< nwords
; i
++)
1592 obj
= ALLOCNO_OBJECT (a
, i
);
1593 COPY_HARD_REG_SET (conflict_regs
[i
],
1594 OBJECT_TOTAL_CONFLICT_HARD_REGS (obj
));
1598 COPY_HARD_REG_SET (*start_profitable_regs
,
1599 reg_class_contents
[ALLOCNO_CLASS (a
)]);
1600 AND_COMPL_HARD_REG_SET (*start_profitable_regs
,
1601 ira_prohibited_class_mode_regs
1602 [ALLOCNO_CLASS (a
)][ALLOCNO_MODE (a
)]);
1605 COPY_HARD_REG_SET (*start_profitable_regs
,
1606 ALLOCNO_COLOR_DATA (a
)->profitable_hard_regs
);
1609 /* Return true if HARD_REGNO is ok for assigning to allocno A with
1610 PROFITABLE_REGS and whose objects have CONFLICT_REGS. */
1612 check_hard_reg_p (ira_allocno_t a
, int hard_regno
,
1613 HARD_REG_SET
*conflict_regs
, HARD_REG_SET profitable_regs
)
1615 int j
, nwords
, nregs
;
1616 enum reg_class aclass
;
1619 aclass
= ALLOCNO_CLASS (a
);
1620 mode
= ALLOCNO_MODE (a
);
1621 if (TEST_HARD_REG_BIT (ira_prohibited_class_mode_regs
[aclass
][mode
],
1624 /* Checking only profitable hard regs. */
1625 if (! TEST_HARD_REG_BIT (profitable_regs
, hard_regno
))
1627 nregs
= hard_regno_nregs (hard_regno
, mode
);
1628 nwords
= ALLOCNO_NUM_OBJECTS (a
);
1629 for (j
= 0; j
< nregs
; j
++)
1632 int set_to_test_start
= 0, set_to_test_end
= nwords
;
1634 if (nregs
== nwords
)
1636 if (REG_WORDS_BIG_ENDIAN
)
1637 set_to_test_start
= nwords
- j
- 1;
1639 set_to_test_start
= j
;
1640 set_to_test_end
= set_to_test_start
+ 1;
1642 for (k
= set_to_test_start
; k
< set_to_test_end
; k
++)
1643 if (TEST_HARD_REG_BIT (conflict_regs
[k
], hard_regno
+ j
))
1645 if (k
!= set_to_test_end
)
1651 /* Return number of registers needed to be saved and restored at
1652 function prologue/epilogue if we allocate HARD_REGNO to hold value
1655 calculate_saved_nregs (int hard_regno
, machine_mode mode
)
1660 ira_assert (hard_regno
>= 0);
1661 for (i
= hard_regno_nregs (hard_regno
, mode
) - 1; i
>= 0; i
--)
1662 if (!allocated_hardreg_p
[hard_regno
+ i
]
1663 && !TEST_HARD_REG_BIT (call_used_reg_set
, hard_regno
+ i
)
1664 && !LOCAL_REGNO (hard_regno
+ i
))
1669 /* Choose a hard register for allocno A. If RETRY_P is TRUE, it means
1670 that the function called from function
1671 `ira_reassign_conflict_allocnos' and `allocno_reload_assign'. In
1672 this case some allocno data are not defined or updated and we
1673 should not touch these data. The function returns true if we
1674 managed to assign a hard register to the allocno.
1676 To assign a hard register, first of all we calculate all conflict
1677 hard registers which can come from conflicting allocnos with
1678 already assigned hard registers. After that we find first free
1679 hard register with the minimal cost. During hard register cost
1680 calculation we take conflict hard register costs into account to
1681 give a chance for conflicting allocnos to get a better hard
1682 register in the future.
1684 If the best hard register cost is bigger than cost of memory usage
1685 for the allocno, we don't assign a hard register to given allocno
1688 If we assign a hard register to the allocno, we update costs of the
1689 hard register for allocnos connected by copies to improve a chance
1690 to coalesce insns represented by the copies when we assign hard
1691 registers to the allocnos connected by the copies. */
1693 assign_hard_reg (ira_allocno_t a
, bool retry_p
)
1695 HARD_REG_SET conflicting_regs
[2], profitable_hard_regs
;
1696 int i
, j
, hard_regno
, best_hard_regno
, class_size
;
1697 int cost
, mem_cost
, min_cost
, full_cost
, min_full_cost
, nwords
, word
;
1699 enum reg_class aclass
;
1701 static int costs
[FIRST_PSEUDO_REGISTER
], full_costs
[FIRST_PSEUDO_REGISTER
];
1703 enum reg_class rclass
;
1706 bool no_stack_reg_p
;
1709 ira_assert (! ALLOCNO_ASSIGNED_P (a
));
1710 get_conflict_and_start_profitable_regs (a
, retry_p
,
1712 &profitable_hard_regs
);
1713 aclass
= ALLOCNO_CLASS (a
);
1714 class_size
= ira_class_hard_regs_num
[aclass
];
1715 best_hard_regno
= -1;
1716 memset (full_costs
, 0, sizeof (int) * class_size
);
1718 memset (costs
, 0, sizeof (int) * class_size
);
1719 memset (full_costs
, 0, sizeof (int) * class_size
);
1721 no_stack_reg_p
= false;
1724 start_update_cost ();
1725 mem_cost
+= ALLOCNO_UPDATED_MEMORY_COST (a
);
1727 ira_allocate_and_copy_costs (&ALLOCNO_UPDATED_HARD_REG_COSTS (a
),
1728 aclass
, ALLOCNO_HARD_REG_COSTS (a
));
1729 a_costs
= ALLOCNO_UPDATED_HARD_REG_COSTS (a
);
1731 no_stack_reg_p
= no_stack_reg_p
|| ALLOCNO_TOTAL_NO_STACK_REG_P (a
);
1733 cost
= ALLOCNO_UPDATED_CLASS_COST (a
);
1734 for (i
= 0; i
< class_size
; i
++)
1735 if (a_costs
!= NULL
)
1737 costs
[i
] += a_costs
[i
];
1738 full_costs
[i
] += a_costs
[i
];
1743 full_costs
[i
] += cost
;
1745 nwords
= ALLOCNO_NUM_OBJECTS (a
);
1746 curr_allocno_process
++;
1747 for (word
= 0; word
< nwords
; word
++)
1749 ira_object_t conflict_obj
;
1750 ira_object_t obj
= ALLOCNO_OBJECT (a
, word
);
1751 ira_object_conflict_iterator oci
;
1753 /* Take preferences of conflicting allocnos into account. */
1754 FOR_EACH_OBJECT_CONFLICT (obj
, conflict_obj
, oci
)
1756 ira_allocno_t conflict_a
= OBJECT_ALLOCNO (conflict_obj
);
1757 enum reg_class conflict_aclass
;
1758 allocno_color_data_t data
= ALLOCNO_COLOR_DATA (conflict_a
);
1760 /* Reload can give another class so we need to check all
1763 && ((!ALLOCNO_ASSIGNED_P (conflict_a
)
1764 || ALLOCNO_HARD_REGNO (conflict_a
) < 0)
1765 && !(hard_reg_set_intersect_p
1766 (profitable_hard_regs
,
1768 (conflict_a
)->profitable_hard_regs
))))
1770 /* All conflict allocnos are in consideration bitmap
1771 when retry_p is false. It might change in future and
1772 if it happens the assert will be broken. It means
1773 the code should be modified for the new
1775 ira_assert (bitmap_bit_p (consideration_allocno_bitmap
,
1776 ALLOCNO_NUM (conflict_a
)));
1779 conflict_aclass
= ALLOCNO_CLASS (conflict_a
);
1780 ira_assert (ira_reg_classes_intersect_p
1781 [aclass
][conflict_aclass
]);
1782 if (ALLOCNO_ASSIGNED_P (conflict_a
))
1784 hard_regno
= ALLOCNO_HARD_REGNO (conflict_a
);
1786 && (ira_hard_reg_set_intersection_p
1787 (hard_regno
, ALLOCNO_MODE (conflict_a
),
1788 reg_class_contents
[aclass
])))
1790 int n_objects
= ALLOCNO_NUM_OBJECTS (conflict_a
);
1793 mode
= ALLOCNO_MODE (conflict_a
);
1794 conflict_nregs
= hard_regno_nregs (hard_regno
, mode
);
1795 if (conflict_nregs
== n_objects
&& conflict_nregs
> 1)
1797 int num
= OBJECT_SUBWORD (conflict_obj
);
1799 if (REG_WORDS_BIG_ENDIAN
)
1800 SET_HARD_REG_BIT (conflicting_regs
[word
],
1801 hard_regno
+ n_objects
- num
- 1);
1803 SET_HARD_REG_BIT (conflicting_regs
[word
],
1808 (conflicting_regs
[word
],
1809 ira_reg_mode_hard_regset
[hard_regno
][mode
]);
1810 if (hard_reg_set_subset_p (profitable_hard_regs
,
1811 conflicting_regs
[word
]))
1816 && ! ALLOCNO_COLOR_DATA (conflict_a
)->may_be_spilled_p
1817 /* Don't process the conflict allocno twice. */
1818 && (ALLOCNO_COLOR_DATA (conflict_a
)->last_process
1819 != curr_allocno_process
))
1821 int k
, *conflict_costs
;
1823 ALLOCNO_COLOR_DATA (conflict_a
)->last_process
1824 = curr_allocno_process
;
1825 ira_allocate_and_copy_costs
1826 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (conflict_a
),
1828 ALLOCNO_CONFLICT_HARD_REG_COSTS (conflict_a
));
1830 = ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (conflict_a
);
1831 if (conflict_costs
!= NULL
)
1832 for (j
= class_size
- 1; j
>= 0; j
--)
1834 hard_regno
= ira_class_hard_regs
[aclass
][j
];
1835 ira_assert (hard_regno
>= 0);
1836 k
= ira_class_hard_reg_index
[conflict_aclass
][hard_regno
];
1838 /* If HARD_REGNO is not available for CONFLICT_A,
1839 the conflict would be ignored, since HARD_REGNO
1840 will never be assigned to CONFLICT_A. */
1841 || !TEST_HARD_REG_BIT (data
->profitable_hard_regs
,
1844 full_costs
[j
] -= conflict_costs
[k
];
1846 queue_update_cost (conflict_a
, NULL
, COST_HOP_DIVISOR
);
1852 /* Take into account preferences of allocnos connected by copies to
1853 the conflict allocnos. */
1854 update_conflict_hard_regno_costs (full_costs
, aclass
, true);
1856 /* Take preferences of allocnos connected by copies into
1860 start_update_cost ();
1861 queue_update_cost (a
, NULL
, COST_HOP_DIVISOR
);
1862 update_conflict_hard_regno_costs (full_costs
, aclass
, false);
1864 min_cost
= min_full_cost
= INT_MAX
;
1865 /* We don't care about giving callee saved registers to allocnos no
1866 living through calls because call clobbered registers are
1867 allocated first (it is usual practice to put them first in
1868 REG_ALLOC_ORDER). */
1869 mode
= ALLOCNO_MODE (a
);
1870 for (i
= 0; i
< class_size
; i
++)
1872 hard_regno
= ira_class_hard_regs
[aclass
][i
];
1875 && FIRST_STACK_REG
<= hard_regno
&& hard_regno
<= LAST_STACK_REG
)
1878 if (! check_hard_reg_p (a
, hard_regno
,
1879 conflicting_regs
, profitable_hard_regs
))
1882 full_cost
= full_costs
[i
];
1883 if (!HONOR_REG_ALLOC_ORDER
)
1885 if ((saved_nregs
= calculate_saved_nregs (hard_regno
, mode
)) != 0)
1886 /* We need to save/restore the hard register in
1887 epilogue/prologue. Therefore we increase the cost. */
1889 rclass
= REGNO_REG_CLASS (hard_regno
);
1890 add_cost
= ((ira_memory_move_cost
[mode
][rclass
][0]
1891 + ira_memory_move_cost
[mode
][rclass
][1])
1892 * saved_nregs
/ hard_regno_nregs (hard_regno
,
1895 full_cost
+= add_cost
;
1898 if (min_cost
> cost
)
1900 if (min_full_cost
> full_cost
)
1902 min_full_cost
= full_cost
;
1903 best_hard_regno
= hard_regno
;
1904 ira_assert (hard_regno
>= 0);
1907 if (min_full_cost
> mem_cost
1908 /* Do not spill static chain pointer pseudo when non-local goto
1910 && ! non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a
)))
1912 if (! retry_p
&& internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
1913 fprintf (ira_dump_file
, "(memory is more profitable %d vs %d) ",
1914 mem_cost
, min_full_cost
);
1915 best_hard_regno
= -1;
1918 if (best_hard_regno
>= 0)
1920 for (i
= hard_regno_nregs (best_hard_regno
, mode
) - 1; i
>= 0; i
--)
1921 allocated_hardreg_p
[best_hard_regno
+ i
] = true;
1924 restore_costs_from_copies (a
);
1925 ALLOCNO_HARD_REGNO (a
) = best_hard_regno
;
1926 ALLOCNO_ASSIGNED_P (a
) = true;
1927 if (best_hard_regno
>= 0)
1928 update_costs_from_copies (a
, true, ! retry_p
);
1929 ira_assert (ALLOCNO_CLASS (a
) == aclass
);
1930 /* We don't need updated costs anymore. */
1931 ira_free_allocno_updated_costs (a
);
1932 return best_hard_regno
>= 0;
1937 /* An array used to sort copies. */
1938 static ira_copy_t
*sorted_copies
;
1940 /* If allocno A is a cap, return non-cap allocno from which A is
1941 created. Otherwise, return A. */
1942 static ira_allocno_t
1943 get_cap_member (ira_allocno_t a
)
1945 ira_allocno_t member
;
1947 while ((member
= ALLOCNO_CAP_MEMBER (a
)) != NULL
)
1952 /* Return TRUE if live ranges of allocnos A1 and A2 intersect. It is
1953 used to find a conflict for new allocnos or allocnos with the
1954 different allocno classes. */
1956 allocnos_conflict_by_live_ranges_p (ira_allocno_t a1
, ira_allocno_t a2
)
1960 int n1
= ALLOCNO_NUM_OBJECTS (a1
);
1961 int n2
= ALLOCNO_NUM_OBJECTS (a2
);
1965 reg1
= regno_reg_rtx
[ALLOCNO_REGNO (a1
)];
1966 reg2
= regno_reg_rtx
[ALLOCNO_REGNO (a2
)];
1967 if (reg1
!= NULL
&& reg2
!= NULL
1968 && ORIGINAL_REGNO (reg1
) == ORIGINAL_REGNO (reg2
))
1971 /* We don't keep live ranges for caps because they can be quite big.
1972 Use ranges of non-cap allocno from which caps are created. */
1973 a1
= get_cap_member (a1
);
1974 a2
= get_cap_member (a2
);
1975 for (i
= 0; i
< n1
; i
++)
1977 ira_object_t c1
= ALLOCNO_OBJECT (a1
, i
);
1979 for (j
= 0; j
< n2
; j
++)
1981 ira_object_t c2
= ALLOCNO_OBJECT (a2
, j
);
1983 if (ira_live_ranges_intersect_p (OBJECT_LIVE_RANGES (c1
),
1984 OBJECT_LIVE_RANGES (c2
)))
1991 /* The function is used to sort copies according to their execution
1994 copy_freq_compare_func (const void *v1p
, const void *v2p
)
1996 ira_copy_t cp1
= *(const ira_copy_t
*) v1p
, cp2
= *(const ira_copy_t
*) v2p
;
2004 /* If frequencies are equal, sort by copies, so that the results of
2005 qsort leave nothing to chance. */
2006 return cp1
->num
- cp2
->num
;
2011 /* Return true if any allocno from thread of A1 conflicts with any
2012 allocno from thread A2. */
2014 allocno_thread_conflict_p (ira_allocno_t a1
, ira_allocno_t a2
)
2016 ira_allocno_t a
, conflict_a
;
2018 for (a
= ALLOCNO_COLOR_DATA (a2
)->next_thread_allocno
;;
2019 a
= ALLOCNO_COLOR_DATA (a
)->next_thread_allocno
)
2021 for (conflict_a
= ALLOCNO_COLOR_DATA (a1
)->next_thread_allocno
;;
2022 conflict_a
= ALLOCNO_COLOR_DATA (conflict_a
)->next_thread_allocno
)
2024 if (allocnos_conflict_by_live_ranges_p (a
, conflict_a
))
2026 if (conflict_a
== a1
)
2035 /* Merge two threads given correspondingly by their first allocnos T1
2036 and T2 (more accurately merging T2 into T1). */
2038 merge_threads (ira_allocno_t t1
, ira_allocno_t t2
)
2040 ira_allocno_t a
, next
, last
;
2042 gcc_assert (t1
!= t2
2043 && ALLOCNO_COLOR_DATA (t1
)->first_thread_allocno
== t1
2044 && ALLOCNO_COLOR_DATA (t2
)->first_thread_allocno
== t2
);
2045 for (last
= t2
, a
= ALLOCNO_COLOR_DATA (t2
)->next_thread_allocno
;;
2046 a
= ALLOCNO_COLOR_DATA (a
)->next_thread_allocno
)
2048 ALLOCNO_COLOR_DATA (a
)->first_thread_allocno
= t1
;
2053 next
= ALLOCNO_COLOR_DATA (t1
)->next_thread_allocno
;
2054 ALLOCNO_COLOR_DATA (t1
)->next_thread_allocno
= t2
;
2055 ALLOCNO_COLOR_DATA (last
)->next_thread_allocno
= next
;
2056 ALLOCNO_COLOR_DATA (t1
)->thread_freq
+= ALLOCNO_COLOR_DATA (t2
)->thread_freq
;
2059 /* Create threads by processing CP_NUM copies from sorted copies. We
2060 process the most expensive copies first. */
2062 form_threads_from_copies (int cp_num
)
2064 ira_allocno_t a
, thread1
, thread2
;
2068 qsort (sorted_copies
, cp_num
, sizeof (ira_copy_t
), copy_freq_compare_func
);
2069 /* Form threads processing copies, most frequently executed
2071 for (; cp_num
!= 0;)
2073 for (i
= 0; i
< cp_num
; i
++)
2075 cp
= sorted_copies
[i
];
2076 thread1
= ALLOCNO_COLOR_DATA (cp
->first
)->first_thread_allocno
;
2077 thread2
= ALLOCNO_COLOR_DATA (cp
->second
)->first_thread_allocno
;
2078 if (thread1
== thread2
)
2080 if (! allocno_thread_conflict_p (thread1
, thread2
))
2082 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
2085 " Forming thread by copy %d:a%dr%d-a%dr%d (freq=%d):\n",
2086 cp
->num
, ALLOCNO_NUM (cp
->first
), ALLOCNO_REGNO (cp
->first
),
2087 ALLOCNO_NUM (cp
->second
), ALLOCNO_REGNO (cp
->second
),
2089 merge_threads (thread1
, thread2
);
2090 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
2092 thread1
= ALLOCNO_COLOR_DATA (thread1
)->first_thread_allocno
;
2093 fprintf (ira_dump_file
, " Result (freq=%d): a%dr%d(%d)",
2094 ALLOCNO_COLOR_DATA (thread1
)->thread_freq
,
2095 ALLOCNO_NUM (thread1
), ALLOCNO_REGNO (thread1
),
2096 ALLOCNO_FREQ (thread1
));
2097 for (a
= ALLOCNO_COLOR_DATA (thread1
)->next_thread_allocno
;
2099 a
= ALLOCNO_COLOR_DATA (a
)->next_thread_allocno
)
2100 fprintf (ira_dump_file
, " a%dr%d(%d)",
2101 ALLOCNO_NUM (a
), ALLOCNO_REGNO (a
),
2103 fprintf (ira_dump_file
, "\n");
2109 /* Collect the rest of copies. */
2110 for (n
= 0; i
< cp_num
; i
++)
2112 cp
= sorted_copies
[i
];
2113 if (ALLOCNO_COLOR_DATA (cp
->first
)->first_thread_allocno
2114 != ALLOCNO_COLOR_DATA (cp
->second
)->first_thread_allocno
)
2115 sorted_copies
[n
++] = cp
;
2121 /* Create threads by processing copies of all alocnos from BUCKET. We
2122 process the most expensive copies first. */
2124 form_threads_from_bucket (ira_allocno_t bucket
)
2127 ira_copy_t cp
, next_cp
;
2130 for (a
= bucket
; a
!= NULL
; a
= ALLOCNO_COLOR_DATA (a
)->next_bucket_allocno
)
2132 for (cp
= ALLOCNO_COPIES (a
); cp
!= NULL
; cp
= next_cp
)
2136 next_cp
= cp
->next_first_allocno_copy
;
2137 sorted_copies
[cp_num
++] = cp
;
2139 else if (cp
->second
== a
)
2140 next_cp
= cp
->next_second_allocno_copy
;
2145 form_threads_from_copies (cp_num
);
2148 /* Create threads by processing copies of colorable allocno A. We
2149 process most expensive copies first. */
2151 form_threads_from_colorable_allocno (ira_allocno_t a
)
2153 ira_allocno_t another_a
;
2154 ira_copy_t cp
, next_cp
;
2157 for (cp
= ALLOCNO_COPIES (a
); cp
!= NULL
; cp
= next_cp
)
2161 next_cp
= cp
->next_first_allocno_copy
;
2162 another_a
= cp
->second
;
2164 else if (cp
->second
== a
)
2166 next_cp
= cp
->next_second_allocno_copy
;
2167 another_a
= cp
->first
;
2171 if ((! ALLOCNO_COLOR_DATA (another_a
)->in_graph_p
2172 && !ALLOCNO_COLOR_DATA (another_a
)->may_be_spilled_p
)
2173 || ALLOCNO_COLOR_DATA (another_a
)->colorable_p
)
2174 sorted_copies
[cp_num
++] = cp
;
2176 form_threads_from_copies (cp_num
);
2179 /* Form initial threads which contain only one allocno. */
2181 init_allocno_threads (void)
2187 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap
, 0, j
, bi
)
2189 a
= ira_allocnos
[j
];
2190 /* Set up initial thread data: */
2191 ALLOCNO_COLOR_DATA (a
)->first_thread_allocno
2192 = ALLOCNO_COLOR_DATA (a
)->next_thread_allocno
= a
;
2193 ALLOCNO_COLOR_DATA (a
)->thread_freq
= ALLOCNO_FREQ (a
);
2199 /* This page contains the allocator based on the Chaitin-Briggs algorithm. */
2201 /* Bucket of allocnos that can colored currently without spilling. */
2202 static ira_allocno_t colorable_allocno_bucket
;
2204 /* Bucket of allocnos that might be not colored currently without
2206 static ira_allocno_t uncolorable_allocno_bucket
;
2208 /* The current number of allocnos in the uncolorable_bucket. */
2209 static int uncolorable_allocnos_num
;
2211 /* Return the current spill priority of allocno A. The less the
2212 number, the more preferable the allocno for spilling. */
2214 allocno_spill_priority (ira_allocno_t a
)
2216 allocno_color_data_t data
= ALLOCNO_COLOR_DATA (a
);
2219 / (ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a
)
2220 * ira_reg_class_max_nregs
[ALLOCNO_CLASS (a
)][ALLOCNO_MODE (a
)]
2224 /* Add allocno A to bucket *BUCKET_PTR. A should be not in a bucket
2227 add_allocno_to_bucket (ira_allocno_t a
, ira_allocno_t
*bucket_ptr
)
2229 ira_allocno_t first_a
;
2230 allocno_color_data_t data
;
2232 if (bucket_ptr
== &uncolorable_allocno_bucket
2233 && ALLOCNO_CLASS (a
) != NO_REGS
)
2235 uncolorable_allocnos_num
++;
2236 ira_assert (uncolorable_allocnos_num
> 0);
2238 first_a
= *bucket_ptr
;
2239 data
= ALLOCNO_COLOR_DATA (a
);
2240 data
->next_bucket_allocno
= first_a
;
2241 data
->prev_bucket_allocno
= NULL
;
2242 if (first_a
!= NULL
)
2243 ALLOCNO_COLOR_DATA (first_a
)->prev_bucket_allocno
= a
;
2247 /* Compare two allocnos to define which allocno should be pushed first
2248 into the coloring stack. If the return is a negative number, the
2249 allocno given by the first parameter will be pushed first. In this
2250 case such allocno has less priority than the second one and the
2251 hard register will be assigned to it after assignment to the second
2252 one. As the result of such assignment order, the second allocno
2253 has a better chance to get the best hard register. */
2255 bucket_allocno_compare_func (const void *v1p
, const void *v2p
)
2257 ira_allocno_t a1
= *(const ira_allocno_t
*) v1p
;
2258 ira_allocno_t a2
= *(const ira_allocno_t
*) v2p
;
2259 int diff
, freq1
, freq2
, a1_num
, a2_num
, pref1
, pref2
;
2260 ira_allocno_t t1
= ALLOCNO_COLOR_DATA (a1
)->first_thread_allocno
;
2261 ira_allocno_t t2
= ALLOCNO_COLOR_DATA (a2
)->first_thread_allocno
;
2262 int cl1
= ALLOCNO_CLASS (a1
), cl2
= ALLOCNO_CLASS (a2
);
2264 freq1
= ALLOCNO_COLOR_DATA (t1
)->thread_freq
;
2265 freq2
= ALLOCNO_COLOR_DATA (t2
)->thread_freq
;
2266 if ((diff
= freq1
- freq2
) != 0)
2269 if ((diff
= ALLOCNO_NUM (t2
) - ALLOCNO_NUM (t1
)) != 0)
2272 /* Push pseudos requiring less hard registers first. It means that
2273 we will assign pseudos requiring more hard registers first
2274 avoiding creation small holes in free hard register file into
2275 which the pseudos requiring more hard registers cannot fit. */
2276 if ((diff
= (ira_reg_class_max_nregs
[cl1
][ALLOCNO_MODE (a1
)]
2277 - ira_reg_class_max_nregs
[cl2
][ALLOCNO_MODE (a2
)])) != 0)
2280 freq1
= ALLOCNO_FREQ (a1
);
2281 freq2
= ALLOCNO_FREQ (a2
);
2282 if ((diff
= freq1
- freq2
) != 0)
2285 a1_num
= ALLOCNO_COLOR_DATA (a1
)->available_regs_num
;
2286 a2_num
= ALLOCNO_COLOR_DATA (a2
)->available_regs_num
;
2287 if ((diff
= a2_num
- a1_num
) != 0)
2289 /* Push allocnos with minimal conflict_allocno_hard_prefs first. */
2290 pref1
= ALLOCNO_COLOR_DATA (a1
)->conflict_allocno_hard_prefs
;
2291 pref2
= ALLOCNO_COLOR_DATA (a2
)->conflict_allocno_hard_prefs
;
2292 if ((diff
= pref1
- pref2
) != 0)
2294 return ALLOCNO_NUM (a2
) - ALLOCNO_NUM (a1
);
2297 /* Sort bucket *BUCKET_PTR and return the result through
2300 sort_bucket (ira_allocno_t
*bucket_ptr
,
2301 int (*compare_func
) (const void *, const void *))
2303 ira_allocno_t a
, head
;
2306 for (n
= 0, a
= *bucket_ptr
;
2308 a
= ALLOCNO_COLOR_DATA (a
)->next_bucket_allocno
)
2309 sorted_allocnos
[n
++] = a
;
2312 qsort (sorted_allocnos
, n
, sizeof (ira_allocno_t
), compare_func
);
2314 for (n
--; n
>= 0; n
--)
2316 a
= sorted_allocnos
[n
];
2317 ALLOCNO_COLOR_DATA (a
)->next_bucket_allocno
= head
;
2318 ALLOCNO_COLOR_DATA (a
)->prev_bucket_allocno
= NULL
;
2320 ALLOCNO_COLOR_DATA (head
)->prev_bucket_allocno
= a
;
2326 /* Add ALLOCNO to colorable bucket maintaining the order according
2327 their priority. ALLOCNO should be not in a bucket before the
2330 add_allocno_to_ordered_colorable_bucket (ira_allocno_t allocno
)
2332 ira_allocno_t before
, after
;
2334 form_threads_from_colorable_allocno (allocno
);
2335 for (before
= colorable_allocno_bucket
, after
= NULL
;
2338 before
= ALLOCNO_COLOR_DATA (before
)->next_bucket_allocno
)
2339 if (bucket_allocno_compare_func (&allocno
, &before
) < 0)
2341 ALLOCNO_COLOR_DATA (allocno
)->next_bucket_allocno
= before
;
2342 ALLOCNO_COLOR_DATA (allocno
)->prev_bucket_allocno
= after
;
2344 colorable_allocno_bucket
= allocno
;
2346 ALLOCNO_COLOR_DATA (after
)->next_bucket_allocno
= allocno
;
2348 ALLOCNO_COLOR_DATA (before
)->prev_bucket_allocno
= allocno
;
2351 /* Delete ALLOCNO from bucket *BUCKET_PTR. It should be there before
2354 delete_allocno_from_bucket (ira_allocno_t allocno
, ira_allocno_t
*bucket_ptr
)
2356 ira_allocno_t prev_allocno
, next_allocno
;
2358 if (bucket_ptr
== &uncolorable_allocno_bucket
2359 && ALLOCNO_CLASS (allocno
) != NO_REGS
)
2361 uncolorable_allocnos_num
--;
2362 ira_assert (uncolorable_allocnos_num
>= 0);
2364 prev_allocno
= ALLOCNO_COLOR_DATA (allocno
)->prev_bucket_allocno
;
2365 next_allocno
= ALLOCNO_COLOR_DATA (allocno
)->next_bucket_allocno
;
2366 if (prev_allocno
!= NULL
)
2367 ALLOCNO_COLOR_DATA (prev_allocno
)->next_bucket_allocno
= next_allocno
;
2370 ira_assert (*bucket_ptr
== allocno
);
2371 *bucket_ptr
= next_allocno
;
2373 if (next_allocno
!= NULL
)
2374 ALLOCNO_COLOR_DATA (next_allocno
)->prev_bucket_allocno
= prev_allocno
;
2377 /* Put allocno A onto the coloring stack without removing it from its
2378 bucket. Pushing allocno to the coloring stack can result in moving
2379 conflicting allocnos from the uncolorable bucket to the colorable
2380 one. Update conflict_allocno_hard_prefs of the conflicting
2381 allocnos which are not on stack yet. */
2383 push_allocno_to_stack (ira_allocno_t a
)
2385 enum reg_class aclass
;
2386 allocno_color_data_t data
, conflict_data
;
2387 int size
, i
, n
= ALLOCNO_NUM_OBJECTS (a
);
2389 data
= ALLOCNO_COLOR_DATA (a
);
2390 data
->in_graph_p
= false;
2391 allocno_stack_vec
.safe_push (a
);
2392 aclass
= ALLOCNO_CLASS (a
);
2393 if (aclass
== NO_REGS
)
2395 size
= ira_reg_class_max_nregs
[aclass
][ALLOCNO_MODE (a
)];
2398 /* We will deal with the subwords individually. */
2399 gcc_assert (size
== ALLOCNO_NUM_OBJECTS (a
));
2402 for (i
= 0; i
< n
; i
++)
2404 ira_object_t obj
= ALLOCNO_OBJECT (a
, i
);
2405 ira_object_t conflict_obj
;
2406 ira_object_conflict_iterator oci
;
2408 FOR_EACH_OBJECT_CONFLICT (obj
, conflict_obj
, oci
)
2410 ira_allocno_t conflict_a
= OBJECT_ALLOCNO (conflict_obj
);
2413 conflict_data
= ALLOCNO_COLOR_DATA (conflict_a
);
2414 if (! conflict_data
->in_graph_p
2415 || ALLOCNO_ASSIGNED_P (conflict_a
)
2416 || !(hard_reg_set_intersect_p
2417 (ALLOCNO_COLOR_DATA (a
)->profitable_hard_regs
,
2418 conflict_data
->profitable_hard_regs
)))
2420 for (pref
= ALLOCNO_PREFS (a
); pref
!= NULL
; pref
= pref
->next_pref
)
2421 conflict_data
->conflict_allocno_hard_prefs
-= pref
->freq
;
2422 if (conflict_data
->colorable_p
)
2424 ira_assert (bitmap_bit_p (coloring_allocno_bitmap
,
2425 ALLOCNO_NUM (conflict_a
)));
2426 if (update_left_conflict_sizes_p (conflict_a
, a
, size
))
2428 delete_allocno_from_bucket
2429 (conflict_a
, &uncolorable_allocno_bucket
);
2430 add_allocno_to_ordered_colorable_bucket (conflict_a
);
2431 if (internal_flag_ira_verbose
> 4 && ira_dump_file
!= NULL
)
2433 fprintf (ira_dump_file
, " Making");
2434 ira_print_expanded_allocno (conflict_a
);
2435 fprintf (ira_dump_file
, " colorable\n");
2443 /* Put ALLOCNO onto the coloring stack and remove it from its bucket.
2444 The allocno is in the colorable bucket if COLORABLE_P is TRUE. */
2446 remove_allocno_from_bucket_and_push (ira_allocno_t allocno
, bool colorable_p
)
2449 delete_allocno_from_bucket (allocno
, &colorable_allocno_bucket
);
2451 delete_allocno_from_bucket (allocno
, &uncolorable_allocno_bucket
);
2452 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
2454 fprintf (ira_dump_file
, " Pushing");
2455 ira_print_expanded_allocno (allocno
);
2457 fprintf (ira_dump_file
, "(cost %d)\n",
2458 ALLOCNO_COLOR_DATA (allocno
)->temp
);
2460 fprintf (ira_dump_file
, "(potential spill: %spri=%d, cost=%d)\n",
2461 ALLOCNO_BAD_SPILL_P (allocno
) ? "bad spill, " : "",
2462 allocno_spill_priority (allocno
),
2463 ALLOCNO_COLOR_DATA (allocno
)->temp
);
2466 ALLOCNO_COLOR_DATA (allocno
)->may_be_spilled_p
= true;
2467 push_allocno_to_stack (allocno
);
2470 /* Put all allocnos from colorable bucket onto the coloring stack. */
2472 push_only_colorable (void)
2474 form_threads_from_bucket (colorable_allocno_bucket
);
2475 sort_bucket (&colorable_allocno_bucket
, bucket_allocno_compare_func
);
2476 for (;colorable_allocno_bucket
!= NULL
;)
2477 remove_allocno_from_bucket_and_push (colorable_allocno_bucket
, true);
2480 /* Return the frequency of exit edges (if EXIT_P) or entry from/to the
2481 loop given by its LOOP_NODE. */
2483 ira_loop_edge_freq (ira_loop_tree_node_t loop_node
, int regno
, bool exit_p
)
2490 ira_assert (current_loops
!= NULL
&& loop_node
->loop
!= NULL
2491 && (regno
< 0 || regno
>= FIRST_PSEUDO_REGISTER
));
2495 FOR_EACH_EDGE (e
, ei
, loop_node
->loop
->header
->preds
)
2496 if (e
->src
!= loop_node
->loop
->latch
2498 || (bitmap_bit_p (df_get_live_out (e
->src
), regno
)
2499 && bitmap_bit_p (df_get_live_in (e
->dest
), regno
))))
2500 freq
+= EDGE_FREQUENCY (e
);
2504 edges
= get_loop_exit_edges (loop_node
->loop
);
2505 FOR_EACH_VEC_ELT (edges
, i
, e
)
2507 || (bitmap_bit_p (df_get_live_out (e
->src
), regno
)
2508 && bitmap_bit_p (df_get_live_in (e
->dest
), regno
)))
2509 freq
+= EDGE_FREQUENCY (e
);
2513 return REG_FREQ_FROM_EDGE_FREQ (freq
);
2516 /* Calculate and return the cost of putting allocno A into memory. */
2518 calculate_allocno_spill_cost (ira_allocno_t a
)
2522 enum reg_class rclass
;
2523 ira_allocno_t parent_allocno
;
2524 ira_loop_tree_node_t parent_node
, loop_node
;
2526 regno
= ALLOCNO_REGNO (a
);
2527 cost
= ALLOCNO_UPDATED_MEMORY_COST (a
) - ALLOCNO_UPDATED_CLASS_COST (a
);
2528 if (ALLOCNO_CAP (a
) != NULL
)
2530 loop_node
= ALLOCNO_LOOP_TREE_NODE (a
);
2531 if ((parent_node
= loop_node
->parent
) == NULL
)
2533 if ((parent_allocno
= parent_node
->regno_allocno_map
[regno
]) == NULL
)
2535 mode
= ALLOCNO_MODE (a
);
2536 rclass
= ALLOCNO_CLASS (a
);
2537 if (ALLOCNO_HARD_REGNO (parent_allocno
) < 0)
2538 cost
-= (ira_memory_move_cost
[mode
][rclass
][0]
2539 * ira_loop_edge_freq (loop_node
, regno
, true)
2540 + ira_memory_move_cost
[mode
][rclass
][1]
2541 * ira_loop_edge_freq (loop_node
, regno
, false));
2544 ira_init_register_move_cost_if_necessary (mode
);
2545 cost
+= ((ira_memory_move_cost
[mode
][rclass
][1]
2546 * ira_loop_edge_freq (loop_node
, regno
, true)
2547 + ira_memory_move_cost
[mode
][rclass
][0]
2548 * ira_loop_edge_freq (loop_node
, regno
, false))
2549 - (ira_register_move_cost
[mode
][rclass
][rclass
]
2550 * (ira_loop_edge_freq (loop_node
, regno
, false)
2551 + ira_loop_edge_freq (loop_node
, regno
, true))));
2556 /* Used for sorting allocnos for spilling. */
2558 allocno_spill_priority_compare (ira_allocno_t a1
, ira_allocno_t a2
)
2560 int pri1
, pri2
, diff
;
2562 /* Avoid spilling static chain pointer pseudo when non-local goto is
2564 if (non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a1
)))
2566 else if (non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a2
)))
2568 if (ALLOCNO_BAD_SPILL_P (a1
) && ! ALLOCNO_BAD_SPILL_P (a2
))
2570 if (ALLOCNO_BAD_SPILL_P (a2
) && ! ALLOCNO_BAD_SPILL_P (a1
))
2572 pri1
= allocno_spill_priority (a1
);
2573 pri2
= allocno_spill_priority (a2
);
2574 if ((diff
= pri1
- pri2
) != 0)
2577 = ALLOCNO_COLOR_DATA (a1
)->temp
- ALLOCNO_COLOR_DATA (a2
)->temp
) != 0)
2579 return ALLOCNO_NUM (a1
) - ALLOCNO_NUM (a2
);
2582 /* Used for sorting allocnos for spilling. */
2584 allocno_spill_sort_compare (const void *v1p
, const void *v2p
)
2586 ira_allocno_t p1
= *(const ira_allocno_t
*) v1p
;
2587 ira_allocno_t p2
= *(const ira_allocno_t
*) v2p
;
2589 return allocno_spill_priority_compare (p1
, p2
);
2592 /* Push allocnos to the coloring stack. The order of allocnos in the
2593 stack defines the order for the subsequent coloring. */
2595 push_allocnos_to_stack (void)
2600 /* Calculate uncolorable allocno spill costs. */
2601 for (a
= uncolorable_allocno_bucket
;
2603 a
= ALLOCNO_COLOR_DATA (a
)->next_bucket_allocno
)
2604 if (ALLOCNO_CLASS (a
) != NO_REGS
)
2606 cost
= calculate_allocno_spill_cost (a
);
2607 /* ??? Remove cost of copies between the coalesced
2609 ALLOCNO_COLOR_DATA (a
)->temp
= cost
;
2611 sort_bucket (&uncolorable_allocno_bucket
, allocno_spill_sort_compare
);
2614 push_only_colorable ();
2615 a
= uncolorable_allocno_bucket
;
2618 remove_allocno_from_bucket_and_push (a
, false);
2620 ira_assert (colorable_allocno_bucket
== NULL
2621 && uncolorable_allocno_bucket
== NULL
);
2622 ira_assert (uncolorable_allocnos_num
== 0);
2625 /* Pop the coloring stack and assign hard registers to the popped
2628 pop_allocnos_from_stack (void)
2630 ira_allocno_t allocno
;
2631 enum reg_class aclass
;
2633 for (;allocno_stack_vec
.length () != 0;)
2635 allocno
= allocno_stack_vec
.pop ();
2636 aclass
= ALLOCNO_CLASS (allocno
);
2637 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
2639 fprintf (ira_dump_file
, " Popping");
2640 ira_print_expanded_allocno (allocno
);
2641 fprintf (ira_dump_file
, " -- ");
2643 if (aclass
== NO_REGS
)
2645 ALLOCNO_HARD_REGNO (allocno
) = -1;
2646 ALLOCNO_ASSIGNED_P (allocno
) = true;
2647 ira_assert (ALLOCNO_UPDATED_HARD_REG_COSTS (allocno
) == NULL
);
2649 (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (allocno
) == NULL
);
2650 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
2651 fprintf (ira_dump_file
, "assign memory\n");
2653 else if (assign_hard_reg (allocno
, false))
2655 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
2656 fprintf (ira_dump_file
, "assign reg %d\n",
2657 ALLOCNO_HARD_REGNO (allocno
));
2659 else if (ALLOCNO_ASSIGNED_P (allocno
))
2661 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
2662 fprintf (ira_dump_file
, "spill%s\n",
2663 ALLOCNO_COLOR_DATA (allocno
)->may_be_spilled_p
2666 ALLOCNO_COLOR_DATA (allocno
)->in_graph_p
= true;
2670 /* Set up number of available hard registers for allocno A. */
2672 setup_allocno_available_regs_num (ira_allocno_t a
)
2674 int i
, n
, hard_regno
, hard_regs_num
, nwords
;
2675 enum reg_class aclass
;
2676 allocno_color_data_t data
;
2678 aclass
= ALLOCNO_CLASS (a
);
2679 data
= ALLOCNO_COLOR_DATA (a
);
2680 data
->available_regs_num
= 0;
2681 if (aclass
== NO_REGS
)
2683 hard_regs_num
= ira_class_hard_regs_num
[aclass
];
2684 nwords
= ALLOCNO_NUM_OBJECTS (a
);
2685 for (n
= 0, i
= hard_regs_num
- 1; i
>= 0; i
--)
2687 hard_regno
= ira_class_hard_regs
[aclass
][i
];
2688 /* Checking only profitable hard regs. */
2689 if (TEST_HARD_REG_BIT (data
->profitable_hard_regs
, hard_regno
))
2692 data
->available_regs_num
= n
;
2693 if (internal_flag_ira_verbose
<= 2 || ira_dump_file
== NULL
)
2697 " Allocno a%dr%d of %s(%d) has %d avail. regs ",
2698 ALLOCNO_NUM (a
), ALLOCNO_REGNO (a
),
2699 reg_class_names
[aclass
], ira_class_hard_regs_num
[aclass
], n
);
2700 print_hard_reg_set (ira_dump_file
, data
->profitable_hard_regs
, false);
2701 fprintf (ira_dump_file
, ", %snode: ",
2702 hard_reg_set_equal_p (data
->profitable_hard_regs
,
2703 data
->hard_regs_node
->hard_regs
->set
)
2705 print_hard_reg_set (ira_dump_file
,
2706 data
->hard_regs_node
->hard_regs
->set
, false);
2707 for (i
= 0; i
< nwords
; i
++)
2709 ira_object_t obj
= ALLOCNO_OBJECT (a
, i
);
2714 fprintf (ira_dump_file
, ", ");
2715 fprintf (ira_dump_file
, " obj %d", i
);
2717 fprintf (ira_dump_file
, " (confl regs = ");
2718 print_hard_reg_set (ira_dump_file
, OBJECT_TOTAL_CONFLICT_HARD_REGS (obj
),
2720 fprintf (ira_dump_file
, ")");
2722 fprintf (ira_dump_file
, "\n");
2725 /* Put ALLOCNO in a bucket corresponding to its number and size of its
2726 conflicting allocnos and hard registers. */
2728 put_allocno_into_bucket (ira_allocno_t allocno
)
2730 ALLOCNO_COLOR_DATA (allocno
)->in_graph_p
= true;
2731 setup_allocno_available_regs_num (allocno
);
2732 if (setup_left_conflict_sizes_p (allocno
))
2733 add_allocno_to_bucket (allocno
, &colorable_allocno_bucket
);
2735 add_allocno_to_bucket (allocno
, &uncolorable_allocno_bucket
);
2738 /* Map: allocno number -> allocno priority. */
2739 static int *allocno_priorities
;
2741 /* Set up priorities for N allocnos in array
2742 CONSIDERATION_ALLOCNOS. */
2744 setup_allocno_priorities (ira_allocno_t
*consideration_allocnos
, int n
)
2746 int i
, length
, nrefs
, priority
, max_priority
, mult
;
2750 for (i
= 0; i
< n
; i
++)
2752 a
= consideration_allocnos
[i
];
2753 nrefs
= ALLOCNO_NREFS (a
);
2754 ira_assert (nrefs
>= 0);
2755 mult
= floor_log2 (ALLOCNO_NREFS (a
)) + 1;
2756 ira_assert (mult
>= 0);
2757 allocno_priorities
[ALLOCNO_NUM (a
)]
2760 * (ALLOCNO_MEMORY_COST (a
) - ALLOCNO_CLASS_COST (a
))
2761 * ira_reg_class_max_nregs
[ALLOCNO_CLASS (a
)][ALLOCNO_MODE (a
)]);
2763 priority
= -priority
;
2764 if (max_priority
< priority
)
2765 max_priority
= priority
;
2767 mult
= max_priority
== 0 ? 1 : INT_MAX
/ max_priority
;
2768 for (i
= 0; i
< n
; i
++)
2770 a
= consideration_allocnos
[i
];
2771 length
= ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a
);
2772 if (ALLOCNO_NUM_OBJECTS (a
) > 1)
2773 length
/= ALLOCNO_NUM_OBJECTS (a
);
2776 allocno_priorities
[ALLOCNO_NUM (a
)]
2777 = allocno_priorities
[ALLOCNO_NUM (a
)] * mult
/ length
;
2781 /* Sort allocnos according to the profit of usage of a hard register
2782 instead of memory for them. */
2784 allocno_cost_compare_func (const void *v1p
, const void *v2p
)
2786 ira_allocno_t p1
= *(const ira_allocno_t
*) v1p
;
2787 ira_allocno_t p2
= *(const ira_allocno_t
*) v2p
;
2790 c1
= ALLOCNO_UPDATED_MEMORY_COST (p1
) - ALLOCNO_UPDATED_CLASS_COST (p1
);
2791 c2
= ALLOCNO_UPDATED_MEMORY_COST (p2
) - ALLOCNO_UPDATED_CLASS_COST (p2
);
2795 /* If regs are equally good, sort by allocno numbers, so that the
2796 results of qsort leave nothing to chance. */
2797 return ALLOCNO_NUM (p1
) - ALLOCNO_NUM (p2
);
2800 /* Return savings on removed copies when ALLOCNO is assigned to
2803 allocno_copy_cost_saving (ira_allocno_t allocno
, int hard_regno
)
2806 machine_mode allocno_mode
= ALLOCNO_MODE (allocno
);
2807 enum reg_class rclass
;
2808 ira_copy_t cp
, next_cp
;
2810 rclass
= REGNO_REG_CLASS (hard_regno
);
2811 if (ira_reg_class_max_nregs
[rclass
][allocno_mode
]
2812 > ira_class_hard_regs_num
[rclass
])
2813 /* For the above condition the cost can be wrong. Use the allocno
2814 class in this case. */
2815 rclass
= ALLOCNO_CLASS (allocno
);
2816 for (cp
= ALLOCNO_COPIES (allocno
); cp
!= NULL
; cp
= next_cp
)
2818 if (cp
->first
== allocno
)
2820 next_cp
= cp
->next_first_allocno_copy
;
2821 if (ALLOCNO_HARD_REGNO (cp
->second
) != hard_regno
)
2824 else if (cp
->second
== allocno
)
2826 next_cp
= cp
->next_second_allocno_copy
;
2827 if (ALLOCNO_HARD_REGNO (cp
->first
) != hard_regno
)
2832 cost
+= cp
->freq
* ira_register_move_cost
[allocno_mode
][rclass
][rclass
];
2837 /* We used Chaitin-Briggs coloring to assign as many pseudos as
2838 possible to hard registers. Let us try to improve allocation with
2839 cost point of view. This function improves the allocation by
2840 spilling some allocnos and assigning the freed hard registers to
2841 other allocnos if it decreases the overall allocation cost. */
2843 improve_allocation (void)
2846 int j
, k
, n
, hregno
, conflict_hregno
, base_cost
, class_size
, word
, nwords
;
2847 int check
, spill_cost
, min_cost
, nregs
, conflict_nregs
, r
, best
;
2849 enum reg_class aclass
;
2852 int costs
[FIRST_PSEUDO_REGISTER
];
2853 HARD_REG_SET conflicting_regs
[2], profitable_hard_regs
;
2857 /* Don't bother to optimize the code with static chain pointer and
2858 non-local goto in order not to spill the chain pointer
2860 if (cfun
->static_chain_decl
&& crtl
->has_nonlocal_goto
)
2862 /* Clear counts used to process conflicting allocnos only once for
2864 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap
, 0, i
, bi
)
2865 ALLOCNO_COLOR_DATA (ira_allocnos
[i
])->temp
= 0;
2867 /* Process each allocno and try to assign a hard register to it by
2868 spilling some its conflicting allocnos. */
2869 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap
, 0, i
, bi
)
2871 a
= ira_allocnos
[i
];
2872 ALLOCNO_COLOR_DATA (a
)->temp
= 0;
2873 if (empty_profitable_hard_regs (a
))
2876 aclass
= ALLOCNO_CLASS (a
);
2877 allocno_costs
= ALLOCNO_HARD_REG_COSTS (a
);
2878 if ((hregno
= ALLOCNO_HARD_REGNO (a
)) < 0)
2879 base_cost
= ALLOCNO_UPDATED_MEMORY_COST (a
);
2880 else if (allocno_costs
== NULL
)
2881 /* It means that assigning a hard register is not profitable
2882 (we don't waste memory for hard register costs in this
2886 base_cost
= (allocno_costs
[ira_class_hard_reg_index
[aclass
][hregno
]]
2887 - allocno_copy_cost_saving (a
, hregno
));
2889 get_conflict_and_start_profitable_regs (a
, false,
2891 &profitable_hard_regs
);
2892 class_size
= ira_class_hard_regs_num
[aclass
];
2893 /* Set up cost improvement for usage of each profitable hard
2894 register for allocno A. */
2895 for (j
= 0; j
< class_size
; j
++)
2897 hregno
= ira_class_hard_regs
[aclass
][j
];
2898 if (! check_hard_reg_p (a
, hregno
,
2899 conflicting_regs
, profitable_hard_regs
))
2901 ira_assert (ira_class_hard_reg_index
[aclass
][hregno
] == j
);
2902 k
= allocno_costs
== NULL
? 0 : j
;
2903 costs
[hregno
] = (allocno_costs
== NULL
2904 ? ALLOCNO_UPDATED_CLASS_COST (a
) : allocno_costs
[k
]);
2905 costs
[hregno
] -= allocno_copy_cost_saving (a
, hregno
);
2906 costs
[hregno
] -= base_cost
;
2907 if (costs
[hregno
] < 0)
2911 /* There is no chance to improve the allocation cost by
2912 assigning hard register to allocno A even without spilling
2913 conflicting allocnos. */
2915 mode
= ALLOCNO_MODE (a
);
2916 nwords
= ALLOCNO_NUM_OBJECTS (a
);
2917 /* Process each allocno conflicting with A and update the cost
2918 improvement for profitable hard registers of A. To use a
2919 hard register for A we need to spill some conflicting
2920 allocnos and that creates penalty for the cost
2922 for (word
= 0; word
< nwords
; word
++)
2924 ira_object_t conflict_obj
;
2925 ira_object_t obj
= ALLOCNO_OBJECT (a
, word
);
2926 ira_object_conflict_iterator oci
;
2928 FOR_EACH_OBJECT_CONFLICT (obj
, conflict_obj
, oci
)
2930 ira_allocno_t conflict_a
= OBJECT_ALLOCNO (conflict_obj
);
2932 if (ALLOCNO_COLOR_DATA (conflict_a
)->temp
== check
)
2933 /* We already processed this conflicting allocno
2934 because we processed earlier another object of the
2935 conflicting allocno. */
2937 ALLOCNO_COLOR_DATA (conflict_a
)->temp
= check
;
2938 if ((conflict_hregno
= ALLOCNO_HARD_REGNO (conflict_a
)) < 0)
2940 spill_cost
= ALLOCNO_UPDATED_MEMORY_COST (conflict_a
);
2941 k
= (ira_class_hard_reg_index
2942 [ALLOCNO_CLASS (conflict_a
)][conflict_hregno
]);
2943 ira_assert (k
>= 0);
2944 if ((allocno_costs
= ALLOCNO_HARD_REG_COSTS (conflict_a
))
2946 spill_cost
-= allocno_costs
[k
];
2948 spill_cost
-= ALLOCNO_UPDATED_CLASS_COST (conflict_a
);
2950 += allocno_copy_cost_saving (conflict_a
, conflict_hregno
);
2951 conflict_nregs
= hard_regno_nregs (conflict_hregno
,
2952 ALLOCNO_MODE (conflict_a
));
2953 for (r
= conflict_hregno
;
2954 r
>= 0 && (int) end_hard_regno (mode
, r
) > conflict_hregno
;
2956 if (check_hard_reg_p (a
, r
,
2957 conflicting_regs
, profitable_hard_regs
))
2958 costs
[r
] += spill_cost
;
2959 for (r
= conflict_hregno
+ 1;
2960 r
< conflict_hregno
+ conflict_nregs
;
2962 if (check_hard_reg_p (a
, r
,
2963 conflicting_regs
, profitable_hard_regs
))
2964 costs
[r
] += spill_cost
;
2969 /* Now we choose hard register for A which results in highest
2970 allocation cost improvement. */
2971 for (j
= 0; j
< class_size
; j
++)
2973 hregno
= ira_class_hard_regs
[aclass
][j
];
2974 if (check_hard_reg_p (a
, hregno
,
2975 conflicting_regs
, profitable_hard_regs
)
2976 && min_cost
> costs
[hregno
])
2979 min_cost
= costs
[hregno
];
2983 /* We are in a situation when assigning any hard register to A
2984 by spilling some conflicting allocnos does not improve the
2987 nregs
= hard_regno_nregs (best
, mode
);
2988 /* Now spill conflicting allocnos which contain a hard register
2989 of A when we assign the best chosen hard register to it. */
2990 for (word
= 0; word
< nwords
; word
++)
2992 ira_object_t conflict_obj
;
2993 ira_object_t obj
= ALLOCNO_OBJECT (a
, word
);
2994 ira_object_conflict_iterator oci
;
2996 FOR_EACH_OBJECT_CONFLICT (obj
, conflict_obj
, oci
)
2998 ira_allocno_t conflict_a
= OBJECT_ALLOCNO (conflict_obj
);
3000 if ((conflict_hregno
= ALLOCNO_HARD_REGNO (conflict_a
)) < 0)
3002 conflict_nregs
= hard_regno_nregs (conflict_hregno
,
3003 ALLOCNO_MODE (conflict_a
));
3004 if (best
+ nregs
<= conflict_hregno
3005 || conflict_hregno
+ conflict_nregs
<= best
)
3006 /* No intersection. */
3008 ALLOCNO_HARD_REGNO (conflict_a
) = -1;
3009 sorted_allocnos
[n
++] = conflict_a
;
3010 if (internal_flag_ira_verbose
> 2 && ira_dump_file
!= NULL
)
3011 fprintf (ira_dump_file
, "Spilling a%dr%d for a%dr%d\n",
3012 ALLOCNO_NUM (conflict_a
), ALLOCNO_REGNO (conflict_a
),
3013 ALLOCNO_NUM (a
), ALLOCNO_REGNO (a
));
3016 /* Assign the best chosen hard register to A. */
3017 ALLOCNO_HARD_REGNO (a
) = best
;
3018 if (internal_flag_ira_verbose
> 2 && ira_dump_file
!= NULL
)
3019 fprintf (ira_dump_file
, "Assigning %d to a%dr%d\n",
3020 best
, ALLOCNO_NUM (a
), ALLOCNO_REGNO (a
));
3024 /* We spilled some allocnos to assign their hard registers to other
3025 allocnos. The spilled allocnos are now in array
3026 'sorted_allocnos'. There is still a possibility that some of the
3027 spilled allocnos can get hard registers. So let us try assign
3028 them hard registers again (just a reminder -- function
3029 'assign_hard_reg' assigns hard registers only if it is possible
3030 and profitable). We process the spilled allocnos with biggest
3031 benefit to get hard register first -- see function
3032 'allocno_cost_compare_func'. */
3033 qsort (sorted_allocnos
, n
, sizeof (ira_allocno_t
),
3034 allocno_cost_compare_func
);
3035 for (j
= 0; j
< n
; j
++)
3037 a
= sorted_allocnos
[j
];
3038 ALLOCNO_ASSIGNED_P (a
) = false;
3039 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
3041 fprintf (ira_dump_file
, " ");
3042 ira_print_expanded_allocno (a
);
3043 fprintf (ira_dump_file
, " -- ");
3045 if (assign_hard_reg (a
, false))
3047 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
3048 fprintf (ira_dump_file
, "assign hard reg %d\n",
3049 ALLOCNO_HARD_REGNO (a
));
3053 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
3054 fprintf (ira_dump_file
, "assign memory\n");
3059 /* Sort allocnos according to their priorities. */
3061 allocno_priority_compare_func (const void *v1p
, const void *v2p
)
3063 ira_allocno_t a1
= *(const ira_allocno_t
*) v1p
;
3064 ira_allocno_t a2
= *(const ira_allocno_t
*) v2p
;
3065 int pri1
, pri2
, diff
;
3067 /* Assign hard reg to static chain pointer pseudo first when
3068 non-local goto is used. */
3069 if ((diff
= (non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a2
))
3070 - non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a1
)))) != 0)
3072 pri1
= allocno_priorities
[ALLOCNO_NUM (a1
)];
3073 pri2
= allocno_priorities
[ALLOCNO_NUM (a2
)];
3075 return SORTGT (pri2
, pri1
);
3077 /* If regs are equally good, sort by allocnos, so that the results of
3078 qsort leave nothing to chance. */
3079 return ALLOCNO_NUM (a1
) - ALLOCNO_NUM (a2
);
3082 /* Chaitin-Briggs coloring for allocnos in COLORING_ALLOCNO_BITMAP
3083 taking into account allocnos in CONSIDERATION_ALLOCNO_BITMAP. */
3085 color_allocnos (void)
3091 setup_profitable_hard_regs ();
3092 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap
, 0, i
, bi
)
3094 allocno_color_data_t data
;
3095 ira_pref_t pref
, next_pref
;
3097 a
= ira_allocnos
[i
];
3098 data
= ALLOCNO_COLOR_DATA (a
);
3099 data
->conflict_allocno_hard_prefs
= 0;
3100 for (pref
= ALLOCNO_PREFS (a
); pref
!= NULL
; pref
= next_pref
)
3102 next_pref
= pref
->next_pref
;
3103 if (! ira_hard_reg_in_set_p (pref
->hard_regno
,
3105 data
->profitable_hard_regs
))
3106 ira_remove_pref (pref
);
3110 if (flag_ira_algorithm
== IRA_ALGORITHM_PRIORITY
)
3113 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap
, 0, i
, bi
)
3115 a
= ira_allocnos
[i
];
3116 if (ALLOCNO_CLASS (a
) == NO_REGS
)
3118 ALLOCNO_HARD_REGNO (a
) = -1;
3119 ALLOCNO_ASSIGNED_P (a
) = true;
3120 ira_assert (ALLOCNO_UPDATED_HARD_REG_COSTS (a
) == NULL
);
3121 ira_assert (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a
) == NULL
);
3122 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
3124 fprintf (ira_dump_file
, " Spill");
3125 ira_print_expanded_allocno (a
);
3126 fprintf (ira_dump_file
, "\n");
3130 sorted_allocnos
[n
++] = a
;
3134 setup_allocno_priorities (sorted_allocnos
, n
);
3135 qsort (sorted_allocnos
, n
, sizeof (ira_allocno_t
),
3136 allocno_priority_compare_func
);
3137 for (i
= 0; i
< n
; i
++)
3139 a
= sorted_allocnos
[i
];
3140 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
3142 fprintf (ira_dump_file
, " ");
3143 ira_print_expanded_allocno (a
);
3144 fprintf (ira_dump_file
, " -- ");
3146 if (assign_hard_reg (a
, false))
3148 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
3149 fprintf (ira_dump_file
, "assign hard reg %d\n",
3150 ALLOCNO_HARD_REGNO (a
));
3154 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
3155 fprintf (ira_dump_file
, "assign memory\n");
3162 form_allocno_hard_regs_nodes_forest ();
3163 if (internal_flag_ira_verbose
> 2 && ira_dump_file
!= NULL
)
3164 print_hard_regs_forest (ira_dump_file
);
3165 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap
, 0, i
, bi
)
3167 a
= ira_allocnos
[i
];
3168 if (ALLOCNO_CLASS (a
) != NO_REGS
&& ! empty_profitable_hard_regs (a
))
3170 ALLOCNO_COLOR_DATA (a
)->in_graph_p
= true;
3171 update_costs_from_prefs (a
);
3172 update_conflict_allocno_hard_prefs (a
);
3176 ALLOCNO_HARD_REGNO (a
) = -1;
3177 ALLOCNO_ASSIGNED_P (a
) = true;
3178 /* We don't need updated costs anymore. */
3179 ira_free_allocno_updated_costs (a
);
3180 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
3182 fprintf (ira_dump_file
, " Spill");
3183 ira_print_expanded_allocno (a
);
3184 fprintf (ira_dump_file
, "\n");
3188 /* Put the allocnos into the corresponding buckets. */
3189 colorable_allocno_bucket
= NULL
;
3190 uncolorable_allocno_bucket
= NULL
;
3191 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap
, 0, i
, bi
)
3193 a
= ira_allocnos
[i
];
3194 if (ALLOCNO_COLOR_DATA (a
)->in_graph_p
)
3195 put_allocno_into_bucket (a
);
3197 push_allocnos_to_stack ();
3198 pop_allocnos_from_stack ();
3199 finish_allocno_hard_regs_nodes_forest ();
3201 improve_allocation ();
3206 /* Output information about the loop given by its LOOP_TREE_NODE. */
3208 print_loop_title (ira_loop_tree_node_t loop_tree_node
)
3212 ira_loop_tree_node_t subloop_node
, dest_loop_node
;
3216 if (loop_tree_node
->parent
== NULL
)
3217 fprintf (ira_dump_file
,
3218 "\n Loop 0 (parent -1, header bb%d, depth 0)\n bbs:",
3222 ira_assert (current_loops
!= NULL
&& loop_tree_node
->loop
!= NULL
);
3223 fprintf (ira_dump_file
,
3224 "\n Loop %d (parent %d, header bb%d, depth %d)\n bbs:",
3225 loop_tree_node
->loop_num
, loop_tree_node
->parent
->loop_num
,
3226 loop_tree_node
->loop
->header
->index
,
3227 loop_depth (loop_tree_node
->loop
));
3229 for (subloop_node
= loop_tree_node
->children
;
3230 subloop_node
!= NULL
;
3231 subloop_node
= subloop_node
->next
)
3232 if (subloop_node
->bb
!= NULL
)
3234 fprintf (ira_dump_file
, " %d", subloop_node
->bb
->index
);
3235 FOR_EACH_EDGE (e
, ei
, subloop_node
->bb
->succs
)
3236 if (e
->dest
!= EXIT_BLOCK_PTR_FOR_FN (cfun
)
3237 && ((dest_loop_node
= IRA_BB_NODE (e
->dest
)->parent
)
3239 fprintf (ira_dump_file
, "(->%d:l%d)",
3240 e
->dest
->index
, dest_loop_node
->loop_num
);
3242 fprintf (ira_dump_file
, "\n all:");
3243 EXECUTE_IF_SET_IN_BITMAP (loop_tree_node
->all_allocnos
, 0, j
, bi
)
3244 fprintf (ira_dump_file
, " %dr%d", j
, ALLOCNO_REGNO (ira_allocnos
[j
]));
3245 fprintf (ira_dump_file
, "\n modified regnos:");
3246 EXECUTE_IF_SET_IN_BITMAP (loop_tree_node
->modified_regnos
, 0, j
, bi
)
3247 fprintf (ira_dump_file
, " %d", j
);
3248 fprintf (ira_dump_file
, "\n border:");
3249 EXECUTE_IF_SET_IN_BITMAP (loop_tree_node
->border_allocnos
, 0, j
, bi
)
3250 fprintf (ira_dump_file
, " %dr%d", j
, ALLOCNO_REGNO (ira_allocnos
[j
]));
3251 fprintf (ira_dump_file
, "\n Pressure:");
3252 for (j
= 0; (int) j
< ira_pressure_classes_num
; j
++)
3254 enum reg_class pclass
;
3256 pclass
= ira_pressure_classes
[j
];
3257 if (loop_tree_node
->reg_pressure
[pclass
] == 0)
3259 fprintf (ira_dump_file
, " %s=%d", reg_class_names
[pclass
],
3260 loop_tree_node
->reg_pressure
[pclass
]);
3262 fprintf (ira_dump_file
, "\n");
3265 /* Color the allocnos inside loop (in the extreme case it can be all
3266 of the function) given the corresponding LOOP_TREE_NODE. The
3267 function is called for each loop during top-down traverse of the
3270 color_pass (ira_loop_tree_node_t loop_tree_node
)
3272 int regno
, hard_regno
, index
= -1, n
;
3273 int cost
, exit_freq
, enter_freq
;
3277 enum reg_class rclass
, aclass
, pclass
;
3278 ira_allocno_t a
, subloop_allocno
;
3279 ira_loop_tree_node_t subloop_node
;
3281 ira_assert (loop_tree_node
->bb
== NULL
);
3282 if (internal_flag_ira_verbose
> 1 && ira_dump_file
!= NULL
)
3283 print_loop_title (loop_tree_node
);
3285 bitmap_copy (coloring_allocno_bitmap
, loop_tree_node
->all_allocnos
);
3286 bitmap_copy (consideration_allocno_bitmap
, coloring_allocno_bitmap
);
3288 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap
, 0, j
, bi
)
3290 a
= ira_allocnos
[j
];
3292 if (! ALLOCNO_ASSIGNED_P (a
))
3294 bitmap_clear_bit (coloring_allocno_bitmap
, ALLOCNO_NUM (a
));
3297 = (allocno_color_data_t
) ira_allocate (sizeof (struct allocno_color_data
)
3299 memset (allocno_color_data
, 0, sizeof (struct allocno_color_data
) * n
);
3300 curr_allocno_process
= 0;
3302 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap
, 0, j
, bi
)
3304 a
= ira_allocnos
[j
];
3305 ALLOCNO_ADD_DATA (a
) = allocno_color_data
+ n
;
3308 init_allocno_threads ();
3309 /* Color all mentioned allocnos including transparent ones. */
3311 /* Process caps. They are processed just once. */
3312 if (flag_ira_region
== IRA_REGION_MIXED
3313 || flag_ira_region
== IRA_REGION_ALL
)
3314 EXECUTE_IF_SET_IN_BITMAP (loop_tree_node
->all_allocnos
, 0, j
, bi
)
3316 a
= ira_allocnos
[j
];
3317 if (ALLOCNO_CAP_MEMBER (a
) == NULL
)
3319 /* Remove from processing in the next loop. */
3320 bitmap_clear_bit (consideration_allocno_bitmap
, j
);
3321 rclass
= ALLOCNO_CLASS (a
);
3322 pclass
= ira_pressure_class_translate
[rclass
];
3323 if (flag_ira_region
== IRA_REGION_MIXED
3324 && (loop_tree_node
->reg_pressure
[pclass
]
3325 <= ira_class_hard_regs_num
[pclass
]))
3327 mode
= ALLOCNO_MODE (a
);
3328 hard_regno
= ALLOCNO_HARD_REGNO (a
);
3329 if (hard_regno
>= 0)
3331 index
= ira_class_hard_reg_index
[rclass
][hard_regno
];
3332 ira_assert (index
>= 0);
3334 regno
= ALLOCNO_REGNO (a
);
3335 subloop_allocno
= ALLOCNO_CAP_MEMBER (a
);
3336 subloop_node
= ALLOCNO_LOOP_TREE_NODE (subloop_allocno
);
3337 ira_assert (!ALLOCNO_ASSIGNED_P (subloop_allocno
));
3338 ALLOCNO_HARD_REGNO (subloop_allocno
) = hard_regno
;
3339 ALLOCNO_ASSIGNED_P (subloop_allocno
) = true;
3340 if (hard_regno
>= 0)
3341 update_costs_from_copies (subloop_allocno
, true, true);
3342 /* We don't need updated costs anymore. */
3343 ira_free_allocno_updated_costs (subloop_allocno
);
3346 /* Update costs of the corresponding allocnos (not caps) in the
3348 for (subloop_node
= loop_tree_node
->subloops
;
3349 subloop_node
!= NULL
;
3350 subloop_node
= subloop_node
->subloop_next
)
3352 ira_assert (subloop_node
->bb
== NULL
);
3353 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap
, 0, j
, bi
)
3355 a
= ira_allocnos
[j
];
3356 ira_assert (ALLOCNO_CAP_MEMBER (a
) == NULL
);
3357 mode
= ALLOCNO_MODE (a
);
3358 rclass
= ALLOCNO_CLASS (a
);
3359 pclass
= ira_pressure_class_translate
[rclass
];
3360 hard_regno
= ALLOCNO_HARD_REGNO (a
);
3361 /* Use hard register class here. ??? */
3362 if (hard_regno
>= 0)
3364 index
= ira_class_hard_reg_index
[rclass
][hard_regno
];
3365 ira_assert (index
>= 0);
3367 regno
= ALLOCNO_REGNO (a
);
3368 /* ??? conflict costs */
3369 subloop_allocno
= subloop_node
->regno_allocno_map
[regno
];
3370 if (subloop_allocno
== NULL
3371 || ALLOCNO_CAP (subloop_allocno
) != NULL
)
3373 ira_assert (ALLOCNO_CLASS (subloop_allocno
) == rclass
);
3374 ira_assert (bitmap_bit_p (subloop_node
->all_allocnos
,
3375 ALLOCNO_NUM (subloop_allocno
)));
3376 if ((flag_ira_region
== IRA_REGION_MIXED
3377 && (loop_tree_node
->reg_pressure
[pclass
]
3378 <= ira_class_hard_regs_num
[pclass
]))
3379 || (pic_offset_table_rtx
!= NULL
3380 && regno
== (int) REGNO (pic_offset_table_rtx
))
3381 /* Avoid overlapped multi-registers. Moves between them
3382 might result in wrong code generation. */
3384 && ira_reg_class_max_nregs
[pclass
][mode
] > 1))
3386 if (! ALLOCNO_ASSIGNED_P (subloop_allocno
))
3388 ALLOCNO_HARD_REGNO (subloop_allocno
) = hard_regno
;
3389 ALLOCNO_ASSIGNED_P (subloop_allocno
) = true;
3390 if (hard_regno
>= 0)
3391 update_costs_from_copies (subloop_allocno
, true, true);
3392 /* We don't need updated costs anymore. */
3393 ira_free_allocno_updated_costs (subloop_allocno
);
3397 exit_freq
= ira_loop_edge_freq (subloop_node
, regno
, true);
3398 enter_freq
= ira_loop_edge_freq (subloop_node
, regno
, false);
3399 ira_assert (regno
< ira_reg_equiv_len
);
3400 if (ira_equiv_no_lvalue_p (regno
))
3402 if (! ALLOCNO_ASSIGNED_P (subloop_allocno
))
3404 ALLOCNO_HARD_REGNO (subloop_allocno
) = hard_regno
;
3405 ALLOCNO_ASSIGNED_P (subloop_allocno
) = true;
3406 if (hard_regno
>= 0)
3407 update_costs_from_copies (subloop_allocno
, true, true);
3408 /* We don't need updated costs anymore. */
3409 ira_free_allocno_updated_costs (subloop_allocno
);
3412 else if (hard_regno
< 0)
3414 ALLOCNO_UPDATED_MEMORY_COST (subloop_allocno
)
3415 -= ((ira_memory_move_cost
[mode
][rclass
][1] * enter_freq
)
3416 + (ira_memory_move_cost
[mode
][rclass
][0] * exit_freq
));
3420 aclass
= ALLOCNO_CLASS (subloop_allocno
);
3421 ira_init_register_move_cost_if_necessary (mode
);
3422 cost
= (ira_register_move_cost
[mode
][rclass
][rclass
]
3423 * (exit_freq
+ enter_freq
));
3424 ira_allocate_and_set_or_copy_costs
3425 (&ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno
), aclass
,
3426 ALLOCNO_UPDATED_CLASS_COST (subloop_allocno
),
3427 ALLOCNO_HARD_REG_COSTS (subloop_allocno
));
3428 ira_allocate_and_set_or_copy_costs
3429 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (subloop_allocno
),
3430 aclass
, 0, ALLOCNO_CONFLICT_HARD_REG_COSTS (subloop_allocno
));
3431 ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno
)[index
] -= cost
;
3432 ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (subloop_allocno
)[index
]
3434 if (ALLOCNO_UPDATED_CLASS_COST (subloop_allocno
)
3435 > ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno
)[index
])
3436 ALLOCNO_UPDATED_CLASS_COST (subloop_allocno
)
3437 = ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno
)[index
];
3438 ALLOCNO_UPDATED_MEMORY_COST (subloop_allocno
)
3439 += (ira_memory_move_cost
[mode
][rclass
][0] * enter_freq
3440 + ira_memory_move_cost
[mode
][rclass
][1] * exit_freq
);
3444 ira_free (allocno_color_data
);
3445 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap
, 0, j
, bi
)
3447 a
= ira_allocnos
[j
];
3448 ALLOCNO_ADD_DATA (a
) = NULL
;
3452 /* Initialize the common data for coloring and calls functions to do
3453 Chaitin-Briggs and regional coloring. */
3457 coloring_allocno_bitmap
= ira_allocate_bitmap ();
3458 if (internal_flag_ira_verbose
> 0 && ira_dump_file
!= NULL
)
3459 fprintf (ira_dump_file
, "\n**** Allocnos coloring:\n\n");
3461 ira_traverse_loop_tree (false, ira_loop_tree_root
, color_pass
, NULL
);
3463 if (internal_flag_ira_verbose
> 1 && ira_dump_file
!= NULL
)
3464 ira_print_disposition (ira_dump_file
);
3466 ira_free_bitmap (coloring_allocno_bitmap
);
3471 /* Move spill/restore code, which are to be generated in ira-emit.c,
3472 to less frequent points (if it is profitable) by reassigning some
3473 allocnos (in loop with subloops containing in another loop) to
3474 memory which results in longer live-range where the corresponding
3475 pseudo-registers will be in memory. */
3477 move_spill_restore (void)
3479 int cost
, regno
, hard_regno
, hard_regno2
, index
;
3481 int enter_freq
, exit_freq
;
3483 enum reg_class rclass
;
3484 ira_allocno_t a
, parent_allocno
, subloop_allocno
;
3485 ira_loop_tree_node_t parent
, loop_node
, subloop_node
;
3486 ira_allocno_iterator ai
;
3491 if (internal_flag_ira_verbose
> 0 && ira_dump_file
!= NULL
)
3492 fprintf (ira_dump_file
, "New iteration of spill/restore move\n");
3493 FOR_EACH_ALLOCNO (a
, ai
)
3495 regno
= ALLOCNO_REGNO (a
);
3496 loop_node
= ALLOCNO_LOOP_TREE_NODE (a
);
3497 if (ALLOCNO_CAP_MEMBER (a
) != NULL
3498 || ALLOCNO_CAP (a
) != NULL
3499 || (hard_regno
= ALLOCNO_HARD_REGNO (a
)) < 0
3500 || loop_node
->children
== NULL
3501 /* don't do the optimization because it can create
3502 copies and the reload pass can spill the allocno set
3503 by copy although the allocno will not get memory
3505 || ira_equiv_no_lvalue_p (regno
)
3506 || !bitmap_bit_p (loop_node
->border_allocnos
, ALLOCNO_NUM (a
))
3507 /* Do not spill static chain pointer pseudo when
3508 non-local goto is used. */
3509 || non_spilled_static_chain_regno_p (regno
))
3511 mode
= ALLOCNO_MODE (a
);
3512 rclass
= ALLOCNO_CLASS (a
);
3513 index
= ira_class_hard_reg_index
[rclass
][hard_regno
];
3514 ira_assert (index
>= 0);
3515 cost
= (ALLOCNO_MEMORY_COST (a
)
3516 - (ALLOCNO_HARD_REG_COSTS (a
) == NULL
3517 ? ALLOCNO_CLASS_COST (a
)
3518 : ALLOCNO_HARD_REG_COSTS (a
)[index
]));
3519 ira_init_register_move_cost_if_necessary (mode
);
3520 for (subloop_node
= loop_node
->subloops
;
3521 subloop_node
!= NULL
;
3522 subloop_node
= subloop_node
->subloop_next
)
3524 ira_assert (subloop_node
->bb
== NULL
);
3525 subloop_allocno
= subloop_node
->regno_allocno_map
[regno
];
3526 if (subloop_allocno
== NULL
)
3528 ira_assert (rclass
== ALLOCNO_CLASS (subloop_allocno
));
3529 /* We have accumulated cost. To get the real cost of
3530 allocno usage in the loop we should subtract costs of
3531 the subloop allocnos. */
3532 cost
-= (ALLOCNO_MEMORY_COST (subloop_allocno
)
3533 - (ALLOCNO_HARD_REG_COSTS (subloop_allocno
) == NULL
3534 ? ALLOCNO_CLASS_COST (subloop_allocno
)
3535 : ALLOCNO_HARD_REG_COSTS (subloop_allocno
)[index
]));
3536 exit_freq
= ira_loop_edge_freq (subloop_node
, regno
, true);
3537 enter_freq
= ira_loop_edge_freq (subloop_node
, regno
, false);
3538 if ((hard_regno2
= ALLOCNO_HARD_REGNO (subloop_allocno
)) < 0)
3539 cost
-= (ira_memory_move_cost
[mode
][rclass
][0] * exit_freq
3540 + ira_memory_move_cost
[mode
][rclass
][1] * enter_freq
);
3544 += (ira_memory_move_cost
[mode
][rclass
][0] * exit_freq
3545 + ira_memory_move_cost
[mode
][rclass
][1] * enter_freq
);
3546 if (hard_regno2
!= hard_regno
)
3547 cost
-= (ira_register_move_cost
[mode
][rclass
][rclass
]
3548 * (exit_freq
+ enter_freq
));
3551 if ((parent
= loop_node
->parent
) != NULL
3552 && (parent_allocno
= parent
->regno_allocno_map
[regno
]) != NULL
)
3554 ira_assert (rclass
== ALLOCNO_CLASS (parent_allocno
));
3555 exit_freq
= ira_loop_edge_freq (loop_node
, regno
, true);
3556 enter_freq
= ira_loop_edge_freq (loop_node
, regno
, false);
3557 if ((hard_regno2
= ALLOCNO_HARD_REGNO (parent_allocno
)) < 0)
3558 cost
-= (ira_memory_move_cost
[mode
][rclass
][0] * exit_freq
3559 + ira_memory_move_cost
[mode
][rclass
][1] * enter_freq
);
3563 += (ira_memory_move_cost
[mode
][rclass
][1] * exit_freq
3564 + ira_memory_move_cost
[mode
][rclass
][0] * enter_freq
);
3565 if (hard_regno2
!= hard_regno
)
3566 cost
-= (ira_register_move_cost
[mode
][rclass
][rclass
]
3567 * (exit_freq
+ enter_freq
));
3572 ALLOCNO_HARD_REGNO (a
) = -1;
3573 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
3577 " Moving spill/restore for a%dr%d up from loop %d",
3578 ALLOCNO_NUM (a
), regno
, loop_node
->loop_num
);
3579 fprintf (ira_dump_file
, " - profit %d\n", -cost
);
3591 /* Update current hard reg costs and current conflict hard reg costs
3592 for allocno A. It is done by processing its copies containing
3593 other allocnos already assigned. */
3595 update_curr_costs (ira_allocno_t a
)
3597 int i
, hard_regno
, cost
;
3599 enum reg_class aclass
, rclass
;
3600 ira_allocno_t another_a
;
3601 ira_copy_t cp
, next_cp
;
3603 ira_free_allocno_updated_costs (a
);
3604 ira_assert (! ALLOCNO_ASSIGNED_P (a
));
3605 aclass
= ALLOCNO_CLASS (a
);
3606 if (aclass
== NO_REGS
)
3608 mode
= ALLOCNO_MODE (a
);
3609 ira_init_register_move_cost_if_necessary (mode
);
3610 for (cp
= ALLOCNO_COPIES (a
); cp
!= NULL
; cp
= next_cp
)
3614 next_cp
= cp
->next_first_allocno_copy
;
3615 another_a
= cp
->second
;
3617 else if (cp
->second
== a
)
3619 next_cp
= cp
->next_second_allocno_copy
;
3620 another_a
= cp
->first
;
3624 if (! ira_reg_classes_intersect_p
[aclass
][ALLOCNO_CLASS (another_a
)]
3625 || ! ALLOCNO_ASSIGNED_P (another_a
)
3626 || (hard_regno
= ALLOCNO_HARD_REGNO (another_a
)) < 0)
3628 rclass
= REGNO_REG_CLASS (hard_regno
);
3629 i
= ira_class_hard_reg_index
[aclass
][hard_regno
];
3632 cost
= (cp
->first
== a
3633 ? ira_register_move_cost
[mode
][rclass
][aclass
]
3634 : ira_register_move_cost
[mode
][aclass
][rclass
]);
3635 ira_allocate_and_set_or_copy_costs
3636 (&ALLOCNO_UPDATED_HARD_REG_COSTS (a
), aclass
, ALLOCNO_CLASS_COST (a
),
3637 ALLOCNO_HARD_REG_COSTS (a
));
3638 ira_allocate_and_set_or_copy_costs
3639 (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a
),
3640 aclass
, 0, ALLOCNO_CONFLICT_HARD_REG_COSTS (a
));
3641 ALLOCNO_UPDATED_HARD_REG_COSTS (a
)[i
] -= cp
->freq
* cost
;
3642 ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a
)[i
] -= cp
->freq
* cost
;
3646 /* Try to assign hard registers to the unassigned allocnos and
3647 allocnos conflicting with them or conflicting with allocnos whose
3648 regno >= START_REGNO. The function is called after ira_flattening,
3649 so more allocnos (including ones created in ira-emit.c) will have a
3650 chance to get a hard register. We use simple assignment algorithm
3651 based on priorities. */
3653 ira_reassign_conflict_allocnos (int start_regno
)
3655 int i
, allocnos_to_color_num
;
3657 enum reg_class aclass
;
3658 bitmap allocnos_to_color
;
3659 ira_allocno_iterator ai
;
3661 allocnos_to_color
= ira_allocate_bitmap ();
3662 allocnos_to_color_num
= 0;
3663 FOR_EACH_ALLOCNO (a
, ai
)
3665 int n
= ALLOCNO_NUM_OBJECTS (a
);
3667 if (! ALLOCNO_ASSIGNED_P (a
)
3668 && ! bitmap_bit_p (allocnos_to_color
, ALLOCNO_NUM (a
)))
3670 if (ALLOCNO_CLASS (a
) != NO_REGS
)
3671 sorted_allocnos
[allocnos_to_color_num
++] = a
;
3674 ALLOCNO_ASSIGNED_P (a
) = true;
3675 ALLOCNO_HARD_REGNO (a
) = -1;
3676 ira_assert (ALLOCNO_UPDATED_HARD_REG_COSTS (a
) == NULL
);
3677 ira_assert (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a
) == NULL
);
3679 bitmap_set_bit (allocnos_to_color
, ALLOCNO_NUM (a
));
3681 if (ALLOCNO_REGNO (a
) < start_regno
3682 || (aclass
= ALLOCNO_CLASS (a
)) == NO_REGS
)
3684 for (i
= 0; i
< n
; i
++)
3686 ira_object_t obj
= ALLOCNO_OBJECT (a
, i
);
3687 ira_object_t conflict_obj
;
3688 ira_object_conflict_iterator oci
;
3690 FOR_EACH_OBJECT_CONFLICT (obj
, conflict_obj
, oci
)
3692 ira_allocno_t conflict_a
= OBJECT_ALLOCNO (conflict_obj
);
3694 ira_assert (ira_reg_classes_intersect_p
3695 [aclass
][ALLOCNO_CLASS (conflict_a
)]);
3696 if (!bitmap_set_bit (allocnos_to_color
, ALLOCNO_NUM (conflict_a
)))
3698 sorted_allocnos
[allocnos_to_color_num
++] = conflict_a
;
3702 ira_free_bitmap (allocnos_to_color
);
3703 if (allocnos_to_color_num
> 1)
3705 setup_allocno_priorities (sorted_allocnos
, allocnos_to_color_num
);
3706 qsort (sorted_allocnos
, allocnos_to_color_num
, sizeof (ira_allocno_t
),
3707 allocno_priority_compare_func
);
3709 for (i
= 0; i
< allocnos_to_color_num
; i
++)
3711 a
= sorted_allocnos
[i
];
3712 ALLOCNO_ASSIGNED_P (a
) = false;
3713 update_curr_costs (a
);
3715 for (i
= 0; i
< allocnos_to_color_num
; i
++)
3717 a
= sorted_allocnos
[i
];
3718 if (assign_hard_reg (a
, true))
3720 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
3723 " Secondary allocation: assign hard reg %d to reg %d\n",
3724 ALLOCNO_HARD_REGNO (a
), ALLOCNO_REGNO (a
));
3731 /* This page contains functions used to find conflicts using allocno
3734 #ifdef ENABLE_IRA_CHECKING
3736 /* Return TRUE if live ranges of pseudo-registers REGNO1 and REGNO2
3737 intersect. This should be used when there is only one region.
3738 Currently this is used during reload. */
3740 conflict_by_live_ranges_p (int regno1
, int regno2
)
3742 ira_allocno_t a1
, a2
;
3744 ira_assert (regno1
>= FIRST_PSEUDO_REGISTER
3745 && regno2
>= FIRST_PSEUDO_REGISTER
);
3746 /* Reg info calculated by dataflow infrastructure can be different
3747 from one calculated by regclass. */
3748 if ((a1
= ira_loop_tree_root
->regno_allocno_map
[regno1
]) == NULL
3749 || (a2
= ira_loop_tree_root
->regno_allocno_map
[regno2
]) == NULL
)
3751 return allocnos_conflict_by_live_ranges_p (a1
, a2
);
3758 /* This page contains code to coalesce memory stack slots used by
3759 spilled allocnos. This results in smaller stack frame, better data
3760 locality, and in smaller code for some architectures like
3761 x86/x86_64 where insn size depends on address displacement value.
3762 On the other hand, it can worsen insn scheduling after the RA but
3763 in practice it is less important than smaller stack frames. */
3765 /* TRUE if we coalesced some allocnos. In other words, if we got
3766 loops formed by members first_coalesced_allocno and
3767 next_coalesced_allocno containing more one allocno. */
3768 static bool allocno_coalesced_p
;
3770 /* Bitmap used to prevent a repeated allocno processing because of
3772 static bitmap processed_coalesced_allocno_bitmap
;
3775 typedef struct coalesce_data
*coalesce_data_t
;
3777 /* To decrease footprint of ira_allocno structure we store all data
3778 needed only for coalescing in the following structure. */
3779 struct coalesce_data
3781 /* Coalesced allocnos form a cyclic list. One allocno given by
3782 FIRST represents all coalesced allocnos. The
3783 list is chained by NEXT. */
3784 ira_allocno_t first
;
3789 /* Container for storing allocno data concerning coalescing. */
3790 static coalesce_data_t allocno_coalesce_data
;
3792 /* Macro to access the data concerning coalescing. */
3793 #define ALLOCNO_COALESCE_DATA(a) ((coalesce_data_t) ALLOCNO_ADD_DATA (a))
3795 /* Merge two sets of coalesced allocnos given correspondingly by
3796 allocnos A1 and A2 (more accurately merging A2 set into A1
3799 merge_allocnos (ira_allocno_t a1
, ira_allocno_t a2
)
3801 ira_allocno_t a
, first
, last
, next
;
3803 first
= ALLOCNO_COALESCE_DATA (a1
)->first
;
3804 a
= ALLOCNO_COALESCE_DATA (a2
)->first
;
3807 for (last
= a2
, a
= ALLOCNO_COALESCE_DATA (a2
)->next
;;
3808 a
= ALLOCNO_COALESCE_DATA (a
)->next
)
3810 ALLOCNO_COALESCE_DATA (a
)->first
= first
;
3815 next
= allocno_coalesce_data
[ALLOCNO_NUM (first
)].next
;
3816 allocno_coalesce_data
[ALLOCNO_NUM (first
)].next
= a2
;
3817 allocno_coalesce_data
[ALLOCNO_NUM (last
)].next
= next
;
3820 /* Return TRUE if there are conflicting allocnos from two sets of
3821 coalesced allocnos given correspondingly by allocnos A1 and A2. We
3822 use live ranges to find conflicts because conflicts are represented
3823 only for allocnos of the same allocno class and during the reload
3824 pass we coalesce allocnos for sharing stack memory slots. */
3826 coalesced_allocno_conflict_p (ira_allocno_t a1
, ira_allocno_t a2
)
3828 ira_allocno_t a
, conflict_a
;
3830 if (allocno_coalesced_p
)
3832 bitmap_clear (processed_coalesced_allocno_bitmap
);
3833 for (a
= ALLOCNO_COALESCE_DATA (a1
)->next
;;
3834 a
= ALLOCNO_COALESCE_DATA (a
)->next
)
3836 bitmap_set_bit (processed_coalesced_allocno_bitmap
, ALLOCNO_NUM (a
));
3841 for (a
= ALLOCNO_COALESCE_DATA (a2
)->next
;;
3842 a
= ALLOCNO_COALESCE_DATA (a
)->next
)
3844 for (conflict_a
= ALLOCNO_COALESCE_DATA (a1
)->next
;;
3845 conflict_a
= ALLOCNO_COALESCE_DATA (conflict_a
)->next
)
3847 if (allocnos_conflict_by_live_ranges_p (a
, conflict_a
))
3849 if (conflict_a
== a1
)
3858 /* The major function for aggressive allocno coalescing. We coalesce
3859 only spilled allocnos. If some allocnos have been coalesced, we
3860 set up flag allocno_coalesced_p. */
3862 coalesce_allocnos (void)
3865 ira_copy_t cp
, next_cp
;
3867 int i
, n
, cp_num
, regno
;
3871 /* Collect copies. */
3872 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap
, 0, j
, bi
)
3874 a
= ira_allocnos
[j
];
3875 regno
= ALLOCNO_REGNO (a
);
3876 if (! ALLOCNO_ASSIGNED_P (a
) || ALLOCNO_HARD_REGNO (a
) >= 0
3877 || ira_equiv_no_lvalue_p (regno
))
3879 for (cp
= ALLOCNO_COPIES (a
); cp
!= NULL
; cp
= next_cp
)
3883 next_cp
= cp
->next_first_allocno_copy
;
3884 regno
= ALLOCNO_REGNO (cp
->second
);
3885 /* For priority coloring we coalesce allocnos only with
3886 the same allocno class not with intersected allocno
3887 classes as it were possible. It is done for
3889 if ((cp
->insn
!= NULL
|| cp
->constraint_p
)
3890 && ALLOCNO_ASSIGNED_P (cp
->second
)
3891 && ALLOCNO_HARD_REGNO (cp
->second
) < 0
3892 && ! ira_equiv_no_lvalue_p (regno
))
3893 sorted_copies
[cp_num
++] = cp
;
3895 else if (cp
->second
== a
)
3896 next_cp
= cp
->next_second_allocno_copy
;
3901 qsort (sorted_copies
, cp_num
, sizeof (ira_copy_t
), copy_freq_compare_func
);
3902 /* Coalesced copies, most frequently executed first. */
3903 for (; cp_num
!= 0;)
3905 for (i
= 0; i
< cp_num
; i
++)
3907 cp
= sorted_copies
[i
];
3908 if (! coalesced_allocno_conflict_p (cp
->first
, cp
->second
))
3910 allocno_coalesced_p
= true;
3911 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
3914 " Coalescing copy %d:a%dr%d-a%dr%d (freq=%d)\n",
3915 cp
->num
, ALLOCNO_NUM (cp
->first
), ALLOCNO_REGNO (cp
->first
),
3916 ALLOCNO_NUM (cp
->second
), ALLOCNO_REGNO (cp
->second
),
3918 merge_allocnos (cp
->first
, cp
->second
);
3923 /* Collect the rest of copies. */
3924 for (n
= 0; i
< cp_num
; i
++)
3926 cp
= sorted_copies
[i
];
3927 if (allocno_coalesce_data
[ALLOCNO_NUM (cp
->first
)].first
3928 != allocno_coalesce_data
[ALLOCNO_NUM (cp
->second
)].first
)
3929 sorted_copies
[n
++] = cp
;
3935 /* Usage cost and order number of coalesced allocno set to which
3936 given pseudo register belongs to. */
3937 static int *regno_coalesced_allocno_cost
;
3938 static int *regno_coalesced_allocno_num
;
3940 /* Sort pseudos according frequencies of coalesced allocno sets they
3941 belong to (putting most frequently ones first), and according to
3942 coalesced allocno set order numbers. */
3944 coalesced_pseudo_reg_freq_compare (const void *v1p
, const void *v2p
)
3946 const int regno1
= *(const int *) v1p
;
3947 const int regno2
= *(const int *) v2p
;
3950 if ((diff
= (regno_coalesced_allocno_cost
[regno2
]
3951 - regno_coalesced_allocno_cost
[regno1
])) != 0)
3953 if ((diff
= (regno_coalesced_allocno_num
[regno1
]
3954 - regno_coalesced_allocno_num
[regno2
])) != 0)
3956 return regno1
- regno2
;
3959 /* Widest width in which each pseudo reg is referred to (via subreg).
3960 It is used for sorting pseudo registers. */
3961 static machine_mode
*regno_max_ref_mode
;
3963 /* Sort pseudos according their slot numbers (putting ones with
3964 smaller numbers first, or last when the frame pointer is not
3967 coalesced_pseudo_reg_slot_compare (const void *v1p
, const void *v2p
)
3969 const int regno1
= *(const int *) v1p
;
3970 const int regno2
= *(const int *) v2p
;
3971 ira_allocno_t a1
= ira_regno_allocno_map
[regno1
];
3972 ira_allocno_t a2
= ira_regno_allocno_map
[regno2
];
3973 int diff
, slot_num1
, slot_num2
;
3974 machine_mode mode1
, mode2
;
3976 if (a1
== NULL
|| ALLOCNO_HARD_REGNO (a1
) >= 0)
3978 if (a2
== NULL
|| ALLOCNO_HARD_REGNO (a2
) >= 0)
3979 return regno1
- regno2
;
3982 else if (a2
== NULL
|| ALLOCNO_HARD_REGNO (a2
) >= 0)
3984 slot_num1
= -ALLOCNO_HARD_REGNO (a1
);
3985 slot_num2
= -ALLOCNO_HARD_REGNO (a2
);
3986 if ((diff
= slot_num1
- slot_num2
) != 0)
3987 return (frame_pointer_needed
3988 || (!FRAME_GROWS_DOWNWARD
) == STACK_GROWS_DOWNWARD
? diff
: -diff
);
3989 mode1
= wider_subreg_mode (PSEUDO_REGNO_MODE (regno1
),
3990 regno_max_ref_mode
[regno1
]);
3991 mode2
= wider_subreg_mode (PSEUDO_REGNO_MODE (regno2
),
3992 regno_max_ref_mode
[regno2
]);
3993 if ((diff
= compare_sizes_for_sort (GET_MODE_SIZE (mode2
),
3994 GET_MODE_SIZE (mode1
))) != 0)
3996 return regno1
- regno2
;
3999 /* Setup REGNO_COALESCED_ALLOCNO_COST and REGNO_COALESCED_ALLOCNO_NUM
4000 for coalesced allocno sets containing allocnos with their regnos
4001 given in array PSEUDO_REGNOS of length N. */
4003 setup_coalesced_allocno_costs_and_nums (int *pseudo_regnos
, int n
)
4005 int i
, num
, regno
, cost
;
4006 ira_allocno_t allocno
, a
;
4008 for (num
= i
= 0; i
< n
; i
++)
4010 regno
= pseudo_regnos
[i
];
4011 allocno
= ira_regno_allocno_map
[regno
];
4012 if (allocno
== NULL
)
4014 regno_coalesced_allocno_cost
[regno
] = 0;
4015 regno_coalesced_allocno_num
[regno
] = ++num
;
4018 if (ALLOCNO_COALESCE_DATA (allocno
)->first
!= allocno
)
4021 for (cost
= 0, a
= ALLOCNO_COALESCE_DATA (allocno
)->next
;;
4022 a
= ALLOCNO_COALESCE_DATA (a
)->next
)
4024 cost
+= ALLOCNO_FREQ (a
);
4028 for (a
= ALLOCNO_COALESCE_DATA (allocno
)->next
;;
4029 a
= ALLOCNO_COALESCE_DATA (a
)->next
)
4031 regno_coalesced_allocno_num
[ALLOCNO_REGNO (a
)] = num
;
4032 regno_coalesced_allocno_cost
[ALLOCNO_REGNO (a
)] = cost
;
4039 /* Collect spilled allocnos representing coalesced allocno sets (the
4040 first coalesced allocno). The collected allocnos are returned
4041 through array SPILLED_COALESCED_ALLOCNOS. The function returns the
4042 number of the collected allocnos. The allocnos are given by their
4043 regnos in array PSEUDO_REGNOS of length N. */
4045 collect_spilled_coalesced_allocnos (int *pseudo_regnos
, int n
,
4046 ira_allocno_t
*spilled_coalesced_allocnos
)
4049 ira_allocno_t allocno
;
4051 for (num
= i
= 0; i
< n
; i
++)
4053 regno
= pseudo_regnos
[i
];
4054 allocno
= ira_regno_allocno_map
[regno
];
4055 if (allocno
== NULL
|| ALLOCNO_HARD_REGNO (allocno
) >= 0
4056 || ALLOCNO_COALESCE_DATA (allocno
)->first
!= allocno
)
4058 spilled_coalesced_allocnos
[num
++] = allocno
;
4063 /* Array of live ranges of size IRA_ALLOCNOS_NUM. Live range for
4064 given slot contains live ranges of coalesced allocnos assigned to
4066 static live_range_t
*slot_coalesced_allocnos_live_ranges
;
4068 /* Return TRUE if coalesced allocnos represented by ALLOCNO has live
4069 ranges intersected with live ranges of coalesced allocnos assigned
4070 to slot with number N. */
4072 slot_coalesced_allocno_live_ranges_intersect_p (ira_allocno_t allocno
, int n
)
4076 for (a
= ALLOCNO_COALESCE_DATA (allocno
)->next
;;
4077 a
= ALLOCNO_COALESCE_DATA (a
)->next
)
4080 int nr
= ALLOCNO_NUM_OBJECTS (a
);
4081 gcc_assert (ALLOCNO_CAP_MEMBER (a
) == NULL
);
4082 for (i
= 0; i
< nr
; i
++)
4084 ira_object_t obj
= ALLOCNO_OBJECT (a
, i
);
4086 if (ira_live_ranges_intersect_p
4087 (slot_coalesced_allocnos_live_ranges
[n
],
4088 OBJECT_LIVE_RANGES (obj
)))
4097 /* Update live ranges of slot to which coalesced allocnos represented
4098 by ALLOCNO were assigned. */
4100 setup_slot_coalesced_allocno_live_ranges (ira_allocno_t allocno
)
4106 n
= ALLOCNO_COALESCE_DATA (allocno
)->temp
;
4107 for (a
= ALLOCNO_COALESCE_DATA (allocno
)->next
;;
4108 a
= ALLOCNO_COALESCE_DATA (a
)->next
)
4110 int nr
= ALLOCNO_NUM_OBJECTS (a
);
4111 gcc_assert (ALLOCNO_CAP_MEMBER (a
) == NULL
);
4112 for (i
= 0; i
< nr
; i
++)
4114 ira_object_t obj
= ALLOCNO_OBJECT (a
, i
);
4116 r
= ira_copy_live_range_list (OBJECT_LIVE_RANGES (obj
));
4117 slot_coalesced_allocnos_live_ranges
[n
]
4118 = ira_merge_live_ranges
4119 (slot_coalesced_allocnos_live_ranges
[n
], r
);
4126 /* We have coalesced allocnos involving in copies. Coalesce allocnos
4127 further in order to share the same memory stack slot. Allocnos
4128 representing sets of allocnos coalesced before the call are given
4129 in array SPILLED_COALESCED_ALLOCNOS of length NUM. Return TRUE if
4130 some allocnos were coalesced in the function. */
4132 coalesce_spill_slots (ira_allocno_t
*spilled_coalesced_allocnos
, int num
)
4134 int i
, j
, n
, last_coalesced_allocno_num
;
4135 ira_allocno_t allocno
, a
;
4136 bool merged_p
= false;
4137 bitmap set_jump_crosses
= regstat_get_setjmp_crosses ();
4139 slot_coalesced_allocnos_live_ranges
4140 = (live_range_t
*) ira_allocate (sizeof (live_range_t
) * ira_allocnos_num
);
4141 memset (slot_coalesced_allocnos_live_ranges
, 0,
4142 sizeof (live_range_t
) * ira_allocnos_num
);
4143 last_coalesced_allocno_num
= 0;
4144 /* Coalesce non-conflicting spilled allocnos preferring most
4146 for (i
= 0; i
< num
; i
++)
4148 allocno
= spilled_coalesced_allocnos
[i
];
4149 if (ALLOCNO_COALESCE_DATA (allocno
)->first
!= allocno
4150 || bitmap_bit_p (set_jump_crosses
, ALLOCNO_REGNO (allocno
))
4151 || ira_equiv_no_lvalue_p (ALLOCNO_REGNO (allocno
)))
4153 for (j
= 0; j
< i
; j
++)
4155 a
= spilled_coalesced_allocnos
[j
];
4156 n
= ALLOCNO_COALESCE_DATA (a
)->temp
;
4157 if (ALLOCNO_COALESCE_DATA (a
)->first
== a
4158 && ! bitmap_bit_p (set_jump_crosses
, ALLOCNO_REGNO (a
))
4159 && ! ira_equiv_no_lvalue_p (ALLOCNO_REGNO (a
))
4160 && ! slot_coalesced_allocno_live_ranges_intersect_p (allocno
, n
))
4165 /* No coalescing: set up number for coalesced allocnos
4166 represented by ALLOCNO. */
4167 ALLOCNO_COALESCE_DATA (allocno
)->temp
= last_coalesced_allocno_num
++;
4168 setup_slot_coalesced_allocno_live_ranges (allocno
);
4172 allocno_coalesced_p
= true;
4174 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
4175 fprintf (ira_dump_file
,
4176 " Coalescing spilled allocnos a%dr%d->a%dr%d\n",
4177 ALLOCNO_NUM (allocno
), ALLOCNO_REGNO (allocno
),
4178 ALLOCNO_NUM (a
), ALLOCNO_REGNO (a
));
4179 ALLOCNO_COALESCE_DATA (allocno
)->temp
4180 = ALLOCNO_COALESCE_DATA (a
)->temp
;
4181 setup_slot_coalesced_allocno_live_ranges (allocno
);
4182 merge_allocnos (a
, allocno
);
4183 ira_assert (ALLOCNO_COALESCE_DATA (a
)->first
== a
);
4186 for (i
= 0; i
< ira_allocnos_num
; i
++)
4187 ira_finish_live_range_list (slot_coalesced_allocnos_live_ranges
[i
]);
4188 ira_free (slot_coalesced_allocnos_live_ranges
);
4192 /* Sort pseudo-register numbers in array PSEUDO_REGNOS of length N for
4193 subsequent assigning stack slots to them in the reload pass. To do
4194 this we coalesce spilled allocnos first to decrease the number of
4195 memory-memory move insns. This function is called by the
4198 ira_sort_regnos_for_alter_reg (int *pseudo_regnos
, int n
,
4199 machine_mode
*reg_max_ref_mode
)
4201 int max_regno
= max_reg_num ();
4202 int i
, regno
, num
, slot_num
;
4203 ira_allocno_t allocno
, a
;
4204 ira_allocno_iterator ai
;
4205 ira_allocno_t
*spilled_coalesced_allocnos
;
4207 ira_assert (! ira_use_lra_p
);
4209 /* Set up allocnos can be coalesced. */
4210 coloring_allocno_bitmap
= ira_allocate_bitmap ();
4211 for (i
= 0; i
< n
; i
++)
4213 regno
= pseudo_regnos
[i
];
4214 allocno
= ira_regno_allocno_map
[regno
];
4215 if (allocno
!= NULL
)
4216 bitmap_set_bit (coloring_allocno_bitmap
, ALLOCNO_NUM (allocno
));
4218 allocno_coalesced_p
= false;
4219 processed_coalesced_allocno_bitmap
= ira_allocate_bitmap ();
4220 allocno_coalesce_data
4221 = (coalesce_data_t
) ira_allocate (sizeof (struct coalesce_data
)
4222 * ira_allocnos_num
);
4223 /* Initialize coalesce data for allocnos. */
4224 FOR_EACH_ALLOCNO (a
, ai
)
4226 ALLOCNO_ADD_DATA (a
) = allocno_coalesce_data
+ ALLOCNO_NUM (a
);
4227 ALLOCNO_COALESCE_DATA (a
)->first
= a
;
4228 ALLOCNO_COALESCE_DATA (a
)->next
= a
;
4230 coalesce_allocnos ();
4231 ira_free_bitmap (coloring_allocno_bitmap
);
4232 regno_coalesced_allocno_cost
4233 = (int *) ira_allocate (max_regno
* sizeof (int));
4234 regno_coalesced_allocno_num
4235 = (int *) ira_allocate (max_regno
* sizeof (int));
4236 memset (regno_coalesced_allocno_num
, 0, max_regno
* sizeof (int));
4237 setup_coalesced_allocno_costs_and_nums (pseudo_regnos
, n
);
4238 /* Sort regnos according frequencies of the corresponding coalesced
4240 qsort (pseudo_regnos
, n
, sizeof (int), coalesced_pseudo_reg_freq_compare
);
4241 spilled_coalesced_allocnos
4242 = (ira_allocno_t
*) ira_allocate (ira_allocnos_num
4243 * sizeof (ira_allocno_t
));
4244 /* Collect allocnos representing the spilled coalesced allocno
4246 num
= collect_spilled_coalesced_allocnos (pseudo_regnos
, n
,
4247 spilled_coalesced_allocnos
);
4248 if (flag_ira_share_spill_slots
4249 && coalesce_spill_slots (spilled_coalesced_allocnos
, num
))
4251 setup_coalesced_allocno_costs_and_nums (pseudo_regnos
, n
);
4252 qsort (pseudo_regnos
, n
, sizeof (int),
4253 coalesced_pseudo_reg_freq_compare
);
4254 num
= collect_spilled_coalesced_allocnos (pseudo_regnos
, n
,
4255 spilled_coalesced_allocnos
);
4257 ira_free_bitmap (processed_coalesced_allocno_bitmap
);
4258 allocno_coalesced_p
= false;
4259 /* Assign stack slot numbers to spilled allocno sets, use smaller
4260 numbers for most frequently used coalesced allocnos. -1 is
4261 reserved for dynamic search of stack slots for pseudos spilled by
4264 for (i
= 0; i
< num
; i
++)
4266 allocno
= spilled_coalesced_allocnos
[i
];
4267 if (ALLOCNO_COALESCE_DATA (allocno
)->first
!= allocno
4268 || ALLOCNO_HARD_REGNO (allocno
) >= 0
4269 || ira_equiv_no_lvalue_p (ALLOCNO_REGNO (allocno
)))
4271 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
4272 fprintf (ira_dump_file
, " Slot %d (freq,size):", slot_num
);
4274 for (a
= ALLOCNO_COALESCE_DATA (allocno
)->next
;;
4275 a
= ALLOCNO_COALESCE_DATA (a
)->next
)
4277 ira_assert (ALLOCNO_HARD_REGNO (a
) < 0);
4278 ALLOCNO_HARD_REGNO (a
) = -slot_num
;
4279 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
4281 machine_mode mode
= wider_subreg_mode
4282 (PSEUDO_REGNO_MODE (ALLOCNO_REGNO (a
)),
4283 reg_max_ref_mode
[ALLOCNO_REGNO (a
)]);
4284 fprintf (ira_dump_file
, " a%dr%d(%d,",
4285 ALLOCNO_NUM (a
), ALLOCNO_REGNO (a
), ALLOCNO_FREQ (a
));
4286 print_dec (GET_MODE_SIZE (mode
), ira_dump_file
, SIGNED
);
4287 fprintf (ira_dump_file
, ")\n");
4293 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
4294 fprintf (ira_dump_file
, "\n");
4296 ira_spilled_reg_stack_slots_num
= slot_num
- 1;
4297 ira_free (spilled_coalesced_allocnos
);
4298 /* Sort regnos according the slot numbers. */
4299 regno_max_ref_mode
= reg_max_ref_mode
;
4300 qsort (pseudo_regnos
, n
, sizeof (int), coalesced_pseudo_reg_slot_compare
);
4301 FOR_EACH_ALLOCNO (a
, ai
)
4302 ALLOCNO_ADD_DATA (a
) = NULL
;
4303 ira_free (allocno_coalesce_data
);
4304 ira_free (regno_coalesced_allocno_num
);
4305 ira_free (regno_coalesced_allocno_cost
);
4310 /* This page contains code used by the reload pass to improve the
4313 /* The function is called from reload to mark changes in the
4314 allocation of REGNO made by the reload. Remember that reg_renumber
4315 reflects the change result. */
4317 ira_mark_allocation_change (int regno
)
4319 ira_allocno_t a
= ira_regno_allocno_map
[regno
];
4320 int old_hard_regno
, hard_regno
, cost
;
4321 enum reg_class aclass
= ALLOCNO_CLASS (a
);
4323 ira_assert (a
!= NULL
);
4324 hard_regno
= reg_renumber
[regno
];
4325 if ((old_hard_regno
= ALLOCNO_HARD_REGNO (a
)) == hard_regno
)
4327 if (old_hard_regno
< 0)
4328 cost
= -ALLOCNO_MEMORY_COST (a
);
4331 ira_assert (ira_class_hard_reg_index
[aclass
][old_hard_regno
] >= 0);
4332 cost
= -(ALLOCNO_HARD_REG_COSTS (a
) == NULL
4333 ? ALLOCNO_CLASS_COST (a
)
4334 : ALLOCNO_HARD_REG_COSTS (a
)
4335 [ira_class_hard_reg_index
[aclass
][old_hard_regno
]]);
4336 update_costs_from_copies (a
, false, false);
4338 ira_overall_cost
-= cost
;
4339 ALLOCNO_HARD_REGNO (a
) = hard_regno
;
4342 ALLOCNO_HARD_REGNO (a
) = -1;
4343 cost
+= ALLOCNO_MEMORY_COST (a
);
4345 else if (ira_class_hard_reg_index
[aclass
][hard_regno
] >= 0)
4347 cost
+= (ALLOCNO_HARD_REG_COSTS (a
) == NULL
4348 ? ALLOCNO_CLASS_COST (a
)
4349 : ALLOCNO_HARD_REG_COSTS (a
)
4350 [ira_class_hard_reg_index
[aclass
][hard_regno
]]);
4351 update_costs_from_copies (a
, true, false);
4354 /* Reload changed class of the allocno. */
4356 ira_overall_cost
+= cost
;
4359 /* This function is called when reload deletes memory-memory move. In
4360 this case we marks that the allocation of the corresponding
4361 allocnos should be not changed in future. Otherwise we risk to get
4364 ira_mark_memory_move_deletion (int dst_regno
, int src_regno
)
4366 ira_allocno_t dst
= ira_regno_allocno_map
[dst_regno
];
4367 ira_allocno_t src
= ira_regno_allocno_map
[src_regno
];
4369 ira_assert (dst
!= NULL
&& src
!= NULL
4370 && ALLOCNO_HARD_REGNO (dst
) < 0
4371 && ALLOCNO_HARD_REGNO (src
) < 0);
4372 ALLOCNO_DONT_REASSIGN_P (dst
) = true;
4373 ALLOCNO_DONT_REASSIGN_P (src
) = true;
4376 /* Try to assign a hard register (except for FORBIDDEN_REGS) to
4377 allocno A and return TRUE in the case of success. */
4379 allocno_reload_assign (ira_allocno_t a
, HARD_REG_SET forbidden_regs
)
4382 enum reg_class aclass
;
4383 int regno
= ALLOCNO_REGNO (a
);
4384 HARD_REG_SET saved
[2];
4387 n
= ALLOCNO_NUM_OBJECTS (a
);
4388 for (i
= 0; i
< n
; i
++)
4390 ira_object_t obj
= ALLOCNO_OBJECT (a
, i
);
4391 COPY_HARD_REG_SET (saved
[i
], OBJECT_TOTAL_CONFLICT_HARD_REGS (obj
));
4392 IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj
), forbidden_regs
);
4393 if (! flag_caller_saves
&& ALLOCNO_CALLS_CROSSED_NUM (a
) != 0)
4394 IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj
),
4397 ALLOCNO_ASSIGNED_P (a
) = false;
4398 aclass
= ALLOCNO_CLASS (a
);
4399 update_curr_costs (a
);
4400 assign_hard_reg (a
, true);
4401 hard_regno
= ALLOCNO_HARD_REGNO (a
);
4402 reg_renumber
[regno
] = hard_regno
;
4404 ALLOCNO_HARD_REGNO (a
) = -1;
4407 ira_assert (ira_class_hard_reg_index
[aclass
][hard_regno
] >= 0);
4409 -= (ALLOCNO_MEMORY_COST (a
)
4410 - (ALLOCNO_HARD_REG_COSTS (a
) == NULL
4411 ? ALLOCNO_CLASS_COST (a
)
4412 : ALLOCNO_HARD_REG_COSTS (a
)[ira_class_hard_reg_index
4413 [aclass
][hard_regno
]]));
4414 if (ALLOCNO_CALLS_CROSSED_NUM (a
) != 0
4415 && ira_hard_reg_set_intersection_p (hard_regno
, ALLOCNO_MODE (a
),
4418 ira_assert (flag_caller_saves
);
4419 caller_save_needed
= 1;
4423 /* If we found a hard register, modify the RTL for the pseudo
4424 register to show the hard register, and mark the pseudo register
4426 if (reg_renumber
[regno
] >= 0)
4428 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
4429 fprintf (ira_dump_file
, ": reassign to %d\n", reg_renumber
[regno
]);
4430 SET_REGNO (regno_reg_rtx
[regno
], reg_renumber
[regno
]);
4431 mark_home_live (regno
);
4433 else if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
4434 fprintf (ira_dump_file
, "\n");
4435 for (i
= 0; i
< n
; i
++)
4437 ira_object_t obj
= ALLOCNO_OBJECT (a
, i
);
4438 COPY_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj
), saved
[i
]);
4440 return reg_renumber
[regno
] >= 0;
4443 /* Sort pseudos according their usage frequencies (putting most
4444 frequently ones first). */
4446 pseudo_reg_compare (const void *v1p
, const void *v2p
)
4448 int regno1
= *(const int *) v1p
;
4449 int regno2
= *(const int *) v2p
;
4452 if ((diff
= REG_FREQ (regno2
) - REG_FREQ (regno1
)) != 0)
4454 return regno1
- regno2
;
4457 /* Try to allocate hard registers to SPILLED_PSEUDO_REGS (there are
4458 NUM of them) or spilled pseudos conflicting with pseudos in
4459 SPILLED_PSEUDO_REGS. Return TRUE and update SPILLED, if the
4460 allocation has been changed. The function doesn't use
4461 BAD_SPILL_REGS and hard registers in PSEUDO_FORBIDDEN_REGS and
4462 PSEUDO_PREVIOUS_REGS for the corresponding pseudos. The function
4463 is called by the reload pass at the end of each reload
4466 ira_reassign_pseudos (int *spilled_pseudo_regs
, int num
,
4467 HARD_REG_SET bad_spill_regs
,
4468 HARD_REG_SET
*pseudo_forbidden_regs
,
4469 HARD_REG_SET
*pseudo_previous_regs
,
4475 HARD_REG_SET forbidden_regs
;
4476 bitmap temp
= BITMAP_ALLOC (NULL
);
4478 /* Add pseudos which conflict with pseudos already in
4479 SPILLED_PSEUDO_REGS to SPILLED_PSEUDO_REGS. This is preferable
4480 to allocating in two steps as some of the conflicts might have
4481 a higher priority than the pseudos passed in SPILLED_PSEUDO_REGS. */
4482 for (i
= 0; i
< num
; i
++)
4483 bitmap_set_bit (temp
, spilled_pseudo_regs
[i
]);
4485 for (i
= 0, n
= num
; i
< n
; i
++)
4488 int regno
= spilled_pseudo_regs
[i
];
4489 bitmap_set_bit (temp
, regno
);
4491 a
= ira_regno_allocno_map
[regno
];
4492 nr
= ALLOCNO_NUM_OBJECTS (a
);
4493 for (j
= 0; j
< nr
; j
++)
4495 ira_object_t conflict_obj
;
4496 ira_object_t obj
= ALLOCNO_OBJECT (a
, j
);
4497 ira_object_conflict_iterator oci
;
4499 FOR_EACH_OBJECT_CONFLICT (obj
, conflict_obj
, oci
)
4501 ira_allocno_t conflict_a
= OBJECT_ALLOCNO (conflict_obj
);
4502 if (ALLOCNO_HARD_REGNO (conflict_a
) < 0
4503 && ! ALLOCNO_DONT_REASSIGN_P (conflict_a
)
4504 && bitmap_set_bit (temp
, ALLOCNO_REGNO (conflict_a
)))
4506 spilled_pseudo_regs
[num
++] = ALLOCNO_REGNO (conflict_a
);
4507 /* ?!? This seems wrong. */
4508 bitmap_set_bit (consideration_allocno_bitmap
,
4509 ALLOCNO_NUM (conflict_a
));
4516 qsort (spilled_pseudo_regs
, num
, sizeof (int), pseudo_reg_compare
);
4518 /* Try to assign hard registers to pseudos from
4519 SPILLED_PSEUDO_REGS. */
4520 for (i
= 0; i
< num
; i
++)
4522 regno
= spilled_pseudo_regs
[i
];
4523 COPY_HARD_REG_SET (forbidden_regs
, bad_spill_regs
);
4524 IOR_HARD_REG_SET (forbidden_regs
, pseudo_forbidden_regs
[regno
]);
4525 IOR_HARD_REG_SET (forbidden_regs
, pseudo_previous_regs
[regno
]);
4526 gcc_assert (reg_renumber
[regno
] < 0);
4527 a
= ira_regno_allocno_map
[regno
];
4528 ira_mark_allocation_change (regno
);
4529 ira_assert (reg_renumber
[regno
] < 0);
4530 if (internal_flag_ira_verbose
> 3 && ira_dump_file
!= NULL
)
4531 fprintf (ira_dump_file
,
4532 " Try Assign %d(a%d), cost=%d", regno
, ALLOCNO_NUM (a
),
4533 ALLOCNO_MEMORY_COST (a
)
4534 - ALLOCNO_CLASS_COST (a
));
4535 allocno_reload_assign (a
, forbidden_regs
);
4536 if (reg_renumber
[regno
] >= 0)
4538 CLEAR_REGNO_REG_SET (spilled
, regno
);
4546 /* The function is called by reload and returns already allocated
4547 stack slot (if any) for REGNO with given INHERENT_SIZE and
4548 TOTAL_SIZE. In the case of failure to find a slot which can be
4549 used for REGNO, the function returns NULL. */
4551 ira_reuse_stack_slot (int regno
, poly_uint64 inherent_size
,
4552 poly_uint64 total_size
)
4555 int slot_num
, best_slot_num
;
4556 int cost
, best_cost
;
4557 ira_copy_t cp
, next_cp
;
4558 ira_allocno_t another_allocno
, allocno
= ira_regno_allocno_map
[regno
];
4561 struct ira_spilled_reg_stack_slot
*slot
= NULL
;
4563 ira_assert (! ira_use_lra_p
);
4565 ira_assert (known_eq (inherent_size
, PSEUDO_REGNO_BYTES (regno
))
4566 && known_le (inherent_size
, total_size
)
4567 && ALLOCNO_HARD_REGNO (allocno
) < 0);
4568 if (! flag_ira_share_spill_slots
)
4570 slot_num
= -ALLOCNO_HARD_REGNO (allocno
) - 2;
4573 slot
= &ira_spilled_reg_stack_slots
[slot_num
];
4578 best_cost
= best_slot_num
= -1;
4580 /* It means that the pseudo was spilled in the reload pass, try
4583 slot_num
< ira_spilled_reg_stack_slots_num
;
4586 slot
= &ira_spilled_reg_stack_slots
[slot_num
];
4587 if (slot
->mem
== NULL_RTX
)
4589 if (maybe_lt (slot
->width
, total_size
)
4590 || maybe_lt (GET_MODE_SIZE (GET_MODE (slot
->mem
)), inherent_size
))
4593 EXECUTE_IF_SET_IN_BITMAP (&slot
->spilled_regs
,
4594 FIRST_PSEUDO_REGISTER
, i
, bi
)
4596 another_allocno
= ira_regno_allocno_map
[i
];
4597 if (allocnos_conflict_by_live_ranges_p (allocno
,
4601 for (cost
= 0, cp
= ALLOCNO_COPIES (allocno
);
4605 if (cp
->first
== allocno
)
4607 next_cp
= cp
->next_first_allocno_copy
;
4608 another_allocno
= cp
->second
;
4610 else if (cp
->second
== allocno
)
4612 next_cp
= cp
->next_second_allocno_copy
;
4613 another_allocno
= cp
->first
;
4617 if (cp
->insn
== NULL_RTX
)
4619 if (bitmap_bit_p (&slot
->spilled_regs
,
4620 ALLOCNO_REGNO (another_allocno
)))
4623 if (cost
> best_cost
)
4626 best_slot_num
= slot_num
;
4633 slot_num
= best_slot_num
;
4634 slot
= &ira_spilled_reg_stack_slots
[slot_num
];
4635 SET_REGNO_REG_SET (&slot
->spilled_regs
, regno
);
4637 ALLOCNO_HARD_REGNO (allocno
) = -slot_num
- 2;
4642 ira_assert (known_ge (slot
->width
, total_size
));
4643 #ifdef ENABLE_IRA_CHECKING
4644 EXECUTE_IF_SET_IN_BITMAP (&slot
->spilled_regs
,
4645 FIRST_PSEUDO_REGISTER
, i
, bi
)
4647 ira_assert (! conflict_by_live_ranges_p (regno
, i
));
4650 SET_REGNO_REG_SET (&slot
->spilled_regs
, regno
);
4651 if (internal_flag_ira_verbose
> 3 && ira_dump_file
)
4653 fprintf (ira_dump_file
, " Assigning %d(freq=%d) slot %d of",
4654 regno
, REG_FREQ (regno
), slot_num
);
4655 EXECUTE_IF_SET_IN_BITMAP (&slot
->spilled_regs
,
4656 FIRST_PSEUDO_REGISTER
, i
, bi
)
4658 if ((unsigned) regno
!= i
)
4659 fprintf (ira_dump_file
, " %d", i
);
4661 fprintf (ira_dump_file
, "\n");
4667 /* This is called by reload every time a new stack slot X with
4668 TOTAL_SIZE was allocated for REGNO. We store this info for
4669 subsequent ira_reuse_stack_slot calls. */
4671 ira_mark_new_stack_slot (rtx x
, int regno
, poly_uint64 total_size
)
4673 struct ira_spilled_reg_stack_slot
*slot
;
4675 ira_allocno_t allocno
;
4677 ira_assert (! ira_use_lra_p
);
4679 ira_assert (known_le (PSEUDO_REGNO_BYTES (regno
), total_size
));
4680 allocno
= ira_regno_allocno_map
[regno
];
4681 slot_num
= -ALLOCNO_HARD_REGNO (allocno
) - 2;
4684 slot_num
= ira_spilled_reg_stack_slots_num
++;
4685 ALLOCNO_HARD_REGNO (allocno
) = -slot_num
- 2;
4687 slot
= &ira_spilled_reg_stack_slots
[slot_num
];
4688 INIT_REG_SET (&slot
->spilled_regs
);
4689 SET_REGNO_REG_SET (&slot
->spilled_regs
, regno
);
4691 slot
->width
= total_size
;
4692 if (internal_flag_ira_verbose
> 3 && ira_dump_file
)
4693 fprintf (ira_dump_file
, " Assigning %d(freq=%d) a new slot %d\n",
4694 regno
, REG_FREQ (regno
), slot_num
);
4698 /* Return spill cost for pseudo-registers whose numbers are in array
4699 REGNOS (with a negative number as an end marker) for reload with
4700 given IN and OUT for INSN. Return also number points (through
4701 EXCESS_PRESSURE_LIVE_LENGTH) where the pseudo-register lives and
4702 the register pressure is high, number of references of the
4703 pseudo-registers (through NREFS), number of callee-clobbered
4704 hard-registers occupied by the pseudo-registers (through
4705 CALL_USED_COUNT), and the first hard regno occupied by the
4706 pseudo-registers (through FIRST_HARD_REGNO). */
4708 calculate_spill_cost (int *regnos
, rtx in
, rtx out
, rtx_insn
*insn
,
4709 int *excess_pressure_live_length
,
4710 int *nrefs
, int *call_used_count
, int *first_hard_regno
)
4712 int i
, cost
, regno
, hard_regno
, j
, count
, saved_cost
, nregs
;
4718 for (length
= count
= cost
= i
= 0;; i
++)
4723 *nrefs
+= REG_N_REFS (regno
);
4724 hard_regno
= reg_renumber
[regno
];
4725 ira_assert (hard_regno
>= 0);
4726 a
= ira_regno_allocno_map
[regno
];
4727 length
+= ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a
) / ALLOCNO_NUM_OBJECTS (a
);
4728 cost
+= ALLOCNO_MEMORY_COST (a
) - ALLOCNO_CLASS_COST (a
);
4729 nregs
= hard_regno_nregs (hard_regno
, ALLOCNO_MODE (a
));
4730 for (j
= 0; j
< nregs
; j
++)
4731 if (! TEST_HARD_REG_BIT (call_used_reg_set
, hard_regno
+ j
))
4735 in_p
= in
&& REG_P (in
) && (int) REGNO (in
) == hard_regno
;
4736 out_p
= out
&& REG_P (out
) && (int) REGNO (out
) == hard_regno
;
4738 && find_regno_note (insn
, REG_DEAD
, hard_regno
) != NULL_RTX
)
4742 saved_cost
+= ira_memory_move_cost
4743 [ALLOCNO_MODE (a
)][ALLOCNO_CLASS (a
)][1];
4746 += ira_memory_move_cost
4747 [ALLOCNO_MODE (a
)][ALLOCNO_CLASS (a
)][0];
4748 cost
-= REG_FREQ_FROM_BB (BLOCK_FOR_INSN (insn
)) * saved_cost
;
4751 *excess_pressure_live_length
= length
;
4752 *call_used_count
= count
;
4756 hard_regno
= reg_renumber
[regnos
[0]];
4758 *first_hard_regno
= hard_regno
;
4762 /* Return TRUE if spilling pseudo-registers whose numbers are in array
4763 REGNOS is better than spilling pseudo-registers with numbers in
4764 OTHER_REGNOS for reload with given IN and OUT for INSN. The
4765 function used by the reload pass to make better register spilling
4768 ira_better_spill_reload_regno_p (int *regnos
, int *other_regnos
,
4769 rtx in
, rtx out
, rtx_insn
*insn
)
4771 int cost
, other_cost
;
4772 int length
, other_length
;
4773 int nrefs
, other_nrefs
;
4774 int call_used_count
, other_call_used_count
;
4775 int hard_regno
, other_hard_regno
;
4777 cost
= calculate_spill_cost (regnos
, in
, out
, insn
,
4778 &length
, &nrefs
, &call_used_count
, &hard_regno
);
4779 other_cost
= calculate_spill_cost (other_regnos
, in
, out
, insn
,
4780 &other_length
, &other_nrefs
,
4781 &other_call_used_count
,
4783 if (nrefs
== 0 && other_nrefs
!= 0)
4785 if (nrefs
!= 0 && other_nrefs
== 0)
4787 if (cost
!= other_cost
)
4788 return cost
< other_cost
;
4789 if (length
!= other_length
)
4790 return length
> other_length
;
4791 #ifdef REG_ALLOC_ORDER
4792 if (hard_regno
>= 0 && other_hard_regno
>= 0)
4793 return (inv_reg_alloc_order
[hard_regno
]
4794 < inv_reg_alloc_order
[other_hard_regno
]);
4796 if (call_used_count
!= other_call_used_count
)
4797 return call_used_count
> other_call_used_count
;
4804 /* Allocate and initialize data necessary for assign_hard_reg. */
4806 ira_initiate_assign (void)
4809 = (ira_allocno_t
*) ira_allocate (sizeof (ira_allocno_t
)
4810 * ira_allocnos_num
);
4811 consideration_allocno_bitmap
= ira_allocate_bitmap ();
4812 initiate_cost_update ();
4813 allocno_priorities
= (int *) ira_allocate (sizeof (int) * ira_allocnos_num
);
4814 sorted_copies
= (ira_copy_t
*) ira_allocate (ira_copies_num
4815 * sizeof (ira_copy_t
));
4818 /* Deallocate data used by assign_hard_reg. */
4820 ira_finish_assign (void)
4822 ira_free (sorted_allocnos
);
4823 ira_free_bitmap (consideration_allocno_bitmap
);
4824 finish_cost_update ();
4825 ira_free (allocno_priorities
);
4826 ira_free (sorted_copies
);
4831 /* Entry function doing color-based register allocation. */
4835 allocno_stack_vec
.create (ira_allocnos_num
);
4836 memset (allocated_hardreg_p
, 0, sizeof (allocated_hardreg_p
));
4837 ira_initiate_assign ();
4839 ira_finish_assign ();
4840 allocno_stack_vec
.release ();
4841 move_spill_restore ();
4846 /* This page contains a simple register allocator without usage of
4847 allocno conflicts. This is used for fast allocation for -O0. */
4849 /* Do register allocation by not using allocno conflicts. It uses
4850 only allocno live ranges. The algorithm is close to Chow's
4851 priority coloring. */
4853 fast_allocation (void)
4855 int i
, j
, k
, num
, class_size
, hard_regno
, best_hard_regno
, cost
, min_cost
;
4858 bool no_stack_reg_p
;
4860 enum reg_class aclass
;
4863 ira_allocno_iterator ai
;
4865 HARD_REG_SET conflict_hard_regs
, *used_hard_regs
;
4867 sorted_allocnos
= (ira_allocno_t
*) ira_allocate (sizeof (ira_allocno_t
)
4868 * ira_allocnos_num
);
4870 FOR_EACH_ALLOCNO (a
, ai
)
4871 sorted_allocnos
[num
++] = a
;
4872 allocno_priorities
= (int *) ira_allocate (sizeof (int) * ira_allocnos_num
);
4873 setup_allocno_priorities (sorted_allocnos
, num
);
4874 used_hard_regs
= (HARD_REG_SET
*) ira_allocate (sizeof (HARD_REG_SET
)
4876 for (i
= 0; i
< ira_max_point
; i
++)
4877 CLEAR_HARD_REG_SET (used_hard_regs
[i
]);
4878 qsort (sorted_allocnos
, num
, sizeof (ira_allocno_t
),
4879 allocno_priority_compare_func
);
4880 for (i
= 0; i
< num
; i
++)
4884 a
= sorted_allocnos
[i
];
4885 nr
= ALLOCNO_NUM_OBJECTS (a
);
4886 CLEAR_HARD_REG_SET (conflict_hard_regs
);
4887 for (l
= 0; l
< nr
; l
++)
4889 ira_object_t obj
= ALLOCNO_OBJECT (a
, l
);
4890 IOR_HARD_REG_SET (conflict_hard_regs
,
4891 OBJECT_CONFLICT_HARD_REGS (obj
));
4892 for (r
= OBJECT_LIVE_RANGES (obj
); r
!= NULL
; r
= r
->next
)
4893 for (j
= r
->start
; j
<= r
->finish
; j
++)
4894 IOR_HARD_REG_SET (conflict_hard_regs
, used_hard_regs
[j
]);
4896 aclass
= ALLOCNO_CLASS (a
);
4897 ALLOCNO_ASSIGNED_P (a
) = true;
4898 ALLOCNO_HARD_REGNO (a
) = -1;
4899 if (hard_reg_set_subset_p (reg_class_contents
[aclass
],
4900 conflict_hard_regs
))
4902 mode
= ALLOCNO_MODE (a
);
4904 no_stack_reg_p
= ALLOCNO_NO_STACK_REG_P (a
);
4906 class_size
= ira_class_hard_regs_num
[aclass
];
4907 costs
= ALLOCNO_HARD_REG_COSTS (a
);
4909 best_hard_regno
= -1;
4910 for (j
= 0; j
< class_size
; j
++)
4912 hard_regno
= ira_class_hard_regs
[aclass
][j
];
4914 if (no_stack_reg_p
&& FIRST_STACK_REG
<= hard_regno
4915 && hard_regno
<= LAST_STACK_REG
)
4918 if (ira_hard_reg_set_intersection_p (hard_regno
, mode
, conflict_hard_regs
)
4919 || (TEST_HARD_REG_BIT
4920 (ira_prohibited_class_mode_regs
[aclass
][mode
], hard_regno
)))
4924 best_hard_regno
= hard_regno
;
4928 if (min_cost
> cost
)
4931 best_hard_regno
= hard_regno
;
4934 if (best_hard_regno
< 0)
4936 ALLOCNO_HARD_REGNO (a
) = hard_regno
= best_hard_regno
;
4937 for (l
= 0; l
< nr
; l
++)
4939 ira_object_t obj
= ALLOCNO_OBJECT (a
, l
);
4940 for (r
= OBJECT_LIVE_RANGES (obj
); r
!= NULL
; r
= r
->next
)
4941 for (k
= r
->start
; k
<= r
->finish
; k
++)
4942 IOR_HARD_REG_SET (used_hard_regs
[k
],
4943 ira_reg_mode_hard_regset
[hard_regno
][mode
]);
4946 ira_free (sorted_allocnos
);
4947 ira_free (used_hard_regs
);
4948 ira_free (allocno_priorities
);
4949 if (internal_flag_ira_verbose
> 1 && ira_dump_file
!= NULL
)
4950 ira_print_disposition (ira_dump_file
);
4955 /* Entry function doing coloring. */
4960 ira_allocno_iterator ai
;
4962 /* Setup updated costs. */
4963 FOR_EACH_ALLOCNO (a
, ai
)
4965 ALLOCNO_UPDATED_MEMORY_COST (a
) = ALLOCNO_MEMORY_COST (a
);
4966 ALLOCNO_UPDATED_CLASS_COST (a
) = ALLOCNO_CLASS_COST (a
);
4968 if (ira_conflicts_p
)