Branch data Line data Source code
1 : : /* IRA allocation based on graph coloring.
2 : : Copyright (C) 2006-2025 Free Software Foundation, Inc.
3 : : Contributed by Vladimir Makarov <vmakarov@redhat.com>.
4 : :
5 : : This file is part of GCC.
6 : :
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
10 : : version.
11 : :
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
15 : : for more details.
16 : :
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/>. */
20 : :
21 : : #include "config.h"
22 : : #include "system.h"
23 : : #include "coretypes.h"
24 : : #include "backend.h"
25 : : #include "target.h"
26 : : #include "rtl.h"
27 : : #include "tree.h"
28 : : #include "predict.h"
29 : : #include "df.h"
30 : : #include "memmodel.h"
31 : : #include "tm_p.h"
32 : : #include "insn-config.h"
33 : : #include "regs.h"
34 : : #include "ira.h"
35 : : #include "ira-int.h"
36 : : #include "reload.h"
37 : : #include "cfgloop.h"
38 : :
39 : : /* To prevent soft conflict detection becoming quadratic in the
40 : : loop depth. Only for very pathological cases, so it hardly
41 : : seems worth a --param. */
42 : : const int max_soft_conflict_loop_depth = 64;
43 : :
44 : : typedef struct allocno_hard_regs *allocno_hard_regs_t;
45 : :
46 : : /* The structure contains information about hard registers can be
47 : : assigned to allocnos. Usually it is allocno profitable hard
48 : : registers but in some cases this set can be a bit different. Major
49 : : reason of the difference is a requirement to use hard register sets
50 : : that form a tree or a forest (set of trees), i.e. hard register set
51 : : of a node should contain hard register sets of its subnodes. */
52 : : struct allocno_hard_regs
53 : : {
54 : : /* Hard registers can be assigned to an allocno. */
55 : : HARD_REG_SET set;
56 : : /* Overall (spilling) cost of all allocnos with given register
57 : : set. */
58 : : int64_t cost;
59 : : };
60 : :
61 : : typedef struct allocno_hard_regs_node *allocno_hard_regs_node_t;
62 : :
63 : : /* A node representing allocno hard registers. Such nodes form a
64 : : forest (set of trees). Each subnode of given node in the forest
65 : : refers for hard register set (usually allocno profitable hard
66 : : register set) which is a subset of one referred from given
67 : : node. */
68 : : struct allocno_hard_regs_node
69 : : {
70 : : /* Set up number of the node in preorder traversing of the forest. */
71 : : int preorder_num;
72 : : /* Used for different calculation like finding conflict size of an
73 : : allocno. */
74 : : int check;
75 : : /* Used for calculation of conflict size of an allocno. The
76 : : conflict size of the allocno is maximal number of given allocno
77 : : hard registers needed for allocation of the conflicting allocnos.
78 : : Given allocno is trivially colored if this number plus the number
79 : : of hard registers needed for given allocno is not greater than
80 : : the number of given allocno hard register set. */
81 : : int conflict_size;
82 : : /* The number of hard registers given by member hard_regs. */
83 : : int hard_regs_num;
84 : : /* The following member is used to form the final forest. */
85 : : bool used_p;
86 : : /* Pointer to the corresponding profitable hard registers. */
87 : : allocno_hard_regs_t hard_regs;
88 : : /* Parent, first subnode, previous and next node with the same
89 : : parent in the forest. */
90 : : allocno_hard_regs_node_t parent, first, prev, next;
91 : : };
92 : :
93 : : /* Info about changing hard reg costs of an allocno. */
94 : : struct update_cost_record
95 : : {
96 : : /* Hard regno for which we changed the cost. */
97 : : int hard_regno;
98 : : /* Divisor used when we changed the cost of HARD_REGNO. */
99 : : int divisor;
100 : : /* Next record for given allocno. */
101 : : struct update_cost_record *next;
102 : : };
103 : :
104 : : /* To decrease footprint of ira_allocno structure we store all data
105 : : needed only for coloring in the following structure. */
106 : : struct allocno_color_data
107 : : {
108 : : /* TRUE value means that the allocno was not removed yet from the
109 : : conflicting graph during coloring. */
110 : : unsigned int in_graph_p : 1;
111 : : /* TRUE if it is put on the stack to make other allocnos
112 : : colorable. */
113 : : unsigned int may_be_spilled_p : 1;
114 : : /* TRUE if the allocno is trivially colorable. */
115 : : unsigned int colorable_p : 1;
116 : : /* Number of hard registers of the allocno class really
117 : : available for the allocno allocation. It is number of the
118 : : profitable hard regs. */
119 : : int available_regs_num;
120 : : /* Sum of frequencies of hard register preferences of all
121 : : conflicting allocnos which are not the coloring stack yet. */
122 : : int conflict_allocno_hard_prefs;
123 : : /* Allocnos in a bucket (used in coloring) chained by the following
124 : : two members. */
125 : : ira_allocno_t next_bucket_allocno;
126 : : ira_allocno_t prev_bucket_allocno;
127 : : /* Used for temporary purposes. */
128 : : int temp;
129 : : /* Used to exclude repeated processing. */
130 : : int last_process;
131 : : /* Profitable hard regs available for this pseudo allocation. It
132 : : means that the set excludes unavailable hard regs and hard regs
133 : : conflicting with given pseudo. They should be of the allocno
134 : : class. */
135 : : HARD_REG_SET profitable_hard_regs;
136 : : /* The allocno hard registers node. */
137 : : allocno_hard_regs_node_t hard_regs_node;
138 : : /* Array of structures allocno_hard_regs_subnode representing
139 : : given allocno hard registers node (the 1st element in the array)
140 : : and all its subnodes in the tree (forest) of allocno hard
141 : : register nodes (see comments above). */
142 : : int hard_regs_subnodes_start;
143 : : /* The length of the previous array. */
144 : : int hard_regs_subnodes_num;
145 : : /* Records about updating allocno hard reg costs from copies. If
146 : : the allocno did not get expected hard register, these records are
147 : : used to restore original hard reg costs of allocnos connected to
148 : : this allocno by copies. */
149 : : struct update_cost_record *update_cost_records;
150 : : /* Threads. We collect allocnos connected by copies into threads
151 : : and try to assign hard regs to allocnos by threads. */
152 : : /* Allocno representing all thread. */
153 : : ira_allocno_t first_thread_allocno;
154 : : /* Allocnos in thread forms a cycle list through the following
155 : : member. */
156 : : ira_allocno_t next_thread_allocno;
157 : : /* All thread frequency. Defined only for first thread allocno. */
158 : : int thread_freq;
159 : : /* Sum of frequencies of hard register preferences of the allocno. */
160 : : int hard_reg_prefs;
161 : : };
162 : :
163 : : /* See above. */
164 : : typedef struct allocno_color_data *allocno_color_data_t;
165 : :
166 : : /* Container for storing allocno data concerning coloring. */
167 : : static allocno_color_data_t allocno_color_data;
168 : :
169 : : /* Macro to access the data concerning coloring. */
170 : : #define ALLOCNO_COLOR_DATA(a) ((allocno_color_data_t) ALLOCNO_ADD_DATA (a))
171 : :
172 : : /* Used for finding allocno colorability to exclude repeated allocno
173 : : processing and for updating preferencing to exclude repeated
174 : : allocno processing during assignment. */
175 : : static int curr_allocno_process;
176 : :
177 : : /* This file contains code for regional graph coloring, spill/restore
178 : : code placement optimization, and code helping the reload pass to do
179 : : a better job. */
180 : :
181 : : /* Bitmap of allocnos which should be colored. */
182 : : static bitmap coloring_allocno_bitmap;
183 : :
184 : : /* Bitmap of allocnos which should be taken into account during
185 : : coloring. In general case it contains allocnos from
186 : : coloring_allocno_bitmap plus other already colored conflicting
187 : : allocnos. */
188 : : static bitmap consideration_allocno_bitmap;
189 : :
190 : : /* All allocnos sorted according their priorities. */
191 : : static ira_allocno_t *sorted_allocnos;
192 : :
193 : : /* Vec representing the stack of allocnos used during coloring. */
194 : : static vec<ira_allocno_t> allocno_stack_vec;
195 : :
196 : : /* Helper for qsort comparison callbacks - return a positive integer if
197 : : X > Y, or a negative value otherwise. Use a conditional expression
198 : : instead of a difference computation to insulate from possible overflow
199 : : issues, e.g. X - Y < 0 for some X > 0 and Y < 0. */
200 : : #define SORTGT(x,y) (((x) > (y)) ? 1 : -1)
201 : :
202 : :
203 : :
204 : : /* Definition of vector of allocno hard registers. */
205 : :
206 : : /* Vector of unique allocno hard registers. */
207 : : static vec<allocno_hard_regs_t> allocno_hard_regs_vec;
208 : :
209 : : struct allocno_hard_regs_hasher : nofree_ptr_hash <allocno_hard_regs>
210 : : {
211 : : static inline hashval_t hash (const allocno_hard_regs *);
212 : : static inline bool equal (const allocno_hard_regs *,
213 : : const allocno_hard_regs *);
214 : : };
215 : :
216 : : /* Returns hash value for allocno hard registers V. */
217 : : inline hashval_t
218 : 299544197 : allocno_hard_regs_hasher::hash (const allocno_hard_regs *hv)
219 : : {
220 : 295281035 : return iterative_hash (&hv->set, sizeof (HARD_REG_SET), 0);
221 : : }
222 : :
223 : : /* Compares allocno hard registers V1 and V2. */
224 : : inline bool
225 : 191020823 : allocno_hard_regs_hasher::equal (const allocno_hard_regs *hv1,
226 : : const allocno_hard_regs *hv2)
227 : : {
228 : 382041646 : return hv1->set == hv2->set;
229 : : }
230 : :
231 : : /* Hash table of unique allocno hard registers. */
232 : : static hash_table<allocno_hard_regs_hasher> *allocno_hard_regs_htab;
233 : :
234 : : /* Return allocno hard registers in the hash table equal to HV. */
235 : : static allocno_hard_regs_t
236 : 81237903 : find_hard_regs (allocno_hard_regs_t hv)
237 : : {
238 : 0 : return allocno_hard_regs_htab->find (hv);
239 : : }
240 : :
241 : : /* Insert allocno hard registers HV in the hash table (if it is not
242 : : there yet) and return the value which in the table. */
243 : : static allocno_hard_regs_t
244 : 59621602 : insert_hard_regs (allocno_hard_regs_t hv)
245 : : {
246 : 59621602 : allocno_hard_regs **slot = allocno_hard_regs_htab->find_slot (hv, INSERT);
247 : :
248 : 59621602 : if (*slot == NULL)
249 : 59621602 : *slot = hv;
250 : 59621602 : return *slot;
251 : : }
252 : :
253 : : /* Initialize data concerning allocno hard registers. */
254 : : static void
255 : 1163819 : init_allocno_hard_regs (void)
256 : : {
257 : 1163819 : allocno_hard_regs_vec.create (200);
258 : 1163819 : allocno_hard_regs_htab
259 : 1163819 : = new hash_table<allocno_hard_regs_hasher> (200);
260 : 1163819 : }
261 : :
262 : : /* Add (or update info about) allocno hard registers with SET and
263 : : COST. */
264 : : static allocno_hard_regs_t
265 : 81237903 : add_allocno_hard_regs (HARD_REG_SET set, int64_t cost)
266 : : {
267 : 81237903 : struct allocno_hard_regs temp;
268 : 81237903 : allocno_hard_regs_t hv;
269 : :
270 : 162475806 : gcc_assert (! hard_reg_set_empty_p (set));
271 : 81237903 : temp.set = set;
272 : 81237903 : if ((hv = find_hard_regs (&temp)) != NULL)
273 : 21616301 : hv->cost += cost;
274 : : else
275 : : {
276 : 119243204 : hv = ((struct allocno_hard_regs *)
277 : 59621602 : ira_allocate (sizeof (struct allocno_hard_regs)));
278 : 59621602 : hv->set = set;
279 : 59621602 : hv->cost = cost;
280 : 59621602 : allocno_hard_regs_vec.safe_push (hv);
281 : 59621602 : insert_hard_regs (hv);
282 : : }
283 : 81237903 : return hv;
284 : : }
285 : :
286 : : /* Finalize data concerning allocno hard registers. */
287 : : static void
288 : 1163819 : finish_allocno_hard_regs (void)
289 : : {
290 : 1163819 : int i;
291 : 1163819 : allocno_hard_regs_t hv;
292 : :
293 : 60785421 : for (i = 0;
294 : 60785421 : allocno_hard_regs_vec.iterate (i, &hv);
295 : : i++)
296 : 59621602 : ira_free (hv);
297 : 1163819 : delete allocno_hard_regs_htab;
298 : 1163819 : allocno_hard_regs_htab = NULL;
299 : 1163819 : allocno_hard_regs_vec.release ();
300 : 1163819 : }
301 : :
302 : : /* Sort hard regs according to their frequency of usage. */
303 : : static int
304 : 35091414 : allocno_hard_regs_compare (const void *v1p, const void *v2p)
305 : : {
306 : 35091414 : allocno_hard_regs_t hv1 = *(const allocno_hard_regs_t *) v1p;
307 : 35091414 : allocno_hard_regs_t hv2 = *(const allocno_hard_regs_t *) v2p;
308 : :
309 : 35091414 : if (hv2->cost > hv1->cost)
310 : : return 1;
311 : 18965703 : else if (hv2->cost < hv1->cost)
312 : : return -1;
313 : 2131581 : return SORTGT (allocno_hard_regs_hasher::hash(hv2), allocno_hard_regs_hasher::hash(hv1));
314 : : }
315 : :
316 : :
317 : :
318 : : /* Used for finding a common ancestor of two allocno hard registers
319 : : nodes in the forest. We use the current value of
320 : : 'node_check_tick' to mark all nodes from one node to the top and
321 : : then walking up from another node until we find a marked node.
322 : :
323 : : It is also used to figure out allocno colorability as a mark that
324 : : we already reset value of member 'conflict_size' for the forest
325 : : node corresponding to the processed allocno. */
326 : : static int node_check_tick;
327 : :
328 : : /* Roots of the forest containing hard register sets can be assigned
329 : : to allocnos. */
330 : : static allocno_hard_regs_node_t hard_regs_roots;
331 : :
332 : : /* Definition of vector of allocno hard register nodes. */
333 : :
334 : : /* Vector used to create the forest. */
335 : : static vec<allocno_hard_regs_node_t> hard_regs_node_vec;
336 : :
337 : : /* Create and return allocno hard registers node containing allocno
338 : : hard registers HV. */
339 : : static allocno_hard_regs_node_t
340 : 57591467 : create_new_allocno_hard_regs_node (allocno_hard_regs_t hv)
341 : : {
342 : 57591467 : allocno_hard_regs_node_t new_node;
343 : :
344 : 57591467 : new_node = ((struct allocno_hard_regs_node *)
345 : 57591467 : ira_allocate (sizeof (struct allocno_hard_regs_node)));
346 : 57591467 : new_node->check = 0;
347 : 57591467 : new_node->hard_regs = hv;
348 : 57591467 : new_node->hard_regs_num = hard_reg_set_size (hv->set);
349 : 57591467 : new_node->first = NULL;
350 : 57591467 : new_node->used_p = false;
351 : 57591467 : return new_node;
352 : : }
353 : :
354 : : /* Add allocno hard registers node NEW_NODE to the forest on its level
355 : : given by ROOTS. */
356 : : static void
357 : 57591467 : add_new_allocno_hard_regs_node_to_forest (allocno_hard_regs_node_t *roots,
358 : : allocno_hard_regs_node_t new_node)
359 : : {
360 : 57591467 : new_node->next = *roots;
361 : 0 : if (new_node->next != NULL)
362 : 55263829 : new_node->next->prev = new_node;
363 : 57591467 : new_node->prev = NULL;
364 : 57591467 : *roots = new_node;
365 : 57591467 : }
366 : :
367 : : /* Add allocno hard registers HV (or its best approximation if it is
368 : : not possible) to the forest on its level given by ROOTS. */
369 : : static void
370 : 7700881 : add_allocno_hard_regs_to_forest (allocno_hard_regs_node_t *roots,
371 : : allocno_hard_regs_t hv)
372 : : {
373 : 13232575 : unsigned int i, start;
374 : 13232575 : allocno_hard_regs_node_t node, prev, new_node;
375 : 13232575 : HARD_REG_SET temp_set;
376 : 13232575 : allocno_hard_regs_t hv2;
377 : :
378 : 13232575 : start = hard_regs_node_vec.length ();
379 : 134314070 : for (node = *roots; node != NULL; node = node->next)
380 : : {
381 : 257692294 : if (hv->set == node->hard_regs->set)
382 : 2232958 : return;
383 : 126613189 : if (hard_reg_set_subset_p (hv->set, node->hard_regs->set))
384 : : {
385 : 5531694 : add_allocno_hard_regs_to_forest (&node->first, hv);
386 : 5531694 : return;
387 : : }
388 : 121081495 : if (hard_reg_set_subset_p (node->hard_regs->set, hv->set))
389 : 69480458 : hard_regs_node_vec.safe_push (node);
390 : 51601037 : else if (hard_reg_set_intersect_p (hv->set, node->hard_regs->set))
391 : : {
392 : 1333599 : temp_set = hv->set & node->hard_regs->set;
393 : 1333599 : hv2 = add_allocno_hard_regs (temp_set, hv->cost);
394 : 1333599 : add_allocno_hard_regs_to_forest (&node->first, hv2);
395 : : }
396 : : }
397 : 5467923 : if (hard_regs_node_vec.length ()
398 : 5467923 : > start + 1)
399 : : {
400 : : /* Create a new node which contains nodes in hard_regs_node_vec. */
401 : 72772649 : CLEAR_HARD_REG_SET (temp_set);
402 : 68435502 : for (i = start;
403 : 72772649 : i < hard_regs_node_vec.length ();
404 : : i++)
405 : : {
406 : 68435502 : node = hard_regs_node_vec[i];
407 : 136871004 : temp_set |= node->hard_regs->set;
408 : : }
409 : 4337147 : hv = add_allocno_hard_regs (temp_set, hv->cost);
410 : 4337147 : new_node = create_new_allocno_hard_regs_node (hv);
411 : 4337147 : prev = NULL;
412 : 4337147 : for (i = start;
413 : 72772649 : i < hard_regs_node_vec.length ();
414 : : i++)
415 : : {
416 : 68435502 : node = hard_regs_node_vec[i];
417 : 68435502 : if (node->prev == NULL)
418 : 46752374 : *roots = node->next;
419 : : else
420 : 21683128 : node->prev->next = node->next;
421 : 68435502 : if (node->next != NULL)
422 : 65284679 : node->next->prev = node->prev;
423 : 68435502 : if (prev == NULL)
424 : 4337147 : new_node->first = node;
425 : : else
426 : 64098355 : prev->next = node;
427 : 68435502 : node->prev = prev;
428 : 68435502 : node->next = NULL;
429 : 68435502 : prev = node;
430 : : }
431 : 7510475 : add_new_allocno_hard_regs_node_to_forest (roots, new_node);
432 : : }
433 : 5467923 : hard_regs_node_vec.truncate (start);
434 : : }
435 : :
436 : : /* Add allocno hard registers nodes starting with the forest level
437 : : given by FIRST which contains biggest set inside SET. */
438 : : static void
439 : 63822671 : collect_allocno_hard_regs_cover (allocno_hard_regs_node_t first,
440 : : HARD_REG_SET set)
441 : : {
442 : 63822671 : allocno_hard_regs_node_t node;
443 : :
444 : 63822671 : ira_assert (first != NULL);
445 : 632594316 : for (node = first; node != NULL; node = node->next)
446 : 1137543290 : if (hard_reg_set_subset_p (node->hard_regs->set, set))
447 : 22832661 : hard_regs_node_vec.safe_push (node);
448 : 545938984 : else if (hard_reg_set_intersect_p (set, node->hard_regs->set))
449 : 42673653 : collect_allocno_hard_regs_cover (node->first, set);
450 : 63822671 : }
451 : :
452 : : /* Set up field parent as PARENT in all allocno hard registers nodes
453 : : in forest given by FIRST. */
454 : : static void
455 : 58755286 : setup_allocno_hard_regs_nodes_parent (allocno_hard_regs_node_t first,
456 : : allocno_hard_regs_node_t parent)
457 : : {
458 : 58755286 : allocno_hard_regs_node_t node;
459 : :
460 : 116346753 : for (node = first; node != NULL; node = node->next)
461 : : {
462 : 57591467 : node->parent = parent;
463 : 57591467 : setup_allocno_hard_regs_nodes_parent (node->first, node);
464 : : }
465 : 58755286 : }
466 : :
467 : : /* Return allocno hard registers node which is a first common ancestor
468 : : node of FIRST and SECOND in the forest. */
469 : : static allocno_hard_regs_node_t
470 : 1683643 : first_common_ancestor_node (allocno_hard_regs_node_t first,
471 : : allocno_hard_regs_node_t second)
472 : : {
473 : 1683643 : allocno_hard_regs_node_t node;
474 : :
475 : 1683643 : node_check_tick++;
476 : 9223053 : for (node = first; node != NULL; node = node->parent)
477 : 7539410 : node->check = node_check_tick;
478 : 2721238 : for (node = second; node != NULL; node = node->parent)
479 : 4404881 : if (node->check == node_check_tick)
480 : 1683643 : return node;
481 : : return first_common_ancestor_node (second, first);
482 : : }
483 : :
484 : : /* Print hard reg set SET to F. */
485 : : static void
486 : 1526 : print_hard_reg_set (FILE *f, HARD_REG_SET set, bool new_line_p)
487 : : {
488 : 1526 : int i, start, end;
489 : :
490 : 141918 : for (start = end = -1, i = 0; i < FIRST_PSEUDO_REGISTER; i++)
491 : : {
492 : 140392 : bool reg_included = TEST_HARD_REG_BIT (set, i);
493 : :
494 : 140392 : if (reg_included)
495 : : {
496 : 51546 : if (start == -1)
497 : 3638 : start = i;
498 : : end = i;
499 : : }
500 : 140392 : if (start >= 0 && (!reg_included || i == FIRST_PSEUDO_REGISTER - 1))
501 : : {
502 : 3638 : if (start == end)
503 : 379 : fprintf (f, " %d", start);
504 : 3259 : else if (start == end + 1)
505 : 0 : fprintf (f, " %d %d", start, end);
506 : : else
507 : 3259 : fprintf (f, " %d-%d", start, end);
508 : : start = -1;
509 : : }
510 : : }
511 : 1526 : if (new_line_p)
512 : 0 : fprintf (f, "\n");
513 : 1526 : }
514 : :
515 : : /* Dump a hard reg set SET to stderr. */
516 : : DEBUG_FUNCTION void
517 : 0 : debug_hard_reg_set (HARD_REG_SET set)
518 : : {
519 : 0 : print_hard_reg_set (stderr, set, true);
520 : 0 : }
521 : :
522 : : /* Print allocno hard register subforest given by ROOTS and its LEVEL
523 : : to F. */
524 : : static void
525 : 209 : print_hard_regs_subforest (FILE *f, allocno_hard_regs_node_t roots,
526 : : int level)
527 : : {
528 : 209 : int i;
529 : 209 : allocno_hard_regs_node_t node;
530 : :
531 : 379 : for (node = roots; node != NULL; node = node->next)
532 : : {
533 : 170 : fprintf (f, " ");
534 : 1518 : for (i = 0; i < level * 2; i++)
535 : 1178 : fprintf (f, " ");
536 : 170 : fprintf (f, "%d:(", node->preorder_num);
537 : 170 : print_hard_reg_set (f, node->hard_regs->set, false);
538 : 170 : fprintf (f, ")@%" PRId64"\n", node->hard_regs->cost);
539 : 170 : print_hard_regs_subforest (f, node->first, level + 1);
540 : : }
541 : 209 : }
542 : :
543 : : /* Print the allocno hard register forest to F. */
544 : : static void
545 : 39 : print_hard_regs_forest (FILE *f)
546 : : {
547 : 39 : fprintf (f, " Hard reg set forest:\n");
548 : 39 : print_hard_regs_subforest (f, hard_regs_roots, 1);
549 : 39 : }
550 : :
551 : : /* Print the allocno hard register forest to stderr. */
552 : : void
553 : 0 : ira_debug_hard_regs_forest (void)
554 : : {
555 : 0 : print_hard_regs_forest (stderr);
556 : 0 : }
557 : :
558 : : /* Remove unused allocno hard registers nodes from forest given by its
559 : : *ROOTS. */
560 : : static void
561 : 5318230 : remove_unused_allocno_hard_regs_nodes (allocno_hard_regs_node_t *roots)
562 : : {
563 : 5318230 : allocno_hard_regs_node_t node, prev, next, last;
564 : :
565 : 62909697 : for (prev = NULL, node = *roots; node != NULL; node = next)
566 : : {
567 : 57591467 : next = node->next;
568 : 57591467 : if (node->used_p)
569 : : {
570 : 4154411 : remove_unused_allocno_hard_regs_nodes (&node->first);
571 : 4154411 : prev = node;
572 : : }
573 : : else
574 : : {
575 : 53437056 : for (last = node->first;
576 : 54743892 : last != NULL && last->next != NULL;
577 : : last = last->next)
578 : : ;
579 : 53437056 : if (last != NULL)
580 : : {
581 : 351989 : if (prev == NULL)
582 : 338136 : *roots = node->first;
583 : : else
584 : 13853 : prev->next = node->first;
585 : 351989 : if (next != NULL)
586 : 340540 : next->prev = last;
587 : 351989 : last->next = next;
588 : 351989 : next = node->first;
589 : : }
590 : : else
591 : : {
592 : 53085067 : if (prev == NULL)
593 : 22491112 : *roots = next;
594 : : else
595 : 30593955 : prev->next = next;
596 : 53085067 : if (next != NULL)
597 : 49340239 : next->prev = prev;
598 : : }
599 : 53437056 : ira_free (node);
600 : : }
601 : : }
602 : 5318230 : }
603 : :
604 : : /* Set up fields preorder_num starting with START_NUM in all allocno
605 : : hard registers nodes in forest given by FIRST. Return biggest set
606 : : PREORDER_NUM increased by 1. */
607 : : static int
608 : 5318230 : enumerate_allocno_hard_regs_nodes (allocno_hard_regs_node_t first,
609 : : allocno_hard_regs_node_t parent,
610 : : int start_num)
611 : : {
612 : 5318230 : allocno_hard_regs_node_t node;
613 : :
614 : 9472641 : for (node = first; node != NULL; node = node->next)
615 : : {
616 : 4154411 : node->preorder_num = start_num++;
617 : 4154411 : node->parent = parent;
618 : 4154411 : start_num = enumerate_allocno_hard_regs_nodes (node->first, node,
619 : : start_num);
620 : : }
621 : 5318230 : return start_num;
622 : : }
623 : :
624 : : /* Number of allocno hard registers nodes in the forest. */
625 : : static int allocno_hard_regs_nodes_num;
626 : :
627 : : /* Table preorder number of allocno hard registers node in the forest
628 : : -> the allocno hard registers node. */
629 : : static allocno_hard_regs_node_t *allocno_hard_regs_nodes;
630 : :
631 : : /* See below. */
632 : : typedef struct allocno_hard_regs_subnode *allocno_hard_regs_subnode_t;
633 : :
634 : : /* The structure is used to describes all subnodes (not only immediate
635 : : ones) in the mentioned above tree for given allocno hard register
636 : : node. The usage of such data accelerates calculation of
637 : : colorability of given allocno. */
638 : : struct allocno_hard_regs_subnode
639 : : {
640 : : /* The conflict size of conflicting allocnos whose hard register
641 : : sets are equal sets (plus supersets if given node is given
642 : : allocno hard registers node) of one in the given node. */
643 : : int left_conflict_size;
644 : : /* The summary conflict size of conflicting allocnos whose hard
645 : : register sets are strict subsets of one in the given node.
646 : : Overall conflict size is
647 : : left_conflict_subnodes_size
648 : : + MIN (max_node_impact - left_conflict_subnodes_size,
649 : : left_conflict_size)
650 : : */
651 : : short left_conflict_subnodes_size;
652 : : short max_node_impact;
653 : : };
654 : :
655 : : /* Container for hard regs subnodes of all allocnos. */
656 : : static allocno_hard_regs_subnode_t allocno_hard_regs_subnodes;
657 : :
658 : : /* Table (preorder number of allocno hard registers node in the
659 : : forest, preorder number of allocno hard registers subnode) -> index
660 : : of the subnode relative to the node. -1 if it is not a
661 : : subnode. */
662 : : static int *allocno_hard_regs_subnode_index;
663 : :
664 : : /* Setup arrays ALLOCNO_HARD_REGS_NODES and
665 : : ALLOCNO_HARD_REGS_SUBNODE_INDEX. */
666 : : static void
667 : 5318230 : setup_allocno_hard_regs_subnode_index (allocno_hard_regs_node_t first)
668 : : {
669 : 5318230 : allocno_hard_regs_node_t node, parent;
670 : 5318230 : int index;
671 : :
672 : 9472641 : for (node = first; node != NULL; node = node->next)
673 : : {
674 : 4154411 : allocno_hard_regs_nodes[node->preorder_num] = node;
675 : 14872101 : for (parent = node; parent != NULL; parent = parent->parent)
676 : : {
677 : 10717690 : index = parent->preorder_num * allocno_hard_regs_nodes_num;
678 : 10717690 : allocno_hard_regs_subnode_index[index + node->preorder_num]
679 : 10717690 : = node->preorder_num - parent->preorder_num;
680 : : }
681 : 4154411 : setup_allocno_hard_regs_subnode_index (node->first);
682 : : }
683 : 5318230 : }
684 : :
685 : : /* Count all allocno hard registers nodes in tree ROOT. */
686 : : static int
687 : 63419723 : get_allocno_hard_regs_subnodes_num (allocno_hard_regs_node_t root)
688 : : {
689 : 63419723 : int len = 1;
690 : :
691 : 105690428 : for (root = root->first; root != NULL; root = root->next)
692 : 42270705 : len += get_allocno_hard_regs_subnodes_num (root);
693 : 63419723 : return len;
694 : : }
695 : :
696 : : /* Build the forest of allocno hard registers nodes and assign each
697 : : allocno a node from the forest. */
698 : : static void
699 : 1163819 : form_allocno_hard_regs_nodes_forest (void)
700 : : {
701 : 1163819 : unsigned int i, j, size, len;
702 : 1163819 : int start;
703 : 1163819 : ira_allocno_t a;
704 : 1163819 : allocno_hard_regs_t hv;
705 : 1163819 : bitmap_iterator bi;
706 : 1163819 : HARD_REG_SET temp;
707 : 1163819 : allocno_hard_regs_node_t node, allocno_hard_regs_node;
708 : 1163819 : allocno_color_data_t allocno_data;
709 : :
710 : 1163819 : node_check_tick = 0;
711 : 1163819 : init_allocno_hard_regs ();
712 : 1163819 : hard_regs_roots = NULL;
713 : 1163819 : hard_regs_node_vec.create (100);
714 : 108235167 : for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
715 : 107071348 : if (! TEST_HARD_REG_BIT (ira_no_alloc_regs, i))
716 : : {
717 : 53254320 : CLEAR_HARD_REG_SET (temp);
718 : 53254320 : SET_HARD_REG_BIT (temp, i);
719 : 53254320 : hv = add_allocno_hard_regs (temp, 0);
720 : 53254320 : node = create_new_allocno_hard_regs_node (hv);
721 : 105344821 : add_new_allocno_hard_regs_node_to_forest (&hard_regs_roots, node);
722 : : }
723 : 1163819 : start = allocno_hard_regs_vec.length ();
724 : 24049026 : EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
725 : : {
726 : 22885207 : a = ira_allocnos[i];
727 : 22885207 : allocno_data = ALLOCNO_COLOR_DATA (a);
728 : :
729 : 45770414 : if (hard_reg_set_empty_p (allocno_data->profitable_hard_regs))
730 : 1736189 : continue;
731 : 21149018 : hv = (add_allocno_hard_regs
732 : 21149018 : (allocno_data->profitable_hard_regs,
733 : 21149018 : ALLOCNO_MEMORY_COST (a) - ALLOCNO_CLASS_COST (a)));
734 : : }
735 : 1163819 : temp = ~ira_no_alloc_regs;
736 : 1163819 : add_allocno_hard_regs (temp, 0);
737 : 3491457 : qsort (allocno_hard_regs_vec.address () + start,
738 : : allocno_hard_regs_vec.length () - start,
739 : : sizeof (allocno_hard_regs_t), allocno_hard_regs_compare);
740 : 1163819 : for (i = start;
741 : 7531101 : allocno_hard_regs_vec.iterate (i, &hv);
742 : : i++)
743 : : {
744 : 6367282 : add_allocno_hard_regs_to_forest (&hard_regs_roots, hv);
745 : 6367282 : ira_assert (hard_regs_node_vec.length () == 0);
746 : : }
747 : : /* We need to set up parent fields for right work of
748 : : first_common_ancestor_node. */
749 : 1163819 : setup_allocno_hard_regs_nodes_parent (hard_regs_roots, NULL);
750 : 24049026 : EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
751 : : {
752 : 22885207 : a = ira_allocnos[i];
753 : 22885207 : allocno_data = ALLOCNO_COLOR_DATA (a);
754 : 45770414 : if (hard_reg_set_empty_p (allocno_data->profitable_hard_regs))
755 : 1736189 : continue;
756 : 21149018 : hard_regs_node_vec.truncate (0);
757 : 21149018 : collect_allocno_hard_regs_cover (hard_regs_roots,
758 : : allocno_data->profitable_hard_regs);
759 : 21149018 : allocno_hard_regs_node = NULL;
760 : 65130697 : for (j = 0; hard_regs_node_vec.iterate (j, &node); j++)
761 : 22832661 : allocno_hard_regs_node
762 : 22832661 : = (j == 0
763 : 22832661 : ? node
764 : 1683643 : : first_common_ancestor_node (node, allocno_hard_regs_node));
765 : : /* That is a temporary storage. */
766 : 21149018 : allocno_hard_regs_node->used_p = true;
767 : 21149018 : allocno_data->hard_regs_node = allocno_hard_regs_node;
768 : : }
769 : 1163819 : ira_assert (hard_regs_roots->next == NULL);
770 : 1163819 : hard_regs_roots->used_p = true;
771 : 1163819 : remove_unused_allocno_hard_regs_nodes (&hard_regs_roots);
772 : 1163819 : allocno_hard_regs_nodes_num
773 : 1163819 : = enumerate_allocno_hard_regs_nodes (hard_regs_roots, NULL, 0);
774 : 1163819 : allocno_hard_regs_nodes
775 : 1163819 : = ((allocno_hard_regs_node_t *)
776 : 1163819 : ira_allocate (allocno_hard_regs_nodes_num
777 : : * sizeof (allocno_hard_regs_node_t)));
778 : 1163819 : size = allocno_hard_regs_nodes_num * allocno_hard_regs_nodes_num;
779 : 1163819 : allocno_hard_regs_subnode_index
780 : 1163819 : = (int *) ira_allocate (size * sizeof (int));
781 : 21269608 : for (i = 0; i < size; i++)
782 : 20105789 : allocno_hard_regs_subnode_index[i] = -1;
783 : 1163819 : setup_allocno_hard_regs_subnode_index (hard_regs_roots);
784 : 1163819 : start = 0;
785 : 24049026 : EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
786 : : {
787 : 22885207 : a = ira_allocnos[i];
788 : 22885207 : allocno_data = ALLOCNO_COLOR_DATA (a);
789 : 45770414 : if (hard_reg_set_empty_p (allocno_data->profitable_hard_regs))
790 : 1736189 : continue;
791 : 21149018 : len = get_allocno_hard_regs_subnodes_num (allocno_data->hard_regs_node);
792 : 21149018 : allocno_data->hard_regs_subnodes_start = start;
793 : 21149018 : allocno_data->hard_regs_subnodes_num = len;
794 : 21149018 : start += len;
795 : : }
796 : 1163819 : allocno_hard_regs_subnodes
797 : 1163819 : = ((allocno_hard_regs_subnode_t)
798 : 1163819 : ira_allocate (sizeof (struct allocno_hard_regs_subnode) * start));
799 : 1163819 : hard_regs_node_vec.release ();
800 : 1163819 : }
801 : :
802 : : /* Free tree of allocno hard registers nodes given by its ROOT. */
803 : : static void
804 : 4154411 : finish_allocno_hard_regs_nodes_tree (allocno_hard_regs_node_t root)
805 : : {
806 : 4154411 : allocno_hard_regs_node_t child, next;
807 : :
808 : 7145003 : for (child = root->first; child != NULL; child = next)
809 : : {
810 : 2990592 : next = child->next;
811 : 2990592 : finish_allocno_hard_regs_nodes_tree (child);
812 : : }
813 : 4154411 : ira_free (root);
814 : 4154411 : }
815 : :
816 : : /* Finish work with the forest of allocno hard registers nodes. */
817 : : static void
818 : 1163819 : finish_allocno_hard_regs_nodes_forest (void)
819 : : {
820 : 1163819 : allocno_hard_regs_node_t node, next;
821 : :
822 : 1163819 : ira_free (allocno_hard_regs_subnodes);
823 : 2327638 : for (node = hard_regs_roots; node != NULL; node = next)
824 : : {
825 : 1163819 : next = node->next;
826 : 1163819 : finish_allocno_hard_regs_nodes_tree (node);
827 : : }
828 : 1163819 : ira_free (allocno_hard_regs_nodes);
829 : 1163819 : ira_free (allocno_hard_regs_subnode_index);
830 : 1163819 : finish_allocno_hard_regs ();
831 : 1163819 : }
832 : :
833 : : /* Set up left conflict sizes and left conflict subnodes sizes of hard
834 : : registers subnodes of allocno A. Return TRUE if allocno A is
835 : : trivially colorable. */
836 : : static bool
837 : 21149018 : setup_left_conflict_sizes_p (ira_allocno_t a)
838 : : {
839 : 21149018 : int i, k, nobj, start;
840 : 21149018 : int conflict_size, left_conflict_subnodes_size, node_preorder_num;
841 : 21149018 : allocno_color_data_t data;
842 : 21149018 : HARD_REG_SET profitable_hard_regs;
843 : 21149018 : allocno_hard_regs_subnode_t subnodes;
844 : 21149018 : allocno_hard_regs_node_t node;
845 : 21149018 : HARD_REG_SET node_set;
846 : :
847 : 21149018 : nobj = ALLOCNO_NUM_OBJECTS (a);
848 : 21149018 : data = ALLOCNO_COLOR_DATA (a);
849 : 21149018 : subnodes = allocno_hard_regs_subnodes + data->hard_regs_subnodes_start;
850 : 21149018 : profitable_hard_regs = data->profitable_hard_regs;
851 : 21149018 : node = data->hard_regs_node;
852 : 21149018 : node_preorder_num = node->preorder_num;
853 : 21149018 : node_set = node->hard_regs->set;
854 : 21149018 : node_check_tick++;
855 : 42726501 : for (k = 0; k < nobj; k++)
856 : : {
857 : 21577483 : ira_object_t obj = ALLOCNO_OBJECT (a, k);
858 : 21577483 : ira_object_t conflict_obj;
859 : 21577483 : ira_object_conflict_iterator oci;
860 : :
861 : 465453713 : FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
862 : : {
863 : 443876230 : int size;
864 : 443876230 : ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
865 : 443876230 : allocno_hard_regs_node_t conflict_node, temp_node;
866 : 443876230 : HARD_REG_SET conflict_node_set;
867 : 443876230 : allocno_color_data_t conflict_data;
868 : :
869 : 443876230 : conflict_data = ALLOCNO_COLOR_DATA (conflict_a);
870 : 496788562 : if (! ALLOCNO_COLOR_DATA (conflict_a)->in_graph_p
871 : 839984514 : || ! hard_reg_set_intersect_p (profitable_hard_regs,
872 : : conflict_data
873 : : ->profitable_hard_regs))
874 : 52912332 : continue;
875 : 390963898 : conflict_node = conflict_data->hard_regs_node;
876 : 390963898 : conflict_node_set = conflict_node->hard_regs->set;
877 : 781927796 : if (hard_reg_set_subset_p (node_set, conflict_node_set))
878 : : temp_node = node;
879 : : else
880 : : {
881 : 96494724 : ira_assert (hard_reg_set_subset_p (conflict_node_set, node_set));
882 : : temp_node = conflict_node;
883 : : }
884 : 390963898 : if (temp_node->check != node_check_tick)
885 : : {
886 : 36549538 : temp_node->check = node_check_tick;
887 : 36549538 : temp_node->conflict_size = 0;
888 : : }
889 : 390963898 : size = (ira_reg_class_max_nregs
890 : 390963898 : [ALLOCNO_CLASS (conflict_a)][ALLOCNO_MODE (conflict_a)]);
891 : 390963898 : if (ALLOCNO_NUM_OBJECTS (conflict_a) > 1)
892 : : /* We will deal with the subwords individually. */
893 : 19835316 : size = 1;
894 : 390963898 : temp_node->conflict_size += size;
895 : : }
896 : : }
897 : 84568741 : for (i = 0; i < data->hard_regs_subnodes_num; i++)
898 : : {
899 : 63419723 : allocno_hard_regs_node_t temp_node;
900 : :
901 : 63419723 : temp_node = allocno_hard_regs_nodes[i + node_preorder_num];
902 : 63419723 : ira_assert (temp_node->preorder_num == i + node_preorder_num);
903 : 126839446 : subnodes[i].left_conflict_size = (temp_node->check != node_check_tick
904 : 63419723 : ? 0 : temp_node->conflict_size);
905 : 126839446 : if (hard_reg_set_subset_p (temp_node->hard_regs->set,
906 : : profitable_hard_regs))
907 : 60122435 : subnodes[i].max_node_impact = temp_node->hard_regs_num;
908 : : else
909 : : {
910 : 3297288 : HARD_REG_SET temp_set;
911 : 3297288 : int j, n, hard_regno;
912 : 3297288 : enum reg_class aclass;
913 : :
914 : 3297288 : temp_set = temp_node->hard_regs->set & profitable_hard_regs;
915 : 3297288 : aclass = ALLOCNO_CLASS (a);
916 : 56449194 : for (n = 0, j = ira_class_hard_regs_num[aclass] - 1; j >= 0; j--)
917 : : {
918 : 53151906 : hard_regno = ira_class_hard_regs[aclass][j];
919 : 53151906 : if (TEST_HARD_REG_BIT (temp_set, hard_regno))
920 : 32720006 : n++;
921 : : }
922 : 3297288 : subnodes[i].max_node_impact = n;
923 : : }
924 : 63419723 : subnodes[i].left_conflict_subnodes_size = 0;
925 : : }
926 : 21149018 : start = node_preorder_num * allocno_hard_regs_nodes_num;
927 : 63419723 : for (i = data->hard_regs_subnodes_num - 1; i > 0; i--)
928 : : {
929 : 42270705 : int size, parent_i;
930 : 42270705 : allocno_hard_regs_node_t parent;
931 : :
932 : 42270705 : size = (subnodes[i].left_conflict_subnodes_size
933 : 42270705 : + MIN (subnodes[i].max_node_impact
934 : : - subnodes[i].left_conflict_subnodes_size,
935 : : subnodes[i].left_conflict_size));
936 : 42270705 : parent = allocno_hard_regs_nodes[i + node_preorder_num]->parent;
937 : 42270705 : gcc_checking_assert(parent);
938 : 42270705 : parent_i
939 : 42270705 : = allocno_hard_regs_subnode_index[start + parent->preorder_num];
940 : 42270705 : gcc_checking_assert(parent_i >= 0);
941 : 42270705 : subnodes[parent_i].left_conflict_subnodes_size += size;
942 : : }
943 : 21149018 : left_conflict_subnodes_size = subnodes[0].left_conflict_subnodes_size;
944 : 21149018 : conflict_size
945 : 21149018 : = (left_conflict_subnodes_size
946 : 21149018 : + MIN (subnodes[0].max_node_impact - left_conflict_subnodes_size,
947 : : subnodes[0].left_conflict_size));
948 : 21149018 : conflict_size += ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)];
949 : 21149018 : data->colorable_p = conflict_size <= data->available_regs_num;
950 : 21149018 : return data->colorable_p;
951 : : }
952 : :
953 : : /* Update left conflict sizes of hard registers subnodes of allocno A
954 : : after removing allocno REMOVED_A with SIZE from the conflict graph.
955 : : Return TRUE if A is trivially colorable. */
956 : : static bool
957 : 168260063 : update_left_conflict_sizes_p (ira_allocno_t a,
958 : : ira_allocno_t removed_a, int size)
959 : : {
960 : 168260063 : int i, conflict_size, before_conflict_size, diff, start;
961 : 168260063 : int node_preorder_num, parent_i;
962 : 168260063 : allocno_hard_regs_node_t node, removed_node, parent;
963 : 168260063 : allocno_hard_regs_subnode_t subnodes;
964 : 168260063 : allocno_color_data_t data = ALLOCNO_COLOR_DATA (a);
965 : :
966 : 168260063 : ira_assert (! data->colorable_p);
967 : 168260063 : node = data->hard_regs_node;
968 : 168260063 : node_preorder_num = node->preorder_num;
969 : 168260063 : removed_node = ALLOCNO_COLOR_DATA (removed_a)->hard_regs_node;
970 : 404462607 : ira_assert (hard_reg_set_subset_p (removed_node->hard_regs->set,
971 : : node->hard_regs->set)
972 : : || hard_reg_set_subset_p (node->hard_regs->set,
973 : : removed_node->hard_regs->set));
974 : 168260063 : start = node_preorder_num * allocno_hard_regs_nodes_num;
975 : 168260063 : i = allocno_hard_regs_subnode_index[start + removed_node->preorder_num];
976 : 168260063 : if (i < 0)
977 : : i = 0;
978 : 168260063 : subnodes = allocno_hard_regs_subnodes + data->hard_regs_subnodes_start;
979 : 168260063 : before_conflict_size
980 : 168260063 : = (subnodes[i].left_conflict_subnodes_size
981 : 168260063 : + MIN (subnodes[i].max_node_impact
982 : : - subnodes[i].left_conflict_subnodes_size,
983 : : subnodes[i].left_conflict_size));
984 : 168260063 : subnodes[i].left_conflict_size -= size;
985 : 189772251 : for (;;)
986 : : {
987 : 179016157 : conflict_size
988 : 179016157 : = (subnodes[i].left_conflict_subnodes_size
989 : 179016157 : + MIN (subnodes[i].max_node_impact
990 : : - subnodes[i].left_conflict_subnodes_size,
991 : : subnodes[i].left_conflict_size));
992 : 179016157 : if ((diff = before_conflict_size - conflict_size) == 0)
993 : : break;
994 : 15876231 : ira_assert (conflict_size < before_conflict_size);
995 : 15876231 : parent = allocno_hard_regs_nodes[i + node_preorder_num]->parent;
996 : 15876231 : if (parent == NULL)
997 : : break;
998 : 15873829 : parent_i
999 : 15873829 : = allocno_hard_regs_subnode_index[start + parent->preorder_num];
1000 : 15873829 : if (parent_i < 0)
1001 : : break;
1002 : 10756094 : i = parent_i;
1003 : 10756094 : before_conflict_size
1004 : 10756094 : = (subnodes[i].left_conflict_subnodes_size
1005 : 10756094 : + MIN (subnodes[i].max_node_impact
1006 : : - subnodes[i].left_conflict_subnodes_size,
1007 : : subnodes[i].left_conflict_size));
1008 : 10756094 : subnodes[i].left_conflict_subnodes_size -= diff;
1009 : : }
1010 : 168260063 : if (i != 0
1011 : 153310906 : || (conflict_size
1012 : 153310906 : + ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]
1013 : 153310906 : > data->available_regs_num))
1014 : : return false;
1015 : 4999500 : data->colorable_p = true;
1016 : 4999500 : return true;
1017 : : }
1018 : :
1019 : : /* Return true if allocno A has empty profitable hard regs. */
1020 : : static bool
1021 : 67740490 : empty_profitable_hard_regs (ira_allocno_t a)
1022 : : {
1023 : 67740490 : allocno_color_data_t data = ALLOCNO_COLOR_DATA (a);
1024 : :
1025 : 44855515 : return hard_reg_set_empty_p (data->profitable_hard_regs);
1026 : : }
1027 : :
1028 : : /* Set up profitable hard registers for each allocno being
1029 : : colored. */
1030 : : static void
1031 : 1163854 : setup_profitable_hard_regs (void)
1032 : : {
1033 : 1163854 : unsigned int i;
1034 : 1163854 : int j, k, nobj, hard_regno, nregs, class_size;
1035 : 1163854 : ira_allocno_t a;
1036 : 1163854 : bitmap_iterator bi;
1037 : 1163854 : enum reg_class aclass;
1038 : 1163854 : machine_mode mode;
1039 : 1163854 : allocno_color_data_t data;
1040 : :
1041 : : /* Initial set up from allocno classes and explicitly conflicting
1042 : : hard regs. */
1043 : 24050157 : EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
1044 : : {
1045 : 22886303 : a = ira_allocnos[i];
1046 : 22886303 : if ((aclass = ALLOCNO_CLASS (a)) == NO_REGS)
1047 : 458009 : continue;
1048 : 22428294 : data = ALLOCNO_COLOR_DATA (a);
1049 : 22428294 : if (ALLOCNO_UPDATED_HARD_REG_COSTS (a) == NULL
1050 : 21307097 : && ALLOCNO_CLASS_COST (a) > ALLOCNO_MEMORY_COST (a)
1051 : : /* Do not empty profitable regs for static chain pointer
1052 : : pseudo when non-local goto is used. */
1053 : 22518850 : && ! non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a)))
1054 : 22886303 : CLEAR_HARD_REG_SET (data->profitable_hard_regs);
1055 : : else
1056 : : {
1057 : 22337738 : mode = ALLOCNO_MODE (a);
1058 : 22337738 : data->profitable_hard_regs
1059 : 22337738 : = ira_useful_class_mode_regs[aclass][mode];
1060 : 22337738 : nobj = ALLOCNO_NUM_OBJECTS (a);
1061 : 45133322 : for (k = 0; k < nobj; k++)
1062 : : {
1063 : 22795584 : ira_object_t obj = ALLOCNO_OBJECT (a, k);
1064 : :
1065 : 22795584 : data->profitable_hard_regs
1066 : 45591168 : &= ~OBJECT_TOTAL_CONFLICT_HARD_REGS (obj);
1067 : : }
1068 : : }
1069 : : }
1070 : : /* Exclude hard regs already assigned for conflicting objects. */
1071 : 24955815 : EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, i, bi)
1072 : : {
1073 : 23791961 : a = ira_allocnos[i];
1074 : 47033251 : if ((aclass = ALLOCNO_CLASS (a)) == NO_REGS
1075 : 23162056 : || ! ALLOCNO_ASSIGNED_P (a)
1076 : 24525723 : || (hard_regno = ALLOCNO_HARD_REGNO (a)) < 0)
1077 : 23241290 : continue;
1078 : 550671 : mode = ALLOCNO_MODE (a);
1079 : 550671 : nregs = hard_regno_nregs (hard_regno, mode);
1080 : 550671 : nobj = ALLOCNO_NUM_OBJECTS (a);
1081 : 1109495 : for (k = 0; k < nobj; k++)
1082 : : {
1083 : 558824 : ira_object_t obj = ALLOCNO_OBJECT (a, k);
1084 : 558824 : ira_object_t conflict_obj;
1085 : 558824 : ira_object_conflict_iterator oci;
1086 : :
1087 : 6477151 : FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
1088 : : {
1089 : 5918327 : ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
1090 : :
1091 : : /* We can process the conflict allocno repeatedly with
1092 : : the same result. */
1093 : 5918327 : if (nregs == nobj && nregs > 1)
1094 : : {
1095 : 394436 : int num = OBJECT_SUBWORD (conflict_obj);
1096 : :
1097 : 394436 : if (REG_WORDS_BIG_ENDIAN)
1098 : : CLEAR_HARD_REG_BIT
1099 : : (ALLOCNO_COLOR_DATA (conflict_a)->profitable_hard_regs,
1100 : : hard_regno + nobj - num - 1);
1101 : : else
1102 : 394436 : CLEAR_HARD_REG_BIT
1103 : 394436 : (ALLOCNO_COLOR_DATA (conflict_a)->profitable_hard_regs,
1104 : 394436 : hard_regno + num);
1105 : : }
1106 : : else
1107 : 5523891 : ALLOCNO_COLOR_DATA (conflict_a)->profitable_hard_regs
1108 : 11047782 : &= ~ira_reg_mode_hard_regset[hard_regno][mode];
1109 : : }
1110 : : }
1111 : : }
1112 : : /* Exclude too costly hard regs. */
1113 : 24050157 : EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
1114 : : {
1115 : 22886303 : int min_cost = INT_MAX;
1116 : 22886303 : int *costs;
1117 : :
1118 : 22886303 : a = ira_allocnos[i];
1119 : 23448699 : if ((aclass = ALLOCNO_CLASS (a)) == NO_REGS
1120 : 45314597 : || empty_profitable_hard_regs (a))
1121 : 562396 : continue;
1122 : 22323907 : data = ALLOCNO_COLOR_DATA (a);
1123 : 22323907 : if ((costs = ALLOCNO_UPDATED_HARD_REG_COSTS (a)) != NULL
1124 : 22323907 : || (costs = ALLOCNO_HARD_REG_COSTS (a)) != NULL)
1125 : : {
1126 : 9358560 : class_size = ira_class_hard_regs_num[aclass];
1127 : 153889677 : for (j = 0; j < class_size; j++)
1128 : : {
1129 : 144531117 : hard_regno = ira_class_hard_regs[aclass][j];
1130 : 144531117 : if (! TEST_HARD_REG_BIT (data->profitable_hard_regs,
1131 : : hard_regno))
1132 : 15171645 : continue;
1133 : 129359472 : if (ALLOCNO_UPDATED_MEMORY_COST (a) < costs[j]
1134 : : /* Do not remove HARD_REGNO for static chain pointer
1135 : : pseudo when non-local goto is used. */
1136 : 129359472 : && ! non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a)))
1137 : 10186542 : CLEAR_HARD_REG_BIT (data->profitable_hard_regs,
1138 : : hard_regno);
1139 : 119172930 : else if (min_cost > costs[j])
1140 : 144531117 : min_cost = costs[j];
1141 : : }
1142 : : }
1143 : 12965347 : else if (ALLOCNO_UPDATED_MEMORY_COST (a)
1144 : 12965347 : < ALLOCNO_UPDATED_CLASS_COST (a)
1145 : : /* Do not empty profitable regs for static chain
1146 : : pointer pseudo when non-local goto is used. */
1147 : 12965347 : && ! non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a)))
1148 : 22886303 : CLEAR_HARD_REG_SET (data->profitable_hard_regs);
1149 : 10161478 : if (ALLOCNO_UPDATED_CLASS_COST (a) > min_cost)
1150 : 53300 : ALLOCNO_UPDATED_CLASS_COST (a) = min_cost;
1151 : : }
1152 : 1163854 : }
1153 : :
1154 : :
1155 : :
1156 : : /* This page contains functions used to choose hard registers for
1157 : : allocnos. */
1158 : :
1159 : : /* Pool for update cost records. */
1160 : : static object_allocator<update_cost_record> update_cost_record_pool
1161 : : ("update cost records");
1162 : :
1163 : : /* Return new update cost record with given params. */
1164 : : static struct update_cost_record *
1165 : 7747943 : get_update_cost_record (int hard_regno, int divisor,
1166 : : struct update_cost_record *next)
1167 : : {
1168 : 7747943 : struct update_cost_record *record;
1169 : :
1170 : 0 : record = update_cost_record_pool.allocate ();
1171 : 7747943 : record->hard_regno = hard_regno;
1172 : 7747943 : record->divisor = divisor;
1173 : 7747943 : record->next = next;
1174 : 7747943 : return record;
1175 : : }
1176 : :
1177 : : /* Free memory for all records in LIST. */
1178 : : static void
1179 : 21544456 : free_update_cost_record_list (struct update_cost_record *list)
1180 : : {
1181 : 21544456 : struct update_cost_record *next;
1182 : :
1183 : 29292399 : while (list != NULL)
1184 : : {
1185 : 7747943 : next = list->next;
1186 : 7747943 : update_cost_record_pool.remove (list);
1187 : 7747943 : list = next;
1188 : : }
1189 : 21544456 : }
1190 : :
1191 : : /* Free memory allocated for all update cost records. */
1192 : : static void
1193 : 1003194 : finish_update_cost_records (void)
1194 : : {
1195 : 0 : update_cost_record_pool.release ();
1196 : 0 : }
1197 : :
1198 : : /* True if we have allocated memory, or intend to do so. */
1199 : : static bool allocated_memory_p;
1200 : :
1201 : : /* Array whose element value is TRUE if the corresponding hard
1202 : : register was already allocated for an allocno. */
1203 : : static bool allocated_hardreg_p[FIRST_PSEUDO_REGISTER];
1204 : :
1205 : : /* Which callee-saved hard registers we've decided to save. */
1206 : : static HARD_REG_SET allocated_callee_save_regs;
1207 : :
1208 : : /* Describes one element in a queue of allocnos whose costs need to be
1209 : : updated. Each allocno in the queue is known to have an allocno
1210 : : class. */
1211 : : struct update_cost_queue_elem
1212 : : {
1213 : : /* This element is in the queue iff CHECK == update_cost_check. */
1214 : : int check;
1215 : :
1216 : : /* COST_HOP_DIVISOR**N, where N is the length of the shortest path
1217 : : connecting this allocno to the one being allocated. */
1218 : : int divisor;
1219 : :
1220 : : /* Allocno from which we started chaining costs of connected
1221 : : allocnos. */
1222 : : ira_allocno_t start;
1223 : :
1224 : : /* Allocno from which we are chaining costs of connected allocnos.
1225 : : It is used not go back in graph of allocnos connected by
1226 : : copies. */
1227 : : ira_allocno_t from;
1228 : :
1229 : : /* The next allocno in the queue, or null if this is the last element. */
1230 : : ira_allocno_t next;
1231 : : };
1232 : :
1233 : : /* The first element in a queue of allocnos whose copy costs need to be
1234 : : updated. Null if the queue is empty. */
1235 : : static ira_allocno_t update_cost_queue;
1236 : :
1237 : : /* The last element in the queue described by update_cost_queue.
1238 : : Not valid if update_cost_queue is null. */
1239 : : static struct update_cost_queue_elem *update_cost_queue_tail;
1240 : :
1241 : : /* A pool of elements in the queue described by update_cost_queue.
1242 : : Elements are indexed by ALLOCNO_NUM. */
1243 : : static struct update_cost_queue_elem *update_cost_queue_elems;
1244 : :
1245 : : /* The current value of update_costs_from_copies call count. */
1246 : : static int update_cost_check;
1247 : :
1248 : : /* Allocate and initialize data necessary for function
1249 : : update_costs_from_copies. */
1250 : : static void
1251 : 1003194 : initiate_cost_update (void)
1252 : : {
1253 : 1003194 : size_t size;
1254 : :
1255 : 1003194 : size = ira_allocnos_num * sizeof (struct update_cost_queue_elem);
1256 : 1003194 : update_cost_queue_elems
1257 : 1003194 : = (struct update_cost_queue_elem *) ira_allocate (size);
1258 : 1003194 : memset (update_cost_queue_elems, 0, size);
1259 : 1003194 : update_cost_check = 0;
1260 : 1003194 : }
1261 : :
1262 : : /* Deallocate data used by function update_costs_from_copies. */
1263 : : static void
1264 : 1003194 : finish_cost_update (void)
1265 : : {
1266 : 1003194 : ira_free (update_cost_queue_elems);
1267 : 1003194 : finish_update_cost_records ();
1268 : 1003194 : }
1269 : :
1270 : : /* When we traverse allocnos to update hard register costs, the cost
1271 : : divisor will be multiplied by the following macro value for each
1272 : : hop from given allocno to directly connected allocnos. */
1273 : : #define COST_HOP_DIVISOR 4
1274 : :
1275 : : /* Start a new cost-updating pass. */
1276 : : static void
1277 : 101205340 : start_update_cost (void)
1278 : : {
1279 : 101205340 : update_cost_check++;
1280 : 101205340 : update_cost_queue = NULL;
1281 : 21544456 : }
1282 : :
1283 : : /* Add (ALLOCNO, START, FROM, DIVISOR) to the end of update_cost_queue, unless
1284 : : ALLOCNO is already in the queue, or has NO_REGS class. */
1285 : : static inline void
1286 : 178730596 : queue_update_cost (ira_allocno_t allocno, ira_allocno_t start,
1287 : : ira_allocno_t from, int divisor)
1288 : : {
1289 : 178730596 : struct update_cost_queue_elem *elem;
1290 : :
1291 : 178730596 : elem = &update_cost_queue_elems[ALLOCNO_NUM (allocno)];
1292 : 178730596 : if (elem->check != update_cost_check
1293 : 132600527 : && ALLOCNO_CLASS (allocno) != NO_REGS)
1294 : : {
1295 : 132600527 : elem->check = update_cost_check;
1296 : 132600527 : elem->start = start;
1297 : 132600527 : elem->from = from;
1298 : 132600527 : elem->divisor = divisor;
1299 : 132600527 : elem->next = NULL;
1300 : 132600527 : if (update_cost_queue == NULL)
1301 : 46695378 : update_cost_queue = allocno;
1302 : : else
1303 : 85905149 : update_cost_queue_tail->next = allocno;
1304 : 132600527 : update_cost_queue_tail = elem;
1305 : : }
1306 : 178730596 : }
1307 : :
1308 : : /* Try to remove the first element from update_cost_queue. Return
1309 : : false if the queue was empty, otherwise make (*ALLOCNO, *START,
1310 : : *FROM, *DIVISOR) describe the removed element. */
1311 : : static inline bool
1312 : 197055309 : get_next_update_cost (ira_allocno_t *allocno, ira_allocno_t *start,
1313 : : ira_allocno_t *from, int *divisor)
1314 : : {
1315 : 197055309 : struct update_cost_queue_elem *elem;
1316 : :
1317 : 197055309 : if (update_cost_queue == NULL)
1318 : : return false;
1319 : :
1320 : 123905897 : *allocno = update_cost_queue;
1321 : 123905897 : elem = &update_cost_queue_elems[ALLOCNO_NUM (*allocno)];
1322 : 123905897 : *start = elem->start;
1323 : 123905897 : *from = elem->from;
1324 : 123905897 : *divisor = elem->divisor;
1325 : 123905897 : update_cost_queue = elem->next;
1326 : 123905897 : return true;
1327 : : }
1328 : :
1329 : : /* Increase costs of HARD_REGNO by UPDATE_COST and conflict cost by
1330 : : UPDATE_CONFLICT_COST for ALLOCNO. Return true if we really
1331 : : modified the cost. */
1332 : : static bool
1333 : 11864542 : update_allocno_cost (ira_allocno_t allocno, int hard_regno,
1334 : : int update_cost, int update_conflict_cost)
1335 : : {
1336 : 11864542 : int i;
1337 : 11864542 : enum reg_class aclass = ALLOCNO_CLASS (allocno);
1338 : :
1339 : 11864542 : i = ira_class_hard_reg_index[aclass][hard_regno];
1340 : 11864542 : if (i < 0)
1341 : : return false;
1342 : 11864542 : ira_allocate_and_set_or_copy_costs
1343 : 11864542 : (&ALLOCNO_UPDATED_HARD_REG_COSTS (allocno), aclass,
1344 : : ALLOCNO_UPDATED_CLASS_COST (allocno),
1345 : : ALLOCNO_HARD_REG_COSTS (allocno));
1346 : 11864542 : ira_allocate_and_set_or_copy_costs
1347 : 11864542 : (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (allocno),
1348 : : aclass, 0, ALLOCNO_CONFLICT_HARD_REG_COSTS (allocno));
1349 : 11864542 : ALLOCNO_UPDATED_HARD_REG_COSTS (allocno)[i] += update_cost;
1350 : 11864542 : ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (allocno)[i] += update_conflict_cost;
1351 : 11864542 : return true;
1352 : : }
1353 : :
1354 : : /* Return TRUE if the object OBJ conflicts with the allocno A. */
1355 : : static bool
1356 : 70365532 : object_conflicts_with_allocno_p (ira_object_t obj, ira_allocno_t a)
1357 : : {
1358 : 70365532 : if (!OBJECT_CONFLICT_VEC_P (obj))
1359 : 107307596 : for (int word = 0; word < ALLOCNO_NUM_OBJECTS (a); word++)
1360 : : {
1361 : 54766004 : ira_object_t another_obj = ALLOCNO_OBJECT (a, word);
1362 : 54766004 : if (OBJECT_CONFLICT_ID (another_obj) >= OBJECT_MIN (obj)
1363 : 52492843 : && OBJECT_CONFLICT_ID (another_obj) <= OBJECT_MAX (obj)
1364 : 89772900 : && TEST_MINMAX_SET_BIT (OBJECT_CONFLICT_BITVEC (obj),
1365 : : OBJECT_CONFLICT_ID (another_obj),
1366 : : OBJECT_MIN (obj), OBJECT_MAX (obj)))
1367 : : return true;
1368 : : }
1369 : : else
1370 : : {
1371 : : /* If this linear walk ever becomes a bottleneck we could add a
1372 : : conflict_vec_sorted_p flag and if not set, sort the conflicts after
1373 : : their ID so we can use a binary search. That would also require
1374 : : tracking the actual number of conflicts in the vector to not rely
1375 : : on the NULL termination. */
1376 : 16741527 : ira_object_conflict_iterator oci;
1377 : 16741527 : ira_object_t conflict_obj;
1378 : 535292638 : FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
1379 : 518986951 : if (OBJECT_ALLOCNO (conflict_obj) == a)
1380 : 435840 : return true;
1381 : : }
1382 : : return false;
1383 : : }
1384 : :
1385 : : /* Return TRUE if allocnos A1 and A2 conflicts. Here we are
1386 : : interested only in conflicts of allocnos with intersecting allocno
1387 : : classes. */
1388 : : static bool
1389 : 69706467 : allocnos_conflict_p (ira_allocno_t a1, ira_allocno_t a2)
1390 : : {
1391 : : /* Compute the upper bound for the linear iteration when the object
1392 : : conflicts are represented as a sparse vector. In particular this
1393 : : will make sure we prefer O(1) bitvector testing. */
1394 : 69706467 : int num_conflicts_in_vec1 = 0, num_conflicts_in_vec2 = 0;
1395 : 140149548 : for (int word = 0; word < ALLOCNO_NUM_OBJECTS (a1); ++word)
1396 : 70443081 : if (OBJECT_CONFLICT_VEC_P (ALLOCNO_OBJECT (a1, word)))
1397 : 18782471 : num_conflicts_in_vec1 += OBJECT_NUM_CONFLICTS (ALLOCNO_OBJECT (a1, word));
1398 : 140308239 : for (int word = 0; word < ALLOCNO_NUM_OBJECTS (a2); ++word)
1399 : 70601772 : if (OBJECT_CONFLICT_VEC_P (ALLOCNO_OBJECT (a2, word)))
1400 : 17341535 : num_conflicts_in_vec2 += OBJECT_NUM_CONFLICTS (ALLOCNO_OBJECT (a2, word));
1401 : 69706467 : if (num_conflicts_in_vec2 < num_conflicts_in_vec1)
1402 : 5614826 : std::swap (a1, a2);
1403 : :
1404 : 138553746 : for (int word = 0; word < ALLOCNO_NUM_OBJECTS (a1); word++)
1405 : : {
1406 : 70365532 : ira_object_t obj = ALLOCNO_OBJECT (a1, word);
1407 : : /* Take preferences of conflicting allocnos into account. */
1408 : 70365532 : if (object_conflicts_with_allocno_p (obj, a2))
1409 : : return true;
1410 : : }
1411 : : return false;
1412 : : }
1413 : :
1414 : : /* Update (decrease if DECR_P) HARD_REGNO cost of allocnos connected
1415 : : by copies to ALLOCNO to increase chances to remove some copies as
1416 : : the result of subsequent assignment. Update conflict costs.
1417 : : Record cost updates if RECORD_P is true. */
1418 : : static void
1419 : 32387870 : update_costs_from_allocno (ira_allocno_t allocno, int hard_regno,
1420 : : int divisor, bool decr_p, bool record_p)
1421 : : {
1422 : 32387870 : int cost, update_cost, update_conflict_cost;
1423 : 32387870 : machine_mode mode;
1424 : 32387870 : enum reg_class rclass, aclass;
1425 : 32387870 : ira_allocno_t another_allocno, start = allocno, from = NULL;
1426 : 32387870 : ira_copy_t cp, next_cp;
1427 : :
1428 : 32387870 : rclass = REGNO_REG_CLASS (hard_regno);
1429 : 43025811 : do
1430 : : {
1431 : 43025811 : mode = ALLOCNO_MODE (allocno);
1432 : 43025811 : ira_init_register_move_cost_if_necessary (mode);
1433 : 86862716 : for (cp = ALLOCNO_COPIES (allocno); cp != NULL; cp = next_cp)
1434 : : {
1435 : 43836905 : if (cp->first == allocno)
1436 : : {
1437 : 20281737 : next_cp = cp->next_first_allocno_copy;
1438 : 20281737 : another_allocno = cp->second;
1439 : : }
1440 : 23555168 : else if (cp->second == allocno)
1441 : : {
1442 : 23555168 : next_cp = cp->next_second_allocno_copy;
1443 : 23555168 : another_allocno = cp->first;
1444 : : }
1445 : : else
1446 : 0 : gcc_unreachable ();
1447 : :
1448 : 43836905 : if (another_allocno == from
1449 : 33161069 : || (ALLOCNO_COLOR_DATA (another_allocno) != NULL
1450 : 32516647 : && (ALLOCNO_COLOR_DATA (allocno)->first_thread_allocno
1451 : 32516647 : != ALLOCNO_COLOR_DATA (another_allocno)->first_thread_allocno)))
1452 : 16407471 : continue;
1453 : :
1454 : 27429434 : aclass = ALLOCNO_CLASS (another_allocno);
1455 : 27429434 : if (! TEST_HARD_REG_BIT (reg_class_contents[aclass],
1456 : : hard_regno)
1457 : 27429434 : || ALLOCNO_ASSIGNED_P (another_allocno))
1458 : 14646066 : continue;
1459 : :
1460 : : /* If we have different modes use the smallest one. It is
1461 : : a sub-register move. It is hard to predict what LRA
1462 : : will reload (the pseudo or its sub-register) but LRA
1463 : : will try to minimize the data movement. Also for some
1464 : : register classes bigger modes might be invalid,
1465 : : e.g. DImode for AREG on x86. For such cases the
1466 : : register move cost will be maximal. */
1467 : 25566736 : mode = narrower_subreg_mode (ALLOCNO_MODE (cp->first),
1468 : 12783368 : ALLOCNO_MODE (cp->second));
1469 : :
1470 : 12783368 : ira_init_register_move_cost_if_necessary (mode);
1471 : :
1472 : 25566736 : cost = (cp->second == allocno
1473 : 12783368 : ? ira_register_move_cost[mode][rclass][aclass]
1474 : 9740293 : : ira_register_move_cost[mode][aclass][rclass]);
1475 : 12783368 : if (decr_p)
1476 : 12783368 : cost = -cost;
1477 : :
1478 : 12783368 : update_cost = cp->freq * cost / divisor;
1479 : 12783368 : update_conflict_cost = update_cost;
1480 : :
1481 : 12783368 : if (internal_flag_ira_verbose > 5 && ira_dump_file != NULL)
1482 : 0 : fprintf (ira_dump_file,
1483 : : " a%dr%d (hr%d): update cost by %d, conflict cost by %d\n",
1484 : : ALLOCNO_NUM (another_allocno), ALLOCNO_REGNO (another_allocno),
1485 : : hard_regno, update_cost, update_conflict_cost);
1486 : 12783368 : if (update_cost == 0)
1487 : 918826 : continue;
1488 : :
1489 : 11864542 : if (! update_allocno_cost (another_allocno, hard_regno,
1490 : : update_cost, update_conflict_cost))
1491 : 0 : continue;
1492 : 11864542 : queue_update_cost (another_allocno, start, allocno,
1493 : : divisor * COST_HOP_DIVISOR);
1494 : 11864542 : if (record_p && ALLOCNO_COLOR_DATA (another_allocno) != NULL)
1495 : 7747943 : ALLOCNO_COLOR_DATA (another_allocno)->update_cost_records
1496 : 7747943 : = get_update_cost_record (hard_regno, divisor,
1497 : : ALLOCNO_COLOR_DATA (another_allocno)
1498 : : ->update_cost_records);
1499 : : }
1500 : : }
1501 : 43025811 : while (get_next_update_cost (&allocno, &start, &from, &divisor));
1502 : 32387870 : }
1503 : :
1504 : : /* Decrease preferred ALLOCNO hard register costs and costs of
1505 : : allocnos connected to ALLOCNO through copy. */
1506 : : static void
1507 : 17052414 : update_costs_from_prefs (ira_allocno_t allocno)
1508 : : {
1509 : 17052414 : ira_pref_t pref;
1510 : :
1511 : 17052414 : start_update_cost ();
1512 : 21009098 : for (pref = ALLOCNO_PREFS (allocno); pref != NULL; pref = pref->next_pref)
1513 : : {
1514 : 3956684 : if (internal_flag_ira_verbose > 5 && ira_dump_file != NULL)
1515 : 0 : fprintf (ira_dump_file, " Start updating from pref of hr%d for a%dr%d:\n",
1516 : : pref->hard_regno, ALLOCNO_NUM (allocno), ALLOCNO_REGNO (allocno));
1517 : 3956684 : update_costs_from_allocno (allocno, pref->hard_regno,
1518 : : COST_HOP_DIVISOR, true, true);
1519 : : }
1520 : 17052414 : }
1521 : :
1522 : : /* Update (decrease if DECR_P) the cost of allocnos connected to
1523 : : ALLOCNO through copies to increase chances to remove some copies as
1524 : : the result of subsequent assignment. ALLOCNO was just assigned to
1525 : : a hard register. Record cost updates if RECORD_P is true. */
1526 : : static void
1527 : 20683243 : update_costs_from_copies (ira_allocno_t allocno, bool decr_p, bool record_p)
1528 : : {
1529 : 20683243 : int hard_regno;
1530 : :
1531 : 20683243 : hard_regno = ALLOCNO_HARD_REGNO (allocno);
1532 : 20683243 : ira_assert (hard_regno >= 0 && ALLOCNO_CLASS (allocno) != NO_REGS);
1533 : 20683243 : start_update_cost ();
1534 : 20683243 : if (internal_flag_ira_verbose > 5 && ira_dump_file != NULL)
1535 : 0 : fprintf (ira_dump_file, " Start updating from a%dr%d by copies:\n",
1536 : : ALLOCNO_NUM (allocno), ALLOCNO_REGNO (allocno));
1537 : 20683243 : update_costs_from_allocno (allocno, hard_regno, 1, decr_p, record_p);
1538 : 20683243 : }
1539 : :
1540 : : /* Update conflict_allocno_hard_prefs of allocnos conflicting with
1541 : : ALLOCNO. */
1542 : : static void
1543 : 21149018 : update_conflict_allocno_hard_prefs (ira_allocno_t allocno)
1544 : : {
1545 : 21149018 : int l, nr = ALLOCNO_NUM_OBJECTS (allocno);
1546 : :
1547 : 42726501 : for (l = 0; l < nr; l++)
1548 : : {
1549 : 21577483 : ira_object_t conflict_obj, obj = ALLOCNO_OBJECT (allocno, l);
1550 : 21577483 : ira_object_conflict_iterator oci;
1551 : :
1552 : 465453713 : FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
1553 : : {
1554 : 443876230 : ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
1555 : 443876230 : allocno_color_data_t conflict_data = ALLOCNO_COLOR_DATA (conflict_a);
1556 : 443876230 : ira_pref_t pref;
1557 : :
1558 : 940664792 : if (!(hard_reg_set_intersect_p
1559 : 887752460 : (ALLOCNO_COLOR_DATA (allocno)->profitable_hard_regs,
1560 : : conflict_data->profitable_hard_regs)))
1561 : 52912332 : continue;
1562 : 390963898 : for (pref = ALLOCNO_PREFS (allocno);
1563 : 417258350 : pref != NULL;
1564 : 26294452 : pref = pref->next_pref)
1565 : 26294452 : conflict_data->conflict_allocno_hard_prefs += pref->freq;
1566 : : }
1567 : : }
1568 : 21149018 : }
1569 : :
1570 : : /* Restore costs of allocnos connected to ALLOCNO by copies as it was
1571 : : before updating costs of these allocnos from given allocno. This
1572 : : is a wise thing to do as if given allocno did not get an expected
1573 : : hard reg, using smaller cost of the hard reg for allocnos connected
1574 : : by copies to given allocno becomes actually misleading. Free all
1575 : : update cost records for ALLOCNO as we don't need them anymore. */
1576 : : static void
1577 : 21544456 : restore_costs_from_copies (ira_allocno_t allocno)
1578 : : {
1579 : 21544456 : struct update_cost_record *records, *curr;
1580 : :
1581 : 21544456 : if (ALLOCNO_COLOR_DATA (allocno) == NULL)
1582 : : return;
1583 : 21544456 : records = ALLOCNO_COLOR_DATA (allocno)->update_cost_records;
1584 : 21544456 : start_update_cost ();
1585 : 21544456 : if (internal_flag_ira_verbose > 5 && ira_dump_file != NULL)
1586 : 0 : fprintf (ira_dump_file, " Start restoring from a%dr%d:\n",
1587 : : ALLOCNO_NUM (allocno), ALLOCNO_REGNO (allocno));
1588 : 29292399 : for (curr = records; curr != NULL; curr = curr->next)
1589 : 7747943 : update_costs_from_allocno (allocno, curr->hard_regno,
1590 : : curr->divisor, true, false);
1591 : 21544456 : free_update_cost_record_list (records);
1592 : 21544456 : ALLOCNO_COLOR_DATA (allocno)->update_cost_records = NULL;
1593 : : }
1594 : :
1595 : : /* This function updates COSTS (decrease if DECR_P) for hard_registers
1596 : : of ACLASS by conflict costs of the unassigned allocnos
1597 : : connected by copies with allocnos in update_cost_queue. This
1598 : : update increases chances to remove some copies. */
1599 : : static void
1600 : 40761542 : update_conflict_hard_regno_costs (int *costs, enum reg_class aclass,
1601 : : bool decr_p)
1602 : : {
1603 : 40761542 : int i, cost, class_size, freq, mult, div, divisor;
1604 : 40761542 : int index, hard_regno;
1605 : 40761542 : int *conflict_costs;
1606 : 40761542 : bool cont_p;
1607 : 40761542 : enum reg_class another_aclass;
1608 : 40761542 : ira_allocno_t allocno, another_allocno, start, from;
1609 : 40761542 : ira_copy_t cp, next_cp;
1610 : :
1611 : 154029498 : while (get_next_update_cost (&allocno, &start, &from, &divisor))
1612 : 203229658 : for (cp = ALLOCNO_COPIES (allocno); cp != NULL; cp = next_cp)
1613 : : {
1614 : 89961702 : if (cp->first == allocno)
1615 : : {
1616 : 43348225 : next_cp = cp->next_first_allocno_copy;
1617 : 43348225 : another_allocno = cp->second;
1618 : : }
1619 : 46613477 : else if (cp->second == allocno)
1620 : : {
1621 : 46613477 : next_cp = cp->next_second_allocno_copy;
1622 : 46613477 : another_allocno = cp->first;
1623 : : }
1624 : : else
1625 : 0 : gcc_unreachable ();
1626 : :
1627 : 89961702 : another_aclass = ALLOCNO_CLASS (another_allocno);
1628 : 89961702 : if (another_allocno == from
1629 : 89961702 : || ALLOCNO_ASSIGNED_P (another_allocno)
1630 : 74362498 : || ALLOCNO_COLOR_DATA (another_allocno)->may_be_spilled_p
1631 : 71516644 : || ! ira_reg_classes_intersect_p[aclass][another_aclass])
1632 : 20255235 : continue;
1633 : 69706467 : if (allocnos_conflict_p (another_allocno, start))
1634 : 1518253 : continue;
1635 : :
1636 : 68188214 : class_size = ira_class_hard_regs_num[another_aclass];
1637 : 68188214 : ira_allocate_and_copy_costs
1638 : 68188214 : (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (another_allocno),
1639 : : another_aclass, ALLOCNO_CONFLICT_HARD_REG_COSTS (another_allocno));
1640 : 68188214 : conflict_costs
1641 : 68188214 : = ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (another_allocno);
1642 : 68188214 : if (conflict_costs == NULL)
1643 : : cont_p = true;
1644 : : else
1645 : : {
1646 : 14688450 : mult = cp->freq;
1647 : 14688450 : freq = ALLOCNO_FREQ (another_allocno);
1648 : 14688450 : if (freq == 0)
1649 : 0 : freq = 1;
1650 : 14688450 : div = freq * divisor;
1651 : 14688450 : cont_p = false;
1652 : 268230526 : for (i = class_size - 1; i >= 0; i--)
1653 : : {
1654 : 253542076 : hard_regno = ira_class_hard_regs[another_aclass][i];
1655 : 253542076 : ira_assert (hard_regno >= 0);
1656 : 253542076 : index = ira_class_hard_reg_index[aclass][hard_regno];
1657 : 253542076 : if (index < 0)
1658 : 20717607 : continue;
1659 : 232824469 : cost = (int) (((int64_t) conflict_costs [i] * mult) / div);
1660 : 232824469 : if (cost == 0)
1661 : 223972451 : continue;
1662 : 8852018 : cont_p = true;
1663 : 8852018 : if (decr_p)
1664 : 5471534 : cost = -cost;
1665 : 8852018 : costs[index] += cost;
1666 : : }
1667 : : }
1668 : : /* Probably 5 hops will be enough. */
1669 : 14688450 : if (cont_p
1670 : 61759789 : && divisor <= (COST_HOP_DIVISOR
1671 : : * COST_HOP_DIVISOR
1672 : : * COST_HOP_DIVISOR
1673 : : * COST_HOP_DIVISOR))
1674 : 60287931 : queue_update_cost (another_allocno, start, from, divisor * COST_HOP_DIVISOR);
1675 : : }
1676 : 40761542 : }
1677 : :
1678 : : /* Set up conflicting (through CONFLICT_REGS) for each object of
1679 : : allocno A and the start allocno profitable regs (through
1680 : : START_PROFITABLE_REGS). Remember that the start profitable regs
1681 : : exclude hard regs which cannot hold value of mode of allocno A.
1682 : : This covers mostly cases when multi-register value should be
1683 : : aligned. */
1684 : : static inline void
1685 : 30306887 : get_conflict_and_start_profitable_regs (ira_allocno_t a, bool retry_p,
1686 : : HARD_REG_SET *conflict_regs,
1687 : : HARD_REG_SET *start_profitable_regs)
1688 : : {
1689 : 30306887 : int i, nwords;
1690 : 30306887 : ira_object_t obj;
1691 : :
1692 : 30306887 : nwords = ALLOCNO_NUM_OBJECTS (a);
1693 : 61481197 : for (i = 0; i < nwords; i++)
1694 : : {
1695 : 31174310 : obj = ALLOCNO_OBJECT (a, i);
1696 : 31174310 : conflict_regs[i] = OBJECT_TOTAL_CONFLICT_HARD_REGS (obj);
1697 : : }
1698 : 30306887 : if (retry_p)
1699 : 0 : *start_profitable_regs
1700 : 0 : = (reg_class_contents[ALLOCNO_CLASS (a)]
1701 : 0 : &~ (ira_prohibited_class_mode_regs
1702 : 0 : [ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]));
1703 : : else
1704 : 30306887 : *start_profitable_regs = ALLOCNO_COLOR_DATA (a)->profitable_hard_regs;
1705 : 30306887 : }
1706 : :
1707 : : /* Return true if HARD_REGNO is ok for assigning to allocno A with
1708 : : PROFITABLE_REGS and whose objects have CONFLICT_REGS. */
1709 : : static inline bool
1710 : 538589953 : check_hard_reg_p (ira_allocno_t a, int hard_regno,
1711 : : HARD_REG_SET *conflict_regs, HARD_REG_SET profitable_regs)
1712 : : {
1713 : 538589953 : int j, nwords, nregs;
1714 : 538589953 : enum reg_class aclass;
1715 : 538589953 : machine_mode mode;
1716 : :
1717 : 538589953 : aclass = ALLOCNO_CLASS (a);
1718 : 538589953 : mode = ALLOCNO_MODE (a);
1719 : 538589953 : if (TEST_HARD_REG_BIT (ira_prohibited_class_mode_regs[aclass][mode],
1720 : : hard_regno))
1721 : : return false;
1722 : : /* Checking only profitable hard regs. */
1723 : 538011176 : if (! TEST_HARD_REG_BIT (profitable_regs, hard_regno))
1724 : : return false;
1725 : 457968865 : nregs = hard_regno_nregs (hard_regno, mode);
1726 : 457968865 : nwords = ALLOCNO_NUM_OBJECTS (a);
1727 : 855023729 : for (j = 0; j < nregs; j++)
1728 : : {
1729 : 467699520 : int k;
1730 : 467699520 : int set_to_test_start = 0, set_to_test_end = nwords;
1731 : :
1732 : 467699520 : if (nregs == nwords)
1733 : : {
1734 : 467069874 : if (REG_WORDS_BIG_ENDIAN)
1735 : : set_to_test_start = nwords - j - 1;
1736 : : else
1737 : 467069874 : set_to_test_start = j;
1738 : 467069874 : set_to_test_end = set_to_test_start + 1;
1739 : : }
1740 : 865361408 : for (k = set_to_test_start; k < set_to_test_end; k++)
1741 : 468306544 : if (TEST_HARD_REG_BIT (conflict_regs[k], hard_regno + j))
1742 : : break;
1743 : 467699520 : if (k != set_to_test_end)
1744 : : break;
1745 : : }
1746 : 457968865 : return j == nregs;
1747 : : }
1748 : :
1749 : : /* Record that we have allocated NREGS registers starting at HARD_REGNO. */
1750 : :
1751 : : static void
1752 : 20572737 : record_allocation (int hard_regno, int nregs)
1753 : : {
1754 : 41511836 : for (int i = 0; i < nregs; ++i)
1755 : 20939099 : if (!allocated_hardreg_p[hard_regno + i])
1756 : : {
1757 : 4287843 : allocated_hardreg_p[hard_regno + i] = true;
1758 : 4287843 : if (!crtl->abi->clobbers_full_reg_p (hard_regno + i))
1759 : 912318 : SET_HARD_REG_BIT (allocated_callee_save_regs, hard_regno + i);
1760 : : }
1761 : 20572737 : }
1762 : :
1763 : : /* Return number of registers needed to be saved and restored at
1764 : : function prologue/epilogue if we allocate HARD_REGNO to hold value
1765 : : of MODE. */
1766 : : static int
1767 : 315510682 : calculate_saved_nregs (int hard_regno, machine_mode mode)
1768 : : {
1769 : 315510682 : int i;
1770 : 315510682 : int nregs = 0;
1771 : :
1772 : 315510682 : ira_assert (hard_regno >= 0);
1773 : 636688824 : for (i = hard_regno_nregs (hard_regno, mode) - 1; i >= 0; i--)
1774 : 321178142 : if (!allocated_hardreg_p[hard_regno + i]
1775 : 176767640 : && ira_hard_regno_nrefs[hard_regno + i] == 0
1776 : 84232536 : && !crtl->abi->clobbers_full_reg_p (hard_regno + i)
1777 : 321178142 : && !LOCAL_REGNO (hard_regno + i))
1778 : 58448687 : nregs++;
1779 : 315510682 : return nregs;
1780 : : }
1781 : :
1782 : : /* Allocnos A1 and A2 are known to conflict. Check whether, in some loop L
1783 : : that is either the current loop or a nested subloop, the conflict is of
1784 : : the following form:
1785 : :
1786 : : - One allocno (X) is a cap allocno for some non-cap allocno X2.
1787 : :
1788 : : - X2 belongs to some loop L2.
1789 : :
1790 : : - The other allocno (Y) is a non-cap allocno.
1791 : :
1792 : : - Y is an ancestor of some allocno Y2 in L2. (Note that such a Y2
1793 : : must exist, given that X and Y conflict.)
1794 : :
1795 : : - Y2 is not referenced in L2 (that is, ALLOCNO_NREFS (Y2) == 0).
1796 : :
1797 : : - Y can use a different allocation from Y2.
1798 : :
1799 : : In this case, Y's register is live across L2 but is not used within it,
1800 : : whereas X's register is used only within L2. The conflict is therefore
1801 : : only "soft", in that it can easily be avoided by spilling Y2 inside L2
1802 : : without affecting any insn references.
1803 : :
1804 : : If the conflict does have this form, return the Y2 that would need to be
1805 : : spilled in order to allow X and Y (and thus A1 and A2) to use the same
1806 : : register. Return null otherwise. Returning null is conservatively correct;
1807 : : any nonnnull return value is an optimization. */
1808 : : ira_allocno_t
1809 : 217154348 : ira_soft_conflict (ira_allocno_t a1, ira_allocno_t a2)
1810 : : {
1811 : : /* Search for the loop L and its associated allocnos X and Y. */
1812 : 217154348 : int search_depth = 0;
1813 : 338532634 : while (ALLOCNO_CAP_MEMBER (a1) && ALLOCNO_CAP_MEMBER (a2))
1814 : : {
1815 : 121378286 : a1 = ALLOCNO_CAP_MEMBER (a1);
1816 : 121378286 : a2 = ALLOCNO_CAP_MEMBER (a2);
1817 : 121378286 : if (search_depth++ > max_soft_conflict_loop_depth)
1818 : : return nullptr;
1819 : : }
1820 : : /* This must be true if A1 and A2 conflict. */
1821 : 217154348 : ira_assert (ALLOCNO_LOOP_TREE_NODE (a1) == ALLOCNO_LOOP_TREE_NODE (a2));
1822 : :
1823 : : /* Make A1 the cap allocno (X in the comment above) and A2 the
1824 : : non-cap allocno (Y in the comment above). */
1825 : 217154348 : if (ALLOCNO_CAP_MEMBER (a2))
1826 : 56372010 : std::swap (a1, a2);
1827 : 217154348 : if (!ALLOCNO_CAP_MEMBER (a1))
1828 : : return nullptr;
1829 : :
1830 : : /* Search for the real allocno that A1 caps (X2 in the comment above). */
1831 : 158181383 : do
1832 : : {
1833 : 158181383 : a1 = ALLOCNO_CAP_MEMBER (a1);
1834 : 158181383 : if (search_depth++ > max_soft_conflict_loop_depth)
1835 : : return nullptr;
1836 : : }
1837 : 158181383 : while (ALLOCNO_CAP_MEMBER (a1));
1838 : :
1839 : : /* Find the associated allocno for A2 (Y2 in the comment above). */
1840 : 78952555 : auto node = ALLOCNO_LOOP_TREE_NODE (a1);
1841 : 78952555 : auto local_a2 = node->regno_allocno_map[ALLOCNO_REGNO (a2)];
1842 : :
1843 : : /* Find the parent of LOCAL_A2/Y2. LOCAL_A2 must be a descendant of A2
1844 : : for the conflict query to make sense, so this parent lookup must succeed.
1845 : :
1846 : : If the parent allocno has no references, it is usually cheaper to
1847 : : spill at that loop level instead. Keep searching until we find
1848 : : a parent allocno that does have references (but don't look past
1849 : : the starting allocno). */
1850 : 108144616 : ira_allocno_t local_parent_a2;
1851 : 108144616 : for (;;)
1852 : : {
1853 : 108144616 : local_parent_a2 = ira_parent_allocno (local_a2);
1854 : 108144616 : if (local_parent_a2 == a2 || ALLOCNO_NREFS (local_parent_a2) != 0)
1855 : : break;
1856 : : local_a2 = local_parent_a2;
1857 : : }
1858 : : if (CHECKING_P)
1859 : : {
1860 : : /* Sanity check to make sure that the conflict we've been given
1861 : : makes sense. */
1862 : : auto test_a2 = local_parent_a2;
1863 : 128989322 : while (test_a2 != a2)
1864 : : {
1865 : 50036767 : test_a2 = ira_parent_allocno (test_a2);
1866 : 50036767 : ira_assert (test_a2);
1867 : : }
1868 : : }
1869 : 78952555 : if (local_a2
1870 : 78952555 : && ALLOCNO_NREFS (local_a2) == 0
1871 : 119180584 : && ira_subloop_allocnos_can_differ_p (local_parent_a2))
1872 : : return local_a2;
1873 : : return nullptr;
1874 : : }
1875 : :
1876 : : /* The caller has decided to allocate HREGNO to A and has proved that
1877 : : this is safe. However, the allocation might require the kind of
1878 : : spilling described in the comment above ira_soft_conflict.
1879 : : The caller has recorded that:
1880 : :
1881 : : - The allocnos in ALLOCNOS_TO_SPILL are the ones that would need
1882 : : to be spilled to satisfy soft conflicts for at least one allocation
1883 : : (not necessarily HREGNO).
1884 : :
1885 : : - The soft conflicts apply only to A allocations that overlap
1886 : : SOFT_CONFLICT_REGS.
1887 : :
1888 : : If allocating HREGNO is subject to any soft conflicts, record the
1889 : : subloop allocnos that need to be spilled. */
1890 : : static void
1891 : 20572737 : spill_soft_conflicts (ira_allocno_t a, bitmap allocnos_to_spill,
1892 : : HARD_REG_SET soft_conflict_regs, int hregno)
1893 : : {
1894 : 20572737 : auto nregs = hard_regno_nregs (hregno, ALLOCNO_MODE (a));
1895 : 20572737 : bitmap_iterator bi;
1896 : 20572737 : unsigned int i;
1897 : 25591849 : EXECUTE_IF_SET_IN_BITMAP (allocnos_to_spill, 0, i, bi)
1898 : : {
1899 : : /* SPILL_A needs to be spilled for at least one allocation
1900 : : (not necessarily this one). */
1901 : 5019112 : auto spill_a = ira_allocnos[i];
1902 : :
1903 : : /* Find the corresponding allocno for this loop. */
1904 : 5019112 : auto conflict_a = spill_a;
1905 : 10342177 : do
1906 : : {
1907 : 10342177 : conflict_a = ira_parent_or_cap_allocno (conflict_a);
1908 : 10342177 : ira_assert (conflict_a);
1909 : : }
1910 : 10342177 : while (ALLOCNO_LOOP_TREE_NODE (conflict_a)->level
1911 : 10342177 : > ALLOCNO_LOOP_TREE_NODE (a)->level);
1912 : :
1913 : 5019112 : ira_assert (ALLOCNO_LOOP_TREE_NODE (conflict_a)
1914 : : == ALLOCNO_LOOP_TREE_NODE (a));
1915 : :
1916 : 5019112 : if (conflict_a == a)
1917 : : {
1918 : : /* SPILL_A is a descendant of A. We don't know (and don't need
1919 : : to know) which cap allocnos have a soft conflict with A.
1920 : : All we need to do is test whether the soft conflict applies
1921 : : to the chosen allocation. */
1922 : 396657 : if (ira_hard_reg_set_intersection_p (hregno, ALLOCNO_MODE (a),
1923 : : soft_conflict_regs))
1924 : 35570 : ALLOCNO_MIGHT_CONFLICT_WITH_PARENT_P (spill_a) = true;
1925 : : }
1926 : : else
1927 : : {
1928 : : /* SPILL_A is a descendant of CONFLICT_A, which has a soft conflict
1929 : : with A. Test whether the soft conflict applies to the current
1930 : : allocation. */
1931 : 4622455 : ira_assert (ira_soft_conflict (a, conflict_a) == spill_a);
1932 : 4622455 : auto conflict_hregno = ALLOCNO_HARD_REGNO (conflict_a);
1933 : 4622455 : ira_assert (conflict_hregno >= 0);
1934 : 4622455 : auto conflict_nregs = hard_regno_nregs (conflict_hregno,
1935 : 4622455 : ALLOCNO_MODE (conflict_a));
1936 : 4622455 : if (hregno + nregs > conflict_hregno
1937 : 1607779 : && conflict_hregno + conflict_nregs > hregno)
1938 : 76194 : ALLOCNO_MIGHT_CONFLICT_WITH_PARENT_P (spill_a) = true;
1939 : : }
1940 : : }
1941 : 20572737 : }
1942 : :
1943 : : /* Choose a hard register for allocno A. If RETRY_P is TRUE, it means
1944 : : that the function called from function
1945 : : `ira_reassign_conflict_allocnos' and `allocno_reload_assign'. In
1946 : : this case some allocno data are not defined or updated and we
1947 : : should not touch these data. The function returns true if we
1948 : : managed to assign a hard register to the allocno.
1949 : :
1950 : : To assign a hard register, first of all we calculate all conflict
1951 : : hard registers which can come from conflicting allocnos with
1952 : : already assigned hard registers. After that we find first free
1953 : : hard register with the minimal cost. During hard register cost
1954 : : calculation we take conflict hard register costs into account to
1955 : : give a chance for conflicting allocnos to get a better hard
1956 : : register in the future.
1957 : :
1958 : : If the best hard register cost is bigger than cost of memory usage
1959 : : for the allocno, we don't assign a hard register to given allocno
1960 : : at all.
1961 : :
1962 : : If we assign a hard register to the allocno, we update costs of the
1963 : : hard register for allocnos connected by copies to improve a chance
1964 : : to coalesce insns represented by the copies when we assign hard
1965 : : registers to the allocnos connected by the copies. */
1966 : : static bool
1967 : 21544456 : assign_hard_reg (ira_allocno_t a, bool retry_p)
1968 : : {
1969 : 21544456 : HARD_REG_SET conflicting_regs[2], profitable_hard_regs;
1970 : 21544456 : int i, j, hard_regno, best_hard_regno, class_size;
1971 : 21544456 : int cost, mem_cost, min_cost, full_cost, min_full_cost, nwords, word;
1972 : 21544456 : int *a_costs;
1973 : 21544456 : enum reg_class aclass;
1974 : 21544456 : machine_mode mode;
1975 : 21544456 : static int costs[FIRST_PSEUDO_REGISTER], full_costs[FIRST_PSEUDO_REGISTER];
1976 : 21544456 : int saved_nregs;
1977 : 21544456 : enum reg_class rclass;
1978 : 21544456 : int add_cost;
1979 : : #ifdef STACK_REGS
1980 : 21544456 : bool no_stack_reg_p;
1981 : : #endif
1982 : 21544456 : auto_bitmap allocnos_to_spill;
1983 : 21544456 : HARD_REG_SET soft_conflict_regs = {};
1984 : 21544456 : int entry_freq = REG_FREQ_FROM_BB (ENTRY_BLOCK_PTR_FOR_FN (cfun));
1985 : 21544456 : int exit_freq = REG_FREQ_FROM_BB (EXIT_BLOCK_PTR_FOR_FN (cfun));
1986 : 21544456 : int spill_cost = 0;
1987 : : /* Whether we have spilled pseudos or used caller-saved registers for values
1988 : : that are live across a call. */
1989 : 21544456 : bool existing_spills_p = allocated_memory_p || caller_save_needed;
1990 : :
1991 : 21544456 : ira_assert (! ALLOCNO_ASSIGNED_P (a));
1992 : 21544456 : get_conflict_and_start_profitable_regs (a, retry_p,
1993 : : conflicting_regs,
1994 : : &profitable_hard_regs);
1995 : 21544456 : aclass = ALLOCNO_CLASS (a);
1996 : 21544456 : class_size = ira_class_hard_regs_num[aclass];
1997 : 21544456 : best_hard_regno = -1;
1998 : 21544456 : mem_cost = 0;
1999 : 21544456 : memset (costs, 0, sizeof (int) * class_size);
2000 : 21544456 : memset (full_costs, 0, sizeof (int) * class_size);
2001 : : #ifdef STACK_REGS
2002 : 21544456 : no_stack_reg_p = false;
2003 : : #endif
2004 : 21544456 : if (! retry_p)
2005 : 21544456 : start_update_cost ();
2006 : 21544456 : mem_cost += ALLOCNO_UPDATED_MEMORY_COST (a);
2007 : :
2008 : 21544456 : if (!existing_spills_p)
2009 : : {
2010 : 7775223 : auto entry_cost = targetm.frame_allocation_cost
2011 : 7775223 : (frame_cost_type::ALLOCATION, allocated_callee_save_regs);
2012 : 7775223 : spill_cost += entry_cost * entry_freq;
2013 : :
2014 : 7775223 : auto exit_cost = targetm.frame_allocation_cost
2015 : 7775223 : (frame_cost_type::DEALLOCATION, allocated_callee_save_regs);
2016 : 7775223 : spill_cost += exit_cost * exit_freq;
2017 : : }
2018 : 21544456 : mem_cost += spill_cost;
2019 : :
2020 : 21544456 : ira_allocate_and_copy_costs (&ALLOCNO_UPDATED_HARD_REG_COSTS (a),
2021 : : aclass, ALLOCNO_HARD_REG_COSTS (a));
2022 : 21544456 : a_costs = ALLOCNO_UPDATED_HARD_REG_COSTS (a);
2023 : : #ifdef STACK_REGS
2024 : 21544456 : no_stack_reg_p = no_stack_reg_p || ALLOCNO_TOTAL_NO_STACK_REG_P (a);
2025 : : #endif
2026 : 21544456 : cost = ALLOCNO_UPDATED_CLASS_COST (a);
2027 : 325919219 : for (i = 0; i < class_size; i++)
2028 : 304374763 : if (a_costs != NULL)
2029 : : {
2030 : 189805948 : costs[i] += a_costs[i];
2031 : 189805948 : full_costs[i] += a_costs[i];
2032 : : }
2033 : : else
2034 : : {
2035 : 114568815 : costs[i] += cost;
2036 : 114568815 : full_costs[i] += cost;
2037 : : }
2038 : 21544456 : nwords = ALLOCNO_NUM_OBJECTS (a);
2039 : 21544456 : curr_allocno_process++;
2040 : 42306537 : for (word = 0; word < nwords; word++)
2041 : : {
2042 : 21925766 : ira_object_t conflict_obj;
2043 : 21925766 : ira_object_t obj = ALLOCNO_OBJECT (a, word);
2044 : 21925766 : ira_object_conflict_iterator oci;
2045 : :
2046 : : /* Take preferences of conflicting allocnos into account. */
2047 : 418404377 : FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
2048 : : {
2049 : 397642296 : ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
2050 : 397642296 : enum reg_class conflict_aclass;
2051 : 397642296 : allocno_color_data_t data = ALLOCNO_COLOR_DATA (conflict_a);
2052 : :
2053 : : /* Reload can give another class so we need to check all
2054 : : allocnos. */
2055 : 447527347 : if (!retry_p
2056 : 397642296 : && ((!ALLOCNO_ASSIGNED_P (conflict_a)
2057 : 226608614 : || ALLOCNO_HARD_REGNO (conflict_a) < 0)
2058 : 280922005 : && !(hard_reg_set_intersect_p
2059 : 280922005 : (profitable_hard_regs,
2060 : : ALLOCNO_COLOR_DATA
2061 : : (conflict_a)->profitable_hard_regs))))
2062 : : {
2063 : : /* All conflict allocnos are in consideration bitmap
2064 : : when retry_p is false. It might change in future and
2065 : : if it happens the assert will be broken. It means
2066 : : the code should be modified for the new
2067 : : assumptions. */
2068 : 49885051 : ira_assert (bitmap_bit_p (consideration_allocno_bitmap,
2069 : : ALLOCNO_NUM (conflict_a)));
2070 : 49885051 : continue;
2071 : : }
2072 : 347757245 : conflict_aclass = ALLOCNO_CLASS (conflict_a);
2073 : 347757245 : ira_assert (ira_reg_classes_intersect_p
2074 : : [aclass][conflict_aclass]);
2075 : 347757245 : if (ALLOCNO_ASSIGNED_P (conflict_a))
2076 : : {
2077 : 178491526 : hard_regno = ALLOCNO_HARD_REGNO (conflict_a);
2078 : 178491526 : if (hard_regno >= 0
2079 : 295211817 : && (ira_hard_reg_set_intersection_p
2080 : 116720291 : (hard_regno, ALLOCNO_MODE (conflict_a),
2081 : : reg_class_contents[aclass])))
2082 : : {
2083 : 113476471 : int n_objects = ALLOCNO_NUM_OBJECTS (conflict_a);
2084 : 113476471 : int conflict_nregs;
2085 : :
2086 : 113476471 : mode = ALLOCNO_MODE (conflict_a);
2087 : 113476471 : conflict_nregs = hard_regno_nregs (hard_regno, mode);
2088 : 113476471 : auto spill_a = (retry_p
2089 : 113476471 : ? nullptr
2090 : 113476471 : : ira_soft_conflict (a, conflict_a));
2091 : 113476471 : if (spill_a)
2092 : : {
2093 : 13634693 : if (bitmap_set_bit (allocnos_to_spill,
2094 : : ALLOCNO_NUM (spill_a)))
2095 : : {
2096 : 4711842 : ira_loop_border_costs border_costs (spill_a);
2097 : 4711842 : auto cost = border_costs.spill_inside_loop_cost ();
2098 : 9441613 : auto note_conflict = [&](int r)
2099 : : {
2100 : 4729771 : SET_HARD_REG_BIT (soft_conflict_regs, r);
2101 : 4729771 : auto hri = ira_class_hard_reg_index[aclass][r];
2102 : 4729771 : if (hri >= 0)
2103 : : {
2104 : 4728390 : costs[hri] += cost;
2105 : 4728390 : full_costs[hri] += cost;
2106 : : }
2107 : 9441613 : };
2108 : 9432213 : for (int r = hard_regno;
2109 : 9432213 : r >= 0 && (int) end_hard_regno (mode, r) > hard_regno;
2110 : : r--)
2111 : 4720371 : note_conflict (r);
2112 : 4721242 : for (int r = hard_regno + 1;
2113 : 4721242 : r < hard_regno + conflict_nregs;
2114 : : r++)
2115 : 9400 : note_conflict (r);
2116 : : }
2117 : : }
2118 : : else
2119 : : {
2120 : 99841778 : if (conflict_nregs == n_objects && conflict_nregs > 1)
2121 : : {
2122 : 2751248 : int num = OBJECT_SUBWORD (conflict_obj);
2123 : :
2124 : 2751248 : if (REG_WORDS_BIG_ENDIAN)
2125 : : SET_HARD_REG_BIT (conflicting_regs[word],
2126 : : hard_regno + n_objects - num - 1);
2127 : : else
2128 : 2751248 : SET_HARD_REG_BIT (conflicting_regs[word],
2129 : 2751248 : hard_regno + num);
2130 : : }
2131 : : else
2132 : 97090530 : conflicting_regs[word]
2133 : 97090530 : |= ira_reg_mode_hard_regset[hard_regno][mode];
2134 : 99841778 : if (hard_reg_set_subset_p (profitable_hard_regs,
2135 : 99841778 : conflicting_regs[word]))
2136 : 1163685 : goto fail;
2137 : : }
2138 : : }
2139 : : }
2140 : 169265719 : else if (! retry_p
2141 : 169265719 : && ! ALLOCNO_COLOR_DATA (conflict_a)->may_be_spilled_p
2142 : : /* Don't process the conflict allocno twice. */
2143 : 88053980 : && (ALLOCNO_COLOR_DATA (conflict_a)->last_process
2144 : 88053980 : != curr_allocno_process))
2145 : : {
2146 : 86197352 : int k, *conflict_costs;
2147 : :
2148 : 86197352 : ALLOCNO_COLOR_DATA (conflict_a)->last_process
2149 : 86197352 : = curr_allocno_process;
2150 : 86197352 : ira_allocate_and_copy_costs
2151 : 86197352 : (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (conflict_a),
2152 : : conflict_aclass,
2153 : : ALLOCNO_CONFLICT_HARD_REG_COSTS (conflict_a));
2154 : 86197352 : conflict_costs
2155 : 86197352 : = ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (conflict_a);
2156 : 86197352 : if (conflict_costs != NULL)
2157 : 299706156 : for (j = class_size - 1; j >= 0; j--)
2158 : : {
2159 : 281413086 : hard_regno = ira_class_hard_regs[aclass][j];
2160 : 281413086 : ira_assert (hard_regno >= 0);
2161 : 281413086 : k = ira_class_hard_reg_index[conflict_aclass][hard_regno];
2162 : 308187742 : if (k < 0
2163 : : /* If HARD_REGNO is not available for CONFLICT_A,
2164 : : the conflict would be ignored, since HARD_REGNO
2165 : : will never be assigned to CONFLICT_A. */
2166 : 281413086 : || !TEST_HARD_REG_BIT (data->profitable_hard_regs,
2167 : : hard_regno))
2168 : 26774656 : continue;
2169 : 254638430 : full_costs[j] -= conflict_costs[k];
2170 : : }
2171 : 86197352 : queue_update_cost (conflict_a, conflict_a, NULL, COST_HOP_DIVISOR);
2172 : : }
2173 : : }
2174 : : }
2175 : 20380771 : if (! retry_p)
2176 : : /* Take into account preferences of allocnos connected by copies to
2177 : : the conflict allocnos. */
2178 : 20380771 : update_conflict_hard_regno_costs (full_costs, aclass, true);
2179 : :
2180 : : /* Take preferences of allocnos connected by copies into
2181 : : account. */
2182 : 20380771 : if (! retry_p)
2183 : : {
2184 : 20380771 : start_update_cost ();
2185 : 20380771 : queue_update_cost (a, a, NULL, COST_HOP_DIVISOR);
2186 : 20380771 : update_conflict_hard_regno_costs (full_costs, aclass, false);
2187 : : }
2188 : 20380771 : min_cost = min_full_cost = INT_MAX;
2189 : : /* We don't care about giving callee saved registers to allocnos no
2190 : : living through calls because call clobbered registers are
2191 : : allocated first (it is usual practice to put them first in
2192 : : REG_ALLOC_ORDER). */
2193 : 20380771 : mode = ALLOCNO_MODE (a);
2194 : 311556222 : for (i = 0; i < class_size; i++)
2195 : : {
2196 : 291175451 : hard_regno = ira_class_hard_regs[aclass][i];
2197 : : #ifdef STACK_REGS
2198 : 291175451 : if (no_stack_reg_p
2199 : 291175451 : && FIRST_STACK_REG <= hard_regno && hard_regno <= LAST_STACK_REG)
2200 : 0 : continue;
2201 : : #endif
2202 : 291175451 : if (! check_hard_reg_p (a, hard_regno,
2203 : : conflicting_regs, profitable_hard_regs))
2204 : 89788875 : continue;
2205 : 201386576 : if (NUM_REGISTER_FILTERS
2206 : : && !test_register_filters (ALLOCNO_REGISTER_FILTERS (a), hard_regno))
2207 : : continue;
2208 : 201386576 : cost = costs[i];
2209 : 201386576 : full_cost = full_costs[i];
2210 : 201386576 : if (!HONOR_REG_ALLOC_ORDER)
2211 : : {
2212 : 201386576 : if ((saved_nregs = calculate_saved_nregs (hard_regno, mode)) != 0)
2213 : : /* We need to save/restore the hard register in
2214 : : epilogue/prologue. Therefore we increase the cost. */
2215 : : {
2216 : 39581545 : int nregs = hard_regno_nregs (hard_regno, mode);
2217 : 39581545 : add_cost = 0;
2218 : 39581545 : rclass = REGNO_REG_CLASS (hard_regno);
2219 : :
2220 : 39581545 : auto entry_cost = targetm.callee_save_cost
2221 : 79163090 : (spill_cost_type::SAVE, hard_regno, mode, saved_nregs,
2222 : 39581545 : ira_memory_move_cost[mode][rclass][0] * saved_nregs / nregs,
2223 : : allocated_callee_save_regs, existing_spills_p);
2224 : : /* In the event of a tie between caller-save and callee-save,
2225 : : prefer callee-save. We apply this to the entry cost rather
2226 : : than the exit cost since the entry frequency must be at
2227 : : least as high as the exit frequency. */
2228 : 39581545 : if (entry_cost > 1)
2229 : 37707290 : entry_cost -= 1;
2230 : 39581545 : add_cost += entry_cost * entry_freq;
2231 : :
2232 : 39581545 : auto exit_cost = targetm.callee_save_cost
2233 : 79163090 : (spill_cost_type::RESTORE, hard_regno, mode, saved_nregs,
2234 : 39581545 : ira_memory_move_cost[mode][rclass][1] * saved_nregs / nregs,
2235 : : allocated_callee_save_regs, existing_spills_p);
2236 : 39581545 : add_cost += exit_cost * exit_freq;
2237 : :
2238 : 39581545 : cost += add_cost;
2239 : 39581545 : full_cost += add_cost;
2240 : : }
2241 : : }
2242 : 201386576 : if (ira_need_caller_save_p (a, hard_regno))
2243 : : {
2244 : 5878566 : cost += spill_cost;
2245 : 5878566 : full_cost += spill_cost;
2246 : : }
2247 : 201386576 : if (min_cost > cost)
2248 : : min_cost = cost;
2249 : 201386576 : if (min_full_cost > full_cost)
2250 : : {
2251 : 26439951 : min_full_cost = full_cost;
2252 : 26439951 : best_hard_regno = hard_regno;
2253 : 26439951 : ira_assert (hard_regno >= 0);
2254 : : }
2255 : 201386576 : if (internal_flag_ira_verbose > 5 && ira_dump_file != NULL)
2256 : 0 : fprintf (ira_dump_file, "(%d=%d,%d) ", hard_regno, cost, full_cost);
2257 : : }
2258 : 20380771 : if (internal_flag_ira_verbose > 5 && ira_dump_file != NULL)
2259 : 0 : fprintf (ira_dump_file, "\n");
2260 : 20380771 : if (min_full_cost > mem_cost
2261 : : /* Do not spill static chain pointer pseudo when non-local goto
2262 : : is used. */
2263 : 20380771 : && ! non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a)))
2264 : : {
2265 : 248199 : if (! retry_p && internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2266 : 0 : fprintf (ira_dump_file, "(memory is more profitable %d vs %d) ",
2267 : : mem_cost, min_full_cost);
2268 : : best_hard_regno = -1;
2269 : : }
2270 : 21296257 : fail:
2271 : 21296257 : if (best_hard_regno >= 0)
2272 : : {
2273 : 20132572 : record_allocation (best_hard_regno,
2274 : 20132572 : hard_regno_nregs (best_hard_regno, mode));
2275 : 20132572 : spill_soft_conflicts (a, allocnos_to_spill, soft_conflict_regs,
2276 : : best_hard_regno);
2277 : : }
2278 : : else
2279 : 1411884 : allocated_memory_p = true;
2280 : 21544456 : if (! retry_p)
2281 : 21544456 : restore_costs_from_copies (a);
2282 : 21544456 : ALLOCNO_HARD_REGNO (a) = best_hard_regno;
2283 : 21544456 : ALLOCNO_ASSIGNED_P (a) = true;
2284 : 21544456 : if (best_hard_regno >= 0 && !retry_p)
2285 : 20132572 : update_costs_from_copies (a, true, true);
2286 : 21544456 : ira_assert (ALLOCNO_CLASS (a) == aclass);
2287 : : /* We don't need updated costs anymore. */
2288 : 21544456 : ira_free_allocno_updated_costs (a);
2289 : 21544456 : return best_hard_regno >= 0;
2290 : 21544456 : }
2291 : :
2292 : :
2293 : :
2294 : : /* An array used to sort copies. */
2295 : : static ira_copy_t *sorted_copies;
2296 : :
2297 : : /* If allocno A is a cap, return non-cap allocno from which A is
2298 : : created. Otherwise, return A. */
2299 : : static ira_allocno_t
2300 : 0 : get_cap_member (ira_allocno_t a)
2301 : : {
2302 : 0 : ira_allocno_t member;
2303 : :
2304 : 25503946 : while ((member = ALLOCNO_CAP_MEMBER (a)) != NULL)
2305 : : a = member;
2306 : 0 : return a;
2307 : : }
2308 : :
2309 : : /* Return TRUE if live ranges of allocnos A1 and A2 intersect. It is
2310 : : used to find a conflict for new allocnos or allocnos with the
2311 : : different allocno classes. */
2312 : : static bool
2313 : 18935812 : allocnos_conflict_by_live_ranges_p (ira_allocno_t a1, ira_allocno_t a2)
2314 : : {
2315 : 18935812 : rtx reg1, reg2;
2316 : 18935812 : int i, j;
2317 : 18935812 : int n1 = ALLOCNO_NUM_OBJECTS (a1);
2318 : 18935812 : int n2 = ALLOCNO_NUM_OBJECTS (a2);
2319 : :
2320 : 18935812 : if (a1 == a2)
2321 : : return false;
2322 : 18935812 : reg1 = regno_reg_rtx[ALLOCNO_REGNO (a1)];
2323 : 18935812 : reg2 = regno_reg_rtx[ALLOCNO_REGNO (a2)];
2324 : 18935812 : if (reg1 != NULL && reg2 != NULL
2325 : 18935812 : && ORIGINAL_REGNO (reg1) == ORIGINAL_REGNO (reg2))
2326 : : return false;
2327 : :
2328 : : /* We don't keep live ranges for caps because they can be quite big.
2329 : : Use ranges of non-cap allocno from which caps are created. */
2330 : 25368062 : a1 = get_cap_member (a1);
2331 : 36700559 : a2 = get_cap_member (a2);
2332 : 36700559 : for (i = 0; i < n1; i++)
2333 : : {
2334 : 18979591 : ira_object_t c1 = ALLOCNO_OBJECT (a1, i);
2335 : :
2336 : 37110134 : for (j = 0; j < n2; j++)
2337 : : {
2338 : 19272076 : ira_object_t c2 = ALLOCNO_OBJECT (a2, j);
2339 : :
2340 : 19272076 : if (ira_live_ranges_intersect_p (OBJECT_LIVE_RANGES (c1),
2341 : : OBJECT_LIVE_RANGES (c2)))
2342 : : return true;
2343 : : }
2344 : : }
2345 : : return false;
2346 : : }
2347 : :
2348 : : /* The function is used to sort copies according to their execution
2349 : : frequencies. */
2350 : : static int
2351 : 108645629 : copy_freq_compare_func (const void *v1p, const void *v2p)
2352 : : {
2353 : 108645629 : ira_copy_t cp1 = *(const ira_copy_t *) v1p, cp2 = *(const ira_copy_t *) v2p;
2354 : 108645629 : int pri1, pri2;
2355 : :
2356 : 108645629 : pri1 = cp1->freq;
2357 : 108645629 : pri2 = cp2->freq;
2358 : 108645629 : if (pri2 - pri1)
2359 : 39534562 : return pri2 - pri1;
2360 : :
2361 : : /* If frequencies are equal, sort by copies, so that the results of
2362 : : qsort leave nothing to chance. */
2363 : 69111067 : return cp1->num - cp2->num;
2364 : : }
2365 : :
2366 : :
2367 : :
2368 : : /* Return true if any allocno from thread of A1 conflicts with any
2369 : : allocno from thread A2. */
2370 : : static bool
2371 : 6276985 : allocno_thread_conflict_p (ira_allocno_t a1, ira_allocno_t a2)
2372 : : {
2373 : 6276985 : ira_allocno_t a, conflict_a;
2374 : :
2375 : 6276985 : for (a = ALLOCNO_COLOR_DATA (a2)->next_thread_allocno;;
2376 : 5465998 : a = ALLOCNO_COLOR_DATA (a)->next_thread_allocno)
2377 : : {
2378 : 11742983 : for (conflict_a = ALLOCNO_COLOR_DATA (a1)->next_thread_allocno;;
2379 : 7192829 : conflict_a = ALLOCNO_COLOR_DATA (conflict_a)->next_thread_allocno)
2380 : : {
2381 : 18935812 : if (allocnos_conflict_by_live_ranges_p (a, conflict_a))
2382 : : return true;
2383 : 17794279 : if (conflict_a == a1)
2384 : : break;
2385 : : }
2386 : 10601450 : if (a == a2)
2387 : : break;
2388 : : }
2389 : : return false;
2390 : : }
2391 : :
2392 : : /* Merge two threads given correspondingly by their first allocnos T1
2393 : : and T2 (more accurately merging T2 into T1). */
2394 : : static void
2395 : 5135452 : merge_threads (ira_allocno_t t1, ira_allocno_t t2)
2396 : : {
2397 : 5135452 : ira_allocno_t a, next, last;
2398 : :
2399 : 5135452 : gcc_assert (t1 != t2
2400 : : && ALLOCNO_COLOR_DATA (t1)->first_thread_allocno == t1
2401 : : && ALLOCNO_COLOR_DATA (t2)->first_thread_allocno == t2);
2402 : 5135452 : for (last = t2, a = ALLOCNO_COLOR_DATA (t2)->next_thread_allocno;;
2403 : 5148924 : a = ALLOCNO_COLOR_DATA (a)->next_thread_allocno)
2404 : : {
2405 : 10284376 : ALLOCNO_COLOR_DATA (a)->first_thread_allocno = t1;
2406 : 10284376 : if (a == t2)
2407 : : break;
2408 : 5148924 : last = a;
2409 : : }
2410 : 5135452 : next = ALLOCNO_COLOR_DATA (t1)->next_thread_allocno;
2411 : 5135452 : ALLOCNO_COLOR_DATA (t1)->next_thread_allocno = t2;
2412 : 5135452 : ALLOCNO_COLOR_DATA (last)->next_thread_allocno = next;
2413 : 5135452 : ALLOCNO_COLOR_DATA (t1)->thread_freq += ALLOCNO_COLOR_DATA (t2)->thread_freq;
2414 : 5135452 : }
2415 : :
2416 : : /* Create threads by processing CP_NUM copies from sorted copies. We
2417 : : process the most expensive copies first. */
2418 : : static void
2419 : 7592226 : form_threads_from_copies (int cp_num)
2420 : : {
2421 : 7592226 : ira_allocno_t a, thread1, thread2;
2422 : 7592226 : ira_copy_t cp;
2423 : :
2424 : 7592226 : qsort (sorted_copies, cp_num, sizeof (ira_copy_t), copy_freq_compare_func);
2425 : : /* Form threads processing copies, most frequently executed
2426 : : first. */
2427 : 14860425 : for (int i = 0; i < cp_num; i++)
2428 : : {
2429 : 7268199 : cp = sorted_copies[i];
2430 : 7268199 : thread1 = ALLOCNO_COLOR_DATA (cp->first)->first_thread_allocno;
2431 : 7268199 : thread2 = ALLOCNO_COLOR_DATA (cp->second)->first_thread_allocno;
2432 : 7268199 : if (thread1 == thread2)
2433 : 991214 : continue;
2434 : 6276985 : if (! allocno_thread_conflict_p (thread1, thread2))
2435 : : {
2436 : 5135452 : if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2437 : 153 : fprintf
2438 : 153 : (ira_dump_file,
2439 : : " Forming thread by copy %d:a%dr%d-a%dr%d (freq=%d):\n",
2440 : 153 : cp->num, ALLOCNO_NUM (cp->first), ALLOCNO_REGNO (cp->first),
2441 : 153 : ALLOCNO_NUM (cp->second), ALLOCNO_REGNO (cp->second),
2442 : : cp->freq);
2443 : 5135452 : merge_threads (thread1, thread2);
2444 : 5135452 : if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2445 : : {
2446 : 153 : thread1 = ALLOCNO_COLOR_DATA (thread1)->first_thread_allocno;
2447 : 153 : fprintf (ira_dump_file, " Result (freq=%d): a%dr%d(%d)",
2448 : 153 : ALLOCNO_COLOR_DATA (thread1)->thread_freq,
2449 : : ALLOCNO_NUM (thread1), ALLOCNO_REGNO (thread1),
2450 : : ALLOCNO_FREQ (thread1));
2451 : 153 : for (a = ALLOCNO_COLOR_DATA (thread1)->next_thread_allocno;
2452 : 349 : a != thread1;
2453 : 196 : a = ALLOCNO_COLOR_DATA (a)->next_thread_allocno)
2454 : 196 : fprintf (ira_dump_file, " a%dr%d(%d)",
2455 : : ALLOCNO_NUM (a), ALLOCNO_REGNO (a),
2456 : : ALLOCNO_FREQ (a));
2457 : 153 : fprintf (ira_dump_file, "\n");
2458 : : }
2459 : : }
2460 : : }
2461 : 7592226 : }
2462 : :
2463 : : /* Create threads by processing copies of all alocnos from BUCKET. We
2464 : : process the most expensive copies first. */
2465 : : static void
2466 : 2592726 : form_threads_from_bucket (ira_allocno_t bucket)
2467 : : {
2468 : 2592726 : ira_allocno_t a;
2469 : 2592726 : ira_copy_t cp, next_cp;
2470 : 2592726 : int cp_num = 0;
2471 : :
2472 : 19645140 : for (a = bucket; a != NULL; a = ALLOCNO_COLOR_DATA (a)->next_bucket_allocno)
2473 : : {
2474 : 27709325 : for (cp = ALLOCNO_COPIES (a); cp != NULL; cp = next_cp)
2475 : : {
2476 : 10656911 : if (cp->first == a)
2477 : : {
2478 : 5241471 : next_cp = cp->next_first_allocno_copy;
2479 : 5241471 : sorted_copies[cp_num++] = cp;
2480 : : }
2481 : 5415440 : else if (cp->second == a)
2482 : 5415440 : next_cp = cp->next_second_allocno_copy;
2483 : : else
2484 : 0 : gcc_unreachable ();
2485 : : }
2486 : : }
2487 : 2592726 : form_threads_from_copies (cp_num);
2488 : 2592726 : }
2489 : :
2490 : : /* Create threads by processing copies of colorable allocno A. We
2491 : : process most expensive copies first. */
2492 : : static void
2493 : 4999500 : form_threads_from_colorable_allocno (ira_allocno_t a)
2494 : : {
2495 : 4999500 : ira_allocno_t another_a;
2496 : 4999500 : ira_copy_t cp, next_cp;
2497 : 4999500 : int cp_num = 0;
2498 : :
2499 : 4999500 : if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2500 : 52 : fprintf (ira_dump_file, " Forming thread from allocno a%dr%d:\n",
2501 : : ALLOCNO_NUM (a), ALLOCNO_REGNO (a));
2502 : 8361488 : for (cp = ALLOCNO_COPIES (a); cp != NULL; cp = next_cp)
2503 : : {
2504 : 3361988 : if (cp->first == a)
2505 : : {
2506 : 1854974 : next_cp = cp->next_first_allocno_copy;
2507 : 1854974 : another_a = cp->second;
2508 : : }
2509 : 1507014 : else if (cp->second == a)
2510 : : {
2511 : 1507014 : next_cp = cp->next_second_allocno_copy;
2512 : 1507014 : another_a = cp->first;
2513 : : }
2514 : : else
2515 : 0 : gcc_unreachable ();
2516 : 3361988 : if ((! ALLOCNO_COLOR_DATA (another_a)->in_graph_p
2517 : 3361988 : && !ALLOCNO_COLOR_DATA (another_a)->may_be_spilled_p)
2518 : 1987233 : || ALLOCNO_COLOR_DATA (another_a)->colorable_p)
2519 : 2026728 : sorted_copies[cp_num++] = cp;
2520 : : }
2521 : 4999500 : form_threads_from_copies (cp_num);
2522 : 4999500 : }
2523 : :
2524 : : /* Form initial threads which contain only one allocno. */
2525 : : static void
2526 : 1163854 : init_allocno_threads (void)
2527 : : {
2528 : 1163854 : ira_allocno_t a;
2529 : 1163854 : unsigned int j;
2530 : 1163854 : bitmap_iterator bi;
2531 : 1163854 : ira_pref_t pref;
2532 : :
2533 : 24955815 : EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
2534 : : {
2535 : 23791961 : a = ira_allocnos[j];
2536 : : /* Set up initial thread data: */
2537 : 23791961 : ALLOCNO_COLOR_DATA (a)->first_thread_allocno
2538 : 23791961 : = ALLOCNO_COLOR_DATA (a)->next_thread_allocno = a;
2539 : 23791961 : ALLOCNO_COLOR_DATA (a)->thread_freq = ALLOCNO_FREQ (a);
2540 : 23791961 : ALLOCNO_COLOR_DATA (a)->hard_reg_prefs = 0;
2541 : 28916973 : for (pref = ALLOCNO_PREFS (a); pref != NULL; pref = pref->next_pref)
2542 : 5125012 : ALLOCNO_COLOR_DATA (a)->hard_reg_prefs += pref->freq;
2543 : : }
2544 : 1163854 : }
2545 : :
2546 : :
2547 : :
2548 : : /* This page contains the allocator based on the Chaitin-Briggs algorithm. */
2549 : :
2550 : : /* Bucket of allocnos that can colored currently without spilling. */
2551 : : static ira_allocno_t colorable_allocno_bucket;
2552 : :
2553 : : /* Bucket of allocnos that might be not colored currently without
2554 : : spilling. */
2555 : : static ira_allocno_t uncolorable_allocno_bucket;
2556 : :
2557 : : /* The current number of allocnos in the uncolorable_bucket. */
2558 : : static int uncolorable_allocnos_num;
2559 : :
2560 : : /* Return the current spill priority of allocno A. The less the
2561 : : number, the more preferable the allocno for spilling. */
2562 : : static inline int
2563 : 368203572 : allocno_spill_priority (ira_allocno_t a)
2564 : : {
2565 : 368203572 : allocno_color_data_t data = ALLOCNO_COLOR_DATA (a);
2566 : :
2567 : 368203572 : return (data->temp
2568 : 368203572 : / (ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a)
2569 : 368203572 : * ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]
2570 : 368203572 : + 1));
2571 : : }
2572 : :
2573 : : /* Add allocno A to bucket *BUCKET_PTR. A should be not in a bucket
2574 : : before the call. */
2575 : : static void
2576 : 21149018 : add_allocno_to_bucket (ira_allocno_t a, ira_allocno_t *bucket_ptr)
2577 : : {
2578 : 21149018 : ira_allocno_t first_a;
2579 : 21149018 : allocno_color_data_t data;
2580 : :
2581 : 21149018 : if (bucket_ptr == &uncolorable_allocno_bucket
2582 : 6428407 : && ALLOCNO_CLASS (a) != NO_REGS)
2583 : : {
2584 : 6428407 : uncolorable_allocnos_num++;
2585 : 6428407 : ira_assert (uncolorable_allocnos_num > 0);
2586 : : }
2587 : 21149018 : first_a = *bucket_ptr;
2588 : 21149018 : data = ALLOCNO_COLOR_DATA (a);
2589 : 21149018 : data->next_bucket_allocno = first_a;
2590 : 21149018 : data->prev_bucket_allocno = NULL;
2591 : 21149018 : if (first_a != NULL)
2592 : 19797435 : ALLOCNO_COLOR_DATA (first_a)->prev_bucket_allocno = a;
2593 : 21149018 : *bucket_ptr = a;
2594 : 21149018 : }
2595 : :
2596 : : /* Compare two allocnos to define which allocno should be pushed first
2597 : : into the coloring stack. If the return is a negative number, the
2598 : : allocno given by the first parameter will be pushed first. In this
2599 : : case such allocno has less priority than the second one and the
2600 : : hard register will be assigned to it after assignment to the second
2601 : : one. As the result of such assignment order, the second allocno
2602 : : has a better chance to get the best hard register. */
2603 : : static int
2604 : 478661115 : bucket_allocno_compare_func (const void *v1p, const void *v2p)
2605 : : {
2606 : 478661115 : ira_allocno_t a1 = *(const ira_allocno_t *) v1p;
2607 : 478661115 : ira_allocno_t a2 = *(const ira_allocno_t *) v2p;
2608 : 478661115 : int diff, freq1, freq2, a1_num, a2_num, pref1, pref2;
2609 : 478661115 : ira_allocno_t t1 = ALLOCNO_COLOR_DATA (a1)->first_thread_allocno;
2610 : 478661115 : ira_allocno_t t2 = ALLOCNO_COLOR_DATA (a2)->first_thread_allocno;
2611 : 478661115 : int cl1 = ALLOCNO_CLASS (a1), cl2 = ALLOCNO_CLASS (a2);
2612 : :
2613 : 478661115 : freq1 = ALLOCNO_COLOR_DATA (t1)->thread_freq;
2614 : 478661115 : freq2 = ALLOCNO_COLOR_DATA (t2)->thread_freq;
2615 : 478661115 : if ((diff = freq1 - freq2) != 0)
2616 : : return diff;
2617 : :
2618 : 173534107 : if ((diff = ALLOCNO_NUM (t2) - ALLOCNO_NUM (t1)) != 0)
2619 : : return diff;
2620 : :
2621 : : /* Push pseudos requiring less hard registers first. It means that
2622 : : we will assign pseudos requiring more hard registers first
2623 : : avoiding creation small holes in free hard register file into
2624 : : which the pseudos requiring more hard registers cannot fit. */
2625 : 22652860 : if ((diff = (ira_reg_class_max_nregs[cl1][ALLOCNO_MODE (a1)]
2626 : 22652860 : - ira_reg_class_max_nregs[cl2][ALLOCNO_MODE (a2)])) != 0)
2627 : : return diff;
2628 : :
2629 : 22454707 : freq1 = ALLOCNO_FREQ (a1);
2630 : 22454707 : freq2 = ALLOCNO_FREQ (a2);
2631 : 22454707 : if ((diff = freq1 - freq2) != 0)
2632 : : return diff;
2633 : :
2634 : 13868734 : a1_num = ALLOCNO_COLOR_DATA (a1)->available_regs_num;
2635 : 13868734 : a2_num = ALLOCNO_COLOR_DATA (a2)->available_regs_num;
2636 : 13868734 : if ((diff = a2_num - a1_num) != 0)
2637 : : return diff;
2638 : : /* Push allocnos with minimal conflict_allocno_hard_prefs first. */
2639 : 11596110 : pref1 = ALLOCNO_COLOR_DATA (a1)->conflict_allocno_hard_prefs;
2640 : 11596110 : pref2 = ALLOCNO_COLOR_DATA (a2)->conflict_allocno_hard_prefs;
2641 : 11596110 : if ((diff = pref1 - pref2) != 0)
2642 : : return diff;
2643 : 11274615 : return ALLOCNO_NUM (a2) - ALLOCNO_NUM (a1);
2644 : : }
2645 : :
2646 : : /* Sort bucket *BUCKET_PTR and return the result through
2647 : : BUCKET_PTR. */
2648 : : static void
2649 : 3756545 : sort_bucket (ira_allocno_t *bucket_ptr,
2650 : : int (*compare_func) (const void *, const void *))
2651 : : {
2652 : 3756545 : ira_allocno_t a, head;
2653 : 3756545 : int n;
2654 : :
2655 : 3756545 : for (n = 0, a = *bucket_ptr;
2656 : 27237366 : a != NULL;
2657 : 23480821 : a = ALLOCNO_COLOR_DATA (a)->next_bucket_allocno)
2658 : 23480821 : sorted_allocnos[n++] = a;
2659 : 3756545 : if (n <= 1)
2660 : : return;
2661 : 1590107 : qsort (sorted_allocnos, n, sizeof (ira_allocno_t), compare_func);
2662 : 1590107 : head = NULL;
2663 : 24832342 : for (n--; n >= 0; n--)
2664 : : {
2665 : 23242235 : a = sorted_allocnos[n];
2666 : 23242235 : ALLOCNO_COLOR_DATA (a)->next_bucket_allocno = head;
2667 : 23242235 : ALLOCNO_COLOR_DATA (a)->prev_bucket_allocno = NULL;
2668 : 23242235 : if (head != NULL)
2669 : 21652128 : ALLOCNO_COLOR_DATA (head)->prev_bucket_allocno = a;
2670 : 23242235 : head = a;
2671 : : }
2672 : 1590107 : *bucket_ptr = head;
2673 : : }
2674 : :
2675 : : /* Add ALLOCNO to colorable bucket maintaining the order according
2676 : : their priority. ALLOCNO should be not in a bucket before the
2677 : : call. */
2678 : : static void
2679 : 4999500 : add_allocno_to_ordered_colorable_bucket (ira_allocno_t allocno)
2680 : : {
2681 : 4999500 : ira_allocno_t before, after;
2682 : :
2683 : 4999500 : form_threads_from_colorable_allocno (allocno);
2684 : 4999500 : for (before = colorable_allocno_bucket, after = NULL;
2685 : 38201900 : before != NULL;
2686 : 33202400 : after = before,
2687 : 33202400 : before = ALLOCNO_COLOR_DATA (before)->next_bucket_allocno)
2688 : 37002787 : if (bucket_allocno_compare_func (&allocno, &before) < 0)
2689 : : break;
2690 : 4999500 : ALLOCNO_COLOR_DATA (allocno)->next_bucket_allocno = before;
2691 : 4999500 : ALLOCNO_COLOR_DATA (allocno)->prev_bucket_allocno = after;
2692 : 4999500 : if (after == NULL)
2693 : 2517580 : colorable_allocno_bucket = allocno;
2694 : : else
2695 : 2481920 : ALLOCNO_COLOR_DATA (after)->next_bucket_allocno = allocno;
2696 : 4999500 : if (before != NULL)
2697 : 3800387 : ALLOCNO_COLOR_DATA (before)->prev_bucket_allocno = allocno;
2698 : 4999500 : }
2699 : :
2700 : : /* Delete ALLOCNO from bucket *BUCKET_PTR. It should be there before
2701 : : the call. */
2702 : : static void
2703 : 26148518 : delete_allocno_from_bucket (ira_allocno_t allocno, ira_allocno_t *bucket_ptr)
2704 : : {
2705 : 26148518 : ira_allocno_t prev_allocno, next_allocno;
2706 : :
2707 : 26148518 : if (bucket_ptr == &uncolorable_allocno_bucket
2708 : 6428407 : && ALLOCNO_CLASS (allocno) != NO_REGS)
2709 : : {
2710 : 6428407 : uncolorable_allocnos_num--;
2711 : 6428407 : ira_assert (uncolorable_allocnos_num >= 0);
2712 : : }
2713 : 26148518 : prev_allocno = ALLOCNO_COLOR_DATA (allocno)->prev_bucket_allocno;
2714 : 26148518 : next_allocno = ALLOCNO_COLOR_DATA (allocno)->next_bucket_allocno;
2715 : 26148518 : if (prev_allocno != NULL)
2716 : 3986585 : ALLOCNO_COLOR_DATA (prev_allocno)->next_bucket_allocno = next_allocno;
2717 : : else
2718 : : {
2719 : 22161933 : ira_assert (*bucket_ptr == allocno);
2720 : 22161933 : *bucket_ptr = next_allocno;
2721 : : }
2722 : 26148518 : if (next_allocno != NULL)
2723 : 23585835 : ALLOCNO_COLOR_DATA (next_allocno)->prev_bucket_allocno = prev_allocno;
2724 : 26148518 : }
2725 : :
2726 : : /* Put allocno A onto the coloring stack without removing it from its
2727 : : bucket. Pushing allocno to the coloring stack can result in moving
2728 : : conflicting allocnos from the uncolorable bucket to the colorable
2729 : : one. Update conflict_allocno_hard_prefs of the conflicting
2730 : : allocnos which are not on stack yet. */
2731 : : static void
2732 : 21149018 : push_allocno_to_stack (ira_allocno_t a)
2733 : : {
2734 : 21149018 : enum reg_class aclass;
2735 : 21149018 : allocno_color_data_t data, conflict_data;
2736 : 21149018 : int size, i, n = ALLOCNO_NUM_OBJECTS (a);
2737 : :
2738 : 21149018 : data = ALLOCNO_COLOR_DATA (a);
2739 : 21149018 : data->in_graph_p = false;
2740 : 21149018 : allocno_stack_vec.safe_push (a);
2741 : 21149018 : aclass = ALLOCNO_CLASS (a);
2742 : 21149018 : if (aclass == NO_REGS)
2743 : : return;
2744 : 21149018 : size = ira_reg_class_max_nregs[aclass][ALLOCNO_MODE (a)];
2745 : 21149018 : if (n > 1)
2746 : : {
2747 : : /* We will deal with the subwords individually. */
2748 : 428465 : gcc_assert (size == ALLOCNO_NUM_OBJECTS (a));
2749 : : size = 1;
2750 : : }
2751 : 42726501 : for (i = 0; i < n; i++)
2752 : : {
2753 : 21577483 : ira_object_t obj = ALLOCNO_OBJECT (a, i);
2754 : 21577483 : ira_object_t conflict_obj;
2755 : 21577483 : ira_object_conflict_iterator oci;
2756 : :
2757 : 465453713 : FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
2758 : : {
2759 : 443876230 : ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
2760 : 443876230 : ira_pref_t pref;
2761 : :
2762 : 443876230 : conflict_data = ALLOCNO_COLOR_DATA (conflict_a);
2763 : 692270511 : if (! conflict_data->in_graph_p
2764 : 198054142 : || ALLOCNO_ASSIGNED_P (conflict_a)
2765 : 443876230 : || !(hard_reg_set_intersect_p
2766 : 396108284 : (ALLOCNO_COLOR_DATA (a)->profitable_hard_regs,
2767 : : conflict_data->profitable_hard_regs)))
2768 : 248394281 : continue;
2769 : 213491825 : for (pref = ALLOCNO_PREFS (a); pref != NULL; pref = pref->next_pref)
2770 : 18009876 : conflict_data->conflict_allocno_hard_prefs -= pref->freq;
2771 : 195481949 : if (conflict_data->colorable_p)
2772 : 27221886 : continue;
2773 : 168260063 : ira_assert (bitmap_bit_p (coloring_allocno_bitmap,
2774 : : ALLOCNO_NUM (conflict_a)));
2775 : 168260063 : if (update_left_conflict_sizes_p (conflict_a, a, size))
2776 : : {
2777 : 4999500 : delete_allocno_from_bucket
2778 : 4999500 : (conflict_a, &uncolorable_allocno_bucket);
2779 : 4999500 : add_allocno_to_ordered_colorable_bucket (conflict_a);
2780 : 4999500 : if (internal_flag_ira_verbose > 4 && ira_dump_file != NULL)
2781 : : {
2782 : 52 : fprintf (ira_dump_file, " Making");
2783 : 52 : ira_print_expanded_allocno (conflict_a);
2784 : 52 : fprintf (ira_dump_file, " colorable\n");
2785 : : }
2786 : : }
2787 : :
2788 : : }
2789 : : }
2790 : : }
2791 : :
2792 : : /* Put ALLOCNO onto the coloring stack and remove it from its bucket.
2793 : : The allocno is in the colorable bucket if COLORABLE_P is TRUE. */
2794 : : static void
2795 : 21149018 : remove_allocno_from_bucket_and_push (ira_allocno_t allocno, bool colorable_p)
2796 : : {
2797 : 21149018 : if (colorable_p)
2798 : 19720111 : delete_allocno_from_bucket (allocno, &colorable_allocno_bucket);
2799 : : else
2800 : 1428907 : delete_allocno_from_bucket (allocno, &uncolorable_allocno_bucket);
2801 : 21149018 : if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2802 : : {
2803 : 452 : fprintf (ira_dump_file, " Pushing");
2804 : 452 : ira_print_expanded_allocno (allocno);
2805 : 452 : if (colorable_p)
2806 : 452 : fprintf (ira_dump_file, "(cost %d)\n",
2807 : 452 : ALLOCNO_COLOR_DATA (allocno)->temp);
2808 : : else
2809 : 0 : fprintf (ira_dump_file, "(potential spill: %spri=%d, cost=%d)\n",
2810 : 0 : ALLOCNO_BAD_SPILL_P (allocno) ? "bad spill, " : "",
2811 : : allocno_spill_priority (allocno),
2812 : 0 : ALLOCNO_COLOR_DATA (allocno)->temp);
2813 : : }
2814 : 21149018 : if (! colorable_p)
2815 : 1428907 : ALLOCNO_COLOR_DATA (allocno)->may_be_spilled_p = true;
2816 : 21149018 : push_allocno_to_stack (allocno);
2817 : 21149018 : }
2818 : :
2819 : : /* Put all allocnos from colorable bucket onto the coloring stack. */
2820 : : static void
2821 : 2592726 : push_only_colorable (void)
2822 : : {
2823 : 2592726 : if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2824 : 39 : fprintf (ira_dump_file, " Forming thread from colorable bucket:\n");
2825 : 2592726 : form_threads_from_bucket (colorable_allocno_bucket);
2826 : 2592726 : for (ira_allocno_t a = colorable_allocno_bucket;
2827 : 19645140 : a != NULL;
2828 : 17052414 : a = ALLOCNO_COLOR_DATA (a)->next_bucket_allocno)
2829 : 17052414 : update_costs_from_prefs (a);
2830 : 2592726 : sort_bucket (&colorable_allocno_bucket, bucket_allocno_compare_func);
2831 : 24905563 : for (;colorable_allocno_bucket != NULL;)
2832 : 19720111 : remove_allocno_from_bucket_and_push (colorable_allocno_bucket, true);
2833 : 2592726 : }
2834 : :
2835 : : /* Return the frequency of exit edges (if EXIT_P) or entry from/to the
2836 : : loop given by its LOOP_NODE. */
2837 : : int
2838 : 30895260 : ira_loop_edge_freq (ira_loop_tree_node_t loop_node, int regno, bool exit_p)
2839 : : {
2840 : 30895260 : int freq, i;
2841 : 30895260 : edge_iterator ei;
2842 : 30895260 : edge e;
2843 : :
2844 : 30895260 : ira_assert (current_loops != NULL && loop_node->loop != NULL
2845 : : && (regno < 0 || regno >= FIRST_PSEUDO_REGISTER));
2846 : 30895260 : freq = 0;
2847 : 30895260 : if (! exit_p)
2848 : : {
2849 : 48800553 : FOR_EACH_EDGE (e, ei, loop_node->loop->header->preds)
2850 : 33352923 : if (e->src != loop_node->loop->latch
2851 : 33352923 : && (regno < 0
2852 : 18394505 : || (bitmap_bit_p (df_get_live_out (e->src), regno)
2853 : 18108491 : && bitmap_bit_p (df_get_live_in (e->dest), regno))))
2854 : 18097555 : freq += EDGE_FREQUENCY (e);
2855 : : }
2856 : : else
2857 : : {
2858 : 15447630 : auto_vec<edge> edges = get_loop_exit_edges (loop_node->loop);
2859 : 81385649 : FOR_EACH_VEC_ELT (edges, i, e)
2860 : 35043578 : if (regno < 0
2861 : 35043578 : || (bitmap_bit_p (df_get_live_out (e->src), regno)
2862 : 31775781 : && bitmap_bit_p (df_get_live_in (e->dest), regno)))
2863 : 17960616 : freq += EDGE_FREQUENCY (e);
2864 : 15447630 : }
2865 : :
2866 : 30895260 : return REG_FREQ_FROM_EDGE_FREQ (freq);
2867 : : }
2868 : :
2869 : : /* Construct an object that describes the boundary between A and its
2870 : : parent allocno. */
2871 : 15447630 : ira_loop_border_costs::ira_loop_border_costs (ira_allocno_t a)
2872 : 15447630 : : m_mode (ALLOCNO_MODE (a)),
2873 : 15447630 : m_class (ALLOCNO_CLASS (a)),
2874 : 15447630 : m_entry_freq (ira_loop_edge_freq (ALLOCNO_LOOP_TREE_NODE (a),
2875 : : ALLOCNO_REGNO (a), false)),
2876 : 15447630 : m_exit_freq (ira_loop_edge_freq (ALLOCNO_LOOP_TREE_NODE (a),
2877 : : ALLOCNO_REGNO (a), true))
2878 : : {
2879 : 15447630 : }
2880 : :
2881 : : /* Calculate and return the cost of putting allocno A into memory. */
2882 : : static int
2883 : 6428407 : calculate_allocno_spill_cost (ira_allocno_t a)
2884 : : {
2885 : 6428407 : int regno, cost;
2886 : 6428407 : ira_allocno_t parent_allocno;
2887 : 6428407 : ira_loop_tree_node_t parent_node, loop_node;
2888 : :
2889 : 6428407 : regno = ALLOCNO_REGNO (a);
2890 : 6428407 : cost = ALLOCNO_UPDATED_MEMORY_COST (a) - ALLOCNO_UPDATED_CLASS_COST (a);
2891 : 6428407 : if (ALLOCNO_CAP (a) != NULL)
2892 : : return cost;
2893 : 4591459 : loop_node = ALLOCNO_LOOP_TREE_NODE (a);
2894 : 4591459 : if ((parent_node = loop_node->parent) == NULL)
2895 : : return cost;
2896 : 885717 : if ((parent_allocno = parent_node->regno_allocno_map[regno]) == NULL)
2897 : : return cost;
2898 : 885717 : ira_loop_border_costs border_costs (a);
2899 : 885717 : if (ALLOCNO_HARD_REGNO (parent_allocno) < 0)
2900 : 252900 : cost -= border_costs.spill_outside_loop_cost ();
2901 : : else
2902 : 1265634 : cost += (border_costs.spill_inside_loop_cost ()
2903 : 632817 : - border_costs.move_between_loops_cost ());
2904 : : return cost;
2905 : : }
2906 : :
2907 : : /* Used for sorting allocnos for spilling. */
2908 : : static inline int
2909 : 199648008 : allocno_spill_priority_compare (ira_allocno_t a1, ira_allocno_t a2)
2910 : : {
2911 : 199648008 : int pri1, pri2, diff;
2912 : :
2913 : : /* Avoid spilling static chain pointer pseudo when non-local goto is
2914 : : used. */
2915 : 199648008 : if (non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a1)))
2916 : : return 1;
2917 : 199648008 : else if (non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a2)))
2918 : : return -1;
2919 : 199648008 : if (ALLOCNO_BAD_SPILL_P (a1) && ! ALLOCNO_BAD_SPILL_P (a2))
2920 : : return 1;
2921 : 192058823 : if (ALLOCNO_BAD_SPILL_P (a2) && ! ALLOCNO_BAD_SPILL_P (a1))
2922 : : return -1;
2923 : 184101786 : pri1 = allocno_spill_priority (a1);
2924 : 184101786 : pri2 = allocno_spill_priority (a2);
2925 : 184101786 : if ((diff = pri1 - pri2) != 0)
2926 : : return diff;
2927 : 51192604 : if ((diff
2928 : 51192604 : = ALLOCNO_COLOR_DATA (a1)->temp - ALLOCNO_COLOR_DATA (a2)->temp) != 0)
2929 : : return diff;
2930 : 39557925 : return ALLOCNO_NUM (a1) - ALLOCNO_NUM (a2);
2931 : : }
2932 : :
2933 : : /* Used for sorting allocnos for spilling. */
2934 : : static int
2935 : 199648008 : allocno_spill_sort_compare (const void *v1p, const void *v2p)
2936 : : {
2937 : 199648008 : ira_allocno_t p1 = *(const ira_allocno_t *) v1p;
2938 : 199648008 : ira_allocno_t p2 = *(const ira_allocno_t *) v2p;
2939 : :
2940 : 199648008 : return allocno_spill_priority_compare (p1, p2);
2941 : : }
2942 : :
2943 : : /* Push allocnos to the coloring stack. The order of allocnos in the
2944 : : stack defines the order for the subsequent coloring. */
2945 : : static void
2946 : 1163819 : push_allocnos_to_stack (void)
2947 : : {
2948 : 1163819 : ira_allocno_t a;
2949 : 1163819 : int cost;
2950 : :
2951 : : /* Calculate uncolorable allocno spill costs. */
2952 : 1163819 : for (a = uncolorable_allocno_bucket;
2953 : 7592226 : a != NULL;
2954 : 6428407 : a = ALLOCNO_COLOR_DATA (a)->next_bucket_allocno)
2955 : 6428407 : if (ALLOCNO_CLASS (a) != NO_REGS)
2956 : : {
2957 : 6428407 : cost = calculate_allocno_spill_cost (a);
2958 : : /* ??? Remove cost of copies between the coalesced
2959 : : allocnos. */
2960 : 6428407 : ALLOCNO_COLOR_DATA (a)->temp = cost;
2961 : : }
2962 : 1163819 : sort_bucket (&uncolorable_allocno_bucket, allocno_spill_sort_compare);
2963 : 4021633 : for (;;)
2964 : : {
2965 : 2592726 : push_only_colorable ();
2966 : 2592726 : a = uncolorable_allocno_bucket;
2967 : 2592726 : if (a == NULL)
2968 : : break;
2969 : 1428907 : remove_allocno_from_bucket_and_push (a, false);
2970 : : }
2971 : 1163819 : ira_assert (colorable_allocno_bucket == NULL
2972 : : && uncolorable_allocno_bucket == NULL);
2973 : 1163819 : ira_assert (uncolorable_allocnos_num == 0);
2974 : 1163819 : }
2975 : :
2976 : : /* Pop the coloring stack and assign hard registers to the popped
2977 : : allocnos. */
2978 : : static void
2979 : 1163819 : pop_allocnos_from_stack (void)
2980 : : {
2981 : 1163819 : ira_allocno_t allocno;
2982 : 1163819 : enum reg_class aclass;
2983 : :
2984 : 22312837 : for (;allocno_stack_vec.length () != 0;)
2985 : : {
2986 : 21149018 : allocno = allocno_stack_vec.pop ();
2987 : 21149018 : aclass = ALLOCNO_CLASS (allocno);
2988 : 21149018 : if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2989 : : {
2990 : 452 : fprintf (ira_dump_file, " Popping");
2991 : 452 : ira_print_expanded_allocno (allocno);
2992 : 452 : fprintf (ira_dump_file, " -- ");
2993 : : }
2994 : 21149018 : if (aclass == NO_REGS)
2995 : : {
2996 : 0 : ALLOCNO_HARD_REGNO (allocno) = -1;
2997 : 0 : ALLOCNO_ASSIGNED_P (allocno) = true;
2998 : 0 : ira_assert (ALLOCNO_UPDATED_HARD_REG_COSTS (allocno) == NULL);
2999 : 0 : ira_assert
3000 : : (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (allocno) == NULL);
3001 : 0 : if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3002 : 0 : fprintf (ira_dump_file, "assign memory\n");
3003 : : }
3004 : 21149018 : else if (assign_hard_reg (allocno, false))
3005 : : {
3006 : 19967340 : if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3007 : 452 : fprintf (ira_dump_file, " assign reg %d\n",
3008 : 452 : ALLOCNO_HARD_REGNO (allocno));
3009 : : }
3010 : 1181678 : else if (ALLOCNO_ASSIGNED_P (allocno))
3011 : : {
3012 : 1181678 : if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3013 : 0 : fprintf (ira_dump_file, "spill%s\n",
3014 : 0 : ALLOCNO_COLOR_DATA (allocno)->may_be_spilled_p
3015 : : ? "" : "!");
3016 : : }
3017 : 21149018 : ALLOCNO_COLOR_DATA (allocno)->in_graph_p = true;
3018 : : }
3019 : 1163819 : }
3020 : :
3021 : : /* Set up number of available hard registers for allocno A. */
3022 : : static void
3023 : 21149018 : setup_allocno_available_regs_num (ira_allocno_t a)
3024 : : {
3025 : 21149018 : int i, n, hard_regno, hard_regs_num, nwords;
3026 : 21149018 : enum reg_class aclass;
3027 : 21149018 : allocno_color_data_t data;
3028 : :
3029 : 21149018 : aclass = ALLOCNO_CLASS (a);
3030 : 21149018 : data = ALLOCNO_COLOR_DATA (a);
3031 : 21149018 : data->available_regs_num = 0;
3032 : 21149018 : if (aclass == NO_REGS)
3033 : : return;
3034 : 21149018 : hard_regs_num = ira_class_hard_regs_num[aclass];
3035 : 21149018 : nwords = ALLOCNO_NUM_OBJECTS (a);
3036 : 320636218 : for (n = 0, i = hard_regs_num - 1; i >= 0; i--)
3037 : : {
3038 : 299487200 : hard_regno = ira_class_hard_regs[aclass][i];
3039 : : /* Checking only profitable hard regs. */
3040 : 299487200 : if (TEST_HARD_REG_BIT (data->profitable_hard_regs, hard_regno))
3041 : 276643980 : n++;
3042 : : }
3043 : 21149018 : data->available_regs_num = n;
3044 : 21149018 : if (internal_flag_ira_verbose <= 2 || ira_dump_file == NULL)
3045 : : return;
3046 : 452 : fprintf
3047 : 452 : (ira_dump_file,
3048 : : " Allocno a%dr%d of %s(%d) has %d avail. regs ",
3049 : : ALLOCNO_NUM (a), ALLOCNO_REGNO (a),
3050 : : reg_class_names[aclass], ira_class_hard_regs_num[aclass], n);
3051 : 452 : print_hard_reg_set (ira_dump_file, data->profitable_hard_regs, false);
3052 : 452 : fprintf (ira_dump_file, ", %snode: ",
3053 : 904 : data->profitable_hard_regs == data->hard_regs_node->hard_regs->set
3054 : : ? "" : "^");
3055 : 452 : print_hard_reg_set (ira_dump_file,
3056 : 452 : data->hard_regs_node->hard_regs->set, false);
3057 : 904 : for (i = 0; i < nwords; i++)
3058 : : {
3059 : 452 : ira_object_t obj = ALLOCNO_OBJECT (a, i);
3060 : :
3061 : 452 : if (nwords != 1)
3062 : : {
3063 : 0 : if (i != 0)
3064 : 0 : fprintf (ira_dump_file, ", ");
3065 : 0 : fprintf (ira_dump_file, " obj %d", i);
3066 : : }
3067 : 452 : fprintf (ira_dump_file, " (confl regs = ");
3068 : 452 : print_hard_reg_set (ira_dump_file, OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
3069 : : false);
3070 : 452 : fprintf (ira_dump_file, ")");
3071 : : }
3072 : 452 : fprintf (ira_dump_file, "\n");
3073 : : }
3074 : :
3075 : : /* Put ALLOCNO in a bucket corresponding to its number and size of its
3076 : : conflicting allocnos and hard registers. */
3077 : : static void
3078 : 21149018 : put_allocno_into_bucket (ira_allocno_t allocno)
3079 : : {
3080 : 21149018 : ALLOCNO_COLOR_DATA (allocno)->in_graph_p = true;
3081 : 21149018 : setup_allocno_available_regs_num (allocno);
3082 : 21149018 : if (setup_left_conflict_sizes_p (allocno))
3083 : 14720611 : add_allocno_to_bucket (allocno, &colorable_allocno_bucket);
3084 : : else
3085 : 6428407 : add_allocno_to_bucket (allocno, &uncolorable_allocno_bucket);
3086 : 21149018 : }
3087 : :
3088 : : /* Map: allocno number -> allocno priority. */
3089 : : static int *allocno_priorities;
3090 : :
3091 : : /* Set up priorities for N allocnos in array
3092 : : CONSIDERATION_ALLOCNOS. */
3093 : : static void
3094 : 428460 : setup_allocno_priorities (ira_allocno_t *consideration_allocnos, int n)
3095 : : {
3096 : 428460 : int i, length, nrefs, priority, max_priority, mult, diff;
3097 : 428460 : ira_allocno_t a;
3098 : :
3099 : 428460 : max_priority = 0;
3100 : 11703656 : for (i = 0; i < n; i++)
3101 : : {
3102 : 11275196 : a = consideration_allocnos[i];
3103 : 11275196 : nrefs = ALLOCNO_NREFS (a);
3104 : 11275196 : ira_assert (nrefs >= 0);
3105 : 11275196 : mult = floor_log2 (ALLOCNO_NREFS (a)) + 1;
3106 : 11275196 : ira_assert (mult >= 0);
3107 : 11275196 : mult *= ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)];
3108 : 11275196 : diff = ALLOCNO_MEMORY_COST (a) - ALLOCNO_CLASS_COST (a);
3109 : : #ifdef __has_builtin
3110 : : #if __has_builtin(__builtin_smul_overflow)
3111 : : #define HAS_SMUL_OVERFLOW
3112 : : #endif
3113 : : #endif
3114 : : /* Multiplication can overflow for very large functions.
3115 : : Check the overflow and constrain the result if necessary: */
3116 : : #ifdef HAS_SMUL_OVERFLOW
3117 : 11275196 : if (__builtin_smul_overflow (mult, diff, &priority)
3118 : 11275196 : || priority < -INT_MAX)
3119 : 1 : priority = diff >= 0 ? INT_MAX : -INT_MAX;
3120 : : #else
3121 : : static_assert
3122 : : (sizeof (long long) >= 2 * sizeof (int),
3123 : : "overflow code does not work for such int and long long sizes");
3124 : : long long priorityll = (long long) mult * diff;
3125 : : if (priorityll < -INT_MAX || priorityll > INT_MAX)
3126 : : priority = diff >= 0 ? INT_MAX : -INT_MAX;
3127 : : else
3128 : : priority = priorityll;
3129 : : #endif
3130 : 11275196 : allocno_priorities[ALLOCNO_NUM (a)] = priority;
3131 : 11275196 : if (priority < 0)
3132 : : priority = -priority;
3133 : 11275196 : if (max_priority < priority)
3134 : : max_priority = priority;
3135 : : }
3136 : 428460 : mult = max_priority == 0 ? 1 : INT_MAX / max_priority;
3137 : 11703656 : for (i = 0; i < n; i++)
3138 : : {
3139 : 11275196 : a = consideration_allocnos[i];
3140 : 11275196 : length = ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a);
3141 : 11275196 : if (ALLOCNO_NUM_OBJECTS (a) > 1)
3142 : 819656 : length /= ALLOCNO_NUM_OBJECTS (a);
3143 : 11275196 : if (length <= 0)
3144 : : length = 1;
3145 : 11275196 : allocno_priorities[ALLOCNO_NUM (a)]
3146 : 11275196 : = allocno_priorities[ALLOCNO_NUM (a)] * mult / length;
3147 : : }
3148 : 428460 : }
3149 : :
3150 : : /* Sort allocnos according to the profit of usage of a hard register
3151 : : instead of memory for them. */
3152 : : static int
3153 : 7279819 : allocno_cost_compare_func (const void *v1p, const void *v2p)
3154 : : {
3155 : 7279819 : ira_allocno_t p1 = *(const ira_allocno_t *) v1p;
3156 : 7279819 : ira_allocno_t p2 = *(const ira_allocno_t *) v2p;
3157 : 7279819 : int c1, c2;
3158 : :
3159 : 7279819 : c1 = ALLOCNO_UPDATED_MEMORY_COST (p1) - ALLOCNO_UPDATED_CLASS_COST (p1);
3160 : 7279819 : c2 = ALLOCNO_UPDATED_MEMORY_COST (p2) - ALLOCNO_UPDATED_CLASS_COST (p2);
3161 : 7279819 : if (c1 - c2)
3162 : 6304760 : return c1 - c2;
3163 : :
3164 : : /* If regs are equally good, sort by allocno numbers, so that the
3165 : : results of qsort leave nothing to chance. */
3166 : 975059 : return ALLOCNO_NUM (p1) - ALLOCNO_NUM (p2);
3167 : : }
3168 : :
3169 : : /* Return savings on removed copies when ALLOCNO is assigned to
3170 : : HARD_REGNO. */
3171 : : static int
3172 : 200033506 : allocno_copy_cost_saving (ira_allocno_t allocno, int hard_regno)
3173 : : {
3174 : 200033506 : int cost = 0;
3175 : 200033506 : machine_mode allocno_mode = ALLOCNO_MODE (allocno);
3176 : 200033506 : enum reg_class rclass;
3177 : 200033506 : ira_copy_t cp, next_cp;
3178 : :
3179 : 200033506 : rclass = REGNO_REG_CLASS (hard_regno);
3180 : 200033506 : if (ira_reg_class_max_nregs[rclass][allocno_mode]
3181 : 200033506 : > ira_class_hard_regs_num[rclass])
3182 : : /* For the above condition the cost can be wrong. Use the allocno
3183 : : class in this case. */
3184 : 3647216 : rclass = ALLOCNO_CLASS (allocno);
3185 : 335669483 : for (cp = ALLOCNO_COPIES (allocno); cp != NULL; cp = next_cp)
3186 : : {
3187 : 135635977 : if (cp->first == allocno)
3188 : : {
3189 : 69322463 : next_cp = cp->next_first_allocno_copy;
3190 : 69322463 : if (ALLOCNO_HARD_REGNO (cp->second) != hard_regno)
3191 : 46458439 : continue;
3192 : : }
3193 : 66313514 : else if (cp->second == allocno)
3194 : : {
3195 : 66313514 : next_cp = cp->next_second_allocno_copy;
3196 : 66313514 : if (ALLOCNO_HARD_REGNO (cp->first) != hard_regno)
3197 : 44150175 : continue;
3198 : : }
3199 : : else
3200 : 0 : gcc_unreachable ();
3201 : 45027363 : ira_init_register_move_cost_if_necessary (allocno_mode);
3202 : 45027363 : cost += cp->freq * ira_register_move_cost[allocno_mode][rclass][rclass];
3203 : : }
3204 : 200033506 : return cost;
3205 : : }
3206 : :
3207 : : /* We used Chaitin-Briggs coloring to assign as many pseudos as
3208 : : possible to hard registers. Let us try to improve allocation with
3209 : : cost point of view. This function improves the allocation by
3210 : : spilling some allocnos and assigning the freed hard registers to
3211 : : other allocnos if it decreases the overall allocation cost. */
3212 : : static void
3213 : 1163854 : improve_allocation (void)
3214 : : {
3215 : 1163854 : unsigned int i;
3216 : 1163854 : int j, k, n, hregno, conflict_hregno, base_cost, class_size, word, nwords;
3217 : 1163854 : int check, spill_cost, min_cost, nregs, conflict_nregs, r, best;
3218 : 1163854 : bool try_p;
3219 : 1163854 : enum reg_class aclass, rclass;
3220 : 1163854 : machine_mode mode;
3221 : 1163854 : int *allocno_costs;
3222 : 1163854 : int costs[FIRST_PSEUDO_REGISTER];
3223 : 1163854 : HARD_REG_SET conflicting_regs[2], profitable_hard_regs;
3224 : 1163854 : ira_allocno_t a;
3225 : 1163854 : bitmap_iterator bi;
3226 : 1163854 : int saved_nregs;
3227 : 1163854 : int add_cost;
3228 : :
3229 : : /* Don't bother to optimize the code with static chain pointer and
3230 : : non-local goto in order not to spill the chain pointer
3231 : : pseudo. */
3232 : 1163854 : if (cfun->static_chain_decl && crtl->has_nonlocal_goto)
3233 : 1080115 : return;
3234 : : /* Clear counts used to process conflicting allocnos only once for
3235 : : each allocno. */
3236 : 24048480 : EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
3237 : 22884975 : ALLOCNO_COLOR_DATA (ira_allocnos[i])->temp = 0;
3238 : 1163505 : check = n = 0;
3239 : : /* Process each allocno and try to assign a hard register to it by
3240 : : spilling some its conflicting allocnos. */
3241 : 24048480 : EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
3242 : : {
3243 : 22884975 : a = ira_allocnos[i];
3244 : 22884975 : ALLOCNO_COLOR_DATA (a)->temp = 0;
3245 : 45769950 : if (empty_profitable_hard_regs (a))
3246 : 22444810 : continue;
3247 : 21148763 : check++;
3248 : 21148763 : aclass = ALLOCNO_CLASS (a);
3249 : 21148763 : allocno_costs = ALLOCNO_HARD_REG_COSTS (a);
3250 : 21148763 : if ((hregno = ALLOCNO_HARD_REGNO (a)) < 0)
3251 : 1437411 : base_cost = ALLOCNO_UPDATED_MEMORY_COST (a);
3252 : 19711352 : else if (allocno_costs == NULL)
3253 : : /* It means that assigning a hard register is not profitable
3254 : : (we don't waste memory for hard register costs in this
3255 : : case). */
3256 : 12386332 : continue;
3257 : : else
3258 : 7325020 : base_cost = (allocno_costs[ira_class_hard_reg_index[aclass][hregno]]
3259 : 7325020 : - allocno_copy_cost_saving (a, hregno));
3260 : 8762431 : try_p = false;
3261 : 8762431 : get_conflict_and_start_profitable_regs (a, false,
3262 : : conflicting_regs,
3263 : : &profitable_hard_regs);
3264 : 8762431 : class_size = ira_class_hard_regs_num[aclass];
3265 : 8762431 : mode = ALLOCNO_MODE (a);
3266 : : /* Set up cost improvement for usage of each profitable hard
3267 : : register for allocno A. */
3268 : 143663412 : for (j = 0; j < class_size; j++)
3269 : : {
3270 : 134900981 : hregno = ira_class_hard_regs[aclass][j];
3271 : 134900981 : if (! check_hard_reg_p (a, hregno,
3272 : : conflicting_regs, profitable_hard_regs))
3273 : 20776875 : continue;
3274 : 114124106 : if (NUM_REGISTER_FILTERS
3275 : : && !test_register_filters (ALLOCNO_REGISTER_FILTERS (a), hregno))
3276 : : continue;
3277 : 114124106 : ira_assert (ira_class_hard_reg_index[aclass][hregno] == j);
3278 : 114124106 : k = allocno_costs == NULL ? 0 : j;
3279 : 228248212 : costs[hregno] = (allocno_costs == NULL
3280 : 114124106 : ? ALLOCNO_UPDATED_CLASS_COST (a) : allocno_costs[k]);
3281 : 114124106 : costs[hregno] -= allocno_copy_cost_saving (a, hregno);
3282 : :
3283 : 114124106 : if ((saved_nregs = calculate_saved_nregs (hregno, mode)) != 0)
3284 : : {
3285 : : /* We need to save/restore the hard register in
3286 : : epilogue/prologue. Therefore we increase the cost.
3287 : : Since the prolog is placed in the entry BB, the frequency
3288 : : of the entry BB is considered while computing the cost. */
3289 : 18113104 : rclass = REGNO_REG_CLASS (hregno);
3290 : 36226208 : add_cost = ((ira_memory_move_cost[mode][rclass][0]
3291 : 18113104 : + ira_memory_move_cost[mode][rclass][1])
3292 : 18113104 : * saved_nregs / hard_regno_nregs (hregno,
3293 : 18113104 : mode) - 1)
3294 : 18113104 : * REG_FREQ_FROM_BB (ENTRY_BLOCK_PTR_FOR_FN (cfun));
3295 : 18113104 : costs[hregno] += add_cost;
3296 : : }
3297 : :
3298 : 114124106 : costs[hregno] -= base_cost;
3299 : 114124106 : if (costs[hregno] < 0)
3300 : 134900981 : try_p = true;
3301 : : }
3302 : 8762431 : if (! try_p)
3303 : : /* There is no chance to improve the allocation cost by
3304 : : assigning hard register to allocno A even without spilling
3305 : : conflicting allocnos. */
3306 : 6690782 : continue;
3307 : 2071649 : auto_bitmap allocnos_to_spill;
3308 : 2071649 : HARD_REG_SET soft_conflict_regs = {};
3309 : 2071649 : mode = ALLOCNO_MODE (a);
3310 : 2071649 : nwords = ALLOCNO_NUM_OBJECTS (a);
3311 : : /* Process each allocno conflicting with A and update the cost
3312 : : improvement for profitable hard registers of A. To use a
3313 : : hard register for A we need to spill some conflicting
3314 : : allocnos and that creates penalty for the cost
3315 : : improvement. */
3316 : 4250219 : for (word = 0; word < nwords; word++)
3317 : : {
3318 : 2178570 : ira_object_t conflict_obj;
3319 : 2178570 : ira_object_t obj = ALLOCNO_OBJECT (a, word);
3320 : 2178570 : ira_object_conflict_iterator oci;
3321 : :
3322 : 169324327 : FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
3323 : : {
3324 : 167145757 : ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
3325 : :
3326 : 167145757 : if (ALLOCNO_COLOR_DATA (conflict_a)->temp == check)
3327 : : /* We already processed this conflicting allocno
3328 : : because we processed earlier another object of the
3329 : : conflicting allocno. */
3330 : 86271471 : continue;
3331 : 157005047 : ALLOCNO_COLOR_DATA (conflict_a)->temp = check;
3332 : 157005047 : if ((conflict_hregno = ALLOCNO_HARD_REGNO (conflict_a)) < 0)
3333 : 57949625 : continue;
3334 : 99055422 : auto spill_a = ira_soft_conflict (a, conflict_a);
3335 : 99055422 : if (spill_a)
3336 : : {
3337 : 20471042 : if (!bitmap_set_bit (allocnos_to_spill,
3338 : : ALLOCNO_NUM (spill_a)))
3339 : 18181136 : continue;
3340 : 2289906 : ira_loop_border_costs border_costs (spill_a);
3341 : 2289906 : spill_cost = border_costs.spill_inside_loop_cost ();
3342 : : }
3343 : : else
3344 : : {
3345 : 78584380 : spill_cost = ALLOCNO_UPDATED_MEMORY_COST (conflict_a);
3346 : 78584380 : k = (ira_class_hard_reg_index
3347 : 78584380 : [ALLOCNO_CLASS (conflict_a)][conflict_hregno]);
3348 : 78584380 : ira_assert (k >= 0);
3349 : 78584380 : if ((allocno_costs = ALLOCNO_HARD_REG_COSTS (conflict_a))
3350 : : != NULL)
3351 : 25028010 : spill_cost -= allocno_costs[k];
3352 : : else
3353 : 53556370 : spill_cost -= ALLOCNO_UPDATED_CLASS_COST (conflict_a);
3354 : 78584380 : spill_cost
3355 : 78584380 : += allocno_copy_cost_saving (conflict_a, conflict_hregno);
3356 : : }
3357 : 80874286 : conflict_nregs = hard_regno_nregs (conflict_hregno,
3358 : 80874286 : ALLOCNO_MODE (conflict_a));
3359 : 166297036 : auto note_conflict = [&](int r)
3360 : : {
3361 : 85422750 : if (check_hard_reg_p (a, r,
3362 : : conflicting_regs, profitable_hard_regs))
3363 : : {
3364 : 50705767 : if (spill_a)
3365 : 1759601 : SET_HARD_REG_BIT (soft_conflict_regs, r);
3366 : 50705767 : costs[r] += spill_cost;
3367 : : }
3368 : 166297036 : };
3369 : 164907549 : for (r = conflict_hregno;
3370 : 164907549 : r >= 0 && (int) end_hard_regno (mode, r) > conflict_hregno;
3371 : : r--)
3372 : 84033263 : note_conflict (r);
3373 : 82263773 : for (r = conflict_hregno + 1;
3374 : 82263773 : r < conflict_hregno + conflict_nregs;
3375 : : r++)
3376 : 1389487 : note_conflict (r);
3377 : : }
3378 : : }
3379 : : min_cost = INT_MAX;
3380 : : best = -1;
3381 : : /* Now we choose hard register for A which results in highest
3382 : : allocation cost improvement. */
3383 : 29162420 : for (j = 0; j < class_size; j++)
3384 : : {
3385 : 27090771 : hregno = ira_class_hard_regs[aclass][j];
3386 : 27090771 : if (check_hard_reg_p (a, hregno,
3387 : : conflicting_regs, profitable_hard_regs)
3388 : 27090771 : && min_cost > costs[hregno])
3389 : : {
3390 : 27090771 : best = hregno;
3391 : 27090771 : min_cost = costs[hregno];
3392 : : }
3393 : : }
3394 : 2071649 : if (min_cost >= 0)
3395 : : /* We are in a situation when assigning any hard register to A
3396 : : by spilling some conflicting allocnos does not improve the
3397 : : allocation cost. */
3398 : 1631484 : continue;
3399 : 440165 : spill_soft_conflicts (a, allocnos_to_spill, soft_conflict_regs, best);
3400 : 440165 : nregs = hard_regno_nregs (best, mode);
3401 : : /* Now spill conflicting allocnos which contain a hard register
3402 : : of A when we assign the best chosen hard register to it. */
3403 : 899345 : for (word = 0; word < nwords; word++)
3404 : : {
3405 : 459180 : ira_object_t conflict_obj;
3406 : 459180 : ira_object_t obj = ALLOCNO_OBJECT (a, word);
3407 : 459180 : ira_object_conflict_iterator oci;
3408 : :
3409 : 25225774 : FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
3410 : : {
3411 : 24766594 : ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
3412 : :
3413 : 24766594 : if ((conflict_hregno = ALLOCNO_HARD_REGNO (conflict_a)) < 0)
3414 : 11505833 : continue;
3415 : 13260761 : conflict_nregs = hard_regno_nregs (conflict_hregno,
3416 : 13260761 : ALLOCNO_MODE (conflict_a));
3417 : 13260761 : if (best + nregs <= conflict_hregno
3418 : 9933200 : || conflict_hregno + conflict_nregs <= best)
3419 : : /* No intersection. */
3420 : 12866396 : continue;
3421 : 394365 : ALLOCNO_HARD_REGNO (conflict_a) = -1;
3422 : 394365 : sorted_allocnos[n++] = conflict_a;
3423 : 394365 : if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
3424 : 0 : fprintf (ira_dump_file, "Spilling a%dr%d for a%dr%d\n",
3425 : : ALLOCNO_NUM (conflict_a), ALLOCNO_REGNO (conflict_a),
3426 : : ALLOCNO_NUM (a), ALLOCNO_REGNO (a));
3427 : : }
3428 : : }
3429 : : /* Assign the best chosen hard register to A. */
3430 : 440165 : ALLOCNO_HARD_REGNO (a) = best;
3431 : :
3432 : 440165 : record_allocation (best, nregs);
3433 : :
3434 : 440165 : if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
3435 : 1 : fprintf (ira_dump_file, "Assigning %d to a%dr%d\n",
3436 : : best, ALLOCNO_NUM (a), ALLOCNO_REGNO (a));
3437 : 2071649 : }
3438 : 1163505 : if (n == 0)
3439 : : return;
3440 : : /* We spilled some allocnos to assign their hard registers to other
3441 : : allocnos. The spilled allocnos are now in array
3442 : : 'sorted_allocnos'. There is still a possibility that some of the
3443 : : spilled allocnos can get hard registers. So let us try assign
3444 : : them hard registers again (just a reminder -- function
3445 : : 'assign_hard_reg' assigns hard registers only if it is possible
3446 : : and profitable). We process the spilled allocnos with biggest
3447 : : benefit to get hard register first -- see function
3448 : : 'allocno_cost_compare_func'. */
3449 : 83739 : qsort (sorted_allocnos, n, sizeof (ira_allocno_t),
3450 : : allocno_cost_compare_func);
3451 : 561843 : for (j = 0; j < n; j++)
3452 : : {
3453 : 394365 : a = sorted_allocnos[j];
3454 : 394365 : ALLOCNO_ASSIGNED_P (a) = false;
3455 : 394365 : if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3456 : : {
3457 : 0 : fprintf (ira_dump_file, " ");
3458 : 0 : ira_print_expanded_allocno (a);
3459 : 0 : fprintf (ira_dump_file, " -- ");
3460 : : }
3461 : 394365 : if (assign_hard_reg (a, false))
3462 : : {
3463 : 164221 : if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3464 : 0 : fprintf (ira_dump_file, "assign hard reg %d\n",
3465 : 0 : ALLOCNO_HARD_REGNO (a));
3466 : : }
3467 : : else
3468 : : {
3469 : 230144 : if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3470 : 0 : fprintf (ira_dump_file, "assign memory\n");
3471 : : }
3472 : : }
3473 : : }
3474 : :
3475 : : /* Sort allocnos according to their priorities. */
3476 : : static int
3477 : 399188469 : allocno_priority_compare_func (const void *v1p, const void *v2p)
3478 : : {
3479 : 399188469 : ira_allocno_t a1 = *(const ira_allocno_t *) v1p;
3480 : 399188469 : ira_allocno_t a2 = *(const ira_allocno_t *) v2p;
3481 : 399188469 : int pri1, pri2, diff;
3482 : :
3483 : : /* Assign hard reg to static chain pointer pseudo first when
3484 : : non-local goto is used. */
3485 : 399188469 : if ((diff = (non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a2))
3486 : 399188469 : - non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a1)))) != 0)
3487 : : return diff;
3488 : 399187581 : pri1 = allocno_priorities[ALLOCNO_NUM (a1)];
3489 : 399187581 : pri2 = allocno_priorities[ALLOCNO_NUM (a2)];
3490 : 399187581 : if (pri2 != pri1)
3491 : 211985770 : return SORTGT (pri2, pri1);
3492 : :
3493 : : /* If regs are equally good, sort by allocnos, so that the results of
3494 : : qsort leave nothing to chance. */
3495 : 264255692 : return ALLOCNO_NUM (a1) - ALLOCNO_NUM (a2);
3496 : : }
3497 : :
3498 : : /* Chaitin-Briggs coloring for allocnos in COLORING_ALLOCNO_BITMAP
3499 : : taking into account allocnos in CONSIDERATION_ALLOCNO_BITMAP. */
3500 : : static void
3501 : 1163854 : color_allocnos (void)
3502 : : {
3503 : 1163854 : unsigned int i, n;
3504 : 1163854 : bitmap_iterator bi;
3505 : 1163854 : ira_allocno_t a;
3506 : :
3507 : 1163854 : setup_profitable_hard_regs ();
3508 : 24050157 : EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
3509 : : {
3510 : 22886303 : allocno_color_data_t data;
3511 : 22886303 : ira_pref_t pref, next_pref;
3512 : :
3513 : 22886303 : a = ira_allocnos[i];
3514 : 22886303 : data = ALLOCNO_COLOR_DATA (a);
3515 : 22886303 : data->conflict_allocno_hard_prefs = 0;
3516 : 27993486 : for (pref = ALLOCNO_PREFS (a); pref != NULL; pref = next_pref)
3517 : : {
3518 : 5107183 : next_pref = pref->next_pref;
3519 : 5107183 : if (! ira_hard_reg_in_set_p (pref->hard_regno,
3520 : 5107183 : ALLOCNO_MODE (a),
3521 : : data->profitable_hard_regs))
3522 : 861003 : ira_remove_pref (pref);
3523 : : }
3524 : : }
3525 : :
3526 : 1163854 : if (flag_ira_algorithm == IRA_ALGORITHM_PRIORITY)
3527 : : {
3528 : 35 : n = 0;
3529 : 1131 : EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
3530 : : {
3531 : 1096 : a = ira_allocnos[i];
3532 : 1096 : if (ALLOCNO_CLASS (a) == NO_REGS)
3533 : : {
3534 : 23 : ALLOCNO_HARD_REGNO (a) = -1;
3535 : 23 : ALLOCNO_ASSIGNED_P (a) = true;
3536 : 23 : ira_assert (ALLOCNO_UPDATED_HARD_REG_COSTS (a) == NULL);
3537 : 23 : ira_assert (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a) == NULL);
3538 : 23 : if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3539 : : {
3540 : 0 : fprintf (ira_dump_file, " Spill");
3541 : 0 : ira_print_expanded_allocno (a);
3542 : 0 : fprintf (ira_dump_file, "\n");
3543 : : }
3544 : 23 : continue;
3545 : : }
3546 : 1073 : sorted_allocnos[n++] = a;
3547 : : }
3548 : 35 : if (n != 0)
3549 : : {
3550 : 32 : setup_allocno_priorities (sorted_allocnos, n);
3551 : 32 : qsort (sorted_allocnos, n, sizeof (ira_allocno_t),
3552 : : allocno_priority_compare_func);
3553 : 1105 : for (i = 0; i < n; i++)
3554 : : {
3555 : 1073 : a = sorted_allocnos[i];
3556 : 1073 : if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3557 : : {
3558 : 0 : fprintf (ira_dump_file, " ");
3559 : 0 : ira_print_expanded_allocno (a);
3560 : 0 : fprintf (ira_dump_file, " -- ");
3561 : : }
3562 : 1073 : if (assign_hard_reg (a, false))
3563 : : {
3564 : 1011 : if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3565 : 0 : fprintf (ira_dump_file, "assign hard reg %d\n",
3566 : 0 : ALLOCNO_HARD_REGNO (a));
3567 : : }
3568 : : else
3569 : : {
3570 : 62 : if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3571 : 0 : fprintf (ira_dump_file, "assign memory\n");
3572 : : }
3573 : : }
3574 : : }
3575 : : }
3576 : : else
3577 : : {
3578 : 1163819 : form_allocno_hard_regs_nodes_forest ();
3579 : 1163819 : if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
3580 : 39 : print_hard_regs_forest (ira_dump_file);
3581 : 24049026 : EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
3582 : : {
3583 : 22885207 : a = ira_allocnos[i];
3584 : 45312428 : if (ALLOCNO_CLASS (a) != NO_REGS && ! empty_profitable_hard_regs (a))
3585 : : {
3586 : 21149018 : ALLOCNO_COLOR_DATA (a)->in_graph_p = true;
3587 : 21149018 : update_conflict_allocno_hard_prefs (a);
3588 : : }
3589 : : else
3590 : : {
3591 : 1736189 : ALLOCNO_HARD_REGNO (a) = -1;
3592 : 1736189 : ALLOCNO_ASSIGNED_P (a) = true;
3593 : : /* We don't need updated costs anymore. */
3594 : 1736189 : ira_free_allocno_updated_costs (a);
3595 : 1736189 : if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3596 : : {
3597 : 1 : fprintf (ira_dump_file, " Spill");
3598 : 1 : ira_print_expanded_allocno (a);
3599 : 1 : fprintf (ira_dump_file, "\n");
3600 : : }
3601 : : }
3602 : : }
3603 : : /* Put the allocnos into the corresponding buckets. */
3604 : 1163819 : colorable_allocno_bucket = NULL;
3605 : 1163819 : uncolorable_allocno_bucket = NULL;
3606 : 24049026 : EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
3607 : : {
3608 : 22885207 : a = ira_allocnos[i];
3609 : 22885207 : if (ALLOCNO_COLOR_DATA (a)->in_graph_p)
3610 : 21149018 : put_allocno_into_bucket (a);
3611 : : }
3612 : 1163819 : push_allocnos_to_stack ();
3613 : 1163819 : pop_allocnos_from_stack ();
3614 : 1163819 : finish_allocno_hard_regs_nodes_forest ();
3615 : : }
3616 : 1163854 : improve_allocation ();
3617 : 1163854 : }
3618 : :
3619 : :
3620 : :
3621 : : /* Output information about the loop given by its LOOP_TREE_NODE. */
3622 : : static void
3623 : 39 : print_loop_title (ira_loop_tree_node_t loop_tree_node)
3624 : : {
3625 : 39 : unsigned int j;
3626 : 39 : bitmap_iterator bi;
3627 : 39 : ira_loop_tree_node_t subloop_node, dest_loop_node;
3628 : 39 : edge e;
3629 : 39 : edge_iterator ei;
3630 : :
3631 : 39 : if (loop_tree_node->parent == NULL)
3632 : 39 : fprintf (ira_dump_file,
3633 : : "\n Loop 0 (parent -1, header bb%d, depth 0)\n bbs:",
3634 : : NUM_FIXED_BLOCKS);
3635 : : else
3636 : : {
3637 : 0 : ira_assert (current_loops != NULL && loop_tree_node->loop != NULL);
3638 : 0 : fprintf (ira_dump_file,
3639 : : "\n Loop %d (parent %d, header bb%d, depth %d)\n bbs:",
3640 : : loop_tree_node->loop_num, loop_tree_node->parent->loop_num,
3641 : 0 : loop_tree_node->loop->header->index,
3642 : 0 : loop_depth (loop_tree_node->loop));
3643 : : }
3644 : 39 : for (subloop_node = loop_tree_node->children;
3645 : 329 : subloop_node != NULL;
3646 : 290 : subloop_node = subloop_node->next)
3647 : 290 : if (subloop_node->bb != NULL)
3648 : : {
3649 : 290 : fprintf (ira_dump_file, " %d", subloop_node->bb->index);
3650 : 707 : FOR_EACH_EDGE (e, ei, subloop_node->bb->succs)
3651 : 417 : if (e->dest != EXIT_BLOCK_PTR_FOR_FN (cfun)
3652 : 417 : && ((dest_loop_node = IRA_BB_NODE (e->dest)->parent)
3653 : : != loop_tree_node))
3654 : 0 : fprintf (ira_dump_file, "(->%d:l%d)",
3655 : : e->dest->index, dest_loop_node->loop_num);
3656 : : }
3657 : 39 : fprintf (ira_dump_file, "\n all:");
3658 : 492 : EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->all_allocnos, 0, j, bi)
3659 : 453 : fprintf (ira_dump_file, " %dr%d", j, ALLOCNO_REGNO (ira_allocnos[j]));
3660 : 39 : fprintf (ira_dump_file, "\n modified regnos:");
3661 : 492 : EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->modified_regnos, 0, j, bi)
3662 : 453 : fprintf (ira_dump_file, " %d", j);
3663 : 39 : fprintf (ira_dump_file, "\n border:");
3664 : 39 : EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->border_allocnos, 0, j, bi)
3665 : 0 : fprintf (ira_dump_file, " %dr%d", j, ALLOCNO_REGNO (ira_allocnos[j]));
3666 : 39 : fprintf (ira_dump_file, "\n Pressure:");
3667 : 195 : for (j = 0; (int) j < ira_pressure_classes_num; j++)
3668 : : {
3669 : 156 : enum reg_class pclass;
3670 : :
3671 : 156 : pclass = ira_pressure_classes[j];
3672 : 156 : if (loop_tree_node->reg_pressure[pclass] == 0)
3673 : 110 : continue;
3674 : 46 : fprintf (ira_dump_file, " %s=%d", reg_class_names[pclass],
3675 : : loop_tree_node->reg_pressure[pclass]);
3676 : : }
3677 : 39 : fprintf (ira_dump_file, "\n");
3678 : 39 : }
3679 : :
3680 : : /* Color the allocnos inside loop (in the extreme case it can be all
3681 : : of the function) given the corresponding LOOP_TREE_NODE. The
3682 : : function is called for each loop during top-down traverse of the
3683 : : loop tree. */
3684 : : static void
3685 : 1163854 : color_pass (ira_loop_tree_node_t loop_tree_node)
3686 : : {
3687 : 1163854 : int regno, hard_regno, index = -1, n;
3688 : 1163854 : int cost;
3689 : 1163854 : unsigned int j;
3690 : 1163854 : bitmap_iterator bi;
3691 : 1163854 : machine_mode mode;
3692 : 1163854 : enum reg_class rclass, aclass;
3693 : 1163854 : ira_allocno_t a, subloop_allocno;
3694 : 1163854 : ira_loop_tree_node_t subloop_node;
3695 : :
3696 : 1163854 : ira_assert (loop_tree_node->bb == NULL);
3697 : 1163854 : if (internal_flag_ira_verbose > 1 && ira_dump_file != NULL)
3698 : 39 : print_loop_title (loop_tree_node);
3699 : :
3700 : 1163854 : bitmap_copy (coloring_allocno_bitmap, loop_tree_node->all_allocnos);
3701 : 1163854 : bitmap_copy (consideration_allocno_bitmap, coloring_allocno_bitmap);
3702 : 1163854 : n = 0;
3703 : 24955815 : EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
3704 : : {
3705 : 23791961 : a = ira_allocnos[j];
3706 : 23791961 : n++;
3707 : 23791961 : if (! ALLOCNO_ASSIGNED_P (a))
3708 : 22886303 : continue;
3709 : 905658 : bitmap_clear_bit (coloring_allocno_bitmap, ALLOCNO_NUM (a));
3710 : : }
3711 : 1163854 : allocno_color_data
3712 : 2327708 : = (allocno_color_data_t) ira_allocate (sizeof (struct allocno_color_data)
3713 : 1163854 : * n);
3714 : 1163854 : memset (allocno_color_data, 0, sizeof (struct allocno_color_data) * n);
3715 : 1163854 : curr_allocno_process = 0;
3716 : 1163854 : n = 0;
3717 : 24955815 : EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
3718 : : {
3719 : 23791961 : a = ira_allocnos[j];
3720 : 23791961 : ALLOCNO_ADD_DATA (a) = allocno_color_data + n;
3721 : 23791961 : n++;
3722 : : }
3723 : 1163854 : init_allocno_threads ();
3724 : : /* Color all mentioned allocnos including transparent ones. */
3725 : 1163854 : color_allocnos ();
3726 : : /* Process caps. They are processed just once. */
3727 : 1163854 : if (flag_ira_region == IRA_REGION_MIXED
3728 : 1163854 : || flag_ira_region == IRA_REGION_ALL)
3729 : 24398821 : EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->all_allocnos, 0, j, bi)
3730 : : {
3731 : 23278128 : a = ira_allocnos[j];
3732 : 23278128 : if (ALLOCNO_CAP_MEMBER (a) == NULL)
3733 : 19732526 : continue;
3734 : : /* Remove from processing in the next loop. */
3735 : 3545602 : bitmap_clear_bit (consideration_allocno_bitmap, j);
3736 : 3545602 : rclass = ALLOCNO_CLASS (a);
3737 : 3545602 : subloop_allocno = ALLOCNO_CAP_MEMBER (a);
3738 : 3545602 : subloop_node = ALLOCNO_LOOP_TREE_NODE (subloop_allocno);
3739 : 3545602 : if (ira_single_region_allocno_p (a, subloop_allocno))
3740 : : {
3741 : 511370 : mode = ALLOCNO_MODE (a);
3742 : 511370 : hard_regno = ALLOCNO_HARD_REGNO (a);
3743 : 511370 : if (hard_regno >= 0)
3744 : : {
3745 : 398161 : index = ira_class_hard_reg_index[rclass][hard_regno];
3746 : 398161 : ira_assert (index >= 0);
3747 : : }
3748 : 511370 : regno = ALLOCNO_REGNO (a);
3749 : 511370 : ira_assert (!ALLOCNO_ASSIGNED_P (subloop_allocno));
3750 : 511370 : ALLOCNO_HARD_REGNO (subloop_allocno) = hard_regno;
3751 : 511370 : ALLOCNO_ASSIGNED_P (subloop_allocno) = true;
3752 : 511370 : if (hard_regno >= 0)
3753 : 398161 : update_costs_from_copies (subloop_allocno, true, true);
3754 : : /* We don't need updated costs anymore. */
3755 : 511370 : ira_free_allocno_updated_costs (subloop_allocno);
3756 : : }
3757 : : }
3758 : : /* Update costs of the corresponding allocnos (not caps) in the
3759 : : subloops. */
3760 : 1163854 : for (subloop_node = loop_tree_node->subloops;
3761 : 1324514 : subloop_node != NULL;
3762 : 160660 : subloop_node = subloop_node->subloop_next)
3763 : : {
3764 : 160660 : ira_assert (subloop_node->bb == NULL);
3765 : 26680310 : EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
3766 : : {
3767 : 26519650 : a = ira_allocnos[j];
3768 : 26519650 : ira_assert (ALLOCNO_CAP_MEMBER (a) == NULL);
3769 : 26519650 : mode = ALLOCNO_MODE (a);
3770 : 26519650 : rclass = ALLOCNO_CLASS (a);
3771 : 26519650 : hard_regno = ALLOCNO_HARD_REGNO (a);
3772 : : /* Use hard register class here. ??? */
3773 : 26519650 : if (hard_regno >= 0)
3774 : : {
3775 : 22855896 : index = ira_class_hard_reg_index[rclass][hard_regno];
3776 : 22855896 : ira_assert (index >= 0);
3777 : : }
3778 : 26519650 : regno = ALLOCNO_REGNO (a);
3779 : : /* ??? conflict costs */
3780 : 26519650 : subloop_allocno = subloop_node->regno_allocno_map[regno];
3781 : 26519650 : if (subloop_allocno == NULL
3782 : 2927298 : || ALLOCNO_CAP (subloop_allocno) != NULL)
3783 : 23593756 : continue;
3784 : 2925894 : ira_assert (ALLOCNO_CLASS (subloop_allocno) == rclass);
3785 : 2925894 : ira_assert (bitmap_bit_p (subloop_node->all_allocnos,
3786 : : ALLOCNO_NUM (subloop_allocno)));
3787 : 2925894 : if (ira_single_region_allocno_p (a, subloop_allocno)
3788 : 2925894 : || !ira_subloop_allocnos_can_differ_p (a, hard_regno >= 0,
3789 : : false))
3790 : : {
3791 : 394288 : gcc_assert (!ALLOCNO_MIGHT_CONFLICT_WITH_PARENT_P
3792 : : (subloop_allocno));
3793 : 394288 : if (! ALLOCNO_ASSIGNED_P (subloop_allocno))
3794 : : {
3795 : 394288 : ALLOCNO_HARD_REGNO (subloop_allocno) = hard_regno;
3796 : 394288 : ALLOCNO_ASSIGNED_P (subloop_allocno) = true;
3797 : 394288 : if (hard_regno >= 0)
3798 : 152510 : update_costs_from_copies (subloop_allocno, true, true);
3799 : : /* We don't need updated costs anymore. */
3800 : 394288 : ira_free_allocno_updated_costs (subloop_allocno);
3801 : : }
3802 : : }
3803 : 2531606 : else if (hard_regno < 0)
3804 : : {
3805 : : /* If we allocate a register to SUBLOOP_ALLOCNO, we'll need
3806 : : to load the register on entry to the subloop and store
3807 : : the register back on exit from the subloop. This incurs
3808 : : a fixed cost for all registers. Since UPDATED_MEMORY_COST
3809 : : is (and should only be) used relative to the register costs
3810 : : for the same allocno, we can subtract this shared register
3811 : : cost from the memory cost. */
3812 : 1437358 : ira_loop_border_costs border_costs (subloop_allocno);
3813 : 1437358 : ALLOCNO_UPDATED_MEMORY_COST (subloop_allocno)
3814 : 1437358 : -= border_costs.spill_outside_loop_cost ();
3815 : : }
3816 : : else
3817 : : {
3818 : 1094248 : ira_loop_border_costs border_costs (subloop_allocno);
3819 : 1094248 : aclass = ALLOCNO_CLASS (subloop_allocno);
3820 : 1094248 : ira_init_register_move_cost_if_necessary (mode);
3821 : 1094248 : cost = border_costs.move_between_loops_cost ();
3822 : 1094248 : ira_allocate_and_set_or_copy_costs
3823 : 1094248 : (&ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno), aclass,
3824 : : ALLOCNO_UPDATED_CLASS_COST (subloop_allocno),
3825 : : ALLOCNO_HARD_REG_COSTS (subloop_allocno));
3826 : 1094248 : ira_allocate_and_set_or_copy_costs
3827 : 1094248 : (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (subloop_allocno),
3828 : : aclass, 0, ALLOCNO_CONFLICT_HARD_REG_COSTS (subloop_allocno));
3829 : 1094248 : ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno)[index] -= cost;
3830 : 1094248 : ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (subloop_allocno)[index]
3831 : 1094248 : -= cost;
3832 : 1094248 : if (ALLOCNO_UPDATED_CLASS_COST (subloop_allocno)
3833 : 1094248 : > ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno)[index])
3834 : 1050804 : ALLOCNO_UPDATED_CLASS_COST (subloop_allocno)
3835 : 1050804 : = ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno)[index];
3836 : : /* If we spill SUBLOOP_ALLOCNO, we'll need to store HARD_REGNO
3837 : : on entry to the subloop and restore HARD_REGNO on exit from
3838 : : the subloop. */
3839 : 1094248 : ALLOCNO_UPDATED_MEMORY_COST (subloop_allocno)
3840 : 1094248 : += border_costs.spill_inside_loop_cost ();
3841 : : }
3842 : : }
3843 : : }
3844 : 1163854 : ira_free (allocno_color_data);
3845 : 21410213 : EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
3846 : : {
3847 : 20246359 : a = ira_allocnos[j];
3848 : 20246359 : ALLOCNO_ADD_DATA (a) = NULL;
3849 : : }
3850 : 1163854 : }
3851 : :
3852 : : /* Initialize the common data for coloring and calls functions to do
3853 : : Chaitin-Briggs and regional coloring. */
3854 : : static void
3855 : 1003194 : do_coloring (void)
3856 : : {
3857 : 1003194 : coloring_allocno_bitmap = ira_allocate_bitmap ();
3858 : 1003194 : if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
3859 : 39 : fprintf (ira_dump_file, "\n**** Allocnos coloring:\n\n");
3860 : :
3861 : 1003194 : ira_traverse_loop_tree (false, ira_loop_tree_root, color_pass, NULL);
3862 : :
3863 : 1003194 : if (internal_flag_ira_verbose > 1 && ira_dump_file != NULL)
3864 : 39 : ira_print_disposition (ira_dump_file);
3865 : :
3866 : 1003194 : ira_free_bitmap (coloring_allocno_bitmap);
3867 : 1003194 : }
3868 : :
3869 : :
3870 : :
3871 : : /* Move spill/restore code, which are to be generated in ira-emit.cc,
3872 : : to less frequent points (if it is profitable) by reassigning some
3873 : : allocnos (in loop with subloops containing in another loop) to
3874 : : memory which results in longer live-range where the corresponding
3875 : : pseudo-registers will be in memory. */
3876 : : static void
3877 : 1003194 : move_spill_restore (void)
3878 : : {
3879 : 1007267 : int cost, regno, hard_regno, hard_regno2, index;
3880 : 1007267 : bool changed_p;
3881 : 1007267 : machine_mode mode;
3882 : 1007267 : enum reg_class rclass;
3883 : 1007267 : ira_allocno_t a, parent_allocno, subloop_allocno;
3884 : 1007267 : ira_loop_tree_node_t parent, loop_node, subloop_node;
3885 : 1007267 : ira_allocno_iterator ai;
3886 : :
3887 : 1007267 : for (;;)
3888 : : {
3889 : 1007267 : changed_p = false;
3890 : 1007267 : if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
3891 : 39 : fprintf (ira_dump_file, "New iteration of spill/restore move\n");
3892 : 31274976 : FOR_EACH_ALLOCNO (a, ai)
3893 : : {
3894 : 30267709 : regno = ALLOCNO_REGNO (a);
3895 : 30267709 : loop_node = ALLOCNO_LOOP_TREE_NODE (a);
3896 : 58999437 : if (ALLOCNO_CAP_MEMBER (a) != NULL
3897 : 23274981 : || ALLOCNO_CAP (a) != NULL
3898 : 20528505 : || (hard_regno = ALLOCNO_HARD_REGNO (a)) < 0
3899 : 16383300 : || loop_node->children == NULL
3900 : : /* don't do the optimization because it can create
3901 : : copies and the reload pass can spill the allocno set
3902 : : by copy although the allocno will not get memory
3903 : : slot. */
3904 : 16383300 : || ira_equiv_no_lvalue_p (regno)
3905 : 14775656 : || !bitmap_bit_p (loop_node->border_allocnos, ALLOCNO_NUM (a))
3906 : : /* Do not spill static chain pointer pseudo when
3907 : : non-local goto is used. */
3908 : 31803690 : || non_spilled_static_chain_regno_p (regno))
3909 : 28731728 : continue;
3910 : 1535981 : mode = ALLOCNO_MODE (a);
3911 : 1535981 : rclass = ALLOCNO_CLASS (a);
3912 : 1535981 : index = ira_class_hard_reg_index[rclass][hard_regno];
3913 : 1535981 : ira_assert (index >= 0);
3914 : 3071962 : cost = (ALLOCNO_MEMORY_COST (a)
3915 : 1535981 : - (ALLOCNO_HARD_REG_COSTS (a) == NULL
3916 : 1535981 : ? ALLOCNO_CLASS_COST (a)
3917 : 313917 : : ALLOCNO_HARD_REG_COSTS (a)[index]));
3918 : 1535981 : ira_init_register_move_cost_if_necessary (mode);
3919 : 1535981 : for (subloop_node = loop_node->subloops;
3920 : 2167890 : subloop_node != NULL;
3921 : 631909 : subloop_node = subloop_node->subloop_next)
3922 : : {
3923 : 631909 : ira_assert (subloop_node->bb == NULL);
3924 : 631909 : subloop_allocno = subloop_node->regno_allocno_map[regno];
3925 : 631909 : if (subloop_allocno == NULL)
3926 : 65225 : continue;
3927 : 566684 : ira_assert (rclass == ALLOCNO_CLASS (subloop_allocno));
3928 : 566684 : ira_loop_border_costs border_costs (subloop_allocno);
3929 : :
3930 : : /* We have accumulated cost. To get the real cost of
3931 : : allocno usage in the loop we should subtract the costs
3932 : : added by propagate_allocno_info for the subloop allocnos. */
3933 : 1133368 : int reg_cost
3934 : 566684 : = (ALLOCNO_HARD_REG_COSTS (subloop_allocno) == NULL
3935 : 566684 : ? ALLOCNO_CLASS_COST (subloop_allocno)
3936 : 98958 : : ALLOCNO_HARD_REG_COSTS (subloop_allocno)[index]);
3937 : :
3938 : 566684 : int spill_cost
3939 : 566684 : = (border_costs.spill_inside_loop_cost ()
3940 : 566684 : + ALLOCNO_MEMORY_COST (subloop_allocno));
3941 : :
3942 : : /* If HARD_REGNO conflicts with SUBLOOP_A then
3943 : : propagate_allocno_info will have propagated
3944 : : the cost of spilling HARD_REGNO in SUBLOOP_NODE.
3945 : : (ira_subloop_allocnos_can_differ_p must be true
3946 : : in that case.) If HARD_REGNO is a caller-saved
3947 : : register, we might have modelled it in the same way.
3948 : :
3949 : : Otherwise, SPILL_COST acted as a cap on the propagated
3950 : : register cost, in cases where the allocations can differ. */
3951 : 566684 : auto conflicts = ira_total_conflict_hard_regs (subloop_allocno);
3952 : 566684 : if (TEST_HARD_REG_BIT (conflicts, hard_regno)
3953 : 566684 : || (ira_need_caller_save_p (subloop_allocno, hard_regno)
3954 : 12447 : && ira_caller_save_loop_spill_p (a, subloop_allocno,
3955 : : spill_cost)))
3956 : : reg_cost = spill_cost;
3957 : 555963 : else if (ira_subloop_allocnos_can_differ_p (a))
3958 : 552962 : reg_cost = MIN (reg_cost, spill_cost);
3959 : :
3960 : 566684 : cost -= ALLOCNO_MEMORY_COST (subloop_allocno) - reg_cost;
3961 : :
3962 : 566684 : if ((hard_regno2 = ALLOCNO_HARD_REGNO (subloop_allocno)) < 0)
3963 : : /* The register was spilled in the subloop. If we spill
3964 : : it in the outer loop too then we'll no longer need to
3965 : : save the register on entry to the subloop and restore
3966 : : the register on exit from the subloop. */
3967 : 69791 : cost -= border_costs.spill_inside_loop_cost ();
3968 : : else
3969 : : {
3970 : : /* The register was also allocated in the subloop. If we
3971 : : spill it in the outer loop then we'll need to load the
3972 : : register on entry to the subloop and store the register
3973 : : back on exit from the subloop. */
3974 : 496893 : cost += border_costs.spill_outside_loop_cost ();
3975 : 496893 : if (hard_regno2 != hard_regno)
3976 : 25664 : cost -= border_costs.move_between_loops_cost ();
3977 : : }
3978 : : }
3979 : 1535981 : if ((parent = loop_node->parent) != NULL
3980 : 1535981 : && (parent_allocno = parent->regno_allocno_map[regno]) != NULL)
3981 : : {
3982 : 1535981 : ira_assert (rclass == ALLOCNO_CLASS (parent_allocno));
3983 : 1535981 : ira_loop_border_costs border_costs (a);
3984 : 1535981 : if ((hard_regno2 = ALLOCNO_HARD_REGNO (parent_allocno)) < 0)
3985 : : /* The register was spilled in the parent loop. If we spill
3986 : : it in this loop too then we'll no longer need to load the
3987 : : register on entry to this loop and save the register back
3988 : : on exit from this loop. */
3989 : 68520 : cost -= border_costs.spill_outside_loop_cost ();
3990 : : else
3991 : : {
3992 : : /* The register was also allocated in the parent loop.
3993 : : If we spill it in this loop then we'll need to save
3994 : : the register on entry to this loop and restore the
3995 : : register on exit from this loop. */
3996 : 1467461 : cost += border_costs.spill_inside_loop_cost ();
3997 : 1467461 : if (hard_regno2 != hard_regno)
3998 : 90358 : cost -= border_costs.move_between_loops_cost ();
3999 : : }
4000 : : }
4001 : 1535981 : if (cost < 0)
4002 : : {
4003 : 11522 : ALLOCNO_HARD_REGNO (a) = -1;
4004 : 11522 : if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4005 : : {
4006 : 0 : fprintf
4007 : 0 : (ira_dump_file,
4008 : : " Moving spill/restore for a%dr%d up from loop %d",
4009 : : ALLOCNO_NUM (a), regno, loop_node->loop_num);
4010 : 0 : fprintf (ira_dump_file, " - profit %d\n", -cost);
4011 : : }
4012 : : changed_p = true;
4013 : : }
4014 : : }
4015 : 1007267 : if (! changed_p)
4016 : : break;
4017 : : }
4018 : 1003194 : }
4019 : :
4020 : :
4021 : :
4022 : : /* Update current hard reg costs and current conflict hard reg costs
4023 : : for allocno A. It is done by processing its copies containing
4024 : : other allocnos already assigned. */
4025 : : static void
4026 : 0 : update_curr_costs (ira_allocno_t a)
4027 : : {
4028 : 0 : int i, hard_regno, cost;
4029 : 0 : machine_mode mode;
4030 : 0 : enum reg_class aclass, rclass;
4031 : 0 : ira_allocno_t another_a;
4032 : 0 : ira_copy_t cp, next_cp;
4033 : :
4034 : 0 : ira_free_allocno_updated_costs (a);
4035 : 0 : ira_assert (! ALLOCNO_ASSIGNED_P (a));
4036 : 0 : aclass = ALLOCNO_CLASS (a);
4037 : 0 : if (aclass == NO_REGS)
4038 : : return;
4039 : 0 : mode = ALLOCNO_MODE (a);
4040 : 0 : ira_init_register_move_cost_if_necessary (mode);
4041 : 0 : for (cp = ALLOCNO_COPIES (a); cp != NULL; cp = next_cp)
4042 : : {
4043 : 0 : if (cp->first == a)
4044 : : {
4045 : 0 : next_cp = cp->next_first_allocno_copy;
4046 : 0 : another_a = cp->second;
4047 : : }
4048 : 0 : else if (cp->second == a)
4049 : : {
4050 : 0 : next_cp = cp->next_second_allocno_copy;
4051 : 0 : another_a = cp->first;
4052 : : }
4053 : : else
4054 : 0 : gcc_unreachable ();
4055 : 0 : if (! ira_reg_classes_intersect_p[aclass][ALLOCNO_CLASS (another_a)]
4056 : 0 : || ! ALLOCNO_ASSIGNED_P (another_a)
4057 : 0 : || (hard_regno = ALLOCNO_HARD_REGNO (another_a)) < 0)
4058 : 0 : continue;
4059 : 0 : rclass = REGNO_REG_CLASS (hard_regno);
4060 : 0 : i = ira_class_hard_reg_index[aclass][hard_regno];
4061 : 0 : if (i < 0)
4062 : 0 : continue;
4063 : 0 : cost = (cp->first == a
4064 : 0 : ? ira_register_move_cost[mode][rclass][aclass]
4065 : 0 : : ira_register_move_cost[mode][aclass][rclass]);
4066 : 0 : ira_allocate_and_set_or_copy_costs
4067 : 0 : (&ALLOCNO_UPDATED_HARD_REG_COSTS (a), aclass, ALLOCNO_CLASS_COST (a),
4068 : : ALLOCNO_HARD_REG_COSTS (a));
4069 : 0 : ira_allocate_and_set_or_copy_costs
4070 : 0 : (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a),
4071 : : aclass, 0, ALLOCNO_CONFLICT_HARD_REG_COSTS (a));
4072 : 0 : ALLOCNO_UPDATED_HARD_REG_COSTS (a)[i] -= cp->freq * cost;
4073 : 0 : ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a)[i] -= cp->freq * cost;
4074 : : }
4075 : : }
4076 : :
4077 : : /* Try to assign hard registers to the unassigned allocnos and
4078 : : allocnos conflicting with them or conflicting with allocnos whose
4079 : : regno >= START_REGNO. The function is called after ira_flattening,
4080 : : so more allocnos (including ones created in ira-emit.cc) will have a
4081 : : chance to get a hard register. We use simple assignment algorithm
4082 : : based on priorities. */
4083 : : void
4084 : 0 : ira_reassign_conflict_allocnos (int start_regno)
4085 : : {
4086 : 0 : int i, allocnos_to_color_num;
4087 : 0 : ira_allocno_t a;
4088 : 0 : enum reg_class aclass;
4089 : 0 : bitmap allocnos_to_color;
4090 : 0 : ira_allocno_iterator ai;
4091 : :
4092 : 0 : allocnos_to_color = ira_allocate_bitmap ();
4093 : 0 : allocnos_to_color_num = 0;
4094 : 0 : FOR_EACH_ALLOCNO (a, ai)
4095 : : {
4096 : 0 : int n = ALLOCNO_NUM_OBJECTS (a);
4097 : :
4098 : 0 : if (! ALLOCNO_ASSIGNED_P (a)
4099 : 0 : && ! bitmap_bit_p (allocnos_to_color, ALLOCNO_NUM (a)))
4100 : : {
4101 : 0 : if (ALLOCNO_CLASS (a) != NO_REGS)
4102 : 0 : sorted_allocnos[allocnos_to_color_num++] = a;
4103 : : else
4104 : : {
4105 : 0 : ALLOCNO_ASSIGNED_P (a) = true;
4106 : 0 : ALLOCNO_HARD_REGNO (a) = -1;
4107 : 0 : ira_assert (ALLOCNO_UPDATED_HARD_REG_COSTS (a) == NULL);
4108 : 0 : ira_assert (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a) == NULL);
4109 : : }
4110 : 0 : bitmap_set_bit (allocnos_to_color, ALLOCNO_NUM (a));
4111 : : }
4112 : 0 : if (ALLOCNO_REGNO (a) < start_regno
4113 : 0 : || (aclass = ALLOCNO_CLASS (a)) == NO_REGS)
4114 : 0 : continue;
4115 : 0 : for (i = 0; i < n; i++)
4116 : : {
4117 : 0 : ira_object_t obj = ALLOCNO_OBJECT (a, i);
4118 : 0 : ira_object_t conflict_obj;
4119 : 0 : ira_object_conflict_iterator oci;
4120 : :
4121 : 0 : FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
4122 : : {
4123 : 0 : ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
4124 : :
4125 : 0 : ira_assert (ira_reg_classes_intersect_p
4126 : : [aclass][ALLOCNO_CLASS (conflict_a)]);
4127 : 0 : if (!bitmap_set_bit (allocnos_to_color, ALLOCNO_NUM (conflict_a)))
4128 : 0 : continue;
4129 : 0 : sorted_allocnos[allocnos_to_color_num++] = conflict_a;
4130 : : }
4131 : : }
4132 : : }
4133 : 0 : ira_free_bitmap (allocnos_to_color);
4134 : 0 : if (allocnos_to_color_num > 1)
4135 : : {
4136 : 0 : setup_allocno_priorities (sorted_allocnos, allocnos_to_color_num);
4137 : 0 : qsort (sorted_allocnos, allocnos_to_color_num, sizeof (ira_allocno_t),
4138 : : allocno_priority_compare_func);
4139 : : }
4140 : 0 : for (i = 0; i < allocnos_to_color_num; i++)
4141 : : {
4142 : 0 : a = sorted_allocnos[i];
4143 : 0 : ALLOCNO_ASSIGNED_P (a) = false;
4144 : 0 : update_curr_costs (a);
4145 : : }
4146 : 0 : for (i = 0; i < allocnos_to_color_num; i++)
4147 : : {
4148 : 0 : a = sorted_allocnos[i];
4149 : 0 : if (assign_hard_reg (a, true))
4150 : : {
4151 : 0 : if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4152 : 0 : fprintf
4153 : 0 : (ira_dump_file,
4154 : : " Secondary allocation: assign hard reg %d to reg %d\n",
4155 : 0 : ALLOCNO_HARD_REGNO (a), ALLOCNO_REGNO (a));
4156 : : }
4157 : : }
4158 : 0 : }
4159 : :
4160 : :
4161 : :
4162 : : /* This page contains functions used to find conflicts using allocno
4163 : : live ranges. */
4164 : :
4165 : : #ifdef ENABLE_IRA_CHECKING
4166 : :
4167 : : /* Return TRUE if live ranges of pseudo-registers REGNO1 and REGNO2
4168 : : intersect. This should be used when there is only one region.
4169 : : Currently this is used during reload. */
4170 : : static bool
4171 : 0 : conflict_by_live_ranges_p (int regno1, int regno2)
4172 : : {
4173 : 0 : ira_allocno_t a1, a2;
4174 : :
4175 : 0 : ira_assert (regno1 >= FIRST_PSEUDO_REGISTER
4176 : : && regno2 >= FIRST_PSEUDO_REGISTER);
4177 : : /* Reg info calculated by dataflow infrastructure can be different
4178 : : from one calculated by regclass. */
4179 : 0 : if ((a1 = ira_loop_tree_root->regno_allocno_map[regno1]) == NULL
4180 : 0 : || (a2 = ira_loop_tree_root->regno_allocno_map[regno2]) == NULL)
4181 : : return false;
4182 : 0 : return allocnos_conflict_by_live_ranges_p (a1, a2);
4183 : : }
4184 : :
4185 : : #endif
4186 : :
4187 : :
4188 : :
4189 : : /* This page contains code to coalesce memory stack slots used by
4190 : : spilled allocnos. This results in smaller stack frame, better data
4191 : : locality, and in smaller code for some architectures like
4192 : : x86/x86_64 where insn size depends on address displacement value.
4193 : : On the other hand, it can worsen insn scheduling after the RA but
4194 : : in practice it is less important than smaller stack frames. */
4195 : :
4196 : : /* TRUE if we coalesced some allocnos. In other words, if we got
4197 : : loops formed by members first_coalesced_allocno and
4198 : : next_coalesced_allocno containing more one allocno. */
4199 : : static bool allocno_coalesced_p;
4200 : :
4201 : : /* Bitmap used to prevent a repeated allocno processing because of
4202 : : coalescing. */
4203 : : static bitmap processed_coalesced_allocno_bitmap;
4204 : :
4205 : : /* See below. */
4206 : : typedef struct coalesce_data *coalesce_data_t;
4207 : :
4208 : : /* To decrease footprint of ira_allocno structure we store all data
4209 : : needed only for coalescing in the following structure. */
4210 : : struct coalesce_data
4211 : : {
4212 : : /* Coalesced allocnos form a cyclic list. One allocno given by
4213 : : FIRST represents all coalesced allocnos. The
4214 : : list is chained by NEXT. */
4215 : : ira_allocno_t first;
4216 : : ira_allocno_t next;
4217 : : int temp;
4218 : : };
4219 : :
4220 : : /* Container for storing allocno data concerning coalescing. */
4221 : : static coalesce_data_t allocno_coalesce_data;
4222 : :
4223 : : /* Macro to access the data concerning coalescing. */
4224 : : #define ALLOCNO_COALESCE_DATA(a) ((coalesce_data_t) ALLOCNO_ADD_DATA (a))
4225 : :
4226 : : /* Merge two sets of coalesced allocnos given correspondingly by
4227 : : allocnos A1 and A2 (more accurately merging A2 set into A1
4228 : : set). */
4229 : : static void
4230 : 0 : merge_allocnos (ira_allocno_t a1, ira_allocno_t a2)
4231 : : {
4232 : 0 : ira_allocno_t a, first, last, next;
4233 : :
4234 : 0 : first = ALLOCNO_COALESCE_DATA (a1)->first;
4235 : 0 : a = ALLOCNO_COALESCE_DATA (a2)->first;
4236 : 0 : if (first == a)
4237 : : return;
4238 : 0 : for (last = a2, a = ALLOCNO_COALESCE_DATA (a2)->next;;
4239 : 0 : a = ALLOCNO_COALESCE_DATA (a)->next)
4240 : : {
4241 : 0 : ALLOCNO_COALESCE_DATA (a)->first = first;
4242 : 0 : if (a == a2)
4243 : : break;
4244 : 0 : last = a;
4245 : : }
4246 : 0 : next = allocno_coalesce_data[ALLOCNO_NUM (first)].next;
4247 : 0 : allocno_coalesce_data[ALLOCNO_NUM (first)].next = a2;
4248 : 0 : allocno_coalesce_data[ALLOCNO_NUM (last)].next = next;
4249 : : }
4250 : :
4251 : : /* Return TRUE if there are conflicting allocnos from two sets of
4252 : : coalesced allocnos given correspondingly by allocnos A1 and A2. We
4253 : : use live ranges to find conflicts because conflicts are represented
4254 : : only for allocnos of the same allocno class and during the reload
4255 : : pass we coalesce allocnos for sharing stack memory slots. */
4256 : : static bool
4257 : 0 : coalesced_allocno_conflict_p (ira_allocno_t a1, ira_allocno_t a2)
4258 : : {
4259 : 0 : ira_allocno_t a, conflict_a;
4260 : :
4261 : 0 : if (allocno_coalesced_p)
4262 : : {
4263 : 0 : bitmap_clear (processed_coalesced_allocno_bitmap);
4264 : 0 : for (a = ALLOCNO_COALESCE_DATA (a1)->next;;
4265 : 0 : a = ALLOCNO_COALESCE_DATA (a)->next)
4266 : : {
4267 : 0 : bitmap_set_bit (processed_coalesced_allocno_bitmap, ALLOCNO_NUM (a));
4268 : 0 : if (a == a1)
4269 : : break;
4270 : : }
4271 : : }
4272 : 0 : for (a = ALLOCNO_COALESCE_DATA (a2)->next;;
4273 : 0 : a = ALLOCNO_COALESCE_DATA (a)->next)
4274 : : {
4275 : 0 : for (conflict_a = ALLOCNO_COALESCE_DATA (a1)->next;;
4276 : 0 : conflict_a = ALLOCNO_COALESCE_DATA (conflict_a)->next)
4277 : : {
4278 : 0 : if (allocnos_conflict_by_live_ranges_p (a, conflict_a))
4279 : : return true;
4280 : 0 : if (conflict_a == a1)
4281 : : break;
4282 : : }
4283 : 0 : if (a == a2)
4284 : : break;
4285 : : }
4286 : : return false;
4287 : : }
4288 : :
4289 : : /* The major function for aggressive allocno coalescing. We coalesce
4290 : : only spilled allocnos. If some allocnos have been coalesced, we
4291 : : set up flag allocno_coalesced_p. */
4292 : : static void
4293 : 0 : coalesce_allocnos (void)
4294 : : {
4295 : 0 : ira_allocno_t a;
4296 : 0 : ira_copy_t cp, next_cp;
4297 : 0 : unsigned int j;
4298 : 0 : int i, n, cp_num, regno;
4299 : 0 : bitmap_iterator bi;
4300 : :
4301 : 0 : cp_num = 0;
4302 : : /* Collect copies. */
4303 : 0 : EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, j, bi)
4304 : : {
4305 : 0 : a = ira_allocnos[j];
4306 : 0 : regno = ALLOCNO_REGNO (a);
4307 : 0 : if (! ALLOCNO_ASSIGNED_P (a) || ALLOCNO_HARD_REGNO (a) >= 0
4308 : 0 : || ira_equiv_no_lvalue_p (regno))
4309 : 0 : continue;
4310 : 0 : for (cp = ALLOCNO_COPIES (a); cp != NULL; cp = next_cp)
4311 : : {
4312 : 0 : if (cp->first == a)
4313 : : {
4314 : 0 : next_cp = cp->next_first_allocno_copy;
4315 : 0 : regno = ALLOCNO_REGNO (cp->second);
4316 : : /* For priority coloring we coalesce allocnos only with
4317 : : the same allocno class not with intersected allocno
4318 : : classes as it were possible. It is done for
4319 : : simplicity. */
4320 : 0 : if ((cp->insn != NULL || cp->constraint_p)
4321 : 0 : && ALLOCNO_ASSIGNED_P (cp->second)
4322 : 0 : && ALLOCNO_HARD_REGNO (cp->second) < 0
4323 : 0 : && ! ira_equiv_no_lvalue_p (regno))
4324 : 0 : sorted_copies[cp_num++] = cp;
4325 : : }
4326 : 0 : else if (cp->second == a)
4327 : 0 : next_cp = cp->next_second_allocno_copy;
4328 : : else
4329 : 0 : gcc_unreachable ();
4330 : : }
4331 : : }
4332 : 0 : qsort (sorted_copies, cp_num, sizeof (ira_copy_t), copy_freq_compare_func);
4333 : : /* Coalesced copies, most frequently executed first. */
4334 : 0 : for (; cp_num != 0;)
4335 : : {
4336 : 0 : for (i = 0; i < cp_num; i++)
4337 : : {
4338 : 0 : cp = sorted_copies[i];
4339 : 0 : if (! coalesced_allocno_conflict_p (cp->first, cp->second))
4340 : : {
4341 : 0 : allocno_coalesced_p = true;
4342 : 0 : if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4343 : 0 : fprintf
4344 : 0 : (ira_dump_file,
4345 : : " Coalescing copy %d:a%dr%d-a%dr%d (freq=%d)\n",
4346 : 0 : cp->num, ALLOCNO_NUM (cp->first), ALLOCNO_REGNO (cp->first),
4347 : 0 : ALLOCNO_NUM (cp->second), ALLOCNO_REGNO (cp->second),
4348 : : cp->freq);
4349 : 0 : merge_allocnos (cp->first, cp->second);
4350 : 0 : i++;
4351 : 0 : break;
4352 : : }
4353 : : }
4354 : : /* Collect the rest of copies. */
4355 : 0 : for (n = 0; i < cp_num; i++)
4356 : : {
4357 : 0 : cp = sorted_copies[i];
4358 : 0 : if (allocno_coalesce_data[ALLOCNO_NUM (cp->first)].first
4359 : 0 : != allocno_coalesce_data[ALLOCNO_NUM (cp->second)].first)
4360 : 0 : sorted_copies[n++] = cp;
4361 : : }
4362 : : cp_num = n;
4363 : : }
4364 : 0 : }
4365 : :
4366 : : /* Usage cost and order number of coalesced allocno set to which
4367 : : given pseudo register belongs to. */
4368 : : static int *regno_coalesced_allocno_cost;
4369 : : static int *regno_coalesced_allocno_num;
4370 : :
4371 : : /* Sort pseudos according frequencies of coalesced allocno sets they
4372 : : belong to (putting most frequently ones first), and according to
4373 : : coalesced allocno set order numbers. */
4374 : : static int
4375 : 0 : coalesced_pseudo_reg_freq_compare (const void *v1p, const void *v2p)
4376 : : {
4377 : 0 : const int regno1 = *(const int *) v1p;
4378 : 0 : const int regno2 = *(const int *) v2p;
4379 : 0 : int diff;
4380 : :
4381 : 0 : if ((diff = (regno_coalesced_allocno_cost[regno2]
4382 : 0 : - regno_coalesced_allocno_cost[regno1])) != 0)
4383 : : return diff;
4384 : 0 : if ((diff = (regno_coalesced_allocno_num[regno1]
4385 : 0 : - regno_coalesced_allocno_num[regno2])) != 0)
4386 : : return diff;
4387 : 0 : return regno1 - regno2;
4388 : : }
4389 : :
4390 : : /* Widest width in which each pseudo reg is referred to (via subreg).
4391 : : It is used for sorting pseudo registers. */
4392 : : static machine_mode *regno_max_ref_mode;
4393 : :
4394 : : /* Sort pseudos according their slot numbers (putting ones with
4395 : : smaller numbers first, or last when the frame pointer is not
4396 : : needed). */
4397 : : static int
4398 : 0 : coalesced_pseudo_reg_slot_compare (const void *v1p, const void *v2p)
4399 : : {
4400 : 0 : const int regno1 = *(const int *) v1p;
4401 : 0 : const int regno2 = *(const int *) v2p;
4402 : 0 : ira_allocno_t a1 = ira_regno_allocno_map[regno1];
4403 : 0 : ira_allocno_t a2 = ira_regno_allocno_map[regno2];
4404 : 0 : int diff, slot_num1, slot_num2;
4405 : 0 : machine_mode mode1, mode2;
4406 : :
4407 : 0 : if (a1 == NULL || ALLOCNO_HARD_REGNO (a1) >= 0)
4408 : : {
4409 : 0 : if (a2 == NULL || ALLOCNO_HARD_REGNO (a2) >= 0)
4410 : 0 : return regno1 - regno2;
4411 : : return 1;
4412 : : }
4413 : 0 : else if (a2 == NULL || ALLOCNO_HARD_REGNO (a2) >= 0)
4414 : : return -1;
4415 : 0 : slot_num1 = -ALLOCNO_HARD_REGNO (a1);
4416 : 0 : slot_num2 = -ALLOCNO_HARD_REGNO (a2);
4417 : 0 : if ((diff = slot_num1 - slot_num2) != 0)
4418 : 0 : return (frame_pointer_needed
4419 : 0 : || (!FRAME_GROWS_DOWNWARD) == STACK_GROWS_DOWNWARD ? diff : -diff);
4420 : 0 : mode1 = wider_subreg_mode (PSEUDO_REGNO_MODE (regno1),
4421 : 0 : regno_max_ref_mode[regno1]);
4422 : 0 : mode2 = wider_subreg_mode (PSEUDO_REGNO_MODE (regno2),
4423 : 0 : regno_max_ref_mode[regno2]);
4424 : 0 : if ((diff = compare_sizes_for_sort (GET_MODE_SIZE (mode2),
4425 : 0 : GET_MODE_SIZE (mode1))) != 0)
4426 : 0 : return diff;
4427 : 0 : return regno1 - regno2;
4428 : : }
4429 : :
4430 : : /* Setup REGNO_COALESCED_ALLOCNO_COST and REGNO_COALESCED_ALLOCNO_NUM
4431 : : for coalesced allocno sets containing allocnos with their regnos
4432 : : given in array PSEUDO_REGNOS of length N. */
4433 : : static void
4434 : 0 : setup_coalesced_allocno_costs_and_nums (int *pseudo_regnos, int n)
4435 : : {
4436 : 0 : int i, num, regno, cost;
4437 : 0 : ira_allocno_t allocno, a;
4438 : :
4439 : 0 : for (num = i = 0; i < n; i++)
4440 : : {
4441 : 0 : regno = pseudo_regnos[i];
4442 : 0 : allocno = ira_regno_allocno_map[regno];
4443 : 0 : if (allocno == NULL)
4444 : : {
4445 : 0 : regno_coalesced_allocno_cost[regno] = 0;
4446 : 0 : regno_coalesced_allocno_num[regno] = ++num;
4447 : 0 : continue;
4448 : : }
4449 : 0 : if (ALLOCNO_COALESCE_DATA (allocno)->first != allocno)
4450 : 0 : continue;
4451 : 0 : num++;
4452 : 0 : for (cost = 0, a = ALLOCNO_COALESCE_DATA (allocno)->next;;
4453 : 0 : a = ALLOCNO_COALESCE_DATA (a)->next)
4454 : : {
4455 : 0 : cost += ALLOCNO_FREQ (a);
4456 : 0 : if (a == allocno)
4457 : : break;
4458 : : }
4459 : 0 : for (a = ALLOCNO_COALESCE_DATA (allocno)->next;;
4460 : 0 : a = ALLOCNO_COALESCE_DATA (a)->next)
4461 : : {
4462 : 0 : regno_coalesced_allocno_num[ALLOCNO_REGNO (a)] = num;
4463 : 0 : regno_coalesced_allocno_cost[ALLOCNO_REGNO (a)] = cost;
4464 : 0 : if (a == allocno)
4465 : : break;
4466 : : }
4467 : : }
4468 : 0 : }
4469 : :
4470 : : /* Collect spilled allocnos representing coalesced allocno sets (the
4471 : : first coalesced allocno). The collected allocnos are returned
4472 : : through array SPILLED_COALESCED_ALLOCNOS. The function returns the
4473 : : number of the collected allocnos. The allocnos are given by their
4474 : : regnos in array PSEUDO_REGNOS of length N. */
4475 : : static int
4476 : 0 : collect_spilled_coalesced_allocnos (int *pseudo_regnos, int n,
4477 : : ira_allocno_t *spilled_coalesced_allocnos)
4478 : : {
4479 : 0 : int i, num, regno;
4480 : 0 : ira_allocno_t allocno;
4481 : :
4482 : 0 : for (num = i = 0; i < n; i++)
4483 : : {
4484 : 0 : regno = pseudo_regnos[i];
4485 : 0 : allocno = ira_regno_allocno_map[regno];
4486 : 0 : if (allocno == NULL || ALLOCNO_HARD_REGNO (allocno) >= 0
4487 : 0 : || ALLOCNO_COALESCE_DATA (allocno)->first != allocno)
4488 : 0 : continue;
4489 : 0 : spilled_coalesced_allocnos[num++] = allocno;
4490 : : }
4491 : 0 : return num;
4492 : : }
4493 : :
4494 : : /* Array of live ranges of size IRA_ALLOCNOS_NUM. Live range for
4495 : : given slot contains live ranges of coalesced allocnos assigned to
4496 : : given slot. */
4497 : : static live_range_t *slot_coalesced_allocnos_live_ranges;
4498 : :
4499 : : /* Return TRUE if coalesced allocnos represented by ALLOCNO has live
4500 : : ranges intersected with live ranges of coalesced allocnos assigned
4501 : : to slot with number N. */
4502 : : static bool
4503 : 0 : slot_coalesced_allocno_live_ranges_intersect_p (ira_allocno_t allocno, int n)
4504 : : {
4505 : 0 : ira_allocno_t a;
4506 : :
4507 : 0 : for (a = ALLOCNO_COALESCE_DATA (allocno)->next;;
4508 : 0 : a = ALLOCNO_COALESCE_DATA (a)->next)
4509 : : {
4510 : 0 : int i;
4511 : 0 : int nr = ALLOCNO_NUM_OBJECTS (a);
4512 : 0 : gcc_assert (ALLOCNO_CAP_MEMBER (a) == NULL);
4513 : 0 : for (i = 0; i < nr; i++)
4514 : : {
4515 : 0 : ira_object_t obj = ALLOCNO_OBJECT (a, i);
4516 : :
4517 : 0 : if (ira_live_ranges_intersect_p
4518 : 0 : (slot_coalesced_allocnos_live_ranges[n],
4519 : : OBJECT_LIVE_RANGES (obj)))
4520 : : return true;
4521 : : }
4522 : 0 : if (a == allocno)
4523 : : break;
4524 : 0 : }
4525 : : return false;
4526 : : }
4527 : :
4528 : : /* Update live ranges of slot to which coalesced allocnos represented
4529 : : by ALLOCNO were assigned. */
4530 : : static void
4531 : 0 : setup_slot_coalesced_allocno_live_ranges (ira_allocno_t allocno)
4532 : : {
4533 : 0 : int i, n;
4534 : 0 : ira_allocno_t a;
4535 : 0 : live_range_t r;
4536 : :
4537 : 0 : n = ALLOCNO_COALESCE_DATA (allocno)->temp;
4538 : 0 : for (a = ALLOCNO_COALESCE_DATA (allocno)->next;;
4539 : 0 : a = ALLOCNO_COALESCE_DATA (a)->next)
4540 : : {
4541 : 0 : int nr = ALLOCNO_NUM_OBJECTS (a);
4542 : 0 : gcc_assert (ALLOCNO_CAP_MEMBER (a) == NULL);
4543 : 0 : for (i = 0; i < nr; i++)
4544 : : {
4545 : 0 : ira_object_t obj = ALLOCNO_OBJECT (a, i);
4546 : :
4547 : 0 : r = ira_copy_live_range_list (OBJECT_LIVE_RANGES (obj));
4548 : 0 : slot_coalesced_allocnos_live_ranges[n]
4549 : 0 : = ira_merge_live_ranges
4550 : 0 : (slot_coalesced_allocnos_live_ranges[n], r);
4551 : : }
4552 : 0 : if (a == allocno)
4553 : : break;
4554 : 0 : }
4555 : 0 : }
4556 : :
4557 : : /* We have coalesced allocnos involving in copies. Coalesce allocnos
4558 : : further in order to share the same memory stack slot. Allocnos
4559 : : representing sets of allocnos coalesced before the call are given
4560 : : in array SPILLED_COALESCED_ALLOCNOS of length NUM. Return TRUE if
4561 : : some allocnos were coalesced in the function. */
4562 : : static bool
4563 : 0 : coalesce_spill_slots (ira_allocno_t *spilled_coalesced_allocnos, int num)
4564 : : {
4565 : 0 : int i, j, n, last_coalesced_allocno_num;
4566 : 0 : ira_allocno_t allocno, a;
4567 : 0 : bool merged_p = false;
4568 : 0 : bitmap set_jump_crosses = regstat_get_setjmp_crosses ();
4569 : :
4570 : 0 : slot_coalesced_allocnos_live_ranges
4571 : 0 : = (live_range_t *) ira_allocate (sizeof (live_range_t) * ira_allocnos_num);
4572 : 0 : memset (slot_coalesced_allocnos_live_ranges, 0,
4573 : 0 : sizeof (live_range_t) * ira_allocnos_num);
4574 : 0 : last_coalesced_allocno_num = 0;
4575 : : /* Coalesce non-conflicting spilled allocnos preferring most
4576 : : frequently used. */
4577 : 0 : for (i = 0; i < num; i++)
4578 : : {
4579 : 0 : allocno = spilled_coalesced_allocnos[i];
4580 : 0 : if (ALLOCNO_COALESCE_DATA (allocno)->first != allocno
4581 : 0 : || bitmap_bit_p (set_jump_crosses, ALLOCNO_REGNO (allocno))
4582 : 0 : || ira_equiv_no_lvalue_p (ALLOCNO_REGNO (allocno)))
4583 : 0 : continue;
4584 : 0 : for (j = 0; j < i; j++)
4585 : : {
4586 : 0 : a = spilled_coalesced_allocnos[j];
4587 : 0 : n = ALLOCNO_COALESCE_DATA (a)->temp;
4588 : 0 : if (ALLOCNO_COALESCE_DATA (a)->first == a
4589 : 0 : && ! bitmap_bit_p (set_jump_crosses, ALLOCNO_REGNO (a))
4590 : 0 : && ! ira_equiv_no_lvalue_p (ALLOCNO_REGNO (a))
4591 : 0 : && ! slot_coalesced_allocno_live_ranges_intersect_p (allocno, n))
4592 : : break;
4593 : : }
4594 : 0 : if (j >= i)
4595 : : {
4596 : : /* No coalescing: set up number for coalesced allocnos
4597 : : represented by ALLOCNO. */
4598 : 0 : ALLOCNO_COALESCE_DATA (allocno)->temp = last_coalesced_allocno_num++;
4599 : 0 : setup_slot_coalesced_allocno_live_ranges (allocno);
4600 : : }
4601 : : else
4602 : : {
4603 : 0 : allocno_coalesced_p = true;
4604 : 0 : merged_p = true;
4605 : 0 : if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4606 : 0 : fprintf (ira_dump_file,
4607 : : " Coalescing spilled allocnos a%dr%d->a%dr%d\n",
4608 : : ALLOCNO_NUM (allocno), ALLOCNO_REGNO (allocno),
4609 : : ALLOCNO_NUM (a), ALLOCNO_REGNO (a));
4610 : 0 : ALLOCNO_COALESCE_DATA (allocno)->temp
4611 : 0 : = ALLOCNO_COALESCE_DATA (a)->temp;
4612 : 0 : setup_slot_coalesced_allocno_live_ranges (allocno);
4613 : 0 : merge_allocnos (a, allocno);
4614 : 0 : ira_assert (ALLOCNO_COALESCE_DATA (a)->first == a);
4615 : : }
4616 : : }
4617 : 0 : for (i = 0; i < ira_allocnos_num; i++)
4618 : 0 : ira_finish_live_range_list (slot_coalesced_allocnos_live_ranges[i]);
4619 : 0 : ira_free (slot_coalesced_allocnos_live_ranges);
4620 : 0 : return merged_p;
4621 : : }
4622 : :
4623 : : /* Sort pseudo-register numbers in array PSEUDO_REGNOS of length N for
4624 : : subsequent assigning stack slots to them in the reload pass. To do
4625 : : this we coalesce spilled allocnos first to decrease the number of
4626 : : memory-memory move insns. This function is called by the
4627 : : reload. */
4628 : : void
4629 : 0 : ira_sort_regnos_for_alter_reg (int *pseudo_regnos, int n,
4630 : : machine_mode *reg_max_ref_mode)
4631 : : {
4632 : 0 : int max_regno = max_reg_num ();
4633 : 0 : int i, regno, num, slot_num;
4634 : 0 : ira_allocno_t allocno, a;
4635 : 0 : ira_allocno_iterator ai;
4636 : 0 : ira_allocno_t *spilled_coalesced_allocnos;
4637 : :
4638 : 0 : ira_assert (! ira_use_lra_p);
4639 : :
4640 : : /* Set up allocnos can be coalesced. */
4641 : 0 : coloring_allocno_bitmap = ira_allocate_bitmap ();
4642 : 0 : for (i = 0; i < n; i++)
4643 : : {
4644 : 0 : regno = pseudo_regnos[i];
4645 : 0 : allocno = ira_regno_allocno_map[regno];
4646 : 0 : if (allocno != NULL)
4647 : 0 : bitmap_set_bit (coloring_allocno_bitmap, ALLOCNO_NUM (allocno));
4648 : : }
4649 : 0 : allocno_coalesced_p = false;
4650 : 0 : processed_coalesced_allocno_bitmap = ira_allocate_bitmap ();
4651 : 0 : allocno_coalesce_data
4652 : 0 : = (coalesce_data_t) ira_allocate (sizeof (struct coalesce_data)
4653 : 0 : * ira_allocnos_num);
4654 : : /* Initialize coalesce data for allocnos. */
4655 : 0 : FOR_EACH_ALLOCNO (a, ai)
4656 : : {
4657 : 0 : ALLOCNO_ADD_DATA (a) = allocno_coalesce_data + ALLOCNO_NUM (a);
4658 : 0 : ALLOCNO_COALESCE_DATA (a)->first = a;
4659 : 0 : ALLOCNO_COALESCE_DATA (a)->next = a;
4660 : : }
4661 : 0 : coalesce_allocnos ();
4662 : 0 : ira_free_bitmap (coloring_allocno_bitmap);
4663 : 0 : regno_coalesced_allocno_cost
4664 : 0 : = (int *) ira_allocate (max_regno * sizeof (int));
4665 : 0 : regno_coalesced_allocno_num
4666 : 0 : = (int *) ira_allocate (max_regno * sizeof (int));
4667 : 0 : memset (regno_coalesced_allocno_num, 0, max_regno * sizeof (int));
4668 : 0 : setup_coalesced_allocno_costs_and_nums (pseudo_regnos, n);
4669 : : /* Sort regnos according frequencies of the corresponding coalesced
4670 : : allocno sets. */
4671 : 0 : qsort (pseudo_regnos, n, sizeof (int), coalesced_pseudo_reg_freq_compare);
4672 : 0 : spilled_coalesced_allocnos
4673 : 0 : = (ira_allocno_t *) ira_allocate (ira_allocnos_num
4674 : : * sizeof (ira_allocno_t));
4675 : : /* Collect allocnos representing the spilled coalesced allocno
4676 : : sets. */
4677 : 0 : num = collect_spilled_coalesced_allocnos (pseudo_regnos, n,
4678 : : spilled_coalesced_allocnos);
4679 : 0 : if (flag_ira_share_spill_slots
4680 : 0 : && coalesce_spill_slots (spilled_coalesced_allocnos, num))
4681 : : {
4682 : 0 : setup_coalesced_allocno_costs_and_nums (pseudo_regnos, n);
4683 : 0 : qsort (pseudo_regnos, n, sizeof (int),
4684 : : coalesced_pseudo_reg_freq_compare);
4685 : 0 : num = collect_spilled_coalesced_allocnos (pseudo_regnos, n,
4686 : : spilled_coalesced_allocnos);
4687 : : }
4688 : 0 : ira_free_bitmap (processed_coalesced_allocno_bitmap);
4689 : 0 : allocno_coalesced_p = false;
4690 : : /* Assign stack slot numbers to spilled allocno sets, use smaller
4691 : : numbers for most frequently used coalesced allocnos. -1 is
4692 : : reserved for dynamic search of stack slots for pseudos spilled by
4693 : : the reload. */
4694 : 0 : slot_num = 1;
4695 : 0 : for (i = 0; i < num; i++)
4696 : : {
4697 : 0 : allocno = spilled_coalesced_allocnos[i];
4698 : 0 : if (ALLOCNO_COALESCE_DATA (allocno)->first != allocno
4699 : 0 : || ALLOCNO_HARD_REGNO (allocno) >= 0
4700 : 0 : || ira_equiv_no_lvalue_p (ALLOCNO_REGNO (allocno)))
4701 : 0 : continue;
4702 : 0 : if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4703 : 0 : fprintf (ira_dump_file, " Slot %d (freq,size):", slot_num);
4704 : 0 : slot_num++;
4705 : 0 : for (a = ALLOCNO_COALESCE_DATA (allocno)->next;;
4706 : 0 : a = ALLOCNO_COALESCE_DATA (a)->next)
4707 : : {
4708 : 0 : ira_assert (ALLOCNO_HARD_REGNO (a) < 0);
4709 : 0 : ALLOCNO_HARD_REGNO (a) = -slot_num;
4710 : 0 : if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4711 : : {
4712 : 0 : machine_mode mode = wider_subreg_mode
4713 : 0 : (PSEUDO_REGNO_MODE (ALLOCNO_REGNO (a)),
4714 : 0 : reg_max_ref_mode[ALLOCNO_REGNO (a)]);
4715 : 0 : fprintf (ira_dump_file, " a%dr%d(%d,",
4716 : : ALLOCNO_NUM (a), ALLOCNO_REGNO (a), ALLOCNO_FREQ (a));
4717 : 0 : print_dec (GET_MODE_SIZE (mode), ira_dump_file, SIGNED);
4718 : 0 : fprintf (ira_dump_file, ")\n");
4719 : : }
4720 : :
4721 : 0 : if (a == allocno)
4722 : : break;
4723 : 0 : }
4724 : 0 : if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4725 : 0 : fprintf (ira_dump_file, "\n");
4726 : : }
4727 : 0 : ira_spilled_reg_stack_slots_num = slot_num - 1;
4728 : 0 : ira_free (spilled_coalesced_allocnos);
4729 : : /* Sort regnos according the slot numbers. */
4730 : 0 : regno_max_ref_mode = reg_max_ref_mode;
4731 : 0 : qsort (pseudo_regnos, n, sizeof (int), coalesced_pseudo_reg_slot_compare);
4732 : 0 : FOR_EACH_ALLOCNO (a, ai)
4733 : 0 : ALLOCNO_ADD_DATA (a) = NULL;
4734 : 0 : ira_free (allocno_coalesce_data);
4735 : 0 : ira_free (regno_coalesced_allocno_num);
4736 : 0 : ira_free (regno_coalesced_allocno_cost);
4737 : 0 : }
4738 : :
4739 : :
4740 : :
4741 : : /* This page contains code used by the reload pass to improve the
4742 : : final code. */
4743 : :
4744 : : /* The function is called from reload to mark changes in the
4745 : : allocation of REGNO made by the reload. Remember that reg_renumber
4746 : : reflects the change result. */
4747 : : void
4748 : 0 : ira_mark_allocation_change (int regno)
4749 : : {
4750 : 0 : ira_allocno_t a = ira_regno_allocno_map[regno];
4751 : 0 : int old_hard_regno, hard_regno, cost;
4752 : 0 : enum reg_class aclass = ALLOCNO_CLASS (a);
4753 : :
4754 : 0 : ira_assert (a != NULL);
4755 : 0 : hard_regno = reg_renumber[regno];
4756 : 0 : if ((old_hard_regno = ALLOCNO_HARD_REGNO (a)) == hard_regno)
4757 : : return;
4758 : 0 : if (old_hard_regno < 0)
4759 : 0 : cost = -ALLOCNO_MEMORY_COST (a);
4760 : : else
4761 : : {
4762 : 0 : ira_assert (ira_class_hard_reg_index[aclass][old_hard_regno] >= 0);
4763 : 0 : cost = -(ALLOCNO_HARD_REG_COSTS (a) == NULL
4764 : 0 : ? ALLOCNO_CLASS_COST (a)
4765 : : : ALLOCNO_HARD_REG_COSTS (a)
4766 : 0 : [ira_class_hard_reg_index[aclass][old_hard_regno]]);
4767 : 0 : update_costs_from_copies (a, false, false);
4768 : : }
4769 : 0 : ira_overall_cost -= cost;
4770 : 0 : ALLOCNO_HARD_REGNO (a) = hard_regno;
4771 : 0 : if (hard_regno < 0)
4772 : : {
4773 : 0 : ALLOCNO_HARD_REGNO (a) = -1;
4774 : 0 : cost += ALLOCNO_MEMORY_COST (a);
4775 : : }
4776 : 0 : else if (ira_class_hard_reg_index[aclass][hard_regno] >= 0)
4777 : : {
4778 : 0 : cost += (ALLOCNO_HARD_REG_COSTS (a) == NULL
4779 : 0 : ? ALLOCNO_CLASS_COST (a)
4780 : : : ALLOCNO_HARD_REG_COSTS (a)
4781 : 0 : [ira_class_hard_reg_index[aclass][hard_regno]]);
4782 : 0 : update_costs_from_copies (a, true, false);
4783 : : }
4784 : : else
4785 : : /* Reload changed class of the allocno. */
4786 : : cost = 0;
4787 : 0 : ira_overall_cost += cost;
4788 : : }
4789 : :
4790 : : /* This function is called when reload deletes memory-memory move. In
4791 : : this case we marks that the allocation of the corresponding
4792 : : allocnos should be not changed in future. Otherwise we risk to get
4793 : : a wrong code. */
4794 : : void
4795 : 0 : ira_mark_memory_move_deletion (int dst_regno, int src_regno)
4796 : : {
4797 : 0 : ira_allocno_t dst = ira_regno_allocno_map[dst_regno];
4798 : 0 : ira_allocno_t src = ira_regno_allocno_map[src_regno];
4799 : :
4800 : 0 : ira_assert (dst != NULL && src != NULL
4801 : : && ALLOCNO_HARD_REGNO (dst) < 0
4802 : : && ALLOCNO_HARD_REGNO (src) < 0);
4803 : 0 : ALLOCNO_DONT_REASSIGN_P (dst) = true;
4804 : 0 : ALLOCNO_DONT_REASSIGN_P (src) = true;
4805 : 0 : }
4806 : :
4807 : : /* Try to assign a hard register (except for FORBIDDEN_REGS) to
4808 : : allocno A and return TRUE in the case of success. */
4809 : : static bool
4810 : 0 : allocno_reload_assign (ira_allocno_t a, HARD_REG_SET forbidden_regs)
4811 : : {
4812 : 0 : int hard_regno;
4813 : 0 : enum reg_class aclass;
4814 : 0 : int regno = ALLOCNO_REGNO (a);
4815 : 0 : HARD_REG_SET saved[2];
4816 : 0 : int i, n;
4817 : :
4818 : 0 : n = ALLOCNO_NUM_OBJECTS (a);
4819 : 0 : for (i = 0; i < n; i++)
4820 : : {
4821 : 0 : ira_object_t obj = ALLOCNO_OBJECT (a, i);
4822 : 0 : saved[i] = OBJECT_TOTAL_CONFLICT_HARD_REGS (obj);
4823 : 0 : OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) |= forbidden_regs;
4824 : 0 : if (! flag_caller_saves && ALLOCNO_CALLS_CROSSED_NUM (a) != 0)
4825 : 0 : OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) |= ira_need_caller_save_regs (a);
4826 : : }
4827 : 0 : ALLOCNO_ASSIGNED_P (a) = false;
4828 : 0 : aclass = ALLOCNO_CLASS (a);
4829 : 0 : update_curr_costs (a);
4830 : 0 : assign_hard_reg (a, true);
4831 : 0 : hard_regno = ALLOCNO_HARD_REGNO (a);
4832 : 0 : reg_renumber[regno] = hard_regno;
4833 : 0 : if (hard_regno < 0)
4834 : 0 : ALLOCNO_HARD_REGNO (a) = -1;
4835 : : else
4836 : : {
4837 : 0 : ira_assert (ira_class_hard_reg_index[aclass][hard_regno] >= 0);
4838 : 0 : ira_overall_cost
4839 : 0 : -= (ALLOCNO_MEMORY_COST (a)
4840 : 0 : - (ALLOCNO_HARD_REG_COSTS (a) == NULL
4841 : 0 : ? ALLOCNO_CLASS_COST (a)
4842 : : : ALLOCNO_HARD_REG_COSTS (a)[ira_class_hard_reg_index
4843 : 0 : [aclass][hard_regno]]));
4844 : 0 : if (ira_need_caller_save_p (a, hard_regno))
4845 : : {
4846 : 0 : ira_assert (flag_caller_saves);
4847 : 0 : caller_save_needed = 1;
4848 : : }
4849 : : }
4850 : :
4851 : : /* If we found a hard register, modify the RTL for the pseudo
4852 : : register to show the hard register, and mark the pseudo register
4853 : : live. */
4854 : 0 : if (reg_renumber[regno] >= 0)
4855 : : {
4856 : 0 : if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4857 : 0 : fprintf (ira_dump_file, ": reassign to %d\n", reg_renumber[regno]);
4858 : 0 : SET_REGNO (regno_reg_rtx[regno], reg_renumber[regno]);
4859 : 0 : mark_home_live (regno);
4860 : : }
4861 : 0 : else if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4862 : 0 : fprintf (ira_dump_file, "\n");
4863 : 0 : for (i = 0; i < n; i++)
4864 : : {
4865 : 0 : ira_object_t obj = ALLOCNO_OBJECT (a, i);
4866 : 0 : OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) = saved[i];
4867 : : }
4868 : 0 : return reg_renumber[regno] >= 0;
4869 : : }
4870 : :
4871 : : /* Sort pseudos according their usage frequencies (putting most
4872 : : frequently ones first). */
4873 : : static int
4874 : 0 : pseudo_reg_compare (const void *v1p, const void *v2p)
4875 : : {
4876 : 0 : int regno1 = *(const int *) v1p;
4877 : 0 : int regno2 = *(const int *) v2p;
4878 : 0 : int diff;
4879 : :
4880 : 0 : if ((diff = REG_FREQ (regno2) - REG_FREQ (regno1)) != 0)
4881 : : return diff;
4882 : 0 : return regno1 - regno2;
4883 : : }
4884 : :
4885 : : /* Try to allocate hard registers to SPILLED_PSEUDO_REGS (there are
4886 : : NUM of them) or spilled pseudos conflicting with pseudos in
4887 : : SPILLED_PSEUDO_REGS. Return TRUE and update SPILLED, if the
4888 : : allocation has been changed. The function doesn't use
4889 : : BAD_SPILL_REGS and hard registers in PSEUDO_FORBIDDEN_REGS and
4890 : : PSEUDO_PREVIOUS_REGS for the corresponding pseudos. The function
4891 : : is called by the reload pass at the end of each reload
4892 : : iteration. */
4893 : : bool
4894 : 0 : ira_reassign_pseudos (int *spilled_pseudo_regs, int num,
4895 : : HARD_REG_SET bad_spill_regs,
4896 : : HARD_REG_SET *pseudo_forbidden_regs,
4897 : : HARD_REG_SET *pseudo_previous_regs,
4898 : : bitmap spilled)
4899 : : {
4900 : 0 : int i, n, regno;
4901 : 0 : bool changed_p;
4902 : 0 : ira_allocno_t a;
4903 : 0 : HARD_REG_SET forbidden_regs;
4904 : 0 : bitmap temp = BITMAP_ALLOC (NULL);
4905 : :
4906 : : /* Add pseudos which conflict with pseudos already in
4907 : : SPILLED_PSEUDO_REGS to SPILLED_PSEUDO_REGS. This is preferable
4908 : : to allocating in two steps as some of the conflicts might have
4909 : : a higher priority than the pseudos passed in SPILLED_PSEUDO_REGS. */
4910 : 0 : for (i = 0; i < num; i++)
4911 : 0 : bitmap_set_bit (temp, spilled_pseudo_regs[i]);
4912 : :
4913 : 0 : for (i = 0, n = num; i < n; i++)
4914 : : {
4915 : 0 : int nr, j;
4916 : 0 : int regno = spilled_pseudo_regs[i];
4917 : 0 : bitmap_set_bit (temp, regno);
4918 : :
4919 : 0 : a = ira_regno_allocno_map[regno];
4920 : 0 : nr = ALLOCNO_NUM_OBJECTS (a);
4921 : 0 : for (j = 0; j < nr; j++)
4922 : : {
4923 : 0 : ira_object_t conflict_obj;
4924 : 0 : ira_object_t obj = ALLOCNO_OBJECT (a, j);
4925 : 0 : ira_object_conflict_iterator oci;
4926 : :
4927 : 0 : FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
4928 : : {
4929 : 0 : ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
4930 : 0 : if (ALLOCNO_HARD_REGNO (conflict_a) < 0
4931 : 0 : && ! ALLOCNO_DONT_REASSIGN_P (conflict_a)
4932 : 0 : && bitmap_set_bit (temp, ALLOCNO_REGNO (conflict_a)))
4933 : : {
4934 : 0 : spilled_pseudo_regs[num++] = ALLOCNO_REGNO (conflict_a);
4935 : : /* ?!? This seems wrong. */
4936 : 0 : bitmap_set_bit (consideration_allocno_bitmap,
4937 : : ALLOCNO_NUM (conflict_a));
4938 : : }
4939 : : }
4940 : : }
4941 : : }
4942 : :
4943 : 0 : if (num > 1)
4944 : 0 : qsort (spilled_pseudo_regs, num, sizeof (int), pseudo_reg_compare);
4945 : : changed_p = false;
4946 : : /* Try to assign hard registers to pseudos from
4947 : : SPILLED_PSEUDO_REGS. */
4948 : 0 : for (i = 0; i < num; i++)
4949 : : {
4950 : 0 : regno = spilled_pseudo_regs[i];
4951 : 0 : forbidden_regs = (bad_spill_regs
4952 : 0 : | pseudo_forbidden_regs[regno]
4953 : 0 : | pseudo_previous_regs[regno]);
4954 : 0 : gcc_assert (reg_renumber[regno] < 0);
4955 : 0 : a = ira_regno_allocno_map[regno];
4956 : 0 : ira_mark_allocation_change (regno);
4957 : 0 : ira_assert (reg_renumber[regno] < 0);
4958 : 0 : if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4959 : 0 : fprintf (ira_dump_file,
4960 : : " Try Assign %d(a%d), cost=%d", regno, ALLOCNO_NUM (a),
4961 : 0 : ALLOCNO_MEMORY_COST (a)
4962 : 0 : - ALLOCNO_CLASS_COST (a));
4963 : 0 : allocno_reload_assign (a, forbidden_regs);
4964 : 0 : if (reg_renumber[regno] >= 0)
4965 : : {
4966 : 0 : CLEAR_REGNO_REG_SET (spilled, regno);
4967 : 0 : changed_p = true;
4968 : : }
4969 : : }
4970 : 0 : BITMAP_FREE (temp);
4971 : 0 : return changed_p;
4972 : : }
4973 : :
4974 : : /* The function is called by reload and returns already allocated
4975 : : stack slot (if any) for REGNO with given INHERENT_SIZE and
4976 : : TOTAL_SIZE. In the case of failure to find a slot which can be
4977 : : used for REGNO, the function returns NULL. */
4978 : : rtx
4979 : 0 : ira_reuse_stack_slot (int regno, poly_uint64 inherent_size,
4980 : : poly_uint64 total_size)
4981 : : {
4982 : 0 : unsigned int i;
4983 : 0 : int slot_num, best_slot_num;
4984 : 0 : int cost, best_cost;
4985 : 0 : ira_copy_t cp, next_cp;
4986 : 0 : ira_allocno_t another_allocno, allocno = ira_regno_allocno_map[regno];
4987 : 0 : rtx x;
4988 : 0 : bitmap_iterator bi;
4989 : 0 : class ira_spilled_reg_stack_slot *slot = NULL;
4990 : :
4991 : 0 : ira_assert (! ira_use_lra_p);
4992 : :
4993 : 0 : ira_assert (known_eq (inherent_size, PSEUDO_REGNO_BYTES (regno))
4994 : : && known_le (inherent_size, total_size)
4995 : : && ALLOCNO_HARD_REGNO (allocno) < 0);
4996 : 0 : if (! flag_ira_share_spill_slots)
4997 : : return NULL_RTX;
4998 : 0 : slot_num = -ALLOCNO_HARD_REGNO (allocno) - 2;
4999 : 0 : if (slot_num != -1)
5000 : : {
5001 : 0 : slot = &ira_spilled_reg_stack_slots[slot_num];
5002 : 0 : x = slot->mem;
5003 : : }
5004 : : else
5005 : : {
5006 : : best_cost = best_slot_num = -1;
5007 : 0 : x = NULL_RTX;
5008 : : /* It means that the pseudo was spilled in the reload pass, try
5009 : : to reuse a slot. */
5010 : 0 : for (slot_num = 0;
5011 : 0 : slot_num < ira_spilled_reg_stack_slots_num;
5012 : : slot_num++)
5013 : : {
5014 : 0 : slot = &ira_spilled_reg_stack_slots[slot_num];
5015 : 0 : if (slot->mem == NULL_RTX)
5016 : 0 : continue;
5017 : 0 : if (maybe_lt (slot->width, total_size)
5018 : 0 : || maybe_lt (GET_MODE_SIZE (GET_MODE (slot->mem)), inherent_size))
5019 : 0 : continue;
5020 : :
5021 : 0 : EXECUTE_IF_SET_IN_BITMAP (&slot->spilled_regs,
5022 : : FIRST_PSEUDO_REGISTER, i, bi)
5023 : : {
5024 : 0 : another_allocno = ira_regno_allocno_map[i];
5025 : 0 : if (allocnos_conflict_by_live_ranges_p (allocno,
5026 : : another_allocno))
5027 : 0 : goto cont;
5028 : : }
5029 : 0 : for (cost = 0, cp = ALLOCNO_COPIES (allocno);
5030 : 0 : cp != NULL;
5031 : : cp = next_cp)
5032 : : {
5033 : 0 : if (cp->first == allocno)
5034 : : {
5035 : 0 : next_cp = cp->next_first_allocno_copy;
5036 : 0 : another_allocno = cp->second;
5037 : : }
5038 : 0 : else if (cp->second == allocno)
5039 : : {
5040 : 0 : next_cp = cp->next_second_allocno_copy;
5041 : 0 : another_allocno = cp->first;
5042 : : }
5043 : : else
5044 : 0 : gcc_unreachable ();
5045 : 0 : if (cp->insn == NULL_RTX)
5046 : 0 : continue;
5047 : 0 : if (bitmap_bit_p (&slot->spilled_regs,
5048 : : ALLOCNO_REGNO (another_allocno)))
5049 : 0 : cost += cp->freq;
5050 : : }
5051 : 0 : if (cost > best_cost)
5052 : : {
5053 : 0 : best_cost = cost;
5054 : 0 : best_slot_num = slot_num;
5055 : : }
5056 : 0 : cont:
5057 : 0 : ;
5058 : : }
5059 : 0 : if (best_cost >= 0)
5060 : : {
5061 : 0 : slot_num = best_slot_num;
5062 : 0 : slot = &ira_spilled_reg_stack_slots[slot_num];
5063 : 0 : SET_REGNO_REG_SET (&slot->spilled_regs, regno);
5064 : 0 : x = slot->mem;
5065 : 0 : ALLOCNO_HARD_REGNO (allocno) = -slot_num - 2;
5066 : : }
5067 : : }
5068 : 0 : if (x != NULL_RTX)
5069 : : {
5070 : 0 : ira_assert (known_ge (slot->width, total_size));
5071 : : #ifdef ENABLE_IRA_CHECKING
5072 : 0 : EXECUTE_IF_SET_IN_BITMAP (&slot->spilled_regs,
5073 : : FIRST_PSEUDO_REGISTER, i, bi)
5074 : : {
5075 : 0 : ira_assert (! conflict_by_live_ranges_p (regno, i));
5076 : : }
5077 : : #endif
5078 : 0 : SET_REGNO_REG_SET (&slot->spilled_regs, regno);
5079 : 0 : if (internal_flag_ira_verbose > 3 && ira_dump_file)
5080 : : {
5081 : 0 : fprintf (ira_dump_file, " Assigning %d(freq=%d) slot %d of",
5082 : 0 : regno, REG_FREQ (regno), slot_num);
5083 : 0 : EXECUTE_IF_SET_IN_BITMAP (&slot->spilled_regs,
5084 : : FIRST_PSEUDO_REGISTER, i, bi)
5085 : : {
5086 : 0 : if ((unsigned) regno != i)
5087 : 0 : fprintf (ira_dump_file, " %d", i);
5088 : : }
5089 : 0 : fprintf (ira_dump_file, "\n");
5090 : : }
5091 : : }
5092 : : return x;
5093 : : }
5094 : :
5095 : : /* This is called by reload every time a new stack slot X with
5096 : : TOTAL_SIZE was allocated for REGNO. We store this info for
5097 : : subsequent ira_reuse_stack_slot calls. */
5098 : : void
5099 : 0 : ira_mark_new_stack_slot (rtx x, int regno, poly_uint64 total_size)
5100 : : {
5101 : 0 : class ira_spilled_reg_stack_slot *slot;
5102 : 0 : int slot_num;
5103 : 0 : ira_allocno_t allocno;
5104 : :
5105 : 0 : ira_assert (! ira_use_lra_p);
5106 : :
5107 : 0 : ira_assert (known_le (PSEUDO_REGNO_BYTES (regno), total_size));
5108 : 0 : allocno = ira_regno_allocno_map[regno];
5109 : 0 : slot_num = -ALLOCNO_HARD_REGNO (allocno) - 2;
5110 : 0 : if (slot_num == -1)
5111 : : {
5112 : 0 : slot_num = ira_spilled_reg_stack_slots_num++;
5113 : 0 : ALLOCNO_HARD_REGNO (allocno) = -slot_num - 2;
5114 : : }
5115 : 0 : slot = &ira_spilled_reg_stack_slots[slot_num];
5116 : 0 : INIT_REG_SET (&slot->spilled_regs);
5117 : 0 : SET_REGNO_REG_SET (&slot->spilled_regs, regno);
5118 : 0 : slot->mem = x;
5119 : 0 : slot->width = total_size;
5120 : 0 : if (internal_flag_ira_verbose > 3 && ira_dump_file)
5121 : 0 : fprintf (ira_dump_file, " Assigning %d(freq=%d) a new slot %d\n",
5122 : 0 : regno, REG_FREQ (regno), slot_num);
5123 : 0 : }
5124 : :
5125 : :
5126 : : /* Return spill cost for pseudo-registers whose numbers are in array
5127 : : REGNOS (with a negative number as an end marker) for reload with
5128 : : given IN and OUT for INSN. Return also number points (through
5129 : : EXCESS_PRESSURE_LIVE_LENGTH) where the pseudo-register lives and
5130 : : the register pressure is high, number of references of the
5131 : : pseudo-registers (through NREFS), the number of psuedo registers
5132 : : whose allocated register wouldn't need saving in the prologue
5133 : : (through CALL_USED_COUNT), and the first hard regno occupied by the
5134 : : pseudo-registers (through FIRST_HARD_REGNO). */
5135 : : static int
5136 : 0 : calculate_spill_cost (int *regnos, rtx in, rtx out, rtx_insn *insn,
5137 : : int *excess_pressure_live_length,
5138 : : int *nrefs, int *call_used_count, int *first_hard_regno)
5139 : : {
5140 : 0 : int i, cost, regno, hard_regno, count, saved_cost;
5141 : 0 : bool in_p, out_p;
5142 : 0 : int length;
5143 : 0 : ira_allocno_t a;
5144 : :
5145 : 0 : *nrefs = 0;
5146 : 0 : for (length = count = cost = i = 0;; i++)
5147 : : {
5148 : 0 : regno = regnos[i];
5149 : 0 : if (regno < 0)
5150 : : break;
5151 : 0 : *nrefs += REG_N_REFS (regno);
5152 : 0 : hard_regno = reg_renumber[regno];
5153 : 0 : ira_assert (hard_regno >= 0);
5154 : 0 : a = ira_regno_allocno_map[regno];
5155 : 0 : length += ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a) / ALLOCNO_NUM_OBJECTS (a);
5156 : 0 : cost += ALLOCNO_MEMORY_COST (a) - ALLOCNO_CLASS_COST (a);
5157 : 0 : if (in_hard_reg_set_p (crtl->abi->full_reg_clobbers (),
5158 : 0 : ALLOCNO_MODE (a), hard_regno))
5159 : 0 : count++;
5160 : 0 : in_p = in && REG_P (in) && (int) REGNO (in) == hard_regno;
5161 : 0 : out_p = out && REG_P (out) && (int) REGNO (out) == hard_regno;
5162 : 0 : if ((in_p || out_p)
5163 : 0 : && find_regno_note (insn, REG_DEAD, hard_regno) != NULL_RTX)
5164 : : {
5165 : 0 : saved_cost = 0;
5166 : 0 : if (in_p)
5167 : 0 : saved_cost += ira_memory_move_cost
5168 : 0 : [ALLOCNO_MODE (a)][ALLOCNO_CLASS (a)][1];
5169 : 0 : if (out_p)
5170 : 0 : saved_cost
5171 : 0 : += ira_memory_move_cost
5172 : 0 : [ALLOCNO_MODE (a)][ALLOCNO_CLASS (a)][0];
5173 : 0 : cost -= REG_FREQ_FROM_BB (BLOCK_FOR_INSN (insn)) * saved_cost;
5174 : : }
5175 : : }
5176 : 0 : *excess_pressure_live_length = length;
5177 : 0 : *call_used_count = count;
5178 : 0 : hard_regno = -1;
5179 : 0 : if (regnos[0] >= 0)
5180 : : {
5181 : 0 : hard_regno = reg_renumber[regnos[0]];
5182 : : }
5183 : 0 : *first_hard_regno = hard_regno;
5184 : 0 : return cost;
5185 : : }
5186 : :
5187 : : /* Return TRUE if spilling pseudo-registers whose numbers are in array
5188 : : REGNOS is better than spilling pseudo-registers with numbers in
5189 : : OTHER_REGNOS for reload with given IN and OUT for INSN. The
5190 : : function used by the reload pass to make better register spilling
5191 : : decisions. */
5192 : : bool
5193 : 0 : ira_better_spill_reload_regno_p (int *regnos, int *other_regnos,
5194 : : rtx in, rtx out, rtx_insn *insn)
5195 : : {
5196 : 0 : int cost, other_cost;
5197 : 0 : int length, other_length;
5198 : 0 : int nrefs, other_nrefs;
5199 : 0 : int call_used_count, other_call_used_count;
5200 : 0 : int hard_regno, other_hard_regno;
5201 : :
5202 : 0 : cost = calculate_spill_cost (regnos, in, out, insn,
5203 : : &length, &nrefs, &call_used_count, &hard_regno);
5204 : 0 : other_cost = calculate_spill_cost (other_regnos, in, out, insn,
5205 : : &other_length, &other_nrefs,
5206 : : &other_call_used_count,
5207 : : &other_hard_regno);
5208 : 0 : if (nrefs == 0 && other_nrefs != 0)
5209 : : return true;
5210 : 0 : if (nrefs != 0 && other_nrefs == 0)
5211 : : return false;
5212 : 0 : if (cost != other_cost)
5213 : 0 : return cost < other_cost;
5214 : 0 : if (length != other_length)
5215 : 0 : return length > other_length;
5216 : : #ifdef REG_ALLOC_ORDER
5217 : 0 : if (hard_regno >= 0 && other_hard_regno >= 0)
5218 : 0 : return (inv_reg_alloc_order[hard_regno]
5219 : 0 : < inv_reg_alloc_order[other_hard_regno]);
5220 : : #else
5221 : : if (call_used_count != other_call_used_count)
5222 : : return call_used_count > other_call_used_count;
5223 : : #endif
5224 : : return false;
5225 : : }
5226 : :
5227 : :
5228 : :
5229 : : /* Allocate and initialize data necessary for assign_hard_reg. */
5230 : : void
5231 : 1003194 : ira_initiate_assign (void)
5232 : : {
5233 : 1003194 : sorted_allocnos
5234 : 2006388 : = (ira_allocno_t *) ira_allocate (sizeof (ira_allocno_t)
5235 : 1003194 : * ira_allocnos_num);
5236 : 1003194 : consideration_allocno_bitmap = ira_allocate_bitmap ();
5237 : 1003194 : initiate_cost_update ();
5238 : 1003194 : allocno_priorities = (int *) ira_allocate (sizeof (int) * ira_allocnos_num);
5239 : 1003194 : sorted_copies = (ira_copy_t *) ira_allocate (ira_copies_num
5240 : : * sizeof (ira_copy_t));
5241 : 1003194 : }
5242 : :
5243 : : /* Deallocate data used by assign_hard_reg. */
5244 : : void
5245 : 1003194 : ira_finish_assign (void)
5246 : : {
5247 : 1003194 : ira_free (sorted_allocnos);
5248 : 1003194 : ira_free_bitmap (consideration_allocno_bitmap);
5249 : 1003194 : finish_cost_update ();
5250 : 1003194 : ira_free (allocno_priorities);
5251 : 1003194 : ira_free (sorted_copies);
5252 : 1003194 : }
5253 : :
5254 : :
5255 : :
5256 : : /* Entry function doing color-based register allocation. */
5257 : : static void
5258 : 1003194 : color (void)
5259 : : {
5260 : 1003194 : allocno_stack_vec.create (ira_allocnos_num);
5261 : 1003194 : memset (allocated_hardreg_p, 0, sizeof (allocated_hardreg_p));
5262 : 1003194 : CLEAR_HARD_REG_SET (allocated_callee_save_regs);
5263 : 1003194 : ira_initiate_assign ();
5264 : 1003194 : do_coloring ();
5265 : 1003194 : ira_finish_assign ();
5266 : 1003194 : allocno_stack_vec.release ();
5267 : 1003194 : move_spill_restore ();
5268 : 1003194 : }
5269 : :
5270 : :
5271 : :
5272 : : /* This page contains a simple register allocator without usage of
5273 : : allocno conflicts. This is used for fast allocation for -O0. */
5274 : :
5275 : : /* Do register allocation by not using allocno conflicts. It uses
5276 : : only allocno live ranges. The algorithm is close to Chow's
5277 : : priority coloring. */
5278 : : static void
5279 : 428428 : fast_allocation (void)
5280 : : {
5281 : 428428 : int i, j, k, num, class_size, hard_regno, best_hard_regno, cost, min_cost;
5282 : 428428 : int *costs;
5283 : : #ifdef STACK_REGS
5284 : 428428 : bool no_stack_reg_p;
5285 : : #endif
5286 : 428428 : enum reg_class aclass;
5287 : 428428 : machine_mode mode;
5288 : 428428 : ira_allocno_t a;
5289 : 428428 : ira_allocno_iterator ai;
5290 : 428428 : live_range_t r;
5291 : 428428 : HARD_REG_SET conflict_hard_regs, *used_hard_regs;
5292 : :
5293 : 856856 : sorted_allocnos = (ira_allocno_t *) ira_allocate (sizeof (ira_allocno_t)
5294 : 428428 : * ira_allocnos_num);
5295 : 428428 : num = 0;
5296 : 11702551 : FOR_EACH_ALLOCNO (a, ai)
5297 : 11274123 : sorted_allocnos[num++] = a;
5298 : 428428 : allocno_priorities = (int *) ira_allocate (sizeof (int) * ira_allocnos_num);
5299 : 428428 : setup_allocno_priorities (sorted_allocnos, num);
5300 : 428428 : used_hard_regs = (HARD_REG_SET *) ira_allocate (sizeof (HARD_REG_SET)
5301 : 428428 : * ira_max_point);
5302 : 18842930 : for (i = 0; i < ira_max_point; i++)
5303 : 35972148 : CLEAR_HARD_REG_SET (used_hard_regs[i]);
5304 : 428428 : qsort (sorted_allocnos, num, sizeof (ira_allocno_t),
5305 : : allocno_priority_compare_func);
5306 : 11702551 : for (i = 0; i < num; i++)
5307 : : {
5308 : 11274123 : int nr, l;
5309 : :
5310 : 11274123 : a = sorted_allocnos[i];
5311 : 11274123 : nr = ALLOCNO_NUM_OBJECTS (a);
5312 : 11274123 : CLEAR_HARD_REG_SET (conflict_hard_regs);
5313 : 23367722 : for (l = 0; l < nr; l++)
5314 : : {
5315 : 12093599 : ira_object_t obj = ALLOCNO_OBJECT (a, l);
5316 : 12093599 : conflict_hard_regs |= OBJECT_CONFLICT_HARD_REGS (obj);
5317 : 25530128 : for (r = OBJECT_LIVE_RANGES (obj); r != NULL; r = r->next)
5318 : 940976153 : for (j = r->start; j <= r->finish; j++)
5319 : 1855079248 : conflict_hard_regs |= used_hard_regs[j];
5320 : : }
5321 : 11274123 : aclass = ALLOCNO_CLASS (a);
5322 : 11274123 : ALLOCNO_ASSIGNED_P (a) = true;
5323 : 11274123 : ALLOCNO_HARD_REGNO (a) = -1;
5324 : 22548246 : if (hard_reg_set_subset_p (reg_class_contents[aclass],
5325 : : conflict_hard_regs))
5326 : 66498 : continue;
5327 : 11207625 : mode = ALLOCNO_MODE (a);
5328 : : #ifdef STACK_REGS
5329 : 11207625 : no_stack_reg_p = ALLOCNO_NO_STACK_REG_P (a);
5330 : : #endif
5331 : 11207625 : class_size = ira_class_hard_regs_num[aclass];
5332 : 11207625 : costs = ALLOCNO_HARD_REG_COSTS (a);
5333 : 11207625 : min_cost = INT_MAX;
5334 : 11207625 : best_hard_regno = -1;
5335 : 40124633 : for (j = 0; j < class_size; j++)
5336 : : {
5337 : 39198136 : hard_regno = ira_class_hard_regs[aclass][j];
5338 : : #ifdef STACK_REGS
5339 : 39198136 : if (no_stack_reg_p && FIRST_STACK_REG <= hard_regno
5340 : 39311 : && hard_regno <= LAST_STACK_REG)
5341 : 0 : continue;
5342 : : #endif
5343 : 39198136 : if (ira_hard_reg_set_intersection_p (hard_regno, mode, conflict_hard_regs)
5344 : 39198136 : || (TEST_HARD_REG_BIT
5345 : 30524257 : (ira_prohibited_class_mode_regs[aclass][mode], hard_regno)))
5346 : 9335775 : continue;
5347 : 29862361 : if (NUM_REGISTER_FILTERS
5348 : : && !test_register_filters (ALLOCNO_REGISTER_FILTERS (a),
5349 : : hard_regno))
5350 : : continue;
5351 : 29862361 : if (costs == NULL)
5352 : : {
5353 : : best_hard_regno = hard_regno;
5354 : : break;
5355 : : }
5356 : 19581233 : cost = costs[j];
5357 : 19581233 : if (min_cost > cost)
5358 : : {
5359 : 28917008 : min_cost = cost;
5360 : 28917008 : best_hard_regno = hard_regno;
5361 : : }
5362 : : }
5363 : 11207625 : if (best_hard_regno < 0)
5364 : 23715 : continue;
5365 : 11183910 : ALLOCNO_HARD_REGNO (a) = hard_regno = best_hard_regno;
5366 : 23149033 : for (l = 0; l < nr; l++)
5367 : : {
5368 : 11965123 : ira_object_t obj = ALLOCNO_OBJECT (a, l);
5369 : 24169655 : for (r = OBJECT_LIVE_RANGES (obj); r != NULL; r = r->next)
5370 : 49329093 : for (k = r->start; k <= r->finish; k++)
5371 : 74249122 : used_hard_regs[k] |= ira_reg_mode_hard_regset[hard_regno][mode];
5372 : : }
5373 : : }
5374 : 428428 : ira_free (sorted_allocnos);
5375 : 428428 : ira_free (used_hard_regs);
5376 : 428428 : ira_free (allocno_priorities);
5377 : 428428 : if (internal_flag_ira_verbose > 1 && ira_dump_file != NULL)
5378 : 56 : ira_print_disposition (ira_dump_file);
5379 : 428428 : }
5380 : :
5381 : :
5382 : :
5383 : : /* Entry function doing coloring. */
5384 : : void
5385 : 1431622 : ira_color (void)
5386 : : {
5387 : 1431622 : ira_allocno_t a;
5388 : 1431622 : ira_allocno_iterator ai;
5389 : :
5390 : : /* Setup updated costs. */
5391 : 1431622 : allocated_memory_p = false;
5392 : 36497706 : FOR_EACH_ALLOCNO (a, ai)
5393 : : {
5394 : 35066084 : ALLOCNO_UPDATED_MEMORY_COST (a) = ALLOCNO_MEMORY_COST (a);
5395 : 35066084 : ALLOCNO_UPDATED_CLASS_COST (a) = ALLOCNO_CLASS_COST (a);
5396 : 35066084 : if (ALLOCNO_CLASS (a) == NO_REGS
5397 : 35066084 : && !ira_equiv_no_lvalue_p (ALLOCNO_REGNO (a)))
5398 : 380548 : allocated_memory_p = true;
5399 : : }
5400 : 1431622 : if (ira_conflicts_p)
5401 : 1003194 : color ();
5402 : : else
5403 : 428428 : fast_allocation ();
5404 : 1431622 : }
|