1 /* IRA allocation based on graph coloring.
2    Copyright (C) 2006-2020 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 only
1360    for true CONFLICT_COST_UPDATE_P.  Record cost updates if RECORD_P is
1361    true.  */
1362 static void
update_costs_from_allocno(ira_allocno_t allocno,int hard_regno,int divisor,bool decr_p,bool record_p,bool conflict_cost_update_p)1363 update_costs_from_allocno (ira_allocno_t allocno, int hard_regno,
1364 			   int divisor, bool decr_p, bool record_p,
1365 			   bool conflict_cost_update_p)
1366 {
1367   int cost, update_cost, update_conflict_cost;
1368   machine_mode mode;
1369   enum reg_class rclass, aclass;
1370   ira_allocno_t another_allocno, start = allocno, from = NULL;
1371   ira_copy_t cp, next_cp;
1372 
1373   rclass = REGNO_REG_CLASS (hard_regno);
1374   do
1375     {
1376       mode = ALLOCNO_MODE (allocno);
1377       ira_init_register_move_cost_if_necessary (mode);
1378       for (cp = ALLOCNO_COPIES (allocno); cp != NULL; cp = next_cp)
1379 	{
1380 	  if (cp->first == allocno)
1381 	    {
1382 	      next_cp = cp->next_first_allocno_copy;
1383 	      another_allocno = cp->second;
1384 	    }
1385 	  else if (cp->second == allocno)
1386 	    {
1387 	      next_cp = cp->next_second_allocno_copy;
1388 	      another_allocno = cp->first;
1389 	    }
1390 	  else
1391 	    gcc_unreachable ();
1392 
1393 	  if (another_allocno == from
1394 	      || allocnos_conflict_p (another_allocno, start))
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 = conflict_cost_update_p ? update_cost : 0;
1423 
1424 	  if (ALLOCNO_COLOR_DATA (another_allocno) != NULL
1425 	      && (ALLOCNO_COLOR_DATA (allocno)->first_thread_allocno
1426 		  != ALLOCNO_COLOR_DATA (another_allocno)->first_thread_allocno))
1427 	    /* Decrease conflict cost of ANOTHER_ALLOCNO if it is not
1428 	       in the same allocation thread.  */
1429 	    update_conflict_cost /= COST_HOP_DIVISOR;
1430 
1431 	  if (update_cost == 0)
1432 	    continue;
1433 
1434 	  if (! update_allocno_cost (another_allocno, hard_regno,
1435 				     update_cost, update_conflict_cost))
1436 	    continue;
1437 	  queue_update_cost (another_allocno, start, allocno,
1438 			     divisor * COST_HOP_DIVISOR);
1439 	  if (record_p && ALLOCNO_COLOR_DATA (another_allocno) != NULL)
1440 	    ALLOCNO_COLOR_DATA (another_allocno)->update_cost_records
1441 	      = get_update_cost_record (hard_regno, divisor,
1442 					ALLOCNO_COLOR_DATA (another_allocno)
1443 					->update_cost_records);
1444 	}
1445     }
1446   while (get_next_update_cost (&allocno, &start, &from, &divisor));
1447 }
1448 
1449 /* Decrease preferred ALLOCNO hard register costs and costs of
1450    allocnos connected to ALLOCNO through copy.  */
1451 static void
update_costs_from_prefs(ira_allocno_t allocno)1452 update_costs_from_prefs (ira_allocno_t allocno)
1453 {
1454   ira_pref_t pref;
1455 
1456   start_update_cost ();
1457   for (pref = ALLOCNO_PREFS (allocno); pref != NULL; pref = pref->next_pref)
1458     update_costs_from_allocno (allocno, pref->hard_regno,
1459 			       COST_HOP_DIVISOR, true, true, false);
1460 }
1461 
1462 /* Update (decrease if DECR_P) the cost of allocnos connected to
1463    ALLOCNO through copies to increase chances to remove some copies as
1464    the result of subsequent assignment.  ALLOCNO was just assigned to
1465    a hard register.  Record cost updates if RECORD_P is true.  */
1466 static void
update_costs_from_copies(ira_allocno_t allocno,bool decr_p,bool record_p)1467 update_costs_from_copies (ira_allocno_t allocno, bool decr_p, bool record_p)
1468 {
1469   int hard_regno;
1470 
1471   hard_regno = ALLOCNO_HARD_REGNO (allocno);
1472   ira_assert (hard_regno >= 0 && ALLOCNO_CLASS (allocno) != NO_REGS);
1473   start_update_cost ();
1474   update_costs_from_allocno (allocno, hard_regno, 1, decr_p, record_p, true);
1475 }
1476 
1477 /* Update conflict_allocno_hard_prefs of allocnos conflicting with
1478    ALLOCNO.  */
1479 static void
update_conflict_allocno_hard_prefs(ira_allocno_t allocno)1480 update_conflict_allocno_hard_prefs (ira_allocno_t allocno)
1481 {
1482   int l, nr = ALLOCNO_NUM_OBJECTS (allocno);
1483 
1484   for (l = 0; l < nr; l++)
1485     {
1486       ira_object_t conflict_obj, obj = ALLOCNO_OBJECT (allocno, l);
1487       ira_object_conflict_iterator oci;
1488 
1489       FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
1490 	{
1491 	  ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
1492 	  allocno_color_data_t conflict_data = ALLOCNO_COLOR_DATA (conflict_a);
1493 	  ira_pref_t pref;
1494 
1495 	  if (!(hard_reg_set_intersect_p
1496 		(ALLOCNO_COLOR_DATA (allocno)->profitable_hard_regs,
1497 		 conflict_data->profitable_hard_regs)))
1498 	    continue;
1499 	  for (pref = ALLOCNO_PREFS (allocno);
1500 	       pref != NULL;
1501 	       pref = pref->next_pref)
1502 	    conflict_data->conflict_allocno_hard_prefs += pref->freq;
1503 	}
1504     }
1505 }
1506 
1507 /* Restore costs of allocnos connected to ALLOCNO by copies as it was
1508    before updating costs of these allocnos from given allocno.  This
1509    is a wise thing to do as if given allocno did not get an expected
1510    hard reg, using smaller cost of the hard reg for allocnos connected
1511    by copies to given allocno becomes actually misleading.  Free all
1512    update cost records for ALLOCNO as we don't need them anymore.  */
1513 static void
restore_costs_from_copies(ira_allocno_t allocno)1514 restore_costs_from_copies (ira_allocno_t allocno)
1515 {
1516   struct update_cost_record *records, *curr;
1517 
1518   if (ALLOCNO_COLOR_DATA (allocno) == NULL)
1519     return;
1520   records = ALLOCNO_COLOR_DATA (allocno)->update_cost_records;
1521   start_update_cost ();
1522   for (curr = records; curr != NULL; curr = curr->next)
1523     update_costs_from_allocno (allocno, curr->hard_regno,
1524 			       curr->divisor, true, false, true);
1525   free_update_cost_record_list (records);
1526   ALLOCNO_COLOR_DATA (allocno)->update_cost_records = NULL;
1527 }
1528 
1529 /* This function updates COSTS (decrease if DECR_P) for hard_registers
1530    of ACLASS by conflict costs of the unassigned allocnos
1531    connected by copies with allocnos in update_cost_queue.  This
1532    update increases chances to remove some copies.  */
1533 static void
update_conflict_hard_regno_costs(int * costs,enum reg_class aclass,bool decr_p)1534 update_conflict_hard_regno_costs (int *costs, enum reg_class aclass,
1535 				  bool decr_p)
1536 {
1537   int i, cost, class_size, freq, mult, div, divisor;
1538   int index, hard_regno;
1539   int *conflict_costs;
1540   bool cont_p;
1541   enum reg_class another_aclass;
1542   ira_allocno_t allocno, another_allocno, start, from;
1543   ira_copy_t cp, next_cp;
1544 
1545   while (get_next_update_cost (&allocno, &start, &from, &divisor))
1546     for (cp = ALLOCNO_COPIES (allocno); cp != NULL; cp = next_cp)
1547       {
1548 	if (cp->first == allocno)
1549 	  {
1550 	    next_cp = cp->next_first_allocno_copy;
1551 	    another_allocno = cp->second;
1552 	  }
1553 	else if (cp->second == allocno)
1554 	  {
1555 	    next_cp = cp->next_second_allocno_copy;
1556 	    another_allocno = cp->first;
1557 	  }
1558 	else
1559 	  gcc_unreachable ();
1560 
1561 	if (another_allocno == from
1562 	    || allocnos_conflict_p (another_allocno, start))
1563 	  continue;
1564 
1565  	another_aclass = ALLOCNO_CLASS (another_allocno);
1566  	if (! ira_reg_classes_intersect_p[aclass][another_aclass]
1567 	    || ALLOCNO_ASSIGNED_P (another_allocno)
1568 	    || ALLOCNO_COLOR_DATA (another_allocno)->may_be_spilled_p)
1569 	  continue;
1570 	class_size = ira_class_hard_regs_num[another_aclass];
1571 	ira_allocate_and_copy_costs
1572 	  (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (another_allocno),
1573 	   another_aclass, ALLOCNO_CONFLICT_HARD_REG_COSTS (another_allocno));
1574 	conflict_costs
1575 	  = ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (another_allocno);
1576 	if (conflict_costs == NULL)
1577 	  cont_p = true;
1578 	else
1579 	  {
1580 	    mult = cp->freq;
1581 	    freq = ALLOCNO_FREQ (another_allocno);
1582 	    if (freq == 0)
1583 	      freq = 1;
1584 	    div = freq * divisor;
1585 	    cont_p = false;
1586 	    for (i = class_size - 1; i >= 0; i--)
1587 	      {
1588 		hard_regno = ira_class_hard_regs[another_aclass][i];
1589 		ira_assert (hard_regno >= 0);
1590 		index = ira_class_hard_reg_index[aclass][hard_regno];
1591 		if (index < 0)
1592 		  continue;
1593 		cost = (int) (((int64_t) conflict_costs [i] * mult) / div);
1594 		if (cost == 0)
1595 		  continue;
1596 		cont_p = true;
1597 		if (decr_p)
1598 		  cost = -cost;
1599 		costs[index] += cost;
1600 	      }
1601 	  }
1602 	/* Probably 5 hops will be enough.  */
1603 	if (cont_p
1604 	    && divisor <= (COST_HOP_DIVISOR
1605 			   * COST_HOP_DIVISOR
1606 			   * COST_HOP_DIVISOR
1607 			   * COST_HOP_DIVISOR))
1608 	  queue_update_cost (another_allocno, start, from, divisor * COST_HOP_DIVISOR);
1609       }
1610 }
1611 
1612 /* Set up conflicting (through CONFLICT_REGS) for each object of
1613    allocno A and the start allocno profitable regs (through
1614    START_PROFITABLE_REGS).  Remember that the start profitable regs
1615    exclude hard regs which cannot hold value of mode of allocno A.
1616    This covers mostly cases when multi-register value should be
1617    aligned.  */
1618 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)1619 get_conflict_and_start_profitable_regs (ira_allocno_t a, bool retry_p,
1620 					HARD_REG_SET *conflict_regs,
1621 					HARD_REG_SET *start_profitable_regs)
1622 {
1623   int i, nwords;
1624   ira_object_t obj;
1625 
1626   nwords = ALLOCNO_NUM_OBJECTS (a);
1627   for (i = 0; i < nwords; i++)
1628     {
1629       obj = ALLOCNO_OBJECT (a, i);
1630       conflict_regs[i] = OBJECT_TOTAL_CONFLICT_HARD_REGS (obj);
1631     }
1632   if (retry_p)
1633     *start_profitable_regs
1634       = (reg_class_contents[ALLOCNO_CLASS (a)]
1635 	 &~ (ira_prohibited_class_mode_regs
1636 	     [ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]));
1637   else
1638     *start_profitable_regs = ALLOCNO_COLOR_DATA (a)->profitable_hard_regs;
1639 }
1640 
1641 /* Return true if HARD_REGNO is ok for assigning to allocno A with
1642    PROFITABLE_REGS and whose objects have CONFLICT_REGS.  */
1643 static inline bool
check_hard_reg_p(ira_allocno_t a,int hard_regno,HARD_REG_SET * conflict_regs,HARD_REG_SET profitable_regs)1644 check_hard_reg_p (ira_allocno_t a, int hard_regno,
1645 		  HARD_REG_SET *conflict_regs, HARD_REG_SET profitable_regs)
1646 {
1647   int j, nwords, nregs;
1648   enum reg_class aclass;
1649   machine_mode mode;
1650 
1651   aclass = ALLOCNO_CLASS (a);
1652   mode = ALLOCNO_MODE (a);
1653   if (TEST_HARD_REG_BIT (ira_prohibited_class_mode_regs[aclass][mode],
1654 			 hard_regno))
1655     return false;
1656   /* Checking only profitable hard regs.  */
1657   if (! TEST_HARD_REG_BIT (profitable_regs, hard_regno))
1658     return false;
1659   nregs = hard_regno_nregs (hard_regno, mode);
1660   nwords = ALLOCNO_NUM_OBJECTS (a);
1661   for (j = 0; j < nregs; j++)
1662     {
1663       int k;
1664       int set_to_test_start = 0, set_to_test_end = nwords;
1665 
1666       if (nregs == nwords)
1667 	{
1668 	  if (REG_WORDS_BIG_ENDIAN)
1669 	    set_to_test_start = nwords - j - 1;
1670 	  else
1671 	    set_to_test_start = j;
1672 	  set_to_test_end = set_to_test_start + 1;
1673 	}
1674       for (k = set_to_test_start; k < set_to_test_end; k++)
1675 	if (TEST_HARD_REG_BIT (conflict_regs[k], hard_regno + j))
1676 	  break;
1677       if (k != set_to_test_end)
1678 	break;
1679     }
1680   return j == nregs;
1681 }
1682 
1683 /* Return number of registers needed to be saved and restored at
1684    function prologue/epilogue if we allocate HARD_REGNO to hold value
1685    of MODE.  */
1686 static int
calculate_saved_nregs(int hard_regno,machine_mode mode)1687 calculate_saved_nregs (int hard_regno, machine_mode mode)
1688 {
1689   int i;
1690   int nregs = 0;
1691 
1692   ira_assert (hard_regno >= 0);
1693   for (i = hard_regno_nregs (hard_regno, mode) - 1; i >= 0; i--)
1694     if (!allocated_hardreg_p[hard_regno + i]
1695 	&& !crtl->abi->clobbers_full_reg_p (hard_regno + i)
1696 	&& !LOCAL_REGNO (hard_regno + i))
1697       nregs++;
1698   return nregs;
1699 }
1700 
1701 /* Choose a hard register for allocno A.  If RETRY_P is TRUE, it means
1702    that the function called from function
1703    `ira_reassign_conflict_allocnos' and `allocno_reload_assign'.  In
1704    this case some allocno data are not defined or updated and we
1705    should not touch these data.  The function returns true if we
1706    managed to assign a hard register to the allocno.
1707 
1708    To assign a hard register, first of all we calculate all conflict
1709    hard registers which can come from conflicting allocnos with
1710    already assigned hard registers.  After that we find first free
1711    hard register with the minimal cost.  During hard register cost
1712    calculation we take conflict hard register costs into account to
1713    give a chance for conflicting allocnos to get a better hard
1714    register in the future.
1715 
1716    If the best hard register cost is bigger than cost of memory usage
1717    for the allocno, we don't assign a hard register to given allocno
1718    at all.
1719 
1720    If we assign a hard register to the allocno, we update costs of the
1721    hard register for allocnos connected by copies to improve a chance
1722    to coalesce insns represented by the copies when we assign hard
1723    registers to the allocnos connected by the copies.  */
1724 static bool
assign_hard_reg(ira_allocno_t a,bool retry_p)1725 assign_hard_reg (ira_allocno_t a, bool retry_p)
1726 {
1727   HARD_REG_SET conflicting_regs[2], profitable_hard_regs;
1728   int i, j, hard_regno, best_hard_regno, class_size;
1729   int cost, mem_cost, min_cost, full_cost, min_full_cost, nwords, word;
1730   int *a_costs;
1731   enum reg_class aclass;
1732   machine_mode mode;
1733   static int costs[FIRST_PSEUDO_REGISTER], full_costs[FIRST_PSEUDO_REGISTER];
1734   int saved_nregs;
1735   enum reg_class rclass;
1736   int add_cost;
1737 #ifdef STACK_REGS
1738   bool no_stack_reg_p;
1739 #endif
1740 
1741   ira_assert (! ALLOCNO_ASSIGNED_P (a));
1742   get_conflict_and_start_profitable_regs (a, retry_p,
1743 					  conflicting_regs,
1744 					  &profitable_hard_regs);
1745   aclass = ALLOCNO_CLASS (a);
1746   class_size = ira_class_hard_regs_num[aclass];
1747   best_hard_regno = -1;
1748   memset (full_costs, 0, sizeof (int) * class_size);
1749   mem_cost = 0;
1750   memset (costs, 0, sizeof (int) * class_size);
1751   memset (full_costs, 0, sizeof (int) * class_size);
1752 #ifdef STACK_REGS
1753   no_stack_reg_p = false;
1754 #endif
1755   if (! retry_p)
1756     start_update_cost ();
1757   mem_cost += ALLOCNO_UPDATED_MEMORY_COST (a);
1758 
1759   ira_allocate_and_copy_costs (&ALLOCNO_UPDATED_HARD_REG_COSTS (a),
1760 			       aclass, ALLOCNO_HARD_REG_COSTS (a));
1761   a_costs = ALLOCNO_UPDATED_HARD_REG_COSTS (a);
1762 #ifdef STACK_REGS
1763   no_stack_reg_p = no_stack_reg_p || ALLOCNO_TOTAL_NO_STACK_REG_P (a);
1764 #endif
1765   cost = ALLOCNO_UPDATED_CLASS_COST (a);
1766   for (i = 0; i < class_size; i++)
1767     if (a_costs != NULL)
1768       {
1769 	costs[i] += a_costs[i];
1770 	full_costs[i] += a_costs[i];
1771       }
1772     else
1773       {
1774 	costs[i] += cost;
1775 	full_costs[i] += cost;
1776       }
1777   nwords = ALLOCNO_NUM_OBJECTS (a);
1778   curr_allocno_process++;
1779   for (word = 0; word < nwords; word++)
1780     {
1781       ira_object_t conflict_obj;
1782       ira_object_t obj = ALLOCNO_OBJECT (a, word);
1783       ira_object_conflict_iterator oci;
1784 
1785       /* Take preferences of conflicting allocnos into account.  */
1786       FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
1787         {
1788 	  ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
1789 	  enum reg_class conflict_aclass;
1790 	  allocno_color_data_t data = ALLOCNO_COLOR_DATA (conflict_a);
1791 
1792 	  /* Reload can give another class so we need to check all
1793 	     allocnos.  */
1794 	  if (!retry_p
1795 	      && ((!ALLOCNO_ASSIGNED_P (conflict_a)
1796 		   || ALLOCNO_HARD_REGNO (conflict_a) < 0)
1797 		  && !(hard_reg_set_intersect_p
1798 		       (profitable_hard_regs,
1799 			ALLOCNO_COLOR_DATA
1800 			(conflict_a)->profitable_hard_regs))))
1801 	    {
1802 	      /* All conflict allocnos are in consideration bitmap
1803 		 when retry_p is false.  It might change in future and
1804 		 if it happens the assert will be broken.  It means
1805 		 the code should be modified for the new
1806 		 assumptions.  */
1807 	      ira_assert (bitmap_bit_p (consideration_allocno_bitmap,
1808 					ALLOCNO_NUM (conflict_a)));
1809 	      continue;
1810 	    }
1811 	  conflict_aclass = ALLOCNO_CLASS (conflict_a);
1812 	  ira_assert (ira_reg_classes_intersect_p
1813 		      [aclass][conflict_aclass]);
1814 	  if (ALLOCNO_ASSIGNED_P (conflict_a))
1815 	    {
1816 	      hard_regno = ALLOCNO_HARD_REGNO (conflict_a);
1817 	      if (hard_regno >= 0
1818 		  && (ira_hard_reg_set_intersection_p
1819 		      (hard_regno, ALLOCNO_MODE (conflict_a),
1820 		       reg_class_contents[aclass])))
1821 		{
1822 		  int n_objects = ALLOCNO_NUM_OBJECTS (conflict_a);
1823 		  int conflict_nregs;
1824 
1825 		  mode = ALLOCNO_MODE (conflict_a);
1826 		  conflict_nregs = hard_regno_nregs (hard_regno, mode);
1827 		  if (conflict_nregs == n_objects && conflict_nregs > 1)
1828 		    {
1829 		      int num = OBJECT_SUBWORD (conflict_obj);
1830 
1831 		      if (REG_WORDS_BIG_ENDIAN)
1832 			SET_HARD_REG_BIT (conflicting_regs[word],
1833 					  hard_regno + n_objects - num - 1);
1834 		      else
1835 			SET_HARD_REG_BIT (conflicting_regs[word],
1836 					  hard_regno + num);
1837 		    }
1838 		  else
1839 		    conflicting_regs[word]
1840 		      |= ira_reg_mode_hard_regset[hard_regno][mode];
1841 		  if (hard_reg_set_subset_p (profitable_hard_regs,
1842 					     conflicting_regs[word]))
1843 		    goto fail;
1844 		}
1845 	    }
1846 	  else if (! retry_p
1847 		   && ! ALLOCNO_COLOR_DATA (conflict_a)->may_be_spilled_p
1848 		   /* Don't process the conflict allocno twice.  */
1849 		   && (ALLOCNO_COLOR_DATA (conflict_a)->last_process
1850 		       != curr_allocno_process))
1851 	    {
1852 	      int k, *conflict_costs;
1853 
1854 	      ALLOCNO_COLOR_DATA (conflict_a)->last_process
1855 		= curr_allocno_process;
1856 	      ira_allocate_and_copy_costs
1857 		(&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (conflict_a),
1858 		 conflict_aclass,
1859 		 ALLOCNO_CONFLICT_HARD_REG_COSTS (conflict_a));
1860 	      conflict_costs
1861 		= ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (conflict_a);
1862 	      if (conflict_costs != NULL)
1863 		for (j = class_size - 1; j >= 0; j--)
1864 		  {
1865 		    hard_regno = ira_class_hard_regs[aclass][j];
1866 		    ira_assert (hard_regno >= 0);
1867 		    k = ira_class_hard_reg_index[conflict_aclass][hard_regno];
1868 		    if (k < 0
1869 			   /* If HARD_REGNO is not available for CONFLICT_A,
1870 			      the conflict would be ignored, since HARD_REGNO
1871 			      will never be assigned to CONFLICT_A.  */
1872 			|| !TEST_HARD_REG_BIT (data->profitable_hard_regs,
1873 					       hard_regno))
1874 		      continue;
1875 		    full_costs[j] -= conflict_costs[k];
1876 		  }
1877 	      queue_update_cost (conflict_a, conflict_a, NULL, COST_HOP_DIVISOR);
1878 	    }
1879 	}
1880     }
1881   if (! retry_p)
1882     /* Take into account preferences of allocnos connected by copies to
1883        the conflict allocnos.  */
1884     update_conflict_hard_regno_costs (full_costs, aclass, true);
1885 
1886   /* Take preferences of allocnos connected by copies into
1887      account.  */
1888   if (! retry_p)
1889     {
1890       start_update_cost ();
1891       queue_update_cost (a, a, NULL, COST_HOP_DIVISOR);
1892       update_conflict_hard_regno_costs (full_costs, aclass, false);
1893     }
1894   min_cost = min_full_cost = INT_MAX;
1895   /* We don't care about giving callee saved registers to allocnos no
1896      living through calls because call clobbered registers are
1897      allocated first (it is usual practice to put them first in
1898      REG_ALLOC_ORDER).  */
1899   mode = ALLOCNO_MODE (a);
1900   for (i = 0; i < class_size; i++)
1901     {
1902       hard_regno = ira_class_hard_regs[aclass][i];
1903 #ifdef STACK_REGS
1904       if (no_stack_reg_p
1905 	  && FIRST_STACK_REG <= hard_regno && hard_regno <= LAST_STACK_REG)
1906 	continue;
1907 #endif
1908       if (! check_hard_reg_p (a, hard_regno,
1909 			      conflicting_regs, profitable_hard_regs))
1910 	continue;
1911       cost = costs[i];
1912       full_cost = full_costs[i];
1913       if (!HONOR_REG_ALLOC_ORDER)
1914 	{
1915 	  if ((saved_nregs = calculate_saved_nregs (hard_regno, mode)) != 0)
1916 	  /* We need to save/restore the hard register in
1917 	     epilogue/prologue.  Therefore we increase the cost.  */
1918 	  {
1919 	    rclass = REGNO_REG_CLASS (hard_regno);
1920 	    add_cost = ((ira_memory_move_cost[mode][rclass][0]
1921 		         + ira_memory_move_cost[mode][rclass][1])
1922 		        * saved_nregs / hard_regno_nregs (hard_regno,
1923 							  mode) - 1);
1924 	    cost += add_cost;
1925 	    full_cost += add_cost;
1926 	  }
1927 	}
1928       if (min_cost > cost)
1929 	min_cost = cost;
1930       if (min_full_cost > full_cost)
1931 	{
1932 	  min_full_cost = full_cost;
1933 	  best_hard_regno = hard_regno;
1934 	  ira_assert (hard_regno >= 0);
1935 	}
1936       if (internal_flag_ira_verbose > 5 && ira_dump_file != NULL)
1937 	fprintf (ira_dump_file, "(%d=%d,%d) ", hard_regno, cost, full_cost);
1938     }
1939   if (min_full_cost > mem_cost
1940       /* Do not spill static chain pointer pseudo when non-local goto
1941 	 is used.  */
1942       && ! non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a)))
1943     {
1944       if (! retry_p && internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
1945 	fprintf (ira_dump_file, "(memory is more profitable %d vs %d) ",
1946 		 mem_cost, min_full_cost);
1947       best_hard_regno = -1;
1948     }
1949  fail:
1950   if (best_hard_regno >= 0)
1951     {
1952       for (i = hard_regno_nregs (best_hard_regno, mode) - 1; i >= 0; i--)
1953 	allocated_hardreg_p[best_hard_regno + i] = true;
1954     }
1955   if (! retry_p)
1956     restore_costs_from_copies (a);
1957   ALLOCNO_HARD_REGNO (a) = best_hard_regno;
1958   ALLOCNO_ASSIGNED_P (a) = true;
1959   if (best_hard_regno >= 0)
1960     update_costs_from_copies (a, true, ! retry_p);
1961   ira_assert (ALLOCNO_CLASS (a) == aclass);
1962   /* We don't need updated costs anymore.  */
1963   ira_free_allocno_updated_costs (a);
1964   return best_hard_regno >= 0;
1965 }
1966 
1967 
1968 
1969 /* An array used to sort copies.  */
1970 static ira_copy_t *sorted_copies;
1971 
1972 /* If allocno A is a cap, return non-cap allocno from which A is
1973    created.  Otherwise, return A.  */
1974 static ira_allocno_t
get_cap_member(ira_allocno_t a)1975 get_cap_member (ira_allocno_t a)
1976 {
1977   ira_allocno_t member;
1978 
1979   while ((member = ALLOCNO_CAP_MEMBER (a)) != NULL)
1980     a = member;
1981   return a;
1982 }
1983 
1984 /* Return TRUE if live ranges of allocnos A1 and A2 intersect.  It is
1985    used to find a conflict for new allocnos or allocnos with the
1986    different allocno classes.  */
1987 static bool
allocnos_conflict_by_live_ranges_p(ira_allocno_t a1,ira_allocno_t a2)1988 allocnos_conflict_by_live_ranges_p (ira_allocno_t a1, ira_allocno_t a2)
1989 {
1990   rtx reg1, reg2;
1991   int i, j;
1992   int n1 = ALLOCNO_NUM_OBJECTS (a1);
1993   int n2 = ALLOCNO_NUM_OBJECTS (a2);
1994 
1995   if (a1 == a2)
1996     return false;
1997   reg1 = regno_reg_rtx[ALLOCNO_REGNO (a1)];
1998   reg2 = regno_reg_rtx[ALLOCNO_REGNO (a2)];
1999   if (reg1 != NULL && reg2 != NULL
2000       && ORIGINAL_REGNO (reg1) == ORIGINAL_REGNO (reg2))
2001     return false;
2002 
2003   /* We don't keep live ranges for caps because they can be quite big.
2004      Use ranges of non-cap allocno from which caps are created.  */
2005   a1 = get_cap_member (a1);
2006   a2 = get_cap_member (a2);
2007   for (i = 0; i < n1; i++)
2008     {
2009       ira_object_t c1 = ALLOCNO_OBJECT (a1, i);
2010 
2011       for (j = 0; j < n2; j++)
2012 	{
2013 	  ira_object_t c2 = ALLOCNO_OBJECT (a2, j);
2014 
2015 	  if (ira_live_ranges_intersect_p (OBJECT_LIVE_RANGES (c1),
2016 					   OBJECT_LIVE_RANGES (c2)))
2017 	    return true;
2018 	}
2019     }
2020   return false;
2021 }
2022 
2023 /* The function is used to sort copies according to their execution
2024    frequencies.  */
2025 static int
copy_freq_compare_func(const void * v1p,const void * v2p)2026 copy_freq_compare_func (const void *v1p, const void *v2p)
2027 {
2028   ira_copy_t cp1 = *(const ira_copy_t *) v1p, cp2 = *(const ira_copy_t *) v2p;
2029   int pri1, pri2;
2030 
2031   pri1 = cp1->freq;
2032   pri2 = cp2->freq;
2033   if (pri2 - pri1)
2034     return pri2 - pri1;
2035 
2036   /* If frequencies are equal, sort by copies, so that the results of
2037      qsort leave nothing to chance.  */
2038   return cp1->num - cp2->num;
2039 }
2040 
2041 
2042 
2043 /* Return true if any allocno from thread of A1 conflicts with any
2044    allocno from thread A2.  */
2045 static bool
allocno_thread_conflict_p(ira_allocno_t a1,ira_allocno_t a2)2046 allocno_thread_conflict_p (ira_allocno_t a1, ira_allocno_t a2)
2047 {
2048   ira_allocno_t a, conflict_a;
2049 
2050   for (a = ALLOCNO_COLOR_DATA (a2)->next_thread_allocno;;
2051        a = ALLOCNO_COLOR_DATA (a)->next_thread_allocno)
2052     {
2053       for (conflict_a = ALLOCNO_COLOR_DATA (a1)->next_thread_allocno;;
2054 	   conflict_a = ALLOCNO_COLOR_DATA (conflict_a)->next_thread_allocno)
2055 	{
2056 	  if (allocnos_conflict_by_live_ranges_p (a, conflict_a))
2057 	    return true;
2058 	  if (conflict_a == a1)
2059 	    break;
2060 	}
2061       if (a == a2)
2062 	break;
2063     }
2064   return false;
2065 }
2066 
2067 /* Merge two threads given correspondingly by their first allocnos T1
2068    and T2 (more accurately merging T2 into T1).  */
2069 static void
merge_threads(ira_allocno_t t1,ira_allocno_t t2)2070 merge_threads (ira_allocno_t t1, ira_allocno_t t2)
2071 {
2072   ira_allocno_t a, next, last;
2073 
2074   gcc_assert (t1 != t2
2075 	      && ALLOCNO_COLOR_DATA (t1)->first_thread_allocno == t1
2076 	      && ALLOCNO_COLOR_DATA (t2)->first_thread_allocno == t2);
2077   for (last = t2, a = ALLOCNO_COLOR_DATA (t2)->next_thread_allocno;;
2078        a = ALLOCNO_COLOR_DATA (a)->next_thread_allocno)
2079     {
2080       ALLOCNO_COLOR_DATA (a)->first_thread_allocno = t1;
2081       if (a == t2)
2082 	break;
2083       last = a;
2084     }
2085   next = ALLOCNO_COLOR_DATA (t1)->next_thread_allocno;
2086   ALLOCNO_COLOR_DATA (t1)->next_thread_allocno = t2;
2087   ALLOCNO_COLOR_DATA (last)->next_thread_allocno = next;
2088   ALLOCNO_COLOR_DATA (t1)->thread_freq += ALLOCNO_COLOR_DATA (t2)->thread_freq;
2089 }
2090 
2091 /* Create threads by processing CP_NUM copies from sorted copies.  We
2092    process the most expensive copies first.  */
2093 static void
form_threads_from_copies(int cp_num)2094 form_threads_from_copies (int cp_num)
2095 {
2096   ira_allocno_t a, thread1, thread2;
2097   ira_copy_t cp;
2098   int i, n;
2099 
2100   qsort (sorted_copies, cp_num, sizeof (ira_copy_t), copy_freq_compare_func);
2101   /* Form threads processing copies, most frequently executed
2102      first.  */
2103   for (; cp_num != 0;)
2104     {
2105       for (i = 0; i < cp_num; i++)
2106 	{
2107 	  cp = sorted_copies[i];
2108 	  thread1 = ALLOCNO_COLOR_DATA (cp->first)->first_thread_allocno;
2109 	  thread2 = ALLOCNO_COLOR_DATA (cp->second)->first_thread_allocno;
2110 	  if (thread1 == thread2)
2111 	    continue;
2112 	  if (! allocno_thread_conflict_p (thread1, thread2))
2113 	    {
2114 	      if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2115 		fprintf
2116 		  (ira_dump_file,
2117 		   "      Forming thread by copy %d:a%dr%d-a%dr%d (freq=%d):\n",
2118 		   cp->num, ALLOCNO_NUM (cp->first), ALLOCNO_REGNO (cp->first),
2119 		   ALLOCNO_NUM (cp->second), ALLOCNO_REGNO (cp->second),
2120 		   cp->freq);
2121 	      merge_threads (thread1, thread2);
2122 	      if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2123 		{
2124 		  thread1 = ALLOCNO_COLOR_DATA (thread1)->first_thread_allocno;
2125 		  fprintf (ira_dump_file, "        Result (freq=%d): a%dr%d(%d)",
2126 			   ALLOCNO_COLOR_DATA (thread1)->thread_freq,
2127 			   ALLOCNO_NUM (thread1), ALLOCNO_REGNO (thread1),
2128 			   ALLOCNO_FREQ (thread1));
2129 		  for (a = ALLOCNO_COLOR_DATA (thread1)->next_thread_allocno;
2130 		       a != thread1;
2131 		       a = ALLOCNO_COLOR_DATA (a)->next_thread_allocno)
2132 		    fprintf (ira_dump_file, " a%dr%d(%d)",
2133 			     ALLOCNO_NUM (a), ALLOCNO_REGNO (a),
2134 			     ALLOCNO_FREQ (a));
2135 		  fprintf (ira_dump_file, "\n");
2136 		}
2137 	      i++;
2138 	      break;
2139 	    }
2140 	}
2141       /* Collect the rest of copies.  */
2142       for (n = 0; i < cp_num; i++)
2143 	{
2144 	  cp = sorted_copies[i];
2145 	  if (ALLOCNO_COLOR_DATA (cp->first)->first_thread_allocno
2146 	      != ALLOCNO_COLOR_DATA (cp->second)->first_thread_allocno)
2147 	    sorted_copies[n++] = cp;
2148 	}
2149       cp_num = n;
2150     }
2151 }
2152 
2153 /* Create threads by processing copies of all alocnos from BUCKET.  We
2154    process the most expensive copies first.  */
2155 static void
form_threads_from_bucket(ira_allocno_t bucket)2156 form_threads_from_bucket (ira_allocno_t bucket)
2157 {
2158   ira_allocno_t a;
2159   ira_copy_t cp, next_cp;
2160   int cp_num = 0;
2161 
2162   for (a = bucket; a != NULL; a = ALLOCNO_COLOR_DATA (a)->next_bucket_allocno)
2163     {
2164       for (cp = ALLOCNO_COPIES (a); cp != NULL; cp = next_cp)
2165 	{
2166 	  if (cp->first == a)
2167 	    {
2168 	      next_cp = cp->next_first_allocno_copy;
2169 	      sorted_copies[cp_num++] = cp;
2170 	    }
2171 	  else if (cp->second == a)
2172 	    next_cp = cp->next_second_allocno_copy;
2173 	  else
2174 	    gcc_unreachable ();
2175 	}
2176     }
2177   form_threads_from_copies (cp_num);
2178 }
2179 
2180 /* Create threads by processing copies of colorable allocno A.  We
2181    process most expensive copies first.  */
2182 static void
form_threads_from_colorable_allocno(ira_allocno_t a)2183 form_threads_from_colorable_allocno (ira_allocno_t a)
2184 {
2185   ira_allocno_t another_a;
2186   ira_copy_t cp, next_cp;
2187   int cp_num = 0;
2188 
2189   for (cp = ALLOCNO_COPIES (a); cp != NULL; cp = next_cp)
2190     {
2191       if (cp->first == a)
2192 	{
2193 	  next_cp = cp->next_first_allocno_copy;
2194 	  another_a = cp->second;
2195 	}
2196       else if (cp->second == a)
2197 	{
2198 	  next_cp = cp->next_second_allocno_copy;
2199 	  another_a = cp->first;
2200 	}
2201       else
2202 	gcc_unreachable ();
2203       if ((! ALLOCNO_COLOR_DATA (another_a)->in_graph_p
2204 	   && !ALLOCNO_COLOR_DATA (another_a)->may_be_spilled_p)
2205 	   || ALLOCNO_COLOR_DATA (another_a)->colorable_p)
2206 	sorted_copies[cp_num++] = cp;
2207     }
2208   form_threads_from_copies (cp_num);
2209 }
2210 
2211 /* Form initial threads which contain only one allocno.  */
2212 static void
init_allocno_threads(void)2213 init_allocno_threads (void)
2214 {
2215   ira_allocno_t a;
2216   unsigned int j;
2217   bitmap_iterator bi;
2218   ira_pref_t pref;
2219 
2220   EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
2221     {
2222       a = ira_allocnos[j];
2223       /* Set up initial thread data: */
2224       ALLOCNO_COLOR_DATA (a)->first_thread_allocno
2225 	= ALLOCNO_COLOR_DATA (a)->next_thread_allocno = a;
2226       ALLOCNO_COLOR_DATA (a)->thread_freq = ALLOCNO_FREQ (a);
2227       ALLOCNO_COLOR_DATA (a)->hard_reg_prefs = 0;
2228       for (pref = ALLOCNO_PREFS (a); pref != NULL; pref = pref->next_pref)
2229 	ALLOCNO_COLOR_DATA (a)->hard_reg_prefs += pref->freq;
2230     }
2231 }
2232 
2233 
2234 
2235 /* This page contains the allocator based on the Chaitin-Briggs algorithm.  */
2236 
2237 /* Bucket of allocnos that can colored currently without spilling.  */
2238 static ira_allocno_t colorable_allocno_bucket;
2239 
2240 /* Bucket of allocnos that might be not colored currently without
2241    spilling.  */
2242 static ira_allocno_t uncolorable_allocno_bucket;
2243 
2244 /* The current number of allocnos in the uncolorable_bucket.  */
2245 static int uncolorable_allocnos_num;
2246 
2247 /* Return the current spill priority of allocno A.  The less the
2248    number, the more preferable the allocno for spilling.  */
2249 static inline int
allocno_spill_priority(ira_allocno_t a)2250 allocno_spill_priority (ira_allocno_t a)
2251 {
2252   allocno_color_data_t data = ALLOCNO_COLOR_DATA (a);
2253 
2254   return (data->temp
2255 	  / (ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a)
2256 	     * ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]
2257 	     + 1));
2258 }
2259 
2260 /* Add allocno A to bucket *BUCKET_PTR.  A should be not in a bucket
2261    before the call.  */
2262 static void
add_allocno_to_bucket(ira_allocno_t a,ira_allocno_t * bucket_ptr)2263 add_allocno_to_bucket (ira_allocno_t a, ira_allocno_t *bucket_ptr)
2264 {
2265   ira_allocno_t first_a;
2266   allocno_color_data_t data;
2267 
2268   if (bucket_ptr == &uncolorable_allocno_bucket
2269       && ALLOCNO_CLASS (a) != NO_REGS)
2270     {
2271       uncolorable_allocnos_num++;
2272       ira_assert (uncolorable_allocnos_num > 0);
2273     }
2274   first_a = *bucket_ptr;
2275   data = ALLOCNO_COLOR_DATA (a);
2276   data->next_bucket_allocno = first_a;
2277   data->prev_bucket_allocno = NULL;
2278   if (first_a != NULL)
2279     ALLOCNO_COLOR_DATA (first_a)->prev_bucket_allocno = a;
2280   *bucket_ptr = a;
2281 }
2282 
2283 /* Compare two allocnos to define which allocno should be pushed first
2284    into the coloring stack.  If the return is a negative number, the
2285    allocno given by the first parameter will be pushed first.  In this
2286    case such allocno has less priority than the second one and the
2287    hard register will be assigned to it after assignment to the second
2288    one.  As the result of such assignment order, the second allocno
2289    has a better chance to get the best hard register.  */
2290 static int
bucket_allocno_compare_func(const void * v1p,const void * v2p)2291 bucket_allocno_compare_func (const void *v1p, const void *v2p)
2292 {
2293   ira_allocno_t a1 = *(const ira_allocno_t *) v1p;
2294   ira_allocno_t a2 = *(const ira_allocno_t *) v2p;
2295   int diff, freq1, freq2, a1_num, a2_num, pref1, pref2;
2296   ira_allocno_t t1 = ALLOCNO_COLOR_DATA (a1)->first_thread_allocno;
2297   ira_allocno_t t2 = ALLOCNO_COLOR_DATA (a2)->first_thread_allocno;
2298   int cl1 = ALLOCNO_CLASS (a1), cl2 = ALLOCNO_CLASS (a2);
2299 
2300   freq1 = ALLOCNO_COLOR_DATA (t1)->thread_freq;
2301   freq2 = ALLOCNO_COLOR_DATA (t2)->thread_freq;
2302   if ((diff = freq1 - freq2) != 0)
2303     return diff;
2304 
2305   if ((diff = ALLOCNO_NUM (t2) - ALLOCNO_NUM (t1)) != 0)
2306     return diff;
2307 
2308   /* Push pseudos requiring less hard registers first.  It means that
2309      we will assign pseudos requiring more hard registers first
2310      avoiding creation small holes in free hard register file into
2311      which the pseudos requiring more hard registers cannot fit.  */
2312   if ((diff = (ira_reg_class_max_nregs[cl1][ALLOCNO_MODE (a1)]
2313 	       - ira_reg_class_max_nregs[cl2][ALLOCNO_MODE (a2)])) != 0)
2314     return diff;
2315 
2316   freq1 = ALLOCNO_FREQ (a1);
2317   freq2 = ALLOCNO_FREQ (a2);
2318   if ((diff = freq1 - freq2) != 0)
2319     return diff;
2320 
2321   a1_num = ALLOCNO_COLOR_DATA (a1)->available_regs_num;
2322   a2_num = ALLOCNO_COLOR_DATA (a2)->available_regs_num;
2323   if ((diff = a2_num - a1_num) != 0)
2324     return diff;
2325   /* Push allocnos with minimal conflict_allocno_hard_prefs first.  */
2326   pref1 = ALLOCNO_COLOR_DATA (a1)->conflict_allocno_hard_prefs;
2327   pref2 = ALLOCNO_COLOR_DATA (a2)->conflict_allocno_hard_prefs;
2328   if ((diff = pref1 - pref2) != 0)
2329     return diff;
2330   return ALLOCNO_NUM (a2) - ALLOCNO_NUM (a1);
2331 }
2332 
2333 /* Sort bucket *BUCKET_PTR and return the result through
2334    BUCKET_PTR.  */
2335 static void
sort_bucket(ira_allocno_t * bucket_ptr,int (* compare_func)(const void *,const void *))2336 sort_bucket (ira_allocno_t *bucket_ptr,
2337 	     int (*compare_func) (const void *, const void *))
2338 {
2339   ira_allocno_t a, head;
2340   int n;
2341 
2342   for (n = 0, a = *bucket_ptr;
2343        a != NULL;
2344        a = ALLOCNO_COLOR_DATA (a)->next_bucket_allocno)
2345     sorted_allocnos[n++] = a;
2346   if (n <= 1)
2347     return;
2348   qsort (sorted_allocnos, n, sizeof (ira_allocno_t), compare_func);
2349   head = NULL;
2350   for (n--; n >= 0; n--)
2351     {
2352       a = sorted_allocnos[n];
2353       ALLOCNO_COLOR_DATA (a)->next_bucket_allocno = head;
2354       ALLOCNO_COLOR_DATA (a)->prev_bucket_allocno = NULL;
2355       if (head != NULL)
2356 	ALLOCNO_COLOR_DATA (head)->prev_bucket_allocno = a;
2357       head = a;
2358     }
2359   *bucket_ptr = head;
2360 }
2361 
2362 /* Add ALLOCNO to colorable bucket maintaining the order according
2363    their priority.  ALLOCNO should be not in a bucket before the
2364    call.  */
2365 static void
add_allocno_to_ordered_colorable_bucket(ira_allocno_t allocno)2366 add_allocno_to_ordered_colorable_bucket (ira_allocno_t allocno)
2367 {
2368   ira_allocno_t before, after;
2369 
2370   form_threads_from_colorable_allocno (allocno);
2371   for (before = colorable_allocno_bucket, after = NULL;
2372        before != NULL;
2373        after = before,
2374 	 before = ALLOCNO_COLOR_DATA (before)->next_bucket_allocno)
2375     if (bucket_allocno_compare_func (&allocno, &before) < 0)
2376       break;
2377   ALLOCNO_COLOR_DATA (allocno)->next_bucket_allocno = before;
2378   ALLOCNO_COLOR_DATA (allocno)->prev_bucket_allocno = after;
2379   if (after == NULL)
2380     colorable_allocno_bucket = allocno;
2381   else
2382     ALLOCNO_COLOR_DATA (after)->next_bucket_allocno = allocno;
2383   if (before != NULL)
2384     ALLOCNO_COLOR_DATA (before)->prev_bucket_allocno = allocno;
2385 }
2386 
2387 /* Delete ALLOCNO from bucket *BUCKET_PTR.  It should be there before
2388    the call.  */
2389 static void
delete_allocno_from_bucket(ira_allocno_t allocno,ira_allocno_t * bucket_ptr)2390 delete_allocno_from_bucket (ira_allocno_t allocno, ira_allocno_t *bucket_ptr)
2391 {
2392   ira_allocno_t prev_allocno, next_allocno;
2393 
2394   if (bucket_ptr == &uncolorable_allocno_bucket
2395       && ALLOCNO_CLASS (allocno) != NO_REGS)
2396     {
2397       uncolorable_allocnos_num--;
2398       ira_assert (uncolorable_allocnos_num >= 0);
2399     }
2400   prev_allocno = ALLOCNO_COLOR_DATA (allocno)->prev_bucket_allocno;
2401   next_allocno = ALLOCNO_COLOR_DATA (allocno)->next_bucket_allocno;
2402   if (prev_allocno != NULL)
2403     ALLOCNO_COLOR_DATA (prev_allocno)->next_bucket_allocno = next_allocno;
2404   else
2405     {
2406       ira_assert (*bucket_ptr == allocno);
2407       *bucket_ptr = next_allocno;
2408     }
2409   if (next_allocno != NULL)
2410     ALLOCNO_COLOR_DATA (next_allocno)->prev_bucket_allocno = prev_allocno;
2411 }
2412 
2413 /* Put allocno A onto the coloring stack without removing it from its
2414    bucket.  Pushing allocno to the coloring stack can result in moving
2415    conflicting allocnos from the uncolorable bucket to the colorable
2416    one.  Update conflict_allocno_hard_prefs of the conflicting
2417    allocnos which are not on stack yet.  */
2418 static void
push_allocno_to_stack(ira_allocno_t a)2419 push_allocno_to_stack (ira_allocno_t a)
2420 {
2421   enum reg_class aclass;
2422   allocno_color_data_t data, conflict_data;
2423   int size, i, n = ALLOCNO_NUM_OBJECTS (a);
2424 
2425   data = ALLOCNO_COLOR_DATA (a);
2426   data->in_graph_p = false;
2427   allocno_stack_vec.safe_push (a);
2428   aclass = ALLOCNO_CLASS (a);
2429   if (aclass == NO_REGS)
2430     return;
2431   size = ira_reg_class_max_nregs[aclass][ALLOCNO_MODE (a)];
2432   if (n > 1)
2433     {
2434       /* We will deal with the subwords individually.  */
2435       gcc_assert (size == ALLOCNO_NUM_OBJECTS (a));
2436       size = 1;
2437     }
2438   for (i = 0; i < n; i++)
2439     {
2440       ira_object_t obj = ALLOCNO_OBJECT (a, i);
2441       ira_object_t conflict_obj;
2442       ira_object_conflict_iterator oci;
2443 
2444       FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
2445 	{
2446 	  ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
2447 	  ira_pref_t pref;
2448 
2449 	  conflict_data = ALLOCNO_COLOR_DATA (conflict_a);
2450 	  if (! conflict_data->in_graph_p
2451 	      || ALLOCNO_ASSIGNED_P (conflict_a)
2452 	      || !(hard_reg_set_intersect_p
2453 		   (ALLOCNO_COLOR_DATA (a)->profitable_hard_regs,
2454 		    conflict_data->profitable_hard_regs)))
2455 	    continue;
2456 	  for (pref = ALLOCNO_PREFS (a); pref != NULL; pref = pref->next_pref)
2457 	    conflict_data->conflict_allocno_hard_prefs -= pref->freq;
2458 	  if (conflict_data->colorable_p)
2459 	    continue;
2460 	  ira_assert (bitmap_bit_p (coloring_allocno_bitmap,
2461 				    ALLOCNO_NUM (conflict_a)));
2462 	  if (update_left_conflict_sizes_p (conflict_a, a, size))
2463 	    {
2464 	      delete_allocno_from_bucket
2465 		(conflict_a, &uncolorable_allocno_bucket);
2466 	      add_allocno_to_ordered_colorable_bucket (conflict_a);
2467 	      if (internal_flag_ira_verbose > 4 && ira_dump_file != NULL)
2468 		{
2469 		  fprintf (ira_dump_file, "        Making");
2470 		  ira_print_expanded_allocno (conflict_a);
2471 		  fprintf (ira_dump_file, " colorable\n");
2472 		}
2473 	    }
2474 
2475 	}
2476     }
2477 }
2478 
2479 /* Put ALLOCNO onto the coloring stack and remove it from its bucket.
2480    The allocno is in the colorable bucket if COLORABLE_P is TRUE.  */
2481 static void
remove_allocno_from_bucket_and_push(ira_allocno_t allocno,bool colorable_p)2482 remove_allocno_from_bucket_and_push (ira_allocno_t allocno, bool colorable_p)
2483 {
2484   if (colorable_p)
2485     delete_allocno_from_bucket (allocno, &colorable_allocno_bucket);
2486   else
2487     delete_allocno_from_bucket (allocno, &uncolorable_allocno_bucket);
2488   if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2489     {
2490       fprintf (ira_dump_file, "      Pushing");
2491       ira_print_expanded_allocno (allocno);
2492       if (colorable_p)
2493 	fprintf (ira_dump_file, "(cost %d)\n",
2494 		 ALLOCNO_COLOR_DATA (allocno)->temp);
2495       else
2496 	fprintf (ira_dump_file, "(potential spill: %spri=%d, cost=%d)\n",
2497 		 ALLOCNO_BAD_SPILL_P (allocno) ? "bad spill, " : "",
2498 		 allocno_spill_priority (allocno),
2499 		 ALLOCNO_COLOR_DATA (allocno)->temp);
2500     }
2501   if (! colorable_p)
2502     ALLOCNO_COLOR_DATA (allocno)->may_be_spilled_p = true;
2503   push_allocno_to_stack (allocno);
2504 }
2505 
2506 /* Put all allocnos from colorable bucket onto the coloring stack.  */
2507 static void
push_only_colorable(void)2508 push_only_colorable (void)
2509 {
2510   form_threads_from_bucket (colorable_allocno_bucket);
2511   sort_bucket (&colorable_allocno_bucket, bucket_allocno_compare_func);
2512   for (;colorable_allocno_bucket != NULL;)
2513     remove_allocno_from_bucket_and_push (colorable_allocno_bucket, true);
2514 }
2515 
2516 /* Return the frequency of exit edges (if EXIT_P) or entry from/to the
2517    loop given by its LOOP_NODE.  */
2518 int
ira_loop_edge_freq(ira_loop_tree_node_t loop_node,int regno,bool exit_p)2519 ira_loop_edge_freq (ira_loop_tree_node_t loop_node, int regno, bool exit_p)
2520 {
2521   int freq, i;
2522   edge_iterator ei;
2523   edge e;
2524   vec<edge> edges;
2525 
2526   ira_assert (current_loops != NULL && loop_node->loop != NULL
2527 	      && (regno < 0 || regno >= FIRST_PSEUDO_REGISTER));
2528   freq = 0;
2529   if (! exit_p)
2530     {
2531       FOR_EACH_EDGE (e, ei, loop_node->loop->header->preds)
2532 	if (e->src != loop_node->loop->latch
2533 	    && (regno < 0
2534 		|| (bitmap_bit_p (df_get_live_out (e->src), regno)
2535 		    && bitmap_bit_p (df_get_live_in (e->dest), regno))))
2536 	  freq += EDGE_FREQUENCY (e);
2537     }
2538   else
2539     {
2540       edges = get_loop_exit_edges (loop_node->loop);
2541       FOR_EACH_VEC_ELT (edges, i, e)
2542 	if (regno < 0
2543 	    || (bitmap_bit_p (df_get_live_out (e->src), regno)
2544 		&& bitmap_bit_p (df_get_live_in (e->dest), regno)))
2545 	  freq += EDGE_FREQUENCY (e);
2546       edges.release ();
2547     }
2548 
2549   return REG_FREQ_FROM_EDGE_FREQ (freq);
2550 }
2551 
2552 /* Calculate and return the cost of putting allocno A into memory.  */
2553 static int
calculate_allocno_spill_cost(ira_allocno_t a)2554 calculate_allocno_spill_cost (ira_allocno_t a)
2555 {
2556   int regno, cost;
2557   machine_mode mode;
2558   enum reg_class rclass;
2559   ira_allocno_t parent_allocno;
2560   ira_loop_tree_node_t parent_node, loop_node;
2561 
2562   regno = ALLOCNO_REGNO (a);
2563   cost = ALLOCNO_UPDATED_MEMORY_COST (a) - ALLOCNO_UPDATED_CLASS_COST (a);
2564   if (ALLOCNO_CAP (a) != NULL)
2565     return cost;
2566   loop_node = ALLOCNO_LOOP_TREE_NODE (a);
2567   if ((parent_node = loop_node->parent) == NULL)
2568     return cost;
2569   if ((parent_allocno = parent_node->regno_allocno_map[regno]) == NULL)
2570     return cost;
2571   mode = ALLOCNO_MODE (a);
2572   rclass = ALLOCNO_CLASS (a);
2573   if (ALLOCNO_HARD_REGNO (parent_allocno) < 0)
2574     cost -= (ira_memory_move_cost[mode][rclass][0]
2575 	     * ira_loop_edge_freq (loop_node, regno, true)
2576 	     + ira_memory_move_cost[mode][rclass][1]
2577 	     * ira_loop_edge_freq (loop_node, regno, false));
2578   else
2579     {
2580       ira_init_register_move_cost_if_necessary (mode);
2581       cost += ((ira_memory_move_cost[mode][rclass][1]
2582 		* ira_loop_edge_freq (loop_node, regno, true)
2583 		+ ira_memory_move_cost[mode][rclass][0]
2584 		* ira_loop_edge_freq (loop_node, regno, false))
2585 	       - (ira_register_move_cost[mode][rclass][rclass]
2586 		  * (ira_loop_edge_freq (loop_node, regno, false)
2587 		     + ira_loop_edge_freq (loop_node, regno, true))));
2588     }
2589   return cost;
2590 }
2591 
2592 /* Used for sorting allocnos for spilling.  */
2593 static inline int
allocno_spill_priority_compare(ira_allocno_t a1,ira_allocno_t a2)2594 allocno_spill_priority_compare (ira_allocno_t a1, ira_allocno_t a2)
2595 {
2596   int pri1, pri2, diff;
2597 
2598   /* Avoid spilling static chain pointer pseudo when non-local goto is
2599      used.  */
2600   if (non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a1)))
2601     return 1;
2602   else if (non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a2)))
2603     return -1;
2604   if (ALLOCNO_BAD_SPILL_P (a1) && ! ALLOCNO_BAD_SPILL_P (a2))
2605     return 1;
2606   if (ALLOCNO_BAD_SPILL_P (a2) && ! ALLOCNO_BAD_SPILL_P (a1))
2607     return -1;
2608   pri1 = allocno_spill_priority (a1);
2609   pri2 = allocno_spill_priority (a2);
2610   if ((diff = pri1 - pri2) != 0)
2611     return diff;
2612   if ((diff
2613        = ALLOCNO_COLOR_DATA (a1)->temp - ALLOCNO_COLOR_DATA (a2)->temp) != 0)
2614     return diff;
2615   return ALLOCNO_NUM (a1) - ALLOCNO_NUM (a2);
2616 }
2617 
2618 /* Used for sorting allocnos for spilling.  */
2619 static int
allocno_spill_sort_compare(const void * v1p,const void * v2p)2620 allocno_spill_sort_compare (const void *v1p, const void *v2p)
2621 {
2622   ira_allocno_t p1 = *(const ira_allocno_t *) v1p;
2623   ira_allocno_t p2 = *(const ira_allocno_t *) v2p;
2624 
2625   return allocno_spill_priority_compare (p1, p2);
2626 }
2627 
2628 /* Push allocnos to the coloring stack.  The order of allocnos in the
2629    stack defines the order for the subsequent coloring.  */
2630 static void
push_allocnos_to_stack(void)2631 push_allocnos_to_stack (void)
2632 {
2633   ira_allocno_t a;
2634   int cost;
2635 
2636   /* Calculate uncolorable allocno spill costs.  */
2637   for (a = uncolorable_allocno_bucket;
2638        a != NULL;
2639        a = ALLOCNO_COLOR_DATA (a)->next_bucket_allocno)
2640     if (ALLOCNO_CLASS (a) != NO_REGS)
2641       {
2642 	cost = calculate_allocno_spill_cost (a);
2643 	/* ??? Remove cost of copies between the coalesced
2644 	   allocnos.  */
2645 	ALLOCNO_COLOR_DATA (a)->temp = cost;
2646       }
2647   sort_bucket (&uncolorable_allocno_bucket, allocno_spill_sort_compare);
2648   for (;;)
2649     {
2650       push_only_colorable ();
2651       a = uncolorable_allocno_bucket;
2652       if (a == NULL)
2653 	break;
2654       remove_allocno_from_bucket_and_push (a, false);
2655     }
2656   ira_assert (colorable_allocno_bucket == NULL
2657 	      && uncolorable_allocno_bucket == NULL);
2658   ira_assert (uncolorable_allocnos_num == 0);
2659 }
2660 
2661 /* Pop the coloring stack and assign hard registers to the popped
2662    allocnos.  */
2663 static void
pop_allocnos_from_stack(void)2664 pop_allocnos_from_stack (void)
2665 {
2666   ira_allocno_t allocno;
2667   enum reg_class aclass;
2668 
2669   for (;allocno_stack_vec.length () != 0;)
2670     {
2671       allocno = allocno_stack_vec.pop ();
2672       aclass = ALLOCNO_CLASS (allocno);
2673       if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2674 	{
2675 	  fprintf (ira_dump_file, "      Popping");
2676 	  ira_print_expanded_allocno (allocno);
2677 	  fprintf (ira_dump_file, "  -- ");
2678 	}
2679       if (aclass == NO_REGS)
2680 	{
2681 	  ALLOCNO_HARD_REGNO (allocno) = -1;
2682 	  ALLOCNO_ASSIGNED_P (allocno) = true;
2683 	  ira_assert (ALLOCNO_UPDATED_HARD_REG_COSTS (allocno) == NULL);
2684 	  ira_assert
2685 	    (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (allocno) == NULL);
2686 	  if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2687 	    fprintf (ira_dump_file, "assign memory\n");
2688 	}
2689       else if (assign_hard_reg (allocno, false))
2690 	{
2691 	  if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2692 	    fprintf (ira_dump_file, "assign reg %d\n",
2693 		     ALLOCNO_HARD_REGNO (allocno));
2694 	}
2695       else if (ALLOCNO_ASSIGNED_P (allocno))
2696 	{
2697 	  if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2698 	    fprintf (ira_dump_file, "spill%s\n",
2699 		     ALLOCNO_COLOR_DATA (allocno)->may_be_spilled_p
2700 		     ? "" : "!");
2701 	}
2702       ALLOCNO_COLOR_DATA (allocno)->in_graph_p = true;
2703     }
2704 }
2705 
2706 /* Set up number of available hard registers for allocno A.  */
2707 static void
setup_allocno_available_regs_num(ira_allocno_t a)2708 setup_allocno_available_regs_num (ira_allocno_t a)
2709 {
2710   int i, n, hard_regno, hard_regs_num, nwords;
2711   enum reg_class aclass;
2712   allocno_color_data_t data;
2713 
2714   aclass = ALLOCNO_CLASS (a);
2715   data = ALLOCNO_COLOR_DATA (a);
2716   data->available_regs_num = 0;
2717   if (aclass == NO_REGS)
2718     return;
2719   hard_regs_num = ira_class_hard_regs_num[aclass];
2720   nwords = ALLOCNO_NUM_OBJECTS (a);
2721   for (n = 0, i = hard_regs_num - 1; i >= 0; i--)
2722     {
2723       hard_regno = ira_class_hard_regs[aclass][i];
2724       /* Checking only profitable hard regs.  */
2725       if (TEST_HARD_REG_BIT (data->profitable_hard_regs, hard_regno))
2726 	n++;
2727     }
2728   data->available_regs_num = n;
2729   if (internal_flag_ira_verbose <= 2 || ira_dump_file == NULL)
2730     return;
2731   fprintf
2732     (ira_dump_file,
2733      "      Allocno a%dr%d of %s(%d) has %d avail. regs ",
2734      ALLOCNO_NUM (a), ALLOCNO_REGNO (a),
2735      reg_class_names[aclass], ira_class_hard_regs_num[aclass], n);
2736   print_hard_reg_set (ira_dump_file, data->profitable_hard_regs, false);
2737   fprintf (ira_dump_file, ", %snode: ",
2738 	   data->profitable_hard_regs == data->hard_regs_node->hard_regs->set
2739 	   ? "" : "^");
2740   print_hard_reg_set (ira_dump_file,
2741 		      data->hard_regs_node->hard_regs->set, false);
2742   for (i = 0; i < nwords; i++)
2743     {
2744       ira_object_t obj = ALLOCNO_OBJECT (a, i);
2745 
2746       if (nwords != 1)
2747 	{
2748 	  if (i != 0)
2749 	    fprintf (ira_dump_file, ", ");
2750 	  fprintf (ira_dump_file, " obj %d", i);
2751 	}
2752       fprintf (ira_dump_file, " (confl regs = ");
2753       print_hard_reg_set (ira_dump_file, OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
2754 			  false);
2755       fprintf (ira_dump_file, ")");
2756     }
2757   fprintf (ira_dump_file, "\n");
2758 }
2759 
2760 /* Put ALLOCNO in a bucket corresponding to its number and size of its
2761    conflicting allocnos and hard registers.  */
2762 static void
put_allocno_into_bucket(ira_allocno_t allocno)2763 put_allocno_into_bucket (ira_allocno_t allocno)
2764 {
2765   ALLOCNO_COLOR_DATA (allocno)->in_graph_p = true;
2766   setup_allocno_available_regs_num (allocno);
2767   if (setup_left_conflict_sizes_p (allocno))
2768     add_allocno_to_bucket (allocno, &colorable_allocno_bucket);
2769   else
2770     add_allocno_to_bucket (allocno, &uncolorable_allocno_bucket);
2771 }
2772 
2773 /* Map: allocno number -> allocno priority.  */
2774 static int *allocno_priorities;
2775 
2776 /* Set up priorities for N allocnos in array
2777    CONSIDERATION_ALLOCNOS.  */
2778 static void
setup_allocno_priorities(ira_allocno_t * consideration_allocnos,int n)2779 setup_allocno_priorities (ira_allocno_t *consideration_allocnos, int n)
2780 {
2781   int i, length, nrefs, priority, max_priority, mult;
2782   ira_allocno_t a;
2783 
2784   max_priority = 0;
2785   for (i = 0; i < n; i++)
2786     {
2787       a = consideration_allocnos[i];
2788       nrefs = ALLOCNO_NREFS (a);
2789       ira_assert (nrefs >= 0);
2790       mult = floor_log2 (ALLOCNO_NREFS (a)) + 1;
2791       ira_assert (mult >= 0);
2792       allocno_priorities[ALLOCNO_NUM (a)]
2793 	= priority
2794 	= (mult
2795 	   * (ALLOCNO_MEMORY_COST (a) - ALLOCNO_CLASS_COST (a))
2796 	   * ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]);
2797       if (priority < 0)
2798 	priority = -priority;
2799       if (max_priority < priority)
2800 	max_priority = priority;
2801     }
2802   mult = max_priority == 0 ? 1 : INT_MAX / max_priority;
2803   for (i = 0; i < n; i++)
2804     {
2805       a = consideration_allocnos[i];
2806       length = ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a);
2807       if (ALLOCNO_NUM_OBJECTS (a) > 1)
2808 	length /= ALLOCNO_NUM_OBJECTS (a);
2809       if (length <= 0)
2810 	length = 1;
2811       allocno_priorities[ALLOCNO_NUM (a)]
2812 	= allocno_priorities[ALLOCNO_NUM (a)] * mult / length;
2813     }
2814 }
2815 
2816 /* Sort allocnos according to the profit of usage of a hard register
2817    instead of memory for them. */
2818 static int
allocno_cost_compare_func(const void * v1p,const void * v2p)2819 allocno_cost_compare_func (const void *v1p, const void *v2p)
2820 {
2821   ira_allocno_t p1 = *(const ira_allocno_t *) v1p;
2822   ira_allocno_t p2 = *(const ira_allocno_t *) v2p;
2823   int c1, c2;
2824 
2825   c1 = ALLOCNO_UPDATED_MEMORY_COST (p1) - ALLOCNO_UPDATED_CLASS_COST (p1);
2826   c2 = ALLOCNO_UPDATED_MEMORY_COST (p2) - ALLOCNO_UPDATED_CLASS_COST (p2);
2827   if (c1 - c2)
2828     return c1 - c2;
2829 
2830   /* If regs are equally good, sort by allocno numbers, so that the
2831      results of qsort leave nothing to chance.  */
2832   return ALLOCNO_NUM (p1) - ALLOCNO_NUM (p2);
2833 }
2834 
2835 /* Return savings on removed copies when ALLOCNO is assigned to
2836    HARD_REGNO.  */
2837 static int
allocno_copy_cost_saving(ira_allocno_t allocno,int hard_regno)2838 allocno_copy_cost_saving (ira_allocno_t allocno, int hard_regno)
2839 {
2840   int cost = 0;
2841   machine_mode allocno_mode = ALLOCNO_MODE (allocno);
2842   enum reg_class rclass;
2843   ira_copy_t cp, next_cp;
2844 
2845   rclass = REGNO_REG_CLASS (hard_regno);
2846   if (ira_reg_class_max_nregs[rclass][allocno_mode]
2847       > ira_class_hard_regs_num[rclass])
2848     /* For the above condition the cost can be wrong.  Use the allocno
2849        class in this case.  */
2850     rclass = ALLOCNO_CLASS (allocno);
2851   for (cp = ALLOCNO_COPIES (allocno); cp != NULL; cp = next_cp)
2852     {
2853       if (cp->first == allocno)
2854 	{
2855 	  next_cp = cp->next_first_allocno_copy;
2856 	  if (ALLOCNO_HARD_REGNO (cp->second) != hard_regno)
2857 	    continue;
2858 	}
2859       else if (cp->second == allocno)
2860 	{
2861 	  next_cp = cp->next_second_allocno_copy;
2862 	  if (ALLOCNO_HARD_REGNO (cp->first) != hard_regno)
2863 	    continue;
2864 	}
2865       else
2866 	gcc_unreachable ();
2867       ira_init_register_move_cost_if_necessary (allocno_mode);
2868       cost += cp->freq * ira_register_move_cost[allocno_mode][rclass][rclass];
2869     }
2870   return cost;
2871 }
2872 
2873 /* We used Chaitin-Briggs coloring to assign as many pseudos as
2874    possible to hard registers.  Let us try to improve allocation with
2875    cost point of view.  This function improves the allocation by
2876    spilling some allocnos and assigning the freed hard registers to
2877    other allocnos if it decreases the overall allocation cost.  */
2878 static void
improve_allocation(void)2879 improve_allocation (void)
2880 {
2881   unsigned int i;
2882   int j, k, n, hregno, conflict_hregno, base_cost, class_size, word, nwords;
2883   int check, spill_cost, min_cost, nregs, conflict_nregs, r, best;
2884   bool try_p;
2885   enum reg_class aclass;
2886   machine_mode mode;
2887   int *allocno_costs;
2888   int costs[FIRST_PSEUDO_REGISTER];
2889   HARD_REG_SET conflicting_regs[2], profitable_hard_regs;
2890   ira_allocno_t a;
2891   bitmap_iterator bi;
2892 
2893   /* Don't bother to optimize the code with static chain pointer and
2894      non-local goto in order not to spill the chain pointer
2895      pseudo.  */
2896   if (cfun->static_chain_decl && crtl->has_nonlocal_goto)
2897     return;
2898   /* Clear counts used to process conflicting allocnos only once for
2899      each allocno.  */
2900   EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
2901     ALLOCNO_COLOR_DATA (ira_allocnos[i])->temp = 0;
2902   check = n = 0;
2903   /* Process each allocno and try to assign a hard register to it by
2904      spilling some its conflicting allocnos.  */
2905   EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
2906     {
2907       a = ira_allocnos[i];
2908       ALLOCNO_COLOR_DATA (a)->temp = 0;
2909       if (empty_profitable_hard_regs (a))
2910 	continue;
2911       check++;
2912       aclass = ALLOCNO_CLASS (a);
2913       allocno_costs = ALLOCNO_HARD_REG_COSTS (a);
2914       if ((hregno = ALLOCNO_HARD_REGNO (a)) < 0)
2915 	base_cost = ALLOCNO_UPDATED_MEMORY_COST (a);
2916       else if (allocno_costs == NULL)
2917 	/* It means that assigning a hard register is not profitable
2918 	   (we don't waste memory for hard register costs in this
2919 	   case).  */
2920 	continue;
2921       else
2922 	base_cost = (allocno_costs[ira_class_hard_reg_index[aclass][hregno]]
2923 		     - allocno_copy_cost_saving (a, hregno));
2924       try_p = false;
2925       get_conflict_and_start_profitable_regs (a, false,
2926 					      conflicting_regs,
2927 					      &profitable_hard_regs);
2928       class_size = ira_class_hard_regs_num[aclass];
2929       /* Set up cost improvement for usage of each profitable hard
2930 	 register for allocno A.  */
2931       for (j = 0; j < class_size; j++)
2932 	{
2933 	  hregno = ira_class_hard_regs[aclass][j];
2934 	  if (! check_hard_reg_p (a, hregno,
2935 				  conflicting_regs, profitable_hard_regs))
2936 	    continue;
2937 	  ira_assert (ira_class_hard_reg_index[aclass][hregno] == j);
2938 	  k = allocno_costs == NULL ? 0 : j;
2939 	  costs[hregno] = (allocno_costs == NULL
2940 			   ? ALLOCNO_UPDATED_CLASS_COST (a) : allocno_costs[k]);
2941 	  costs[hregno] -= allocno_copy_cost_saving (a, hregno);
2942 	  costs[hregno] -= base_cost;
2943 	  if (costs[hregno] < 0)
2944 	    try_p = true;
2945 	}
2946       if (! try_p)
2947 	/* There is no chance to improve the allocation cost by
2948 	   assigning hard register to allocno A even without spilling
2949 	   conflicting allocnos.  */
2950 	continue;
2951       mode = ALLOCNO_MODE (a);
2952       nwords = ALLOCNO_NUM_OBJECTS (a);
2953       /* Process each allocno conflicting with A and update the cost
2954 	 improvement for profitable hard registers of A.  To use a
2955 	 hard register for A we need to spill some conflicting
2956 	 allocnos and that creates penalty for the cost
2957 	 improvement.  */
2958       for (word = 0; word < nwords; word++)
2959 	{
2960 	  ira_object_t conflict_obj;
2961 	  ira_object_t obj = ALLOCNO_OBJECT (a, word);
2962 	  ira_object_conflict_iterator oci;
2963 
2964 	  FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
2965 	    {
2966 	      ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
2967 
2968 	      if (ALLOCNO_COLOR_DATA (conflict_a)->temp == check)
2969 		/* We already processed this conflicting allocno
2970 		   because we processed earlier another object of the
2971 		   conflicting allocno.  */
2972 		continue;
2973 	      ALLOCNO_COLOR_DATA (conflict_a)->temp = check;
2974 	      if ((conflict_hregno = ALLOCNO_HARD_REGNO (conflict_a)) < 0)
2975 		continue;
2976 	      spill_cost = ALLOCNO_UPDATED_MEMORY_COST (conflict_a);
2977 	      k = (ira_class_hard_reg_index
2978 		   [ALLOCNO_CLASS (conflict_a)][conflict_hregno]);
2979 	      ira_assert (k >= 0);
2980 	      if ((allocno_costs = ALLOCNO_HARD_REG_COSTS (conflict_a))
2981 		  != NULL)
2982 		spill_cost -= allocno_costs[k];
2983 	      else
2984 		spill_cost -= ALLOCNO_UPDATED_CLASS_COST (conflict_a);
2985 	      spill_cost
2986 		+= allocno_copy_cost_saving (conflict_a, conflict_hregno);
2987 	      conflict_nregs = hard_regno_nregs (conflict_hregno,
2988 						 ALLOCNO_MODE (conflict_a));
2989 	      for (r = conflict_hregno;
2990 		   r >= 0 && (int) end_hard_regno (mode, r) > conflict_hregno;
2991 		   r--)
2992 		if (check_hard_reg_p (a, r,
2993 				      conflicting_regs, profitable_hard_regs))
2994 		  costs[r] += spill_cost;
2995 	      for (r = conflict_hregno + 1;
2996 		   r < conflict_hregno + conflict_nregs;
2997 		   r++)
2998 		if (check_hard_reg_p (a, r,
2999 				      conflicting_regs, profitable_hard_regs))
3000 		  costs[r] += spill_cost;
3001 	    }
3002 	}
3003       min_cost = INT_MAX;
3004       best = -1;
3005       /* Now we choose hard register for A which results in highest
3006 	 allocation cost improvement.  */
3007       for (j = 0; j < class_size; j++)
3008 	{
3009 	  hregno = ira_class_hard_regs[aclass][j];
3010 	  if (check_hard_reg_p (a, hregno,
3011 				conflicting_regs, profitable_hard_regs)
3012 	      && min_cost > costs[hregno])
3013 	    {
3014 	      best = hregno;
3015 	      min_cost = costs[hregno];
3016 	    }
3017 	}
3018       if (min_cost >= 0)
3019 	/* We are in a situation when assigning any hard register to A
3020 	   by spilling some conflicting allocnos does not improve the
3021 	   allocation cost.  */
3022 	continue;
3023       nregs = hard_regno_nregs (best, mode);
3024       /* Now spill conflicting allocnos which contain a hard register
3025 	 of A when we assign the best chosen hard register to it.  */
3026       for (word = 0; word < nwords; word++)
3027 	{
3028 	  ira_object_t conflict_obj;
3029 	  ira_object_t obj = ALLOCNO_OBJECT (a, word);
3030 	  ira_object_conflict_iterator oci;
3031 
3032 	  FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
3033 	    {
3034 	      ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
3035 
3036 	      if ((conflict_hregno = ALLOCNO_HARD_REGNO (conflict_a)) < 0)
3037 		continue;
3038 	      conflict_nregs = hard_regno_nregs (conflict_hregno,
3039 						 ALLOCNO_MODE (conflict_a));
3040 	      if (best + nregs <= conflict_hregno
3041 		  || conflict_hregno + conflict_nregs <= best)
3042 		/* No intersection.  */
3043 		continue;
3044 	      ALLOCNO_HARD_REGNO (conflict_a) = -1;
3045 	      sorted_allocnos[n++] = conflict_a;
3046 	      if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
3047 		fprintf (ira_dump_file, "Spilling a%dr%d for a%dr%d\n",
3048 			 ALLOCNO_NUM (conflict_a), ALLOCNO_REGNO (conflict_a),
3049 			 ALLOCNO_NUM (a), ALLOCNO_REGNO (a));
3050 	    }
3051 	}
3052       /* Assign the best chosen hard register to A.  */
3053       ALLOCNO_HARD_REGNO (a) = best;
3054       if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
3055 	fprintf (ira_dump_file, "Assigning %d to a%dr%d\n",
3056 		 best, ALLOCNO_NUM (a), ALLOCNO_REGNO (a));
3057     }
3058   if (n == 0)
3059     return;
3060   /* We spilled some allocnos to assign their hard registers to other
3061      allocnos.  The spilled allocnos are now in array
3062      'sorted_allocnos'.  There is still a possibility that some of the
3063      spilled allocnos can get hard registers.  So let us try assign
3064      them hard registers again (just a reminder -- function
3065      'assign_hard_reg' assigns hard registers only if it is possible
3066      and profitable).  We process the spilled allocnos with biggest
3067      benefit to get hard register first -- see function
3068      'allocno_cost_compare_func'.  */
3069   qsort (sorted_allocnos, n, sizeof (ira_allocno_t),
3070 	 allocno_cost_compare_func);
3071   for (j = 0; j < n; j++)
3072     {
3073       a = sorted_allocnos[j];
3074       ALLOCNO_ASSIGNED_P (a) = false;
3075       if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3076 	{
3077 	  fprintf (ira_dump_file, "      ");
3078 	  ira_print_expanded_allocno (a);
3079 	  fprintf (ira_dump_file, "  -- ");
3080 	}
3081       if (assign_hard_reg (a, false))
3082 	{
3083 	  if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3084 	    fprintf (ira_dump_file, "assign hard reg %d\n",
3085 		     ALLOCNO_HARD_REGNO (a));
3086 	}
3087       else
3088 	{
3089 	  if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3090 	    fprintf (ira_dump_file, "assign memory\n");
3091 	}
3092     }
3093 }
3094 
3095 /* Sort allocnos according to their priorities.  */
3096 static int
allocno_priority_compare_func(const void * v1p,const void * v2p)3097 allocno_priority_compare_func (const void *v1p, const void *v2p)
3098 {
3099   ira_allocno_t a1 = *(const ira_allocno_t *) v1p;
3100   ira_allocno_t a2 = *(const ira_allocno_t *) v2p;
3101   int pri1, pri2, diff;
3102 
3103   /* Assign hard reg to static chain pointer pseudo first when
3104      non-local goto is used.  */
3105   if ((diff = (non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a2))
3106 	       - non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a1)))) != 0)
3107     return diff;
3108   pri1 = allocno_priorities[ALLOCNO_NUM (a1)];
3109   pri2 = allocno_priorities[ALLOCNO_NUM (a2)];
3110   if (pri2 != pri1)
3111     return SORTGT (pri2, pri1);
3112 
3113   /* If regs are equally good, sort by allocnos, so that the results of
3114      qsort leave nothing to chance.  */
3115   return ALLOCNO_NUM (a1) - ALLOCNO_NUM (a2);
3116 }
3117 
3118 /* Chaitin-Briggs coloring for allocnos in COLORING_ALLOCNO_BITMAP
3119    taking into account allocnos in CONSIDERATION_ALLOCNO_BITMAP.  */
3120 static void
color_allocnos(void)3121 color_allocnos (void)
3122 {
3123   unsigned int i, n;
3124   bitmap_iterator bi;
3125   ira_allocno_t a;
3126 
3127   setup_profitable_hard_regs ();
3128   EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
3129     {
3130       allocno_color_data_t data;
3131       ira_pref_t pref, next_pref;
3132 
3133       a = ira_allocnos[i];
3134       data = ALLOCNO_COLOR_DATA (a);
3135       data->conflict_allocno_hard_prefs = 0;
3136       for (pref = ALLOCNO_PREFS (a); pref != NULL; pref = next_pref)
3137 	{
3138 	  next_pref = pref->next_pref;
3139 	  if (! ira_hard_reg_in_set_p (pref->hard_regno,
3140 				       ALLOCNO_MODE (a),
3141 				       data->profitable_hard_regs))
3142 	    ira_remove_pref (pref);
3143 	}
3144     }
3145 
3146   if (flag_ira_algorithm == IRA_ALGORITHM_PRIORITY)
3147     {
3148       n = 0;
3149       EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
3150 	{
3151 	  a = ira_allocnos[i];
3152 	  if (ALLOCNO_CLASS (a) == NO_REGS)
3153 	    {
3154 	      ALLOCNO_HARD_REGNO (a) = -1;
3155 	      ALLOCNO_ASSIGNED_P (a) = true;
3156 	      ira_assert (ALLOCNO_UPDATED_HARD_REG_COSTS (a) == NULL);
3157 	      ira_assert (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a) == NULL);
3158 	      if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3159 		{
3160 		  fprintf (ira_dump_file, "      Spill");
3161 		  ira_print_expanded_allocno (a);
3162 		  fprintf (ira_dump_file, "\n");
3163 		}
3164 	      continue;
3165 	    }
3166 	  sorted_allocnos[n++] = a;
3167 	}
3168       if (n != 0)
3169 	{
3170 	  setup_allocno_priorities (sorted_allocnos, n);
3171 	  qsort (sorted_allocnos, n, sizeof (ira_allocno_t),
3172 		 allocno_priority_compare_func);
3173 	  for (i = 0; i < n; i++)
3174 	    {
3175 	      a = sorted_allocnos[i];
3176 	      if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3177 		{
3178 		  fprintf (ira_dump_file, "      ");
3179 		  ira_print_expanded_allocno (a);
3180 		  fprintf (ira_dump_file, "  -- ");
3181 		}
3182 	      if (assign_hard_reg (a, false))
3183 		{
3184 		  if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3185 		    fprintf (ira_dump_file, "assign hard reg %d\n",
3186 			     ALLOCNO_HARD_REGNO (a));
3187 		}
3188 	      else
3189 		{
3190 		  if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3191 		    fprintf (ira_dump_file, "assign memory\n");
3192 		}
3193 	    }
3194 	}
3195     }
3196   else
3197     {
3198       form_allocno_hard_regs_nodes_forest ();
3199       if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
3200 	print_hard_regs_forest (ira_dump_file);
3201       EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
3202 	{
3203 	  a = ira_allocnos[i];
3204 	  if (ALLOCNO_CLASS (a) != NO_REGS && ! empty_profitable_hard_regs (a))
3205 	    {
3206 	      ALLOCNO_COLOR_DATA (a)->in_graph_p = true;
3207 	      update_costs_from_prefs (a);
3208 	      update_conflict_allocno_hard_prefs (a);
3209 	    }
3210 	  else
3211 	    {
3212 	      ALLOCNO_HARD_REGNO (a) = -1;
3213 	      ALLOCNO_ASSIGNED_P (a) = true;
3214 	      /* We don't need updated costs anymore.  */
3215 	      ira_free_allocno_updated_costs (a);
3216 	      if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3217 		{
3218 		  fprintf (ira_dump_file, "      Spill");
3219 		  ira_print_expanded_allocno (a);
3220 		  fprintf (ira_dump_file, "\n");
3221 		}
3222 	    }
3223 	}
3224       /* Put the allocnos into the corresponding buckets.  */
3225       colorable_allocno_bucket = NULL;
3226       uncolorable_allocno_bucket = NULL;
3227       EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
3228 	{
3229 	  a = ira_allocnos[i];
3230 	  if (ALLOCNO_COLOR_DATA (a)->in_graph_p)
3231 	    put_allocno_into_bucket (a);
3232 	}
3233       push_allocnos_to_stack ();
3234       pop_allocnos_from_stack ();
3235       finish_allocno_hard_regs_nodes_forest ();
3236     }
3237   improve_allocation ();
3238 }
3239 
3240 
3241 
3242 /* Output information about the loop given by its LOOP_TREE_NODE.  */
3243 static void
print_loop_title(ira_loop_tree_node_t loop_tree_node)3244 print_loop_title (ira_loop_tree_node_t loop_tree_node)
3245 {
3246   unsigned int j;
3247   bitmap_iterator bi;
3248   ira_loop_tree_node_t subloop_node, dest_loop_node;
3249   edge e;
3250   edge_iterator ei;
3251 
3252   if (loop_tree_node->parent == NULL)
3253     fprintf (ira_dump_file,
3254 	     "\n  Loop 0 (parent -1, header bb%d, depth 0)\n    bbs:",
3255 	     NUM_FIXED_BLOCKS);
3256   else
3257     {
3258       ira_assert (current_loops != NULL && loop_tree_node->loop != NULL);
3259       fprintf (ira_dump_file,
3260 	       "\n  Loop %d (parent %d, header bb%d, depth %d)\n    bbs:",
3261 	       loop_tree_node->loop_num, loop_tree_node->parent->loop_num,
3262 	       loop_tree_node->loop->header->index,
3263 	       loop_depth (loop_tree_node->loop));
3264     }
3265   for (subloop_node = loop_tree_node->children;
3266        subloop_node != NULL;
3267        subloop_node = subloop_node->next)
3268     if (subloop_node->bb != NULL)
3269       {
3270 	fprintf (ira_dump_file, " %d", subloop_node->bb->index);
3271 	FOR_EACH_EDGE (e, ei, subloop_node->bb->succs)
3272 	  if (e->dest != EXIT_BLOCK_PTR_FOR_FN (cfun)
3273 	      && ((dest_loop_node = IRA_BB_NODE (e->dest)->parent)
3274 		  != loop_tree_node))
3275 	    fprintf (ira_dump_file, "(->%d:l%d)",
3276 		     e->dest->index, dest_loop_node->loop_num);
3277       }
3278   fprintf (ira_dump_file, "\n    all:");
3279   EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->all_allocnos, 0, j, bi)
3280     fprintf (ira_dump_file, " %dr%d", j, ALLOCNO_REGNO (ira_allocnos[j]));
3281   fprintf (ira_dump_file, "\n    modified regnos:");
3282   EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->modified_regnos, 0, j, bi)
3283     fprintf (ira_dump_file, " %d", j);
3284   fprintf (ira_dump_file, "\n    border:");
3285   EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->border_allocnos, 0, j, bi)
3286     fprintf (ira_dump_file, " %dr%d", j, ALLOCNO_REGNO (ira_allocnos[j]));
3287   fprintf (ira_dump_file, "\n    Pressure:");
3288   for (j = 0; (int) j < ira_pressure_classes_num; j++)
3289     {
3290       enum reg_class pclass;
3291 
3292       pclass = ira_pressure_classes[j];
3293       if (loop_tree_node->reg_pressure[pclass] == 0)
3294 	continue;
3295       fprintf (ira_dump_file, " %s=%d", reg_class_names[pclass],
3296 	       loop_tree_node->reg_pressure[pclass]);
3297     }
3298   fprintf (ira_dump_file, "\n");
3299 }
3300 
3301 /* Color the allocnos inside loop (in the extreme case it can be all
3302    of the function) given the corresponding LOOP_TREE_NODE.  The
3303    function is called for each loop during top-down traverse of the
3304    loop tree.  */
3305 static void
color_pass(ira_loop_tree_node_t loop_tree_node)3306 color_pass (ira_loop_tree_node_t loop_tree_node)
3307 {
3308   int regno, hard_regno, index = -1, n;
3309   int cost, exit_freq, enter_freq;
3310   unsigned int j;
3311   bitmap_iterator bi;
3312   machine_mode mode;
3313   enum reg_class rclass, aclass, pclass;
3314   ira_allocno_t a, subloop_allocno;
3315   ira_loop_tree_node_t subloop_node;
3316 
3317   ira_assert (loop_tree_node->bb == NULL);
3318   if (internal_flag_ira_verbose > 1 && ira_dump_file != NULL)
3319     print_loop_title (loop_tree_node);
3320 
3321   bitmap_copy (coloring_allocno_bitmap, loop_tree_node->all_allocnos);
3322   bitmap_copy (consideration_allocno_bitmap, coloring_allocno_bitmap);
3323   n = 0;
3324   EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
3325     {
3326       a = ira_allocnos[j];
3327       n++;
3328       if (! ALLOCNO_ASSIGNED_P (a))
3329 	continue;
3330       bitmap_clear_bit (coloring_allocno_bitmap, ALLOCNO_NUM (a));
3331     }
3332   allocno_color_data
3333     = (allocno_color_data_t) ira_allocate (sizeof (struct allocno_color_data)
3334 					   * n);
3335   memset (allocno_color_data, 0, sizeof (struct allocno_color_data) * n);
3336   curr_allocno_process = 0;
3337   n = 0;
3338   EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
3339     {
3340       a = ira_allocnos[j];
3341       ALLOCNO_ADD_DATA (a) = allocno_color_data + n;
3342       n++;
3343     }
3344   init_allocno_threads ();
3345   /* Color all mentioned allocnos including transparent ones.  */
3346   color_allocnos ();
3347   /* Process caps.  They are processed just once.  */
3348   if (flag_ira_region == IRA_REGION_MIXED
3349       || flag_ira_region == IRA_REGION_ALL)
3350     EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->all_allocnos, 0, j, bi)
3351       {
3352 	a = ira_allocnos[j];
3353 	if (ALLOCNO_CAP_MEMBER (a) == NULL)
3354 	  continue;
3355 	/* Remove from processing in the next loop.  */
3356 	bitmap_clear_bit (consideration_allocno_bitmap, j);
3357 	rclass = ALLOCNO_CLASS (a);
3358 	pclass = ira_pressure_class_translate[rclass];
3359 	if (flag_ira_region == IRA_REGION_MIXED
3360 	    && (loop_tree_node->reg_pressure[pclass]
3361 		<= ira_class_hard_regs_num[pclass]))
3362 	  {
3363 	    mode = ALLOCNO_MODE (a);
3364 	    hard_regno = ALLOCNO_HARD_REGNO (a);
3365 	    if (hard_regno >= 0)
3366 	      {
3367 		index = ira_class_hard_reg_index[rclass][hard_regno];
3368 		ira_assert (index >= 0);
3369 	      }
3370 	    regno = ALLOCNO_REGNO (a);
3371 	    subloop_allocno = ALLOCNO_CAP_MEMBER (a);
3372 	    subloop_node = ALLOCNO_LOOP_TREE_NODE (subloop_allocno);
3373 	    ira_assert (!ALLOCNO_ASSIGNED_P (subloop_allocno));
3374 	    ALLOCNO_HARD_REGNO (subloop_allocno) = hard_regno;
3375 	    ALLOCNO_ASSIGNED_P (subloop_allocno) = true;
3376 	    if (hard_regno >= 0)
3377 	      update_costs_from_copies (subloop_allocno, true, true);
3378 	    /* We don't need updated costs anymore.  */
3379 	    ira_free_allocno_updated_costs (subloop_allocno);
3380 	  }
3381       }
3382   /* Update costs of the corresponding allocnos (not caps) in the
3383      subloops.  */
3384   for (subloop_node = loop_tree_node->subloops;
3385        subloop_node != NULL;
3386        subloop_node = subloop_node->subloop_next)
3387     {
3388       ira_assert (subloop_node->bb == NULL);
3389       EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
3390         {
3391 	  a = ira_allocnos[j];
3392 	  ira_assert (ALLOCNO_CAP_MEMBER (a) == NULL);
3393 	  mode = ALLOCNO_MODE (a);
3394 	  rclass = ALLOCNO_CLASS (a);
3395 	  pclass = ira_pressure_class_translate[rclass];
3396 	  hard_regno = ALLOCNO_HARD_REGNO (a);
3397 	  /* Use hard register class here.  ??? */
3398 	  if (hard_regno >= 0)
3399 	    {
3400 	      index = ira_class_hard_reg_index[rclass][hard_regno];
3401 	      ira_assert (index >= 0);
3402 	    }
3403 	  regno = ALLOCNO_REGNO (a);
3404 	  /* ??? conflict costs */
3405 	  subloop_allocno = subloop_node->regno_allocno_map[regno];
3406 	  if (subloop_allocno == NULL
3407 	      || ALLOCNO_CAP (subloop_allocno) != NULL)
3408 	    continue;
3409 	  ira_assert (ALLOCNO_CLASS (subloop_allocno) == rclass);
3410 	  ira_assert (bitmap_bit_p (subloop_node->all_allocnos,
3411 				    ALLOCNO_NUM (subloop_allocno)));
3412 	  if ((flag_ira_region == IRA_REGION_MIXED
3413 	       && (loop_tree_node->reg_pressure[pclass]
3414 		   <= ira_class_hard_regs_num[pclass]))
3415 	      || (pic_offset_table_rtx != NULL
3416 		  && regno == (int) REGNO (pic_offset_table_rtx))
3417 	      /* Avoid overlapped multi-registers. Moves between them
3418 		 might result in wrong code generation.  */
3419 	      || (hard_regno >= 0
3420 		  && ira_reg_class_max_nregs[pclass][mode] > 1))
3421 	    {
3422 	      if (! ALLOCNO_ASSIGNED_P (subloop_allocno))
3423 		{
3424 		  ALLOCNO_HARD_REGNO (subloop_allocno) = hard_regno;
3425 		  ALLOCNO_ASSIGNED_P (subloop_allocno) = true;
3426 		  if (hard_regno >= 0)
3427 		    update_costs_from_copies (subloop_allocno, true, true);
3428 		  /* We don't need updated costs anymore.  */
3429 		  ira_free_allocno_updated_costs (subloop_allocno);
3430 		}
3431 	      continue;
3432 	    }
3433 	  exit_freq = ira_loop_edge_freq (subloop_node, regno, true);
3434 	  enter_freq = ira_loop_edge_freq (subloop_node, regno, false);
3435 	  ira_assert (regno < ira_reg_equiv_len);
3436 	  if (ira_equiv_no_lvalue_p (regno))
3437 	    {
3438 	      if (! ALLOCNO_ASSIGNED_P (subloop_allocno))
3439 		{
3440 		  ALLOCNO_HARD_REGNO (subloop_allocno) = hard_regno;
3441 		  ALLOCNO_ASSIGNED_P (subloop_allocno) = true;
3442 		  if (hard_regno >= 0)
3443 		    update_costs_from_copies (subloop_allocno, true, true);
3444 		  /* We don't need updated costs anymore.  */
3445 		  ira_free_allocno_updated_costs (subloop_allocno);
3446 		}
3447 	    }
3448 	  else if (hard_regno < 0)
3449 	    {
3450 	      ALLOCNO_UPDATED_MEMORY_COST (subloop_allocno)
3451 		-= ((ira_memory_move_cost[mode][rclass][1] * enter_freq)
3452 		    + (ira_memory_move_cost[mode][rclass][0] * exit_freq));
3453 	    }
3454 	  else
3455 	    {
3456 	      aclass = ALLOCNO_CLASS (subloop_allocno);
3457 	      ira_init_register_move_cost_if_necessary (mode);
3458 	      cost = (ira_register_move_cost[mode][rclass][rclass]
3459 		      * (exit_freq + enter_freq));
3460 	      ira_allocate_and_set_or_copy_costs
3461 		(&ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno), aclass,
3462 		 ALLOCNO_UPDATED_CLASS_COST (subloop_allocno),
3463 		 ALLOCNO_HARD_REG_COSTS (subloop_allocno));
3464 	      ira_allocate_and_set_or_copy_costs
3465 		(&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (subloop_allocno),
3466 		 aclass, 0, ALLOCNO_CONFLICT_HARD_REG_COSTS (subloop_allocno));
3467 	      ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno)[index] -= cost;
3468 	      ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (subloop_allocno)[index]
3469 		-= cost;
3470 	      if (ALLOCNO_UPDATED_CLASS_COST (subloop_allocno)
3471 		  > ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno)[index])
3472 		ALLOCNO_UPDATED_CLASS_COST (subloop_allocno)
3473 		  = ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno)[index];
3474 	      ALLOCNO_UPDATED_MEMORY_COST (subloop_allocno)
3475 		+= (ira_memory_move_cost[mode][rclass][0] * enter_freq
3476 		    + ira_memory_move_cost[mode][rclass][1] * exit_freq);
3477 	    }
3478 	}
3479     }
3480   ira_free (allocno_color_data);
3481   EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
3482     {
3483       a = ira_allocnos[j];
3484       ALLOCNO_ADD_DATA (a) = NULL;
3485     }
3486 }
3487 
3488 /* Initialize the common data for coloring and calls functions to do
3489    Chaitin-Briggs and regional coloring.  */
3490 static void
do_coloring(void)3491 do_coloring (void)
3492 {
3493   coloring_allocno_bitmap = ira_allocate_bitmap ();
3494   if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
3495     fprintf (ira_dump_file, "\n**** Allocnos coloring:\n\n");
3496 
3497   ira_traverse_loop_tree (false, ira_loop_tree_root, color_pass, NULL);
3498 
3499   if (internal_flag_ira_verbose > 1 && ira_dump_file != NULL)
3500     ira_print_disposition (ira_dump_file);
3501 
3502   ira_free_bitmap (coloring_allocno_bitmap);
3503 }
3504 
3505 
3506 
3507 /* Move spill/restore code, which are to be generated in ira-emit.c,
3508    to less frequent points (if it is profitable) by reassigning some
3509    allocnos (in loop with subloops containing in another loop) to
3510    memory which results in longer live-range where the corresponding
3511    pseudo-registers will be in memory.  */
3512 static void
move_spill_restore(void)3513 move_spill_restore (void)
3514 {
3515   int cost, regno, hard_regno, hard_regno2, index;
3516   bool changed_p;
3517   int enter_freq, exit_freq;
3518   machine_mode mode;
3519   enum reg_class rclass;
3520   ira_allocno_t a, parent_allocno, subloop_allocno;
3521   ira_loop_tree_node_t parent, loop_node, subloop_node;
3522   ira_allocno_iterator ai;
3523 
3524   for (;;)
3525     {
3526       changed_p = false;
3527       if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
3528 	fprintf (ira_dump_file, "New iteration of spill/restore move\n");
3529       FOR_EACH_ALLOCNO (a, ai)
3530 	{
3531 	  regno = ALLOCNO_REGNO (a);
3532 	  loop_node = ALLOCNO_LOOP_TREE_NODE (a);
3533 	  if (ALLOCNO_CAP_MEMBER (a) != NULL
3534 	      || ALLOCNO_CAP (a) != NULL
3535 	      || (hard_regno = ALLOCNO_HARD_REGNO (a)) < 0
3536 	      || loop_node->children == NULL
3537 	      /* don't do the optimization because it can create
3538 		 copies and the reload pass can spill the allocno set
3539 		 by copy although the allocno will not get memory
3540 		 slot.  */
3541 	      || ira_equiv_no_lvalue_p (regno)
3542 	      || !bitmap_bit_p (loop_node->border_allocnos, ALLOCNO_NUM (a))
3543 	      /* Do not spill static chain pointer pseudo when
3544 		 non-local goto is used.  */
3545 	      || non_spilled_static_chain_regno_p (regno))
3546 	    continue;
3547 	  mode = ALLOCNO_MODE (a);
3548 	  rclass = ALLOCNO_CLASS (a);
3549 	  index = ira_class_hard_reg_index[rclass][hard_regno];
3550 	  ira_assert (index >= 0);
3551 	  cost = (ALLOCNO_MEMORY_COST (a)
3552 		  - (ALLOCNO_HARD_REG_COSTS (a) == NULL
3553 		     ? ALLOCNO_CLASS_COST (a)
3554 		     : ALLOCNO_HARD_REG_COSTS (a)[index]));
3555 	  ira_init_register_move_cost_if_necessary (mode);
3556 	  for (subloop_node = loop_node->subloops;
3557 	       subloop_node != NULL;
3558 	       subloop_node = subloop_node->subloop_next)
3559 	    {
3560 	      ira_assert (subloop_node->bb == NULL);
3561 	      subloop_allocno = subloop_node->regno_allocno_map[regno];
3562 	      if (subloop_allocno == NULL)
3563 		continue;
3564 	      ira_assert (rclass == ALLOCNO_CLASS (subloop_allocno));
3565 	      /* We have accumulated cost.  To get the real cost of
3566 		 allocno usage in the loop we should subtract costs of
3567 		 the subloop allocnos.  */
3568 	      cost -= (ALLOCNO_MEMORY_COST (subloop_allocno)
3569 		       - (ALLOCNO_HARD_REG_COSTS (subloop_allocno) == NULL
3570 			  ? ALLOCNO_CLASS_COST (subloop_allocno)
3571 			  : ALLOCNO_HARD_REG_COSTS (subloop_allocno)[index]));
3572 	      exit_freq = ira_loop_edge_freq (subloop_node, regno, true);
3573 	      enter_freq = ira_loop_edge_freq (subloop_node, regno, false);
3574 	      if ((hard_regno2 = ALLOCNO_HARD_REGNO (subloop_allocno)) < 0)
3575 		cost -= (ira_memory_move_cost[mode][rclass][0] * exit_freq
3576 			 + ira_memory_move_cost[mode][rclass][1] * enter_freq);
3577 	      else
3578 		{
3579 		  cost
3580 		    += (ira_memory_move_cost[mode][rclass][0] * exit_freq
3581 			+ ira_memory_move_cost[mode][rclass][1] * enter_freq);
3582 		  if (hard_regno2 != hard_regno)
3583 		    cost -= (ira_register_move_cost[mode][rclass][rclass]
3584 			     * (exit_freq + enter_freq));
3585 		}
3586 	    }
3587 	  if ((parent = loop_node->parent) != NULL
3588 	      && (parent_allocno = parent->regno_allocno_map[regno]) != NULL)
3589 	    {
3590 	      ira_assert (rclass == ALLOCNO_CLASS (parent_allocno));
3591 	      exit_freq	= ira_loop_edge_freq (loop_node, regno, true);
3592 	      enter_freq = ira_loop_edge_freq (loop_node, regno, false);
3593 	      if ((hard_regno2 = ALLOCNO_HARD_REGNO (parent_allocno)) < 0)
3594 		cost -= (ira_memory_move_cost[mode][rclass][0] * exit_freq
3595 			 + ira_memory_move_cost[mode][rclass][1] * enter_freq);
3596 	      else
3597 		{
3598 		  cost
3599 		    += (ira_memory_move_cost[mode][rclass][1] * exit_freq
3600 			+ ira_memory_move_cost[mode][rclass][0] * enter_freq);
3601 		  if (hard_regno2 != hard_regno)
3602 		    cost -= (ira_register_move_cost[mode][rclass][rclass]
3603 			     * (exit_freq + enter_freq));
3604 		}
3605 	    }
3606 	  if (cost < 0)
3607 	    {
3608 	      ALLOCNO_HARD_REGNO (a) = -1;
3609 	      if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3610 		{
3611 		  fprintf
3612 		    (ira_dump_file,
3613 		     "      Moving spill/restore for a%dr%d up from loop %d",
3614 		     ALLOCNO_NUM (a), regno, loop_node->loop_num);
3615 		  fprintf (ira_dump_file, " - profit %d\n", -cost);
3616 		}
3617 	      changed_p = true;
3618 	    }
3619 	}
3620       if (! changed_p)
3621 	break;
3622     }
3623 }
3624 
3625 
3626 
3627 /* Update current hard reg costs and current conflict hard reg costs
3628    for allocno A.  It is done by processing its copies containing
3629    other allocnos already assigned.  */
3630 static void
update_curr_costs(ira_allocno_t a)3631 update_curr_costs (ira_allocno_t a)
3632 {
3633   int i, hard_regno, cost;
3634   machine_mode mode;
3635   enum reg_class aclass, rclass;
3636   ira_allocno_t another_a;
3637   ira_copy_t cp, next_cp;
3638 
3639   ira_free_allocno_updated_costs (a);
3640   ira_assert (! ALLOCNO_ASSIGNED_P (a));
3641   aclass = ALLOCNO_CLASS (a);
3642   if (aclass == NO_REGS)
3643     return;
3644   mode = ALLOCNO_MODE (a);
3645   ira_init_register_move_cost_if_necessary (mode);
3646   for (cp = ALLOCNO_COPIES (a); cp != NULL; cp = next_cp)
3647     {
3648       if (cp->first == a)
3649 	{
3650 	  next_cp = cp->next_first_allocno_copy;
3651 	  another_a = cp->second;
3652 	}
3653       else if (cp->second == a)
3654 	{
3655 	  next_cp = cp->next_second_allocno_copy;
3656 	  another_a = cp->first;
3657 	}
3658       else
3659 	gcc_unreachable ();
3660       if (! ira_reg_classes_intersect_p[aclass][ALLOCNO_CLASS (another_a)]
3661 	  || ! ALLOCNO_ASSIGNED_P (another_a)
3662 	  || (hard_regno = ALLOCNO_HARD_REGNO (another_a)) < 0)
3663 	continue;
3664       rclass = REGNO_REG_CLASS (hard_regno);
3665       i = ira_class_hard_reg_index[aclass][hard_regno];
3666       if (i < 0)
3667 	continue;
3668       cost = (cp->first == a
3669 	      ? ira_register_move_cost[mode][rclass][aclass]
3670 	      : ira_register_move_cost[mode][aclass][rclass]);
3671       ira_allocate_and_set_or_copy_costs
3672 	(&ALLOCNO_UPDATED_HARD_REG_COSTS (a), aclass, ALLOCNO_CLASS_COST (a),
3673 	 ALLOCNO_HARD_REG_COSTS (a));
3674       ira_allocate_and_set_or_copy_costs
3675 	(&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a),
3676 	 aclass, 0, ALLOCNO_CONFLICT_HARD_REG_COSTS (a));
3677       ALLOCNO_UPDATED_HARD_REG_COSTS (a)[i] -= cp->freq * cost;
3678       ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a)[i] -= cp->freq * cost;
3679     }
3680 }
3681 
3682 /* Try to assign hard registers to the unassigned allocnos and
3683    allocnos conflicting with them or conflicting with allocnos whose
3684    regno >= START_REGNO.  The function is called after ira_flattening,
3685    so more allocnos (including ones created in ira-emit.c) will have a
3686    chance to get a hard register.  We use simple assignment algorithm
3687    based on priorities.  */
3688 void
ira_reassign_conflict_allocnos(int start_regno)3689 ira_reassign_conflict_allocnos (int start_regno)
3690 {
3691   int i, allocnos_to_color_num;
3692   ira_allocno_t a;
3693   enum reg_class aclass;
3694   bitmap allocnos_to_color;
3695   ira_allocno_iterator ai;
3696 
3697   allocnos_to_color = ira_allocate_bitmap ();
3698   allocnos_to_color_num = 0;
3699   FOR_EACH_ALLOCNO (a, ai)
3700     {
3701       int n = ALLOCNO_NUM_OBJECTS (a);
3702 
3703       if (! ALLOCNO_ASSIGNED_P (a)
3704 	  && ! bitmap_bit_p (allocnos_to_color, ALLOCNO_NUM (a)))
3705 	{
3706 	  if (ALLOCNO_CLASS (a) != NO_REGS)
3707 	    sorted_allocnos[allocnos_to_color_num++] = a;
3708 	  else
3709 	    {
3710 	      ALLOCNO_ASSIGNED_P (a) = true;
3711 	      ALLOCNO_HARD_REGNO (a) = -1;
3712 	      ira_assert (ALLOCNO_UPDATED_HARD_REG_COSTS (a) == NULL);
3713 	      ira_assert (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a) == NULL);
3714 	    }
3715 	  bitmap_set_bit (allocnos_to_color, ALLOCNO_NUM (a));
3716 	}
3717       if (ALLOCNO_REGNO (a) < start_regno
3718 	  || (aclass = ALLOCNO_CLASS (a)) == NO_REGS)
3719 	continue;
3720       for (i = 0; i < n; i++)
3721 	{
3722 	  ira_object_t obj = ALLOCNO_OBJECT (a, i);
3723 	  ira_object_t conflict_obj;
3724 	  ira_object_conflict_iterator oci;
3725 
3726 	  FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
3727 	    {
3728 	      ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
3729 
3730 	      ira_assert (ira_reg_classes_intersect_p
3731 			  [aclass][ALLOCNO_CLASS (conflict_a)]);
3732 	      if (!bitmap_set_bit (allocnos_to_color, ALLOCNO_NUM (conflict_a)))
3733 		continue;
3734 	      sorted_allocnos[allocnos_to_color_num++] = conflict_a;
3735 	    }
3736 	}
3737     }
3738   ira_free_bitmap (allocnos_to_color);
3739   if (allocnos_to_color_num > 1)
3740     {
3741       setup_allocno_priorities (sorted_allocnos, allocnos_to_color_num);
3742       qsort (sorted_allocnos, allocnos_to_color_num, sizeof (ira_allocno_t),
3743 	     allocno_priority_compare_func);
3744     }
3745   for (i = 0; i < allocnos_to_color_num; i++)
3746     {
3747       a = sorted_allocnos[i];
3748       ALLOCNO_ASSIGNED_P (a) = false;
3749       update_curr_costs (a);
3750     }
3751   for (i = 0; i < allocnos_to_color_num; i++)
3752     {
3753       a = sorted_allocnos[i];
3754       if (assign_hard_reg (a, true))
3755 	{
3756 	  if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3757 	    fprintf
3758 	      (ira_dump_file,
3759 	       "      Secondary allocation: assign hard reg %d to reg %d\n",
3760 	       ALLOCNO_HARD_REGNO (a), ALLOCNO_REGNO (a));
3761 	}
3762     }
3763 }
3764 
3765 
3766 
3767 /* This page contains functions used to find conflicts using allocno
3768    live ranges.  */
3769 
3770 #ifdef ENABLE_IRA_CHECKING
3771 
3772 /* Return TRUE if live ranges of pseudo-registers REGNO1 and REGNO2
3773    intersect.  This should be used when there is only one region.
3774    Currently this is used during reload.  */
3775 static bool
conflict_by_live_ranges_p(int regno1,int regno2)3776 conflict_by_live_ranges_p (int regno1, int regno2)
3777 {
3778   ira_allocno_t a1, a2;
3779 
3780   ira_assert (regno1 >= FIRST_PSEUDO_REGISTER
3781 	      && regno2 >= FIRST_PSEUDO_REGISTER);
3782   /* Reg info calculated by dataflow infrastructure can be different
3783      from one calculated by regclass.  */
3784   if ((a1 = ira_loop_tree_root->regno_allocno_map[regno1]) == NULL
3785       || (a2 = ira_loop_tree_root->regno_allocno_map[regno2]) == NULL)
3786     return false;
3787   return allocnos_conflict_by_live_ranges_p (a1, a2);
3788 }
3789 
3790 #endif
3791 
3792 
3793 
3794 /* This page contains code to coalesce memory stack slots used by
3795    spilled allocnos.  This results in smaller stack frame, better data
3796    locality, and in smaller code for some architectures like
3797    x86/x86_64 where insn size depends on address displacement value.
3798    On the other hand, it can worsen insn scheduling after the RA but
3799    in practice it is less important than smaller stack frames.  */
3800 
3801 /* TRUE if we coalesced some allocnos.  In other words, if we got
3802    loops formed by members first_coalesced_allocno and
3803    next_coalesced_allocno containing more one allocno.  */
3804 static bool allocno_coalesced_p;
3805 
3806 /* Bitmap used to prevent a repeated allocno processing because of
3807    coalescing.  */
3808 static bitmap processed_coalesced_allocno_bitmap;
3809 
3810 /* See below.  */
3811 typedef struct coalesce_data *coalesce_data_t;
3812 
3813 /* To decrease footprint of ira_allocno structure we store all data
3814    needed only for coalescing in the following structure.  */
3815 struct coalesce_data
3816 {
3817   /* Coalesced allocnos form a cyclic list.  One allocno given by
3818      FIRST represents all coalesced allocnos.  The
3819      list is chained by NEXT.  */
3820   ira_allocno_t first;
3821   ira_allocno_t next;
3822   int temp;
3823 };
3824 
3825 /* Container for storing allocno data concerning coalescing.  */
3826 static coalesce_data_t allocno_coalesce_data;
3827 
3828 /* Macro to access the data concerning coalescing.  */
3829 #define ALLOCNO_COALESCE_DATA(a) ((coalesce_data_t) ALLOCNO_ADD_DATA (a))
3830 
3831 /* Merge two sets of coalesced allocnos given correspondingly by
3832    allocnos A1 and A2 (more accurately merging A2 set into A1
3833    set).  */
3834 static void
merge_allocnos(ira_allocno_t a1,ira_allocno_t a2)3835 merge_allocnos (ira_allocno_t a1, ira_allocno_t a2)
3836 {
3837   ira_allocno_t a, first, last, next;
3838 
3839   first = ALLOCNO_COALESCE_DATA (a1)->first;
3840   a = ALLOCNO_COALESCE_DATA (a2)->first;
3841   if (first == a)
3842     return;
3843   for (last = a2, a = ALLOCNO_COALESCE_DATA (a2)->next;;
3844        a = ALLOCNO_COALESCE_DATA (a)->next)
3845     {
3846       ALLOCNO_COALESCE_DATA (a)->first = first;
3847       if (a == a2)
3848 	break;
3849       last = a;
3850     }
3851   next = allocno_coalesce_data[ALLOCNO_NUM (first)].next;
3852   allocno_coalesce_data[ALLOCNO_NUM (first)].next = a2;
3853   allocno_coalesce_data[ALLOCNO_NUM (last)].next = next;
3854 }
3855 
3856 /* Return TRUE if there are conflicting allocnos from two sets of
3857    coalesced allocnos given correspondingly by allocnos A1 and A2.  We
3858    use live ranges to find conflicts because conflicts are represented
3859    only for allocnos of the same allocno class and during the reload
3860    pass we coalesce allocnos for sharing stack memory slots.  */
3861 static bool
coalesced_allocno_conflict_p(ira_allocno_t a1,ira_allocno_t a2)3862 coalesced_allocno_conflict_p (ira_allocno_t a1, ira_allocno_t a2)
3863 {
3864   ira_allocno_t a, conflict_a;
3865 
3866   if (allocno_coalesced_p)
3867     {
3868       bitmap_clear (processed_coalesced_allocno_bitmap);
3869       for (a = ALLOCNO_COALESCE_DATA (a1)->next;;
3870 	   a = ALLOCNO_COALESCE_DATA (a)->next)
3871 	{
3872 	  bitmap_set_bit (processed_coalesced_allocno_bitmap, ALLOCNO_NUM (a));
3873 	  if (a == a1)
3874 	    break;
3875 	}
3876     }
3877   for (a = ALLOCNO_COALESCE_DATA (a2)->next;;
3878        a = ALLOCNO_COALESCE_DATA (a)->next)
3879     {
3880       for (conflict_a = ALLOCNO_COALESCE_DATA (a1)->next;;
3881 	   conflict_a = ALLOCNO_COALESCE_DATA (conflict_a)->next)
3882 	{
3883 	  if (allocnos_conflict_by_live_ranges_p (a, conflict_a))
3884 	    return true;
3885 	  if (conflict_a == a1)
3886 	    break;
3887 	}
3888       if (a == a2)
3889 	break;
3890     }
3891   return false;
3892 }
3893 
3894 /* The major function for aggressive allocno coalescing.  We coalesce
3895    only spilled allocnos.  If some allocnos have been coalesced, we
3896    set up flag allocno_coalesced_p.  */
3897 static void
coalesce_allocnos(void)3898 coalesce_allocnos (void)
3899 {
3900   ira_allocno_t a;
3901   ira_copy_t cp, next_cp;
3902   unsigned int j;
3903   int i, n, cp_num, regno;
3904   bitmap_iterator bi;
3905 
3906   cp_num = 0;
3907   /* Collect copies.  */
3908   EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, j, bi)
3909     {
3910       a = ira_allocnos[j];
3911       regno = ALLOCNO_REGNO (a);
3912       if (! ALLOCNO_ASSIGNED_P (a) || ALLOCNO_HARD_REGNO (a) >= 0
3913 	  || ira_equiv_no_lvalue_p (regno))
3914 	continue;
3915       for (cp = ALLOCNO_COPIES (a); cp != NULL; cp = next_cp)
3916 	{
3917 	  if (cp->first == a)
3918 	    {
3919 	      next_cp = cp->next_first_allocno_copy;
3920 	      regno = ALLOCNO_REGNO (cp->second);
3921 	      /* For priority coloring we coalesce allocnos only with
3922 		 the same allocno class not with intersected allocno
3923 		 classes as it were possible.  It is done for
3924 		 simplicity.  */
3925 	      if ((cp->insn != NULL || cp->constraint_p)
3926 		  && ALLOCNO_ASSIGNED_P (cp->second)
3927 		  && ALLOCNO_HARD_REGNO (cp->second) < 0
3928 		  && ! ira_equiv_no_lvalue_p (regno))
3929 		sorted_copies[cp_num++] = cp;
3930 	    }
3931 	  else if (cp->second == a)
3932 	    next_cp = cp->next_second_allocno_copy;
3933 	  else
3934 	    gcc_unreachable ();
3935 	}
3936     }
3937   qsort (sorted_copies, cp_num, sizeof (ira_copy_t), copy_freq_compare_func);
3938   /* Coalesced copies, most frequently executed first.  */
3939   for (; cp_num != 0;)
3940     {
3941       for (i = 0; i < cp_num; i++)
3942 	{
3943 	  cp = sorted_copies[i];
3944 	  if (! coalesced_allocno_conflict_p (cp->first, cp->second))
3945 	    {
3946 	      allocno_coalesced_p = true;
3947 	      if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3948 		fprintf
3949 		  (ira_dump_file,
3950 		   "      Coalescing copy %d:a%dr%d-a%dr%d (freq=%d)\n",
3951 		   cp->num, ALLOCNO_NUM (cp->first), ALLOCNO_REGNO (cp->first),
3952 		   ALLOCNO_NUM (cp->second), ALLOCNO_REGNO (cp->second),
3953 		   cp->freq);
3954 	      merge_allocnos (cp->first, cp->second);
3955 	      i++;
3956 	      break;
3957 	    }
3958 	}
3959       /* Collect the rest of copies.  */
3960       for (n = 0; i < cp_num; i++)
3961 	{
3962 	  cp = sorted_copies[i];
3963 	  if (allocno_coalesce_data[ALLOCNO_NUM (cp->first)].first
3964 	      != allocno_coalesce_data[ALLOCNO_NUM (cp->second)].first)
3965 	    sorted_copies[n++] = cp;
3966 	}
3967       cp_num = n;
3968     }
3969 }
3970 
3971 /* Usage cost and order number of coalesced allocno set to which
3972    given pseudo register belongs to.  */
3973 static int *regno_coalesced_allocno_cost;
3974 static int *regno_coalesced_allocno_num;
3975 
3976 /* Sort pseudos according frequencies of coalesced allocno sets they
3977    belong to (putting most frequently ones first), and according to
3978    coalesced allocno set order numbers.  */
3979 static int
coalesced_pseudo_reg_freq_compare(const void * v1p,const void * v2p)3980 coalesced_pseudo_reg_freq_compare (const void *v1p, const void *v2p)
3981 {
3982   const int regno1 = *(const int *) v1p;
3983   const int regno2 = *(const int *) v2p;
3984   int diff;
3985 
3986   if ((diff = (regno_coalesced_allocno_cost[regno2]
3987 	       - regno_coalesced_allocno_cost[regno1])) != 0)
3988     return diff;
3989   if ((diff = (regno_coalesced_allocno_num[regno1]
3990 	       - regno_coalesced_allocno_num[regno2])) != 0)
3991     return diff;
3992   return regno1 - regno2;
3993 }
3994 
3995 /* Widest width in which each pseudo reg is referred to (via subreg).
3996    It is used for sorting pseudo registers.  */
3997 static machine_mode *regno_max_ref_mode;
3998 
3999 /* Sort pseudos according their slot numbers (putting ones with
4000   smaller numbers first, or last when the frame pointer is not
4001   needed).  */
4002 static int
coalesced_pseudo_reg_slot_compare(const void * v1p,const void * v2p)4003 coalesced_pseudo_reg_slot_compare (const void *v1p, const void *v2p)
4004 {
4005   const int regno1 = *(const int *) v1p;
4006   const int regno2 = *(const int *) v2p;
4007   ira_allocno_t a1 = ira_regno_allocno_map[regno1];
4008   ira_allocno_t a2 = ira_regno_allocno_map[regno2];
4009   int diff, slot_num1, slot_num2;
4010   machine_mode mode1, mode2;
4011 
4012   if (a1 == NULL || ALLOCNO_HARD_REGNO (a1) >= 0)
4013     {
4014       if (a2 == NULL || ALLOCNO_HARD_REGNO (a2) >= 0)
4015 	return regno1 - regno2;
4016       return 1;
4017     }
4018   else if (a2 == NULL || ALLOCNO_HARD_REGNO (a2) >= 0)
4019     return -1;
4020   slot_num1 = -ALLOCNO_HARD_REGNO (a1);
4021   slot_num2 = -ALLOCNO_HARD_REGNO (a2);
4022   if ((diff = slot_num1 - slot_num2) != 0)
4023     return (frame_pointer_needed
4024 	    || (!FRAME_GROWS_DOWNWARD) == STACK_GROWS_DOWNWARD ? diff : -diff);
4025   mode1 = wider_subreg_mode (PSEUDO_REGNO_MODE (regno1),
4026 			     regno_max_ref_mode[regno1]);
4027   mode2 = wider_subreg_mode (PSEUDO_REGNO_MODE (regno2),
4028 			     regno_max_ref_mode[regno2]);
4029   if ((diff = compare_sizes_for_sort (GET_MODE_SIZE (mode2),
4030 				      GET_MODE_SIZE (mode1))) != 0)
4031     return diff;
4032   return regno1 - regno2;
4033 }
4034 
4035 /* Setup REGNO_COALESCED_ALLOCNO_COST and REGNO_COALESCED_ALLOCNO_NUM
4036    for coalesced allocno sets containing allocnos with their regnos
4037    given in array PSEUDO_REGNOS of length N.  */
4038 static void
setup_coalesced_allocno_costs_and_nums(int * pseudo_regnos,int n)4039 setup_coalesced_allocno_costs_and_nums (int *pseudo_regnos, int n)
4040 {
4041   int i, num, regno, cost;
4042   ira_allocno_t allocno, a;
4043 
4044   for (num = i = 0; i < n; i++)
4045     {
4046       regno = pseudo_regnos[i];
4047       allocno = ira_regno_allocno_map[regno];
4048       if (allocno == NULL)
4049 	{
4050 	  regno_coalesced_allocno_cost[regno] = 0;
4051 	  regno_coalesced_allocno_num[regno] = ++num;
4052 	  continue;
4053 	}
4054       if (ALLOCNO_COALESCE_DATA (allocno)->first != allocno)
4055 	continue;
4056       num++;
4057       for (cost = 0, a = ALLOCNO_COALESCE_DATA (allocno)->next;;
4058 	   a = ALLOCNO_COALESCE_DATA (a)->next)
4059 	{
4060 	  cost += ALLOCNO_FREQ (a);
4061 	  if (a == allocno)
4062 	    break;
4063 	}
4064       for (a = ALLOCNO_COALESCE_DATA (allocno)->next;;
4065 	   a = ALLOCNO_COALESCE_DATA (a)->next)
4066 	{
4067 	  regno_coalesced_allocno_num[ALLOCNO_REGNO (a)] = num;
4068 	  regno_coalesced_allocno_cost[ALLOCNO_REGNO (a)] = cost;
4069 	  if (a == allocno)
4070 	    break;
4071 	}
4072     }
4073 }
4074 
4075 /* Collect spilled allocnos representing coalesced allocno sets (the
4076    first coalesced allocno).  The collected allocnos are returned
4077    through array SPILLED_COALESCED_ALLOCNOS.  The function returns the
4078    number of the collected allocnos.  The allocnos are given by their
4079    regnos in array PSEUDO_REGNOS of length N.  */
4080 static int
collect_spilled_coalesced_allocnos(int * pseudo_regnos,int n,ira_allocno_t * spilled_coalesced_allocnos)4081 collect_spilled_coalesced_allocnos (int *pseudo_regnos, int n,
4082 				    ira_allocno_t *spilled_coalesced_allocnos)
4083 {
4084   int i, num, regno;
4085   ira_allocno_t allocno;
4086 
4087   for (num = i = 0; i < n; i++)
4088     {
4089       regno = pseudo_regnos[i];
4090       allocno = ira_regno_allocno_map[regno];
4091       if (allocno == NULL || ALLOCNO_HARD_REGNO (allocno) >= 0
4092 	  || ALLOCNO_COALESCE_DATA (allocno)->first != allocno)
4093 	continue;
4094       spilled_coalesced_allocnos[num++] = allocno;
4095     }
4096   return num;
4097 }
4098 
4099 /* Array of live ranges of size IRA_ALLOCNOS_NUM.  Live range for
4100    given slot contains live ranges of coalesced allocnos assigned to
4101    given slot.  */
4102 static live_range_t *slot_coalesced_allocnos_live_ranges;
4103 
4104 /* Return TRUE if coalesced allocnos represented by ALLOCNO has live
4105    ranges intersected with live ranges of coalesced allocnos assigned
4106    to slot with number N.  */
4107 static bool
slot_coalesced_allocno_live_ranges_intersect_p(ira_allocno_t allocno,int n)4108 slot_coalesced_allocno_live_ranges_intersect_p (ira_allocno_t allocno, int n)
4109 {
4110   ira_allocno_t a;
4111 
4112   for (a = ALLOCNO_COALESCE_DATA (allocno)->next;;
4113        a = ALLOCNO_COALESCE_DATA (a)->next)
4114     {
4115       int i;
4116       int nr = ALLOCNO_NUM_OBJECTS (a);
4117       gcc_assert (ALLOCNO_CAP_MEMBER (a) == NULL);
4118       for (i = 0; i < nr; i++)
4119 	{
4120 	  ira_object_t obj = ALLOCNO_OBJECT (a, i);
4121 
4122 	  if (ira_live_ranges_intersect_p
4123 	      (slot_coalesced_allocnos_live_ranges[n],
4124 	       OBJECT_LIVE_RANGES (obj)))
4125 	    return true;
4126 	}
4127       if (a == allocno)
4128 	break;
4129     }
4130   return false;
4131 }
4132 
4133 /* Update live ranges of slot to which coalesced allocnos represented
4134    by ALLOCNO were assigned.  */
4135 static void
setup_slot_coalesced_allocno_live_ranges(ira_allocno_t allocno)4136 setup_slot_coalesced_allocno_live_ranges (ira_allocno_t allocno)
4137 {
4138   int i, n;
4139   ira_allocno_t a;
4140   live_range_t r;
4141 
4142   n = ALLOCNO_COALESCE_DATA (allocno)->temp;
4143   for (a = ALLOCNO_COALESCE_DATA (allocno)->next;;
4144        a = ALLOCNO_COALESCE_DATA (a)->next)
4145     {
4146       int nr = ALLOCNO_NUM_OBJECTS (a);
4147       gcc_assert (ALLOCNO_CAP_MEMBER (a) == NULL);
4148       for (i = 0; i < nr; i++)
4149 	{
4150 	  ira_object_t obj = ALLOCNO_OBJECT (a, i);
4151 
4152 	  r = ira_copy_live_range_list (OBJECT_LIVE_RANGES (obj));
4153 	  slot_coalesced_allocnos_live_ranges[n]
4154 	    = ira_merge_live_ranges
4155 	      (slot_coalesced_allocnos_live_ranges[n], r);
4156 	}
4157       if (a == allocno)
4158 	break;
4159     }
4160 }
4161 
4162 /* We have coalesced allocnos involving in copies.  Coalesce allocnos
4163    further in order to share the same memory stack slot.  Allocnos
4164    representing sets of allocnos coalesced before the call are given
4165    in array SPILLED_COALESCED_ALLOCNOS of length NUM.  Return TRUE if
4166    some allocnos were coalesced in the function.  */
4167 static bool
coalesce_spill_slots(ira_allocno_t * spilled_coalesced_allocnos,int num)4168 coalesce_spill_slots (ira_allocno_t *spilled_coalesced_allocnos, int num)
4169 {
4170   int i, j, n, last_coalesced_allocno_num;
4171   ira_allocno_t allocno, a;
4172   bool merged_p = false;
4173   bitmap set_jump_crosses = regstat_get_setjmp_crosses ();
4174 
4175   slot_coalesced_allocnos_live_ranges
4176     = (live_range_t *) ira_allocate (sizeof (live_range_t) * ira_allocnos_num);
4177   memset (slot_coalesced_allocnos_live_ranges, 0,
4178 	  sizeof (live_range_t) * ira_allocnos_num);
4179   last_coalesced_allocno_num = 0;
4180   /* Coalesce non-conflicting spilled allocnos preferring most
4181      frequently used.  */
4182   for (i = 0; i < num; i++)
4183     {
4184       allocno = spilled_coalesced_allocnos[i];
4185       if (ALLOCNO_COALESCE_DATA (allocno)->first != allocno
4186 	  || bitmap_bit_p (set_jump_crosses, ALLOCNO_REGNO (allocno))
4187 	  || ira_equiv_no_lvalue_p (ALLOCNO_REGNO (allocno)))
4188 	continue;
4189       for (j = 0; j < i; j++)
4190 	{
4191 	  a = spilled_coalesced_allocnos[j];
4192 	  n = ALLOCNO_COALESCE_DATA (a)->temp;
4193 	  if (ALLOCNO_COALESCE_DATA (a)->first == a
4194 	      && ! bitmap_bit_p (set_jump_crosses, ALLOCNO_REGNO (a))
4195 	      && ! ira_equiv_no_lvalue_p (ALLOCNO_REGNO (a))
4196 	      && ! slot_coalesced_allocno_live_ranges_intersect_p (allocno, n))
4197 	    break;
4198 	}
4199       if (j >= i)
4200 	{
4201 	  /* No coalescing: set up number for coalesced allocnos
4202 	     represented by ALLOCNO.  */
4203 	  ALLOCNO_COALESCE_DATA (allocno)->temp = last_coalesced_allocno_num++;
4204 	  setup_slot_coalesced_allocno_live_ranges (allocno);
4205 	}
4206       else
4207 	{
4208 	  allocno_coalesced_p = true;
4209 	  merged_p = true;
4210 	  if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4211 	    fprintf (ira_dump_file,
4212 		     "      Coalescing spilled allocnos a%dr%d->a%dr%d\n",
4213 		     ALLOCNO_NUM (allocno), ALLOCNO_REGNO (allocno),
4214 		     ALLOCNO_NUM (a), ALLOCNO_REGNO (a));
4215 	  ALLOCNO_COALESCE_DATA (allocno)->temp
4216 	    = ALLOCNO_COALESCE_DATA (a)->temp;
4217 	  setup_slot_coalesced_allocno_live_ranges (allocno);
4218 	  merge_allocnos (a, allocno);
4219 	  ira_assert (ALLOCNO_COALESCE_DATA (a)->first == a);
4220 	}
4221     }
4222   for (i = 0; i < ira_allocnos_num; i++)
4223     ira_finish_live_range_list (slot_coalesced_allocnos_live_ranges[i]);
4224   ira_free (slot_coalesced_allocnos_live_ranges);
4225   return merged_p;
4226 }
4227 
4228 /* Sort pseudo-register numbers in array PSEUDO_REGNOS of length N for
4229    subsequent assigning stack slots to them in the reload pass.  To do
4230    this we coalesce spilled allocnos first to decrease the number of
4231    memory-memory move insns.  This function is called by the
4232    reload.  */
4233 void
ira_sort_regnos_for_alter_reg(int * pseudo_regnos,int n,machine_mode * reg_max_ref_mode)4234 ira_sort_regnos_for_alter_reg (int *pseudo_regnos, int n,
4235 			       machine_mode *reg_max_ref_mode)
4236 {
4237   int max_regno = max_reg_num ();
4238   int i, regno, num, slot_num;
4239   ira_allocno_t allocno, a;
4240   ira_allocno_iterator ai;
4241   ira_allocno_t *spilled_coalesced_allocnos;
4242 
4243   ira_assert (! ira_use_lra_p);
4244 
4245   /* Set up allocnos can be coalesced.  */
4246   coloring_allocno_bitmap = ira_allocate_bitmap ();
4247   for (i = 0; i < n; i++)
4248     {
4249       regno = pseudo_regnos[i];
4250       allocno = ira_regno_allocno_map[regno];
4251       if (allocno != NULL)
4252 	bitmap_set_bit (coloring_allocno_bitmap, ALLOCNO_NUM (allocno));
4253     }
4254   allocno_coalesced_p = false;
4255   processed_coalesced_allocno_bitmap = ira_allocate_bitmap ();
4256   allocno_coalesce_data
4257     = (coalesce_data_t) ira_allocate (sizeof (struct coalesce_data)
4258 				      * ira_allocnos_num);
4259   /* Initialize coalesce data for allocnos.  */
4260   FOR_EACH_ALLOCNO (a, ai)
4261     {
4262       ALLOCNO_ADD_DATA (a) = allocno_coalesce_data + ALLOCNO_NUM (a);
4263       ALLOCNO_COALESCE_DATA (a)->first = a;
4264       ALLOCNO_COALESCE_DATA (a)->next = a;
4265     }
4266   coalesce_allocnos ();
4267   ira_free_bitmap (coloring_allocno_bitmap);
4268   regno_coalesced_allocno_cost
4269     = (int *) ira_allocate (max_regno * sizeof (int));
4270   regno_coalesced_allocno_num
4271     = (int *) ira_allocate (max_regno * sizeof (int));
4272   memset (regno_coalesced_allocno_num, 0, max_regno * sizeof (int));
4273   setup_coalesced_allocno_costs_and_nums (pseudo_regnos, n);
4274   /* Sort regnos according frequencies of the corresponding coalesced
4275      allocno sets.  */
4276   qsort (pseudo_regnos, n, sizeof (int), coalesced_pseudo_reg_freq_compare);
4277   spilled_coalesced_allocnos
4278     = (ira_allocno_t *) ira_allocate (ira_allocnos_num
4279 				      * sizeof (ira_allocno_t));
4280   /* Collect allocnos representing the spilled coalesced allocno
4281      sets.  */
4282   num = collect_spilled_coalesced_allocnos (pseudo_regnos, n,
4283 					    spilled_coalesced_allocnos);
4284   if (flag_ira_share_spill_slots
4285       && coalesce_spill_slots (spilled_coalesced_allocnos, num))
4286     {
4287       setup_coalesced_allocno_costs_and_nums (pseudo_regnos, n);
4288       qsort (pseudo_regnos, n, sizeof (int),
4289 	     coalesced_pseudo_reg_freq_compare);
4290       num = collect_spilled_coalesced_allocnos (pseudo_regnos, n,
4291 						spilled_coalesced_allocnos);
4292     }
4293   ira_free_bitmap (processed_coalesced_allocno_bitmap);
4294   allocno_coalesced_p = false;
4295   /* Assign stack slot numbers to spilled allocno sets, use smaller
4296      numbers for most frequently used coalesced allocnos.  -1 is
4297      reserved for dynamic search of stack slots for pseudos spilled by
4298      the reload.  */
4299   slot_num = 1;
4300   for (i = 0; i < num; i++)
4301     {
4302       allocno = spilled_coalesced_allocnos[i];
4303       if (ALLOCNO_COALESCE_DATA (allocno)->first != allocno
4304 	  || ALLOCNO_HARD_REGNO (allocno) >= 0
4305 	  || ira_equiv_no_lvalue_p (ALLOCNO_REGNO (allocno)))
4306 	continue;
4307       if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4308 	fprintf (ira_dump_file, "      Slot %d (freq,size):", slot_num);
4309       slot_num++;
4310       for (a = ALLOCNO_COALESCE_DATA (allocno)->next;;
4311 	   a = ALLOCNO_COALESCE_DATA (a)->next)
4312 	{
4313 	  ira_assert (ALLOCNO_HARD_REGNO (a) < 0);
4314 	  ALLOCNO_HARD_REGNO (a) = -slot_num;
4315 	  if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4316 	    {
4317 	      machine_mode mode = wider_subreg_mode
4318 		(PSEUDO_REGNO_MODE (ALLOCNO_REGNO (a)),
4319 		 reg_max_ref_mode[ALLOCNO_REGNO (a)]);
4320 	      fprintf (ira_dump_file, " a%dr%d(%d,",
4321 		       ALLOCNO_NUM (a), ALLOCNO_REGNO (a), ALLOCNO_FREQ (a));
4322 	      print_dec (GET_MODE_SIZE (mode), ira_dump_file, SIGNED);
4323 	      fprintf (ira_dump_file, ")\n");
4324 	    }
4325 
4326 	  if (a == allocno)
4327 	    break;
4328 	}
4329       if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4330 	fprintf (ira_dump_file, "\n");
4331     }
4332   ira_spilled_reg_stack_slots_num = slot_num - 1;
4333   ira_free (spilled_coalesced_allocnos);
4334   /* Sort regnos according the slot numbers.  */
4335   regno_max_ref_mode = reg_max_ref_mode;
4336   qsort (pseudo_regnos, n, sizeof (int), coalesced_pseudo_reg_slot_compare);
4337   FOR_EACH_ALLOCNO (a, ai)
4338     ALLOCNO_ADD_DATA (a) = NULL;
4339   ira_free (allocno_coalesce_data);
4340   ira_free (regno_coalesced_allocno_num);
4341   ira_free (regno_coalesced_allocno_cost);
4342 }
4343 
4344 
4345 
4346 /* This page contains code used by the reload pass to improve the
4347    final code.  */
4348 
4349 /* The function is called from reload to mark changes in the
4350    allocation of REGNO made by the reload.  Remember that reg_renumber
4351    reflects the change result.  */
4352 void
ira_mark_allocation_change(int regno)4353 ira_mark_allocation_change (int regno)
4354 {
4355   ira_allocno_t a = ira_regno_allocno_map[regno];
4356   int old_hard_regno, hard_regno, cost;
4357   enum reg_class aclass = ALLOCNO_CLASS (a);
4358 
4359   ira_assert (a != NULL);
4360   hard_regno = reg_renumber[regno];
4361   if ((old_hard_regno = ALLOCNO_HARD_REGNO (a)) == hard_regno)
4362     return;
4363   if (old_hard_regno < 0)
4364     cost = -ALLOCNO_MEMORY_COST (a);
4365   else
4366     {
4367       ira_assert (ira_class_hard_reg_index[aclass][old_hard_regno] >= 0);
4368       cost = -(ALLOCNO_HARD_REG_COSTS (a) == NULL
4369 	       ? ALLOCNO_CLASS_COST (a)
4370 	       : ALLOCNO_HARD_REG_COSTS (a)
4371 	         [ira_class_hard_reg_index[aclass][old_hard_regno]]);
4372       update_costs_from_copies (a, false, false);
4373     }
4374   ira_overall_cost -= cost;
4375   ALLOCNO_HARD_REGNO (a) = hard_regno;
4376   if (hard_regno < 0)
4377     {
4378       ALLOCNO_HARD_REGNO (a) = -1;
4379       cost += ALLOCNO_MEMORY_COST (a);
4380     }
4381   else if (ira_class_hard_reg_index[aclass][hard_regno] >= 0)
4382     {
4383       cost += (ALLOCNO_HARD_REG_COSTS (a) == NULL
4384 	       ? ALLOCNO_CLASS_COST (a)
4385 	       : ALLOCNO_HARD_REG_COSTS (a)
4386 	         [ira_class_hard_reg_index[aclass][hard_regno]]);
4387       update_costs_from_copies (a, true, false);
4388     }
4389   else
4390     /* Reload changed class of the allocno.  */
4391     cost = 0;
4392   ira_overall_cost += cost;
4393 }
4394 
4395 /* This function is called when reload deletes memory-memory move.  In
4396    this case we marks that the allocation of the corresponding
4397    allocnos should be not changed in future.  Otherwise we risk to get
4398    a wrong code.  */
4399 void
ira_mark_memory_move_deletion(int dst_regno,int src_regno)4400 ira_mark_memory_move_deletion (int dst_regno, int src_regno)
4401 {
4402   ira_allocno_t dst = ira_regno_allocno_map[dst_regno];
4403   ira_allocno_t src = ira_regno_allocno_map[src_regno];
4404 
4405   ira_assert (dst != NULL && src != NULL
4406 	      && ALLOCNO_HARD_REGNO (dst) < 0
4407 	      && ALLOCNO_HARD_REGNO (src) < 0);
4408   ALLOCNO_DONT_REASSIGN_P (dst) = true;
4409   ALLOCNO_DONT_REASSIGN_P (src) = true;
4410 }
4411 
4412 /* Try to assign a hard register (except for FORBIDDEN_REGS) to
4413    allocno A and return TRUE in the case of success.  */
4414 static bool
allocno_reload_assign(ira_allocno_t a,HARD_REG_SET forbidden_regs)4415 allocno_reload_assign (ira_allocno_t a, HARD_REG_SET forbidden_regs)
4416 {
4417   int hard_regno;
4418   enum reg_class aclass;
4419   int regno = ALLOCNO_REGNO (a);
4420   HARD_REG_SET saved[2];
4421   int i, n;
4422 
4423   n = ALLOCNO_NUM_OBJECTS (a);
4424   for (i = 0; i < n; i++)
4425     {
4426       ira_object_t obj = ALLOCNO_OBJECT (a, i);
4427       saved[i] = OBJECT_TOTAL_CONFLICT_HARD_REGS (obj);
4428       OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) |= forbidden_regs;
4429       if (! flag_caller_saves && ALLOCNO_CALLS_CROSSED_NUM (a) != 0)
4430 	OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) |= ira_need_caller_save_regs (a);
4431     }
4432   ALLOCNO_ASSIGNED_P (a) = false;
4433   aclass = ALLOCNO_CLASS (a);
4434   update_curr_costs (a);
4435   assign_hard_reg (a, true);
4436   hard_regno = ALLOCNO_HARD_REGNO (a);
4437   reg_renumber[regno] = hard_regno;
4438   if (hard_regno < 0)
4439     ALLOCNO_HARD_REGNO (a) = -1;
4440   else
4441     {
4442       ira_assert (ira_class_hard_reg_index[aclass][hard_regno] >= 0);
4443       ira_overall_cost
4444 	-= (ALLOCNO_MEMORY_COST (a)
4445 	    - (ALLOCNO_HARD_REG_COSTS (a) == NULL
4446 	       ? ALLOCNO_CLASS_COST (a)
4447 	       : ALLOCNO_HARD_REG_COSTS (a)[ira_class_hard_reg_index
4448 					    [aclass][hard_regno]]));
4449       if (ira_need_caller_save_p (a, hard_regno))
4450 	{
4451 	  ira_assert (flag_caller_saves);
4452 	  caller_save_needed = 1;
4453 	}
4454     }
4455 
4456   /* If we found a hard register, modify the RTL for the pseudo
4457      register to show the hard register, and mark the pseudo register
4458      live.  */
4459   if (reg_renumber[regno] >= 0)
4460     {
4461       if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4462 	fprintf (ira_dump_file, ": reassign to %d\n", reg_renumber[regno]);
4463       SET_REGNO (regno_reg_rtx[regno], reg_renumber[regno]);
4464       mark_home_live (regno);
4465     }
4466   else if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4467     fprintf (ira_dump_file, "\n");
4468   for (i = 0; i < n; i++)
4469     {
4470       ira_object_t obj = ALLOCNO_OBJECT (a, i);
4471       OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) = saved[i];
4472     }
4473   return reg_renumber[regno] >= 0;
4474 }
4475 
4476 /* Sort pseudos according their usage frequencies (putting most
4477    frequently ones first).  */
4478 static int
pseudo_reg_compare(const void * v1p,const void * v2p)4479 pseudo_reg_compare (const void *v1p, const void *v2p)
4480 {
4481   int regno1 = *(const int *) v1p;
4482   int regno2 = *(const int *) v2p;
4483   int diff;
4484 
4485   if ((diff = REG_FREQ (regno2) - REG_FREQ (regno1)) != 0)
4486     return diff;
4487   return regno1 - regno2;
4488 }
4489 
4490 /* Try to allocate hard registers to SPILLED_PSEUDO_REGS (there are
4491    NUM of them) or spilled pseudos conflicting with pseudos in
4492    SPILLED_PSEUDO_REGS.  Return TRUE and update SPILLED, if the
4493    allocation has been changed.  The function doesn't use
4494    BAD_SPILL_REGS and hard registers in PSEUDO_FORBIDDEN_REGS and
4495    PSEUDO_PREVIOUS_REGS for the corresponding pseudos.  The function
4496    is called by the reload pass at the end of each reload
4497    iteration.  */
4498 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)4499 ira_reassign_pseudos (int *spilled_pseudo_regs, int num,
4500 		      HARD_REG_SET bad_spill_regs,
4501 		      HARD_REG_SET *pseudo_forbidden_regs,
4502 		      HARD_REG_SET *pseudo_previous_regs,
4503 		      bitmap spilled)
4504 {
4505   int i, n, regno;
4506   bool changed_p;
4507   ira_allocno_t a;
4508   HARD_REG_SET forbidden_regs;
4509   bitmap temp = BITMAP_ALLOC (NULL);
4510 
4511   /* Add pseudos which conflict with pseudos already in
4512      SPILLED_PSEUDO_REGS to SPILLED_PSEUDO_REGS.  This is preferable
4513      to allocating in two steps as some of the conflicts might have
4514      a higher priority than the pseudos passed in SPILLED_PSEUDO_REGS.  */
4515   for (i = 0; i < num; i++)
4516     bitmap_set_bit (temp, spilled_pseudo_regs[i]);
4517 
4518   for (i = 0, n = num; i < n; i++)
4519     {
4520       int nr, j;
4521       int regno = spilled_pseudo_regs[i];
4522       bitmap_set_bit (temp, regno);
4523 
4524       a = ira_regno_allocno_map[regno];
4525       nr = ALLOCNO_NUM_OBJECTS (a);
4526       for (j = 0; j < nr; j++)
4527 	{
4528 	  ira_object_t conflict_obj;
4529 	  ira_object_t obj = ALLOCNO_OBJECT (a, j);
4530 	  ira_object_conflict_iterator oci;
4531 
4532 	  FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
4533 	    {
4534 	      ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
4535 	      if (ALLOCNO_HARD_REGNO (conflict_a) < 0
4536 		  && ! ALLOCNO_DONT_REASSIGN_P (conflict_a)
4537 		  && bitmap_set_bit (temp, ALLOCNO_REGNO (conflict_a)))
4538 		{
4539 		  spilled_pseudo_regs[num++] = ALLOCNO_REGNO (conflict_a);
4540 		  /* ?!? This seems wrong.  */
4541 		  bitmap_set_bit (consideration_allocno_bitmap,
4542 				  ALLOCNO_NUM (conflict_a));
4543 		}
4544 	    }
4545 	}
4546     }
4547 
4548   if (num > 1)
4549     qsort (spilled_pseudo_regs, num, sizeof (int), pseudo_reg_compare);
4550   changed_p = false;
4551   /* Try to assign hard registers to pseudos from
4552      SPILLED_PSEUDO_REGS.  */
4553   for (i = 0; i < num; i++)
4554     {
4555       regno = spilled_pseudo_regs[i];
4556       forbidden_regs = (bad_spill_regs
4557 			| pseudo_forbidden_regs[regno]
4558 			| pseudo_previous_regs[regno]);
4559       gcc_assert (reg_renumber[regno] < 0);
4560       a = ira_regno_allocno_map[regno];
4561       ira_mark_allocation_change (regno);
4562       ira_assert (reg_renumber[regno] < 0);
4563       if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4564 	fprintf (ira_dump_file,
4565 		 "      Try Assign %d(a%d), cost=%d", regno, ALLOCNO_NUM (a),
4566 		 ALLOCNO_MEMORY_COST (a)
4567 		 - ALLOCNO_CLASS_COST (a));
4568       allocno_reload_assign (a, forbidden_regs);
4569       if (reg_renumber[regno] >= 0)
4570 	{
4571 	  CLEAR_REGNO_REG_SET (spilled, regno);
4572 	  changed_p = true;
4573 	}
4574     }
4575   BITMAP_FREE (temp);
4576   return changed_p;
4577 }
4578 
4579 /* The function is called by reload and returns already allocated
4580    stack slot (if any) for REGNO with given INHERENT_SIZE and
4581    TOTAL_SIZE.  In the case of failure to find a slot which can be
4582    used for REGNO, the function returns NULL.  */
4583 rtx
ira_reuse_stack_slot(int regno,poly_uint64 inherent_size,poly_uint64 total_size)4584 ira_reuse_stack_slot (int regno, poly_uint64 inherent_size,
4585 		      poly_uint64 total_size)
4586 {
4587   unsigned int i;
4588   int slot_num, best_slot_num;
4589   int cost, best_cost;
4590   ira_copy_t cp, next_cp;
4591   ira_allocno_t another_allocno, allocno = ira_regno_allocno_map[regno];
4592   rtx x;
4593   bitmap_iterator bi;
4594   class ira_spilled_reg_stack_slot *slot = NULL;
4595 
4596   ira_assert (! ira_use_lra_p);
4597 
4598   ira_assert (known_eq (inherent_size, PSEUDO_REGNO_BYTES (regno))
4599 	      && known_le (inherent_size, total_size)
4600 	      && ALLOCNO_HARD_REGNO (allocno) < 0);
4601   if (! flag_ira_share_spill_slots)
4602     return NULL_RTX;
4603   slot_num = -ALLOCNO_HARD_REGNO (allocno) - 2;
4604   if (slot_num != -1)
4605     {
4606       slot = &ira_spilled_reg_stack_slots[slot_num];
4607       x = slot->mem;
4608     }
4609   else
4610     {
4611       best_cost = best_slot_num = -1;
4612       x = NULL_RTX;
4613       /* It means that the pseudo was spilled in the reload pass, try
4614 	 to reuse a slot.  */
4615       for (slot_num = 0;
4616 	   slot_num < ira_spilled_reg_stack_slots_num;
4617 	   slot_num++)
4618 	{
4619 	  slot = &ira_spilled_reg_stack_slots[slot_num];
4620 	  if (slot->mem == NULL_RTX)
4621 	    continue;
4622 	  if (maybe_lt (slot->width, total_size)
4623 	      || maybe_lt (GET_MODE_SIZE (GET_MODE (slot->mem)), inherent_size))
4624 	    continue;
4625 
4626 	  EXECUTE_IF_SET_IN_BITMAP (&slot->spilled_regs,
4627 				    FIRST_PSEUDO_REGISTER, i, bi)
4628 	    {
4629 	      another_allocno = ira_regno_allocno_map[i];
4630 	      if (allocnos_conflict_by_live_ranges_p (allocno,
4631 						      another_allocno))
4632 		goto cont;
4633 	    }
4634 	  for (cost = 0, cp = ALLOCNO_COPIES (allocno);
4635 	       cp != NULL;
4636 	       cp = next_cp)
4637 	    {
4638 	      if (cp->first == allocno)
4639 		{
4640 		  next_cp = cp->next_first_allocno_copy;
4641 		  another_allocno = cp->second;
4642 		}
4643 	      else if (cp->second == allocno)
4644 		{
4645 		  next_cp = cp->next_second_allocno_copy;
4646 		  another_allocno = cp->first;
4647 		}
4648 	      else
4649 		gcc_unreachable ();
4650 	      if (cp->insn == NULL_RTX)
4651 		continue;
4652 	      if (bitmap_bit_p (&slot->spilled_regs,
4653 				ALLOCNO_REGNO (another_allocno)))
4654 		cost += cp->freq;
4655 	    }
4656 	  if (cost > best_cost)
4657 	    {
4658 	      best_cost = cost;
4659 	      best_slot_num = slot_num;
4660 	    }
4661 	cont:
4662 	  ;
4663 	}
4664       if (best_cost >= 0)
4665 	{
4666 	  slot_num = best_slot_num;
4667 	  slot = &ira_spilled_reg_stack_slots[slot_num];
4668 	  SET_REGNO_REG_SET (&slot->spilled_regs, regno);
4669 	  x = slot->mem;
4670 	  ALLOCNO_HARD_REGNO (allocno) = -slot_num - 2;
4671 	}
4672     }
4673   if (x != NULL_RTX)
4674     {
4675       ira_assert (known_ge (slot->width, total_size));
4676 #ifdef ENABLE_IRA_CHECKING
4677       EXECUTE_IF_SET_IN_BITMAP (&slot->spilled_regs,
4678 				FIRST_PSEUDO_REGISTER, i, bi)
4679 	{
4680 	  ira_assert (! conflict_by_live_ranges_p (regno, i));
4681 	}
4682 #endif
4683       SET_REGNO_REG_SET (&slot->spilled_regs, regno);
4684       if (internal_flag_ira_verbose > 3 && ira_dump_file)
4685 	{
4686 	  fprintf (ira_dump_file, "      Assigning %d(freq=%d) slot %d of",
4687 		   regno, REG_FREQ (regno), slot_num);
4688 	  EXECUTE_IF_SET_IN_BITMAP (&slot->spilled_regs,
4689 				    FIRST_PSEUDO_REGISTER, i, bi)
4690 	    {
4691 	      if ((unsigned) regno != i)
4692 		fprintf (ira_dump_file, " %d", i);
4693 	    }
4694 	  fprintf (ira_dump_file, "\n");
4695 	}
4696     }
4697   return x;
4698 }
4699 
4700 /* This is called by reload every time a new stack slot X with
4701    TOTAL_SIZE was allocated for REGNO.  We store this info for
4702    subsequent ira_reuse_stack_slot calls.  */
4703 void
ira_mark_new_stack_slot(rtx x,int regno,poly_uint64 total_size)4704 ira_mark_new_stack_slot (rtx x, int regno, poly_uint64 total_size)
4705 {
4706   class ira_spilled_reg_stack_slot *slot;
4707   int slot_num;
4708   ira_allocno_t allocno;
4709 
4710   ira_assert (! ira_use_lra_p);
4711 
4712   ira_assert (known_le (PSEUDO_REGNO_BYTES (regno), total_size));
4713   allocno = ira_regno_allocno_map[regno];
4714   slot_num = -ALLOCNO_HARD_REGNO (allocno) - 2;
4715   if (slot_num == -1)
4716     {
4717       slot_num = ira_spilled_reg_stack_slots_num++;
4718       ALLOCNO_HARD_REGNO (allocno) = -slot_num - 2;
4719     }
4720   slot = &ira_spilled_reg_stack_slots[slot_num];
4721   INIT_REG_SET (&slot->spilled_regs);
4722   SET_REGNO_REG_SET (&slot->spilled_regs, regno);
4723   slot->mem = x;
4724   slot->width = total_size;
4725   if (internal_flag_ira_verbose > 3 && ira_dump_file)
4726     fprintf (ira_dump_file, "      Assigning %d(freq=%d) a new slot %d\n",
4727 	     regno, REG_FREQ (regno), slot_num);
4728 }
4729 
4730 
4731 /* Return spill cost for pseudo-registers whose numbers are in array
4732    REGNOS (with a negative number as an end marker) for reload with
4733    given IN and OUT for INSN.  Return also number points (through
4734    EXCESS_PRESSURE_LIVE_LENGTH) where the pseudo-register lives and
4735    the register pressure is high, number of references of the
4736    pseudo-registers (through NREFS), the number of psuedo registers
4737    whose allocated register wouldn't need saving in the prologue
4738    (through CALL_USED_COUNT), and the first hard regno occupied by the
4739    pseudo-registers (through FIRST_HARD_REGNO).  */
4740 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)4741 calculate_spill_cost (int *regnos, rtx in, rtx out, rtx_insn *insn,
4742 		      int *excess_pressure_live_length,
4743 		      int *nrefs, int *call_used_count, int *first_hard_regno)
4744 {
4745   int i, cost, regno, hard_regno, count, saved_cost;
4746   bool in_p, out_p;
4747   int length;
4748   ira_allocno_t a;
4749 
4750   *nrefs = 0;
4751   for (length = count = cost = i = 0;; i++)
4752     {
4753       regno = regnos[i];
4754       if (regno < 0)
4755 	break;
4756       *nrefs += REG_N_REFS (regno);
4757       hard_regno = reg_renumber[regno];
4758       ira_assert (hard_regno >= 0);
4759       a = ira_regno_allocno_map[regno];
4760       length += ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a) / ALLOCNO_NUM_OBJECTS (a);
4761       cost += ALLOCNO_MEMORY_COST (a) - ALLOCNO_CLASS_COST (a);
4762       if (in_hard_reg_set_p (crtl->abi->full_reg_clobbers (),
4763 			     ALLOCNO_MODE (a), hard_regno))
4764 	count++;
4765       in_p = in && REG_P (in) && (int) REGNO (in) == hard_regno;
4766       out_p = out && REG_P (out) && (int) REGNO (out) == hard_regno;
4767       if ((in_p || out_p)
4768 	  && find_regno_note (insn, REG_DEAD, hard_regno) != NULL_RTX)
4769 	{
4770 	  saved_cost = 0;
4771 	  if (in_p)
4772 	    saved_cost += ira_memory_move_cost
4773 	                  [ALLOCNO_MODE (a)][ALLOCNO_CLASS (a)][1];
4774 	  if (out_p)
4775 	    saved_cost
4776 	      += ira_memory_move_cost
4777 	         [ALLOCNO_MODE (a)][ALLOCNO_CLASS (a)][0];
4778 	  cost -= REG_FREQ_FROM_BB (BLOCK_FOR_INSN (insn)) * saved_cost;
4779 	}
4780     }
4781   *excess_pressure_live_length = length;
4782   *call_used_count = count;
4783   hard_regno = -1;
4784   if (regnos[0] >= 0)
4785     {
4786       hard_regno = reg_renumber[regnos[0]];
4787     }
4788   *first_hard_regno = hard_regno;
4789   return cost;
4790 }
4791 
4792 /* Return TRUE if spilling pseudo-registers whose numbers are in array
4793    REGNOS is better than spilling pseudo-registers with numbers in
4794    OTHER_REGNOS for reload with given IN and OUT for INSN.  The
4795    function used by the reload pass to make better register spilling
4796    decisions.  */
4797 bool
ira_better_spill_reload_regno_p(int * regnos,int * other_regnos,rtx in,rtx out,rtx_insn * insn)4798 ira_better_spill_reload_regno_p (int *regnos, int *other_regnos,
4799 				 rtx in, rtx out, rtx_insn *insn)
4800 {
4801   int cost, other_cost;
4802   int length, other_length;
4803   int nrefs, other_nrefs;
4804   int call_used_count, other_call_used_count;
4805   int hard_regno, other_hard_regno;
4806 
4807   cost = calculate_spill_cost (regnos, in, out, insn,
4808 			       &length, &nrefs, &call_used_count, &hard_regno);
4809   other_cost = calculate_spill_cost (other_regnos, in, out, insn,
4810 				     &other_length, &other_nrefs,
4811 				     &other_call_used_count,
4812 				     &other_hard_regno);
4813   if (nrefs == 0 && other_nrefs != 0)
4814     return true;
4815   if (nrefs != 0 && other_nrefs == 0)
4816     return false;
4817   if (cost != other_cost)
4818     return cost < other_cost;
4819   if (length != other_length)
4820     return length > other_length;
4821 #ifdef REG_ALLOC_ORDER
4822   if (hard_regno >= 0 && other_hard_regno >= 0)
4823     return (inv_reg_alloc_order[hard_regno]
4824 	    < inv_reg_alloc_order[other_hard_regno]);
4825 #else
4826   if (call_used_count != other_call_used_count)
4827     return call_used_count > other_call_used_count;
4828 #endif
4829   return false;
4830 }
4831 
4832 
4833 
4834 /* Allocate and initialize data necessary for assign_hard_reg.  */
4835 void
ira_initiate_assign(void)4836 ira_initiate_assign (void)
4837 {
4838   sorted_allocnos
4839     = (ira_allocno_t *) ira_allocate (sizeof (ira_allocno_t)
4840 				      * ira_allocnos_num);
4841   consideration_allocno_bitmap = ira_allocate_bitmap ();
4842   initiate_cost_update ();
4843   allocno_priorities = (int *) ira_allocate (sizeof (int) * ira_allocnos_num);
4844   sorted_copies = (ira_copy_t *) ira_allocate (ira_copies_num
4845 					       * sizeof (ira_copy_t));
4846 }
4847 
4848 /* Deallocate data used by assign_hard_reg.  */
4849 void
ira_finish_assign(void)4850 ira_finish_assign (void)
4851 {
4852   ira_free (sorted_allocnos);
4853   ira_free_bitmap (consideration_allocno_bitmap);
4854   finish_cost_update ();
4855   ira_free (allocno_priorities);
4856   ira_free (sorted_copies);
4857 }
4858 
4859 
4860 
4861 /* Entry function doing color-based register allocation.  */
4862 static void
color(void)4863 color (void)
4864 {
4865   allocno_stack_vec.create (ira_allocnos_num);
4866   memset (allocated_hardreg_p, 0, sizeof (allocated_hardreg_p));
4867   ira_initiate_assign ();
4868   do_coloring ();
4869   ira_finish_assign ();
4870   allocno_stack_vec.release ();
4871   move_spill_restore ();
4872 }
4873 
4874 
4875 
4876 /* This page contains a simple register allocator without usage of
4877    allocno conflicts.  This is used for fast allocation for -O0.  */
4878 
4879 /* Do register allocation by not using allocno conflicts.  It uses
4880    only allocno live ranges.  The algorithm is close to Chow's
4881    priority coloring.  */
4882 static void
fast_allocation(void)4883 fast_allocation (void)
4884 {
4885   int i, j, k, num, class_size, hard_regno, best_hard_regno, cost, min_cost;
4886   int *costs;
4887 #ifdef STACK_REGS
4888   bool no_stack_reg_p;
4889 #endif
4890   enum reg_class aclass;
4891   machine_mode mode;
4892   ira_allocno_t a;
4893   ira_allocno_iterator ai;
4894   live_range_t r;
4895   HARD_REG_SET conflict_hard_regs, *used_hard_regs;
4896 
4897   sorted_allocnos = (ira_allocno_t *) ira_allocate (sizeof (ira_allocno_t)
4898 						    * ira_allocnos_num);
4899   num = 0;
4900   FOR_EACH_ALLOCNO (a, ai)
4901     sorted_allocnos[num++] = a;
4902   allocno_priorities = (int *) ira_allocate (sizeof (int) * ira_allocnos_num);
4903   setup_allocno_priorities (sorted_allocnos, num);
4904   used_hard_regs = (HARD_REG_SET *) ira_allocate (sizeof (HARD_REG_SET)
4905 						  * ira_max_point);
4906   for (i = 0; i < ira_max_point; i++)
4907     CLEAR_HARD_REG_SET (used_hard_regs[i]);
4908   qsort (sorted_allocnos, num, sizeof (ira_allocno_t),
4909 	 allocno_priority_compare_func);
4910   for (i = 0; i < num; i++)
4911     {
4912       int nr, l;
4913 
4914       a = sorted_allocnos[i];
4915       nr = ALLOCNO_NUM_OBJECTS (a);
4916       CLEAR_HARD_REG_SET (conflict_hard_regs);
4917       for (l = 0; l < nr; l++)
4918 	{
4919 	  ira_object_t obj = ALLOCNO_OBJECT (a, l);
4920 	  conflict_hard_regs |= OBJECT_CONFLICT_HARD_REGS (obj);
4921 	  for (r = OBJECT_LIVE_RANGES (obj); r != NULL; r = r->next)
4922 	    for (j = r->start; j <= r->finish; j++)
4923 	      conflict_hard_regs |= used_hard_regs[j];
4924 	}
4925       aclass = ALLOCNO_CLASS (a);
4926       ALLOCNO_ASSIGNED_P (a) = true;
4927       ALLOCNO_HARD_REGNO (a) = -1;
4928       if (hard_reg_set_subset_p (reg_class_contents[aclass],
4929 				 conflict_hard_regs))
4930 	continue;
4931       mode = ALLOCNO_MODE (a);
4932 #ifdef STACK_REGS
4933       no_stack_reg_p = ALLOCNO_NO_STACK_REG_P (a);
4934 #endif
4935       class_size = ira_class_hard_regs_num[aclass];
4936       costs = ALLOCNO_HARD_REG_COSTS (a);
4937       min_cost = INT_MAX;
4938       best_hard_regno = -1;
4939       for (j = 0; j < class_size; j++)
4940 	{
4941 	  hard_regno = ira_class_hard_regs[aclass][j];
4942 #ifdef STACK_REGS
4943 	  if (no_stack_reg_p && FIRST_STACK_REG <= hard_regno
4944 	      && hard_regno <= LAST_STACK_REG)
4945 	    continue;
4946 #endif
4947 	  if (ira_hard_reg_set_intersection_p (hard_regno, mode, conflict_hard_regs)
4948 	      || (TEST_HARD_REG_BIT
4949 		  (ira_prohibited_class_mode_regs[aclass][mode], hard_regno)))
4950 	    continue;
4951 	  if (costs == NULL)
4952 	    {
4953 	      best_hard_regno = hard_regno;
4954 	      break;
4955 	    }
4956 	  cost = costs[j];
4957 	  if (min_cost > cost)
4958 	    {
4959 	      min_cost = cost;
4960 	      best_hard_regno = hard_regno;
4961 	    }
4962 	}
4963       if (best_hard_regno < 0)
4964 	continue;
4965       ALLOCNO_HARD_REGNO (a) = hard_regno = best_hard_regno;
4966       for (l = 0; l < nr; l++)
4967 	{
4968 	  ira_object_t obj = ALLOCNO_OBJECT (a, l);
4969 	  for (r = OBJECT_LIVE_RANGES (obj); r != NULL; r = r->next)
4970 	    for (k = r->start; k <= r->finish; k++)
4971 	      used_hard_regs[k] |= ira_reg_mode_hard_regset[hard_regno][mode];
4972 	}
4973     }
4974   ira_free (sorted_allocnos);
4975   ira_free (used_hard_regs);
4976   ira_free (allocno_priorities);
4977   if (internal_flag_ira_verbose > 1 && ira_dump_file != NULL)
4978     ira_print_disposition (ira_dump_file);
4979 }
4980 
4981 
4982 
4983 /* Entry function doing coloring.  */
4984 void
ira_color(void)4985 ira_color (void)
4986 {
4987   ira_allocno_t a;
4988   ira_allocno_iterator ai;
4989 
4990   /* Setup updated costs.  */
4991   FOR_EACH_ALLOCNO (a, ai)
4992     {
4993       ALLOCNO_UPDATED_MEMORY_COST (a) = ALLOCNO_MEMORY_COST (a);
4994       ALLOCNO_UPDATED_CLASS_COST (a) = ALLOCNO_CLASS_COST (a);
4995     }
4996   if (ira_conflicts_p)
4997     color ();
4998   else
4999     fast_allocation ();
5000 }
5001