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