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

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.