LCOV - code coverage report
Current view: top level - gcc - ira-color.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 74.0 % 2754 2037
Test Date: 2026-02-28 14:20:25 Functions: 79.0 % 119 94
Legend: Lines:     hit not hit

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

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.