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