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