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