LCOV - code coverage report
Current view: top level - gcc - regrename.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 90.5 % 964 872
Test Date: 2026-09-19 16:22:48 Functions: 100.0 % 34 34
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Register renaming for the GNU compiler.
       2              :    Copyright (C) 2000-2026 Free Software Foundation, Inc.
       3              : 
       4              :    This file is part of GCC.
       5              : 
       6              :    GCC is free software; you can redistribute it and/or modify it
       7              :    under the terms of the GNU General Public License as published by
       8              :    the Free Software Foundation; either version 3, or (at your option)
       9              :    any later version.
      10              : 
      11              :    GCC is distributed in the hope that it will be useful, but WITHOUT
      12              :    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
      13              :    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
      14              :    License for more details.
      15              : 
      16              :    You should have received a copy of the GNU General Public License
      17              :    along with GCC; see the file COPYING3.  If not see
      18              :    <http://www.gnu.org/licenses/>.  */
      19              : 
      20              : #include "config.h"
      21              : #include "system.h"
      22              : #include "coretypes.h"
      23              : #include "backend.h"
      24              : #include "target.h"
      25              : #include "rtl.h"
      26              : #include "df.h"
      27              : #include "memmodel.h"
      28              : #include "tm_p.h"
      29              : #include "insn-config.h"
      30              : #include "regs.h"
      31              : #include "emit-rtl.h"
      32              : #include "recog.h"
      33              : #include "addresses.h"
      34              : #include "cfganal.h"
      35              : #include "tree-pass.h"
      36              : #include "function-abi.h"
      37              : #include "regrename.h"
      38              : 
      39              : /* This file implements the RTL register renaming pass of the compiler.  It is
      40              :    a semi-local pass whose goal is to maximize the usage of the register file
      41              :    of the processor by substituting registers for others in the solution given
      42              :    by the register allocator.  The algorithm is as follows:
      43              : 
      44              :      1. Local def/use chains are built: within each basic block, chains are
      45              :         opened and closed; if a chain isn't closed at the end of the block,
      46              :         it is dropped.  We pre-open chains if we have already examined a
      47              :         predecessor block and found chains live at the end which match
      48              :         live registers at the start of the new block.
      49              : 
      50              :      2. We try to combine the local chains across basic block boundaries by
      51              :         comparing chains that were open at the start or end of a block to
      52              :         those in successor/predecessor blocks.
      53              : 
      54              :      3. For each chain, the set of possible renaming registers is computed.
      55              :         This takes into account the renaming of previously processed chains.
      56              :         Optionally, a preferred class is computed for the renaming register.
      57              : 
      58              :      4. The best renaming register is computed for the chain in the above set,
      59              :         using a round-robin allocation.  If a preferred class exists, then the
      60              :         round-robin allocation is done within the class first, if possible.
      61              :         The round-robin allocation of renaming registers itself is global.
      62              : 
      63              :      5. If a renaming register has been found, it is substituted in the chain.
      64              : 
      65              :   Targets can parameterize the pass by specifying a preferred class for the
      66              :   renaming register for a given (super)class of registers to be renamed.
      67              : 
      68              :   DEBUG_INSNs are treated specially, in particular registers occurring inside
      69              :   them are treated as requiring ALL_REGS as a class.  */
      70              : 
      71              : #if HOST_BITS_PER_WIDE_INT <= MAX_RECOG_OPERANDS
      72              : #error "Use a different bitmap implementation for untracked_operands."
      73              : #endif
      74              : 
      75              : enum scan_actions
      76              : {
      77              :   terminate_write,
      78              :   terminate_dead,
      79              :   mark_all_read,
      80              :   mark_read,
      81              :   mark_write,
      82              :   /* mark_access is for marking the destination regs in
      83              :      REG_FRAME_RELATED_EXPR notes (as if they were read) so that the
      84              :      note is updated properly.  */
      85              :   mark_access
      86              : };
      87              : 
      88              : static const char * const scan_actions_name[] =
      89              : {
      90              :   "terminate_write",
      91              :   "terminate_dead",
      92              :   "mark_all_read",
      93              :   "mark_read",
      94              :   "mark_write",
      95              :   "mark_access"
      96              : };
      97              : 
      98              : /* TICK and THIS_TICK are used to record the last time we saw each
      99              :    register.  */
     100              : static int tick[FIRST_PSEUDO_REGISTER];
     101              : static int this_tick = 0;
     102              : 
     103              : static struct obstack rename_obstack;
     104              : 
     105              : /* If nonnull, the code calling into the register renamer requested
     106              :    information about insn operands, and we store it here.  */
     107              : vec<insn_rr_info> insn_rr;
     108              : 
     109              : static void scan_rtx (rtx_insn *, rtx *, enum reg_class, enum scan_actions,
     110              :                       enum op_type);
     111              : static bool build_def_use (basic_block);
     112              : 
     113              : /* The id to be given to the next opened chain.  */
     114              : static unsigned current_id;
     115              : 
     116              : /* A mapping of unique id numbers to chains.  */
     117              : static vec<du_head_p> id_to_chain;
     118              : 
     119              : /* List of currently open chains.  */
     120              : static class du_head *open_chains;
     121              : 
     122              : /* Bitmap of open chains.  The bits set always match the list found in
     123              :    open_chains.  */
     124              : static bitmap_head open_chains_set;
     125              : 
     126              : /* Record the registers being tracked in open_chains.  */
     127              : static HARD_REG_SET live_in_chains;
     128              : 
     129              : /* Record the registers that are live but not tracked.  The intersection
     130              :    between this and live_in_chains is empty.  */
     131              : static HARD_REG_SET live_hard_regs;
     132              : 
     133              : /* Set while scanning RTL if INSN_RR is nonnull, i.e. if the current analysis
     134              :    is for a caller that requires operand data.  Used in
     135              :    record_operand_use.  */
     136              : static operand_rr_info *cur_operand;
     137              : 
     138              : /* Set while scanning RTL if a register dies.  Used to tie chains.  */
     139              : static class du_head *terminated_this_insn;
     140              : 
     141              : /* Return the chain corresponding to id number ID.  Take into account that
     142              :    chains may have been merged.  */
     143              : du_head_p
     144    110303051 : regrename_chain_from_id (unsigned int id)
     145              : {
     146    110303051 :   du_head_p first_chain = id_to_chain[id];
     147    110303051 :   du_head_p chain = first_chain;
     148    175431030 :   while (chain->id != id)
     149              :     {
     150     65127979 :       id = chain->id;
     151     65127979 :       chain = id_to_chain[id];
     152              :     }
     153    110303051 :   first_chain->id = id;
     154    110303051 :   return chain;
     155              : }
     156              : 
     157              : /* Dump all def/use chains, starting at id FROM.  */
     158              : 
     159              : static void
     160          100 : dump_def_use_chain (int from)
     161              : {
     162          100 :   du_head_p head;
     163          100 :   int i;
     164          964 :   FOR_EACH_VEC_ELT_FROM (id_to_chain, i, head, from)
     165              :     {
     166          864 :       struct du_chain *this_du = head->first;
     167              : 
     168          864 :       fprintf (dump_file, "Register %s (%d):",
     169          864 :                reg_names[head->regno], head->nregs);
     170         2590 :       while (this_du)
     171              :         {
     172          862 :           fprintf (dump_file, " %d [%s]", INSN_UID (this_du->insn),
     173          862 :                    reg_class_names[this_du->cl]);
     174          862 :           this_du = this_du->next_use;
     175              :         }
     176          864 :       fprintf (dump_file, "\n");
     177          864 :       head = head->next_chain;
     178              :     }
     179          100 : }
     180              : 
     181              : static void
     182        23342 : free_chain_data (void)
     183              : {
     184        23342 :   int i;
     185        23342 :   du_head_p ptr;
     186      5021656 :   for (i = 0; id_to_chain.iterate (i, &ptr); i++)
     187      4998314 :     bitmap_clear (&ptr->conflicts);
     188              : 
     189        23342 :   id_to_chain.release ();
     190        23342 : }
     191              : 
     192              : /* Walk all chains starting with CHAINS and record that they conflict with
     193              :    another chain whose id is ID.  */
     194              : 
     195              : static void
     196      4998314 : mark_conflict (class du_head *chains, unsigned id)
     197              : {
     198     30307656 :   while (chains)
     199              :     {
     200     25309342 :       bitmap_set_bit (&chains->conflicts, id);
     201     25309342 :       chains = chains->next_chain;
     202              :     }
     203            0 : }
     204              : 
     205              : /* Examine cur_operand, and if it is nonnull, record information about the
     206              :    use THIS_DU which is part of the chain HEAD.  */
     207              : 
     208              : static void
     209      5471037 : record_operand_use (class du_head *head, struct du_chain *this_du)
     210              : {
     211      5471037 :   if (cur_operand == NULL || cur_operand->failed)
     212              :     return;
     213            0 :   if (head->cannot_rename)
     214              :     {
     215            0 :       cur_operand->failed = true;
     216            0 :       return;
     217              :     }
     218            0 :   gcc_assert (cur_operand->n_chains < MAX_REGS_PER_ADDRESS);
     219            0 :   cur_operand->heads[cur_operand->n_chains] = head;
     220            0 :   cur_operand->chains[cur_operand->n_chains++] = this_du;
     221              : }
     222              : 
     223              : /* Create a new chain for THIS_NREGS registers starting at THIS_REGNO,
     224              :    and record its occurrence in *LOC, which is being written to in INSN.
     225              :    This access requires a register of class CL.  */
     226              : 
     227              : static du_head_p
     228      4998314 : create_new_chain (unsigned this_regno, unsigned this_nregs, rtx *loc,
     229              :                   rtx_insn *insn, enum reg_class cl)
     230              : {
     231      4998314 :   class du_head *head = XOBNEW (&rename_obstack, class du_head);
     232      4998314 :   struct du_chain *this_du;
     233      4998314 :   int nregs;
     234              : 
     235      4998314 :   memset ((void *)head, 0, sizeof *head);
     236      4998314 :   head->next_chain = open_chains;
     237      4998314 :   head->regno = this_regno;
     238      4998314 :   head->nregs = this_nregs;
     239              : 
     240      4998314 :   id_to_chain.safe_push (head);
     241      4998314 :   head->id = current_id++;
     242              : 
     243      4998314 :   bitmap_initialize (&head->conflicts, &bitmap_default_obstack);
     244      4998314 :   bitmap_copy (&head->conflicts, &open_chains_set);
     245      4998314 :   mark_conflict (open_chains, head->id);
     246              : 
     247              :   /* Since we're tracking this as a chain now, remove it from the
     248              :      list of conflicting live hard registers and track it in
     249              :      live_in_chains instead.  */
     250      4998314 :   nregs = head->nregs;
     251      9998297 :   while (nregs-- > 0)
     252              :     {
     253      4999983 :       SET_HARD_REG_BIT (live_in_chains, head->regno + nregs);
     254      4999983 :       CLEAR_HARD_REG_BIT (live_hard_regs, head->regno + nregs);
     255              :     }
     256              : 
     257      4998314 :   head->hard_conflicts = live_hard_regs;
     258      4998314 :   bitmap_set_bit (&open_chains_set, head->id);
     259              : 
     260      4998314 :   open_chains = head;
     261              : 
     262      4998314 :   if (dump_file)
     263              :     {
     264          864 :       fprintf (dump_file, "Creating chain %s (%d)",
     265          864 :                reg_names[head->regno], head->id);
     266          864 :       if (insn != NULL_RTX)
     267          136 :         fprintf (dump_file, " at insn %d", INSN_UID (insn));
     268          864 :       fprintf (dump_file, "\n");
     269              :     }
     270              : 
     271      4998314 :   if (insn == NULL_RTX)
     272              :     {
     273      3509641 :       head->first = head->last = NULL;
     274      3509641 :       return head;
     275              :     }
     276              : 
     277      1488673 :   this_du = XOBNEW (&rename_obstack, struct du_chain);
     278      1488673 :   head->first = head->last = this_du;
     279              : 
     280      1488673 :   this_du->next_use = 0;
     281      1488673 :   this_du->loc = loc;
     282      1488673 :   this_du->insn = insn;
     283      1488673 :   this_du->cl = cl;
     284      1488673 :   record_operand_use (head, this_du);
     285      1488673 :   return head;
     286              : }
     287              : 
     288              : /* For a def-use chain HEAD, find which registers overlap its lifetime and
     289              :    set the corresponding bits in *PSET.  */
     290              : 
     291              : static void
     292      1003227 : merge_overlapping_regs (HARD_REG_SET *pset, class du_head *head)
     293              : {
     294      1003227 :   bitmap_iterator bi;
     295      1003227 :   unsigned i;
     296      1003227 :   *pset |= head->hard_conflicts;
     297     48418261 :   EXECUTE_IF_SET_IN_BITMAP (&head->conflicts, 0, i, bi)
     298              :     {
     299     47415034 :       du_head_p other = regrename_chain_from_id (i);
     300     47415034 :       unsigned j = other->nregs;
     301     47415034 :       gcc_assert (other != head);
     302     94843739 :       while (j-- > 0)
     303     47428705 :         SET_HARD_REG_BIT (*pset, other->regno + j);
     304              :     }
     305      1003227 : }
     306              : 
     307              : /* Return true if (reg:MODE REGNO) would be clobbered by a call covered
     308              :    by THIS_HEAD.  */
     309              : 
     310              : static bool
     311     22140815 : call_clobbered_in_chain_p (du_head *this_head, machine_mode mode,
     312              :                            unsigned int regno)
     313              : {
     314     22140815 :   return call_clobbered_in_region_p (this_head->call_abis,
     315            0 :                                      this_head->call_clobber_mask,
     316            0 :                                      mode, regno);
     317              : }
     318              : 
     319              : /* Check if NEW_REG can be the candidate register to rename for
     320              :    REG in THIS_HEAD chain.  THIS_UNAVAILABLE is a set of unavailable hard
     321              :    registers.  */
     322              : 
     323              : static bool
     324     92377276 : check_new_reg_p (int reg ATTRIBUTE_UNUSED, int new_reg,
     325              :                  class du_head *this_head, HARD_REG_SET this_unavailable)
     326              : {
     327     92377276 :   int nregs = 1;
     328     92377276 :   int i;
     329     92377276 :   struct du_chain *tmp;
     330              : 
     331              :   /* See whether new_reg accepts all modes that occur in
     332              :      definition and uses and record the number of regs it would take.  */
     333    343083875 :   for (tmp = this_head->first; tmp; tmp = tmp->next_use)
     334              :     {
     335    295207781 :       int n;
     336              :       /* Completely ignore DEBUG_INSNs, otherwise we can get
     337              :          -fcompare-debug failures.  */
     338    295207781 :       if (DEBUG_INSN_P (tmp->insn))
     339      5193496 :         continue;
     340              : 
     341    290014285 :       if (!targetm.hard_regno_mode_ok (new_reg, GET_MODE (*tmp->loc)))
     342              :         return false;
     343    245513103 :       n = hard_regno_nregs (new_reg, GET_MODE (*tmp->loc));
     344    245513103 :       if (n > nregs)
     345    250706599 :         nregs = n;
     346              :     }
     347              : 
     348     53723438 :   for (i = nregs - 1; i >= 0; --i)
     349     47881938 :     if (TEST_HARD_REG_BIT (this_unavailable, new_reg + i)
     350     17710234 :         || fixed_regs[new_reg + i]
     351      6662343 :         || global_regs[new_reg + i]
     352              :         /* Can't use regs which aren't saved by the prologue.  */
     353      6662343 :         || (! df_regs_ever_live_p (new_reg + i)
     354      1309376 :             && ! crtl->abi->clobbers_full_reg_p (new_reg + i))
     355              : #ifdef LEAF_REGISTERS
     356              :         /* We can't use a non-leaf register if we're in a
     357              :            leaf function.  */
     358              :         || (crtl->is_leaf
     359              :             && !LEAF_REGISTERS[new_reg + i])
     360              : #endif
     361     53927070 :         || ! HARD_REGNO_RENAME_OK (reg + i, new_reg + i))
     362              :       return false;
     363              : 
     364              :   /* See whether it accepts all modes that occur in
     365              :      definition and uses.  */
     366     28144646 :   for (tmp = this_head->first; tmp; tmp = tmp->next_use)
     367              :     {
     368     22303146 :       if (DEBUG_INSN_P (tmp->insn))
     369       162331 :         continue;
     370              : 
     371     22140815 :       if (call_clobbered_in_chain_p (this_head, GET_MODE (*tmp->loc), new_reg))
     372              :         return false;
     373              :     }
     374              : 
     375              :   return true;
     376              : }
     377              : 
     378              : /* For the chain THIS_HEAD, compute and return the best register to
     379              :    rename to.  SUPER_CLASS is the superunion of register classes in
     380              :    the chain.  UNAVAILABLE is a set of registers that cannot be used.
     381              :    OLD_REG is the register currently used for the chain.  BEST_RENAME
     382              :    controls whether the register chosen must be better than the
     383              :    current one or just respect the given constraint.  */
     384              : 
     385              : int
     386      1003227 : find_rename_reg (du_head_p this_head, enum reg_class super_class,
     387              :                  HARD_REG_SET *unavailable, int old_reg, bool best_rename)
     388              : {
     389      1003227 :   bool has_preferred_class;
     390      1003227 :   enum reg_class preferred_class;
     391      1003227 :   int pass;
     392      1003227 :   int best_new_reg = old_reg;
     393              : 
     394              :   /* Mark registers that overlap this chain's lifetime as unavailable.  */
     395      1003227 :   merge_overlapping_regs (unavailable, this_head);
     396              : 
     397              :   /* Compute preferred rename class of super union of all the classes
     398              :      in the chain.  */
     399      1003227 :   preferred_class
     400      1003227 :     = (enum reg_class) targetm.preferred_rename_class (super_class);
     401              : 
     402              :   /* Pick and check the register from the tied chain iff the tied chain
     403              :      is not renamed.  */
     404        69869 :   if (this_head->tied_chain && !this_head->tied_chain->renamed
     405      1061035 :       && check_new_reg_p (old_reg, this_head->tied_chain->regno,
     406              :                           this_head, *unavailable))
     407        14023 :     return this_head->tied_chain->regno;
     408              : 
     409              :   /* If the first non-debug insn is a noop move, then do not rename in this
     410              :      chain as doing so would inhibit removal of the noop move.  */
     411       989322 :   for (struct du_chain *tmp = this_head->first; tmp; tmp = tmp->next_use)
     412       989322 :     if (DEBUG_INSN_P (tmp->insn))
     413          118 :       continue;
     414       989204 :     else if (noop_move_p (tmp->insn))
     415              :       return best_new_reg;
     416              :     else
     417              :       break;
     418              : 
     419              :   /* If PREFERRED_CLASS is not NO_REGS, we iterate in the first pass
     420              :      over registers that belong to PREFERRED_CLASS and try to find the
     421              :      best register within the class.  If that failed, we iterate in
     422              :      the second pass over registers that don't belong to the class.
     423              :      If PREFERRED_CLASS is NO_REGS, we iterate over all registers in
     424              :      ascending order without any preference.  */
     425       982122 :   has_preferred_class = (preferred_class != NO_REGS);
     426      1964244 :   for (pass = (has_preferred_class ? 0 : 1); pass < 2; pass++)
     427              :     {
     428              :       int new_reg;
     429     93301590 :       for (new_reg = 0; new_reg < FIRST_PSEUDO_REGISTER; new_reg++)
     430              :         {
     431     92319468 :           if (has_preferred_class
     432     92319468 :               && (pass == 0)
     433            0 :               != TEST_HARD_REG_BIT (reg_class_contents[preferred_class],
     434              :                                     new_reg))
     435            0 :             continue;
     436              : 
     437     92319468 :           if (!check_new_reg_p (old_reg, new_reg, this_head, *unavailable))
     438     86491991 :             continue;
     439              : 
     440      5827477 :           if (!best_rename)
     441              :             return new_reg;
     442              : 
     443              :           /* In the first pass, we force the renaming of registers that
     444              :              don't belong to PREFERRED_CLASS to registers that do, even
     445              :              though the latters were used not very long ago.  */
     446      5827477 :           if ((pass == 0
     447            0 :               && !TEST_HARD_REG_BIT (reg_class_contents[preferred_class],
     448              :                                      best_new_reg))
     449      5827477 :               || tick[best_new_reg] > tick[new_reg])
     450              :             best_new_reg = new_reg;
     451              :         }
     452       982122 :       if (pass == 0 && best_new_reg != old_reg)
     453              :         break;
     454              :     }
     455              :   return best_new_reg;
     456              : }
     457              : 
     458              : /* Iterate over elements in the chain HEAD in order to:
     459              :    1. Count number of uses, storing it in *PN_USES.
     460              :    2. Narrow the set of registers we can use for renaming, adding
     461              :       unavailable registers to *PUNAVAILABLE, which must be
     462              :       initialized by the caller.
     463              :    3. Compute the superunion of register classes in this chain
     464              :       and return it.  */
     465              : reg_class
     466      4547429 : regrename_find_superclass (du_head_p head, int *pn_uses,
     467              :                            HARD_REG_SET *punavailable)
     468              : {
     469      4547429 :   int n_uses = 0;
     470      4547429 :   reg_class super_class = NO_REGS;
     471      9408401 :   for (du_chain *tmp = head->first; tmp; tmp = tmp->next_use)
     472              :     {
     473      4860972 :       if (DEBUG_INSN_P (tmp->insn))
     474        86740 :         continue;
     475      4774232 :       n_uses++;
     476      4774232 :       *punavailable |= ~reg_class_contents[tmp->cl];
     477      4774232 :       super_class
     478      4774232 :         = reg_class_superunion[(int) super_class][(int) tmp->cl];
     479              :     }
     480      4547429 :   *pn_uses = n_uses;
     481      4547429 :   return super_class;
     482              : }
     483              : 
     484              : /* Perform register renaming on the current function.  */
     485              : static void
     486        23342 : rename_chains (void)
     487              : {
     488        23342 :   HARD_REG_SET unavailable;
     489        23342 :   du_head_p this_head;
     490        23342 :   int i;
     491              : 
     492        23342 :   memset (tick, 0, sizeof tick);
     493              : 
     494        23342 :   CLEAR_HARD_REG_SET (unavailable);
     495              :   /* Don't clobber traceback for noreturn functions.  */
     496        23342 :   if (frame_pointer_needed)
     497              :     {
     498          757 :       add_to_hard_reg_set (&unavailable, Pmode, FRAME_POINTER_REGNUM);
     499          716 :       if (!HARD_FRAME_POINTER_IS_FRAME_POINTER)
     500          716 :         add_to_hard_reg_set (&unavailable, Pmode, HARD_FRAME_POINTER_REGNUM);
     501              :     }
     502              : 
     503      5021656 :   FOR_EACH_VEC_ELT (id_to_chain, i, this_head)
     504              :     {
     505      4998314 :       int best_new_reg;
     506      4998314 :       int n_uses;
     507      4998314 :       HARD_REG_SET this_unavailable;
     508      4998314 :       int reg = this_head->regno;
     509              : 
     510      4998314 :       if (this_head->cannot_rename)
     511      4464634 :         continue;
     512              : 
     513      4624969 :       if (fixed_regs[reg] || global_regs[reg]
     514      4623938 :           || (!HARD_FRAME_POINTER_IS_FRAME_POINTER && frame_pointer_needed
     515       896431 :               && reg == HARD_FRAME_POINTER_REGNUM)
     516              :           || (HARD_FRAME_POINTER_IS_FRAME_POINTER && frame_pointer_needed
     517              :               && reg == FRAME_POINTER_REGNUM))
     518        77540 :         continue;
     519              : 
     520      4547429 :       this_unavailable = unavailable;
     521              : 
     522      4547429 :       reg_class super_class = regrename_find_superclass (this_head, &n_uses,
     523              :                                                          &this_unavailable);
     524      4547429 :       if (n_uses < 2)
     525      3544202 :         continue;
     526              : 
     527      1003227 :       best_new_reg = find_rename_reg (this_head, super_class,
     528              :                                       &this_unavailable, reg, true);
     529              : 
     530      1003227 :       if (dump_file)
     531              :         {
     532          110 :           fprintf (dump_file, "Register %s in insn %d",
     533          110 :                    reg_names[reg], INSN_UID (this_head->first->insn));
     534          110 :           if (this_head->call_abis)
     535            4 :             fprintf (dump_file, " crosses a call");
     536              :         }
     537              : 
     538      1003227 :       if (best_new_reg == reg)
     539              :         {
     540       469547 :           tick[reg] = ++this_tick;
     541       469547 :           if (dump_file)
     542           50 :             fprintf (dump_file, "; no available better choice\n");
     543       469547 :           continue;
     544              :         }
     545              : 
     546       533680 :       if (regrename_do_replace (this_head, best_new_reg))
     547              :         {
     548       533635 :           if (dump_file)
     549           60 :             fprintf (dump_file, ", renamed as %s\n", reg_names[best_new_reg]);
     550       533635 :           tick[best_new_reg] = ++this_tick;
     551       533635 :           df_set_regs_ever_live (best_new_reg, true);
     552              :         }
     553              :       else
     554              :         {
     555           45 :           if (dump_file)
     556            0 :             fprintf (dump_file, ", renaming as %s failed\n",
     557              :                      reg_names[best_new_reg]);
     558           45 :           tick[reg] = ++this_tick;
     559              :         }
     560              :     }
     561        23342 : }
     562              : 
     563              : /* A structure to record information for each hard register at the start of
     564              :    a basic block.  */
     565              : struct incoming_reg_info {
     566              :   /* Holds the number of registers used in the chain that gave us information
     567              :      about this register.  Zero means no information known yet, while a
     568              :      negative value is used for something that is part of, but not the first
     569              :      register in a multi-register value.  */
     570              :   int nregs;
     571              :   /* Set to true if we have accesses that conflict in the number of registers
     572              :      used.  */
     573              :   bool unusable;
     574              : };
     575              : 
     576              : /* A structure recording information about each basic block.  It is saved
     577              :    and restored around basic block boundaries.
     578              :    A pointer to such a structure is stored in each basic block's aux field
     579              :    during regrename_analyze, except for blocks we know can't be optimized
     580              :    (such as entry and exit blocks).  */
     581              : class bb_rename_info
     582              : {
     583              : public:
     584              :   /* The basic block corresponding to this structure.  */
     585              :   basic_block bb;
     586              :   /* Copies of the global information.  */
     587              :   bitmap_head open_chains_set;
     588              :   bitmap_head incoming_open_chains_set;
     589              :   struct incoming_reg_info incoming[FIRST_PSEUDO_REGISTER];
     590              : };
     591              : 
     592              : /* Initialize a rename_info structure P for basic block BB, which starts a new
     593              :    scan.  */
     594              : static void
     595       615927 : init_rename_info (class bb_rename_info *p, basic_block bb)
     596              : {
     597       615927 :   int i;
     598       615927 :   df_ref def;
     599       615927 :   HARD_REG_SET start_chains_set;
     600              : 
     601       615927 :   p->bb = bb;
     602       615927 :   bitmap_initialize (&p->open_chains_set, &bitmap_default_obstack);
     603       615927 :   bitmap_initialize (&p->incoming_open_chains_set, &bitmap_default_obstack);
     604              : 
     605       615927 :   open_chains = NULL;
     606       615927 :   bitmap_clear (&open_chains_set);
     607              : 
     608      2463708 :   CLEAR_HARD_REG_SET (live_in_chains);
     609       615927 :   REG_SET_TO_HARD_REG_SET (live_hard_regs, df_get_live_in (bb));
     610      1232253 :   FOR_EACH_ARTIFICIAL_DEF (def, bb->index)
     611          399 :     if (DF_REF_FLAGS (def) & DF_REF_AT_TOP)
     612          399 :       SET_HARD_REG_BIT (live_hard_regs, DF_REF_REGNO (def));
     613              : 
     614              :   /* Open chains based on information from (at least one) predecessor
     615              :      block.  This gives us a chance later on to combine chains across
     616              :      basic block boundaries.  Inconsistencies (in access sizes) will
     617              :      be caught normally and dealt with conservatively by disabling the
     618              :      chain for renaming, and there is no risk of losing optimization
     619              :      opportunities by opening chains either: if we did not open the
     620              :      chains, we'd have to track the live register as a hard reg, and
     621              :      we'd be unable to rename it in any case.  */
     622     58513065 :   CLEAR_HARD_REG_SET (start_chains_set);
     623     58513065 :   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
     624              :     {
     625     57897138 :       struct incoming_reg_info *iri = p->incoming + i;
     626      3990969 :       if (iri->nregs > 0 && !iri->unusable
     627     65879076 :           && range_in_hard_reg_set_p (live_hard_regs, i, iri->nregs))
     628              :         {
     629      3509606 :           SET_HARD_REG_BIT (start_chains_set, i);
     630      3509606 :           remove_range_from_hard_reg_set (&live_hard_regs, i, iri->nregs);
     631              :         }
     632              :     }
     633       615927 :   struct incoming_reg_info *iri;
     634       615927 :   unsigned int j = 0;
     635       615927 :   hard_reg_set_iterator hrsi;
     636      4125533 :   EXECUTE_IF_SET_IN_HARD_REG_SET (start_chains_set, 0, j, hrsi)
     637              :     {
     638      3509606 :       du_head_p chain;
     639      3509606 :       if (dump_file)
     640          728 :         fprintf (dump_file, "opening incoming chain\n");
     641      3509606 :       iri = p->incoming + j;
     642      3509606 :       chain = create_new_chain (j, iri->nregs, NULL, NULL, NO_REGS);
     643      3509606 :       bitmap_set_bit (&p->incoming_open_chains_set, chain->id);
     644              :     }
     645       615927 : }
     646              : 
     647              : /* Record in RI that the block corresponding to it has an incoming
     648              :    live value, described by CHAIN.  */
     649              : static void
     650      6076208 : set_incoming_from_chain (class bb_rename_info *ri, du_head_p chain)
     651              : {
     652      6076208 :   int i;
     653      6076208 :   int incoming_nregs = ri->incoming[chain->regno].nregs;
     654      6076208 :   int nregs;
     655              : 
     656              :   /* If we've recorded the same information before, everything is fine.  */
     657      6076208 :   if (incoming_nregs == chain->nregs)
     658              :     {
     659      2083208 :       if (dump_file)
     660          358 :         fprintf (dump_file, "reg %d/%d already recorded\n",
     661              :                  chain->regno, chain->nregs);
     662              :       return;
     663              :     }
     664              : 
     665              :   /* If we have no information for any of the involved registers, update
     666              :      the incoming array.  */
     667              :   nregs = chain->nregs;
     668      7986000 :   while (nregs-- > 0)
     669      3993000 :     if (ri->incoming[chain->regno + nregs].nregs != 0
     670      3993000 :         || ri->incoming[chain->regno + nregs].unusable)
     671              :       break;
     672      3993000 :   if (nregs < 0)
     673              :     {
     674      3993000 :       nregs = chain->nregs;
     675      3993000 :       ri->incoming[chain->regno].nregs = nregs;
     676      3993000 :       while (nregs-- > 1)
     677            0 :         ri->incoming[chain->regno + nregs].nregs = -nregs;
     678      3993000 :       if (dump_file)
     679          840 :         fprintf (dump_file, "recorded reg %d/%d\n",
     680              :                  chain->regno, chain->nregs);
     681              :       return;
     682              :     }
     683              : 
     684              :   /* There must be some kind of conflict.  Prevent both the old and
     685              :      new ranges from being used.  */
     686            0 :   if (incoming_nregs < 0)
     687            0 :     ri->incoming[chain->regno + incoming_nregs].unusable = true;
     688            0 :   for (i = 0; i < chain->nregs; i++)
     689            0 :     ri->incoming[chain->regno + i].unusable = true;
     690              : }
     691              : 
     692              : /* Merge the two chains C1 and C2 so that all conflict information is
     693              :    recorded and C1, and the id of C2 is changed to that of C1.  */
     694              : static void
     695      5082341 : merge_chains (du_head_p c1, du_head_p c2)
     696              : {
     697      5082341 :   if (c1 == c2)
     698              :     return;
     699              : 
     700      3645773 :   if (c2->first != NULL)
     701              :     {
     702      1110760 :       if (c1->first == NULL)
     703        48215 :         c1->first = c2->first;
     704              :       else
     705      1062545 :         c1->last->next_use = c2->first;
     706      1110760 :       c1->last = c2->last;
     707              :     }
     708              : 
     709      3645773 :   c2->first = c2->last = NULL;
     710      3645773 :   c2->id = c1->id;
     711              : 
     712      3645773 :   c1->hard_conflicts |= c2->hard_conflicts;
     713      3645773 :   bitmap_ior_into (&c1->conflicts, &c2->conflicts);
     714              : 
     715      3645773 :   c1->call_clobber_mask |= c2->call_clobber_mask;
     716      3645773 :   c1->call_abis |= c2->call_abis;
     717      3645773 :   c1->cannot_rename |= c2->cannot_rename;
     718              : }
     719              : 
     720              : /* Analyze the current function and build chains for renaming.
     721              :    If INCLUDE_ALL_BLOCKS_P is set to true, process all blocks,
     722              :    ignoring BB_DISABLE_SCHEDULE.  The default value is true.  */
     723              : 
     724              : void
     725        23342 : regrename_analyze (bitmap bb_mask, bool include_all_block_p)
     726              : {
     727        23342 :   class bb_rename_info *rename_info;
     728        23342 :   int i;
     729        23342 :   basic_block bb;
     730        23342 :   int n_bbs;
     731        23342 :   int *inverse_postorder;
     732              : 
     733        23342 :   inverse_postorder = XNEWVEC (int, last_basic_block_for_fn (cfun));
     734        23342 :   n_bbs = pre_and_rev_post_order_compute (NULL, inverse_postorder, false);
     735              : 
     736              :   /* Gather some information about the blocks in this function.  */
     737        23342 :   rename_info = XCNEWVEC (class bb_rename_info, n_basic_blocks_for_fn (cfun));
     738        23342 :   i = 0;
     739       639269 :   FOR_EACH_BB_FN (bb, cfun)
     740              :     {
     741       615927 :       class bb_rename_info *ri = rename_info + i;
     742       615927 :       ri->bb = bb;
     743       615927 :       if (bb_mask != NULL && !bitmap_bit_p (bb_mask, bb->index))
     744            0 :         bb->aux = NULL;
     745              :       else
     746       615927 :         bb->aux = ri;
     747       615927 :       i++;
     748              :     }
     749              : 
     750        23342 :   current_id = 0;
     751        23342 :   id_to_chain.create (0);
     752        23342 :   bitmap_initialize (&open_chains_set, &bitmap_default_obstack);
     753              : 
     754              :   /* The order in which we visit blocks ensures that whenever
     755              :      possible, we only process a block after at least one of its
     756              :      predecessors, which provides a "seeding" effect to make the logic
     757              :      in set_incoming_from_chain and init_rename_info useful.  */
     758              : 
     759       639269 :   for (i = 0; i < n_bbs; i++)
     760              :     {
     761       615927 :       basic_block bb1 = BASIC_BLOCK_FOR_FN (cfun, inverse_postorder[i]);
     762       615927 :       class bb_rename_info *this_info;
     763       615927 :       bool success;
     764       615927 :       edge e;
     765       615927 :       edge_iterator ei;
     766       615927 :       int old_length = id_to_chain.length ();
     767              : 
     768       615927 :       this_info = (class bb_rename_info *) bb1->aux;
     769       615927 :       if (this_info == NULL)
     770            0 :         continue;
     771              : 
     772       615927 :       if (dump_file)
     773          100 :         fprintf (dump_file, "\nprocessing block %d:\n", bb1->index);
     774              : 
     775       615927 :       if (!include_all_block_p && (bb1->flags & BB_DISABLE_SCHEDULE) != 0)
     776              :         {
     777            0 :           if (dump_file)
     778            0 :             fprintf (dump_file, "avoid disrupting the sms schedule of bb %d\n",
     779              :                      bb1->index);
     780            0 :           continue;
     781              :         }
     782              : 
     783       615927 :       init_rename_info (this_info, bb1);
     784              : 
     785       615927 :       success = build_def_use (bb1);
     786       615927 :       if (!success)
     787              :         {
     788            0 :           if (dump_file)
     789            0 :             fprintf (dump_file, "failed\n");
     790            0 :           bb1->aux = NULL;
     791            0 :           id_to_chain.truncate (old_length);
     792            0 :           current_id = old_length;
     793            0 :           bitmap_clear (&this_info->incoming_open_chains_set);
     794            0 :           open_chains = NULL;
     795            0 :           if (insn_rr.exists ())
     796              :             {
     797            0 :               rtx_insn *insn;
     798            0 :               FOR_BB_INSNS (bb1, insn)
     799              :                 {
     800            0 :                   insn_rr_info *p = &insn_rr[INSN_UID (insn)];
     801            0 :                   p->op_info = NULL;
     802              :                 }
     803              :             }
     804            0 :           continue;
     805            0 :         }
     806              : 
     807       615927 :       if (dump_file)
     808          100 :         dump_def_use_chain (old_length);
     809       615927 :       bitmap_copy (&this_info->open_chains_set, &open_chains_set);
     810              : 
     811              :       /* Add successor blocks to the worklist if necessary, and record
     812              :          data about our own open chains at the end of this block, which
     813              :          will be used to pre-open chains when processing the successors.  */
     814      1569364 :       FOR_EACH_EDGE (e, ei, bb1->succs)
     815              :         {
     816       953437 :           class bb_rename_info *dest_ri;
     817       953437 :           class du_head *chain;
     818              : 
     819       953437 :           if (dump_file)
     820          152 :             fprintf (dump_file, "successor block %d\n", e->dest->index);
     821              : 
     822       953437 :           if (e->flags & (EDGE_EH | EDGE_ABNORMAL))
     823         3463 :             continue;
     824       949974 :           dest_ri = (class bb_rename_info *)e->dest->aux;
     825       949974 :           if (dest_ri == NULL)
     826        22941 :             continue;
     827      7003241 :           for (chain = open_chains; chain; chain = chain->next_chain)
     828      6076208 :             set_incoming_from_chain (dest_ri, chain);
     829              :         }
     830              :     }
     831              : 
     832        23342 :   free (inverse_postorder);
     833              : 
     834              :   /* Now, combine the chains data we have gathered across basic block
     835              :      boundaries.
     836              : 
     837              :      For every basic block, there may be chains open at the start, or at the
     838              :      end.  Rather than exclude them from renaming, we look for open chains
     839              :      with matching registers at the other side of the CFG edge.
     840              : 
     841              :      For a given chain using register R, open at the start of block B, we
     842              :      must find an open chain using R on the other side of every edge leading
     843              :      to B, if the register is live across this edge.  In the code below,
     844              :      N_PREDS_USED counts the number of edges where the register is live, and
     845              :      N_PREDS_JOINED counts those where we found an appropriate chain for
     846              :      joining.
     847              : 
     848              :      We perform the analysis for both incoming and outgoing edges, but we
     849              :      only need to merge once (in the second part, after verifying outgoing
     850              :      edges).  */
     851       639269 :   FOR_EACH_BB_FN (bb, cfun)
     852              :     {
     853       615927 :       class bb_rename_info *bb_ri = (class bb_rename_info *) bb->aux;
     854       615927 :       unsigned j;
     855       615927 :       bitmap_iterator bi;
     856              : 
     857       615927 :       if (bb_ri == NULL)
     858            0 :         continue;
     859              : 
     860       615927 :       if (dump_file)
     861          100 :         fprintf (dump_file, "processing bb %d in edges\n", bb->index);
     862              : 
     863      4125533 :       EXECUTE_IF_SET_IN_BITMAP (&bb_ri->incoming_open_chains_set, 0, j, bi)
     864              :         {
     865      3509606 :           edge e;
     866      3509606 :           edge_iterator ei;
     867      3509606 :           class du_head *chain = regrename_chain_from_id (j);
     868      3509606 :           int n_preds_used = 0, n_preds_joined = 0;
     869              : 
     870      8599262 :           FOR_EACH_EDGE (e, ei, bb->preds)
     871              :             {
     872              :               class bb_rename_info *src_ri;
     873              :               unsigned k;
     874              :               bitmap_iterator bi2;
     875              :               HARD_REG_SET live;
     876     15268968 :               bool success = false;
     877              : 
     878      5089656 :               REG_SET_TO_HARD_REG_SET (live, df_get_live_out (e->src));
     879     10179312 :               if (!range_overlaps_hard_reg_set_p (live, chain->regno,
     880              :                                                   chain->nregs))
     881          109 :                 continue;
     882      5089583 :               n_preds_used++;
     883              : 
     884      5089583 :               if (e->flags & (EDGE_EH | EDGE_ABNORMAL))
     885           36 :                 continue;
     886              : 
     887      5089547 :               src_ri = (class bb_rename_info *)e->src->aux;
     888      5089547 :               if (src_ri == NULL)
     889            0 :                 continue;
     890              : 
     891     28475510 :               EXECUTE_IF_SET_IN_BITMAP (&src_ri->open_chains_set,
     892              :                                         0, k, bi2)
     893              :                 {
     894     28468271 :                   class du_head *outgoing_chain = regrename_chain_from_id (k);
     895              : 
     896     28468271 :                   if (outgoing_chain->regno == chain->regno
     897      5082308 :                       && outgoing_chain->nregs == chain->nregs)
     898              :                     {
     899      5082308 :                       n_preds_joined++;
     900      5082308 :                       success = true;
     901      5082308 :                       break;
     902              :                     }
     903              :                 }
     904      5089547 :               if (!success && dump_file)
     905            4 :                 fprintf (dump_file, "failure to match with pred block %d\n",
     906            4 :                          e->src->index);
     907              :             }
     908      3509606 :           if (n_preds_joined < n_preds_used)
     909              :             {
     910         4648 :               if (dump_file)
     911            4 :                 fprintf (dump_file, "cannot rename chain %d\n", j);
     912         4648 :               chain->cannot_rename = 1;
     913              :             }
     914              :         }
     915              :     }
     916       639269 :   FOR_EACH_BB_FN (bb, cfun)
     917              :     {
     918       615927 :       class bb_rename_info *bb_ri = (class bb_rename_info *) bb->aux;
     919       615927 :       unsigned j;
     920       615927 :       bitmap_iterator bi;
     921              : 
     922       615927 :       if (bb_ri == NULL)
     923            0 :         continue;
     924              : 
     925       615927 :       if (dump_file)
     926          100 :         fprintf (dump_file, "processing bb %d out edges\n", bb->index);
     927              : 
     928      4310617 :       EXECUTE_IF_SET_IN_BITMAP (&bb_ri->open_chains_set, 0, j, bi)
     929              :         {
     930      3694690 :           edge e;
     931      3694690 :           edge_iterator ei;
     932      3694690 :           class du_head *chain = regrename_chain_from_id (j);
     933      3694690 :           int n_succs_used = 0, n_succs_joined = 0;
     934              : 
     935      9808731 :           FOR_EACH_EDGE (e, ei, bb->succs)
     936              :             {
     937     18342123 :               bool printed = false;
     938              :               class bb_rename_info *dest_ri;
     939              :               unsigned k;
     940              :               bitmap_iterator bi2;
     941              :               HARD_REG_SET live;
     942              : 
     943      6114041 :               REG_SET_TO_HARD_REG_SET (live, df_get_live_in (e->dest));
     944     12228082 :               if (!range_overlaps_hard_reg_set_p (live, chain->regno,
     945              :                                                   chain->nregs))
     946      1030770 :                 continue;
     947              : 
     948      5120232 :               n_succs_used++;
     949              : 
     950      5120232 :               dest_ri = (class bb_rename_info *)e->dest->aux;
     951      5120232 :               if (dest_ri == NULL)
     952        36961 :                 continue;
     953              : 
     954     27216380 :               EXECUTE_IF_SET_IN_BITMAP (&dest_ri->incoming_open_chains_set,
     955              :                                         0, k, bi2)
     956              :                 {
     957     27215450 :                   class du_head *incoming_chain = regrename_chain_from_id (k);
     958              : 
     959     27215450 :                   if (incoming_chain->regno == chain->regno
     960      5082341 :                       && incoming_chain->nregs == chain->nregs)
     961              :                     {
     962      5082341 :                       if (dump_file)
     963              :                         {
     964         1072 :                           if (!printed)
     965         1072 :                             fprintf (dump_file,
     966              :                                      "merging blocks for edge %d -> %d\n",
     967         1072 :                                      e->src->index, e->dest->index);
     968         1072 :                           printed = true;
     969         1072 :                           fprintf (dump_file,
     970              :                                    "  merging chains %d (->%d) and %d (->%d) [%s]\n",
     971              :                                    k, incoming_chain->id, j, chain->id,
     972         1072 :                                    reg_names[incoming_chain->regno]);
     973              :                         }
     974              : 
     975      5082341 :                       merge_chains (chain, incoming_chain);
     976      5082341 :                       n_succs_joined++;
     977      5082341 :                       break;
     978              :                     }
     979              :                 }
     980              :             }
     981      3694690 :           if (n_succs_joined < n_succs_used)
     982              :             {
     983        37817 :               if (dump_file)
     984           12 :                 fprintf (dump_file, "cannot rename chain %d\n",
     985              :                          j);
     986        37817 :               chain->cannot_rename = 1;
     987              :             }
     988              :         }
     989              :     }
     990              : 
     991        23342 :   free (rename_info);
     992              : 
     993       639269 :   FOR_EACH_BB_FN (bb, cfun)
     994       615927 :     bb->aux = NULL;
     995        23342 : }
     996              : 
     997              : /* Attempt to replace all uses of the register in the chain beginning with
     998              :    HEAD with REG.  Returns true on success and false if the replacement is
     999              :    rejected because the insns would not validate.  The latter can happen
    1000              :    e.g. if a match_parallel predicate enforces restrictions on register
    1001              :    numbering in its subpatterns.  */
    1002              : 
    1003              : bool
    1004       533680 : regrename_do_replace (class du_head *head, int reg)
    1005              : {
    1006       533680 :   struct du_chain *chain;
    1007       533680 :   unsigned int base_regno = head->regno;
    1008       533680 :   machine_mode mode;
    1009       533680 :   rtx last_reg = NULL_RTX, last_repl = NULL_RTX;
    1010              : 
    1011      2542543 :   for (chain = head->first; chain; chain = chain->next_use)
    1012              :     {
    1013      2008863 :       unsigned int regno = ORIGINAL_REGNO (*chain->loc);
    1014      2008863 :       class reg_attrs *attr = REG_ATTRS (*chain->loc);
    1015      2008863 :       int reg_ptr = REG_POINTER (*chain->loc);
    1016              : 
    1017      2008863 :       if (DEBUG_INSN_P (chain->insn) && REGNO (*chain->loc) != base_regno)
    1018          300 :         validate_change (chain->insn, &(INSN_VAR_LOCATION_LOC (chain->insn)),
    1019              :                          gen_rtx_UNKNOWN_VAR_LOC (), true);
    1020              :       else
    1021              :         {
    1022      2008563 :           if (*chain->loc != last_reg)
    1023              :             {
    1024      1114628 :               last_repl = gen_raw_REG (GET_MODE (*chain->loc), reg);
    1025      1114628 :               if (regno >= FIRST_PSEUDO_REGISTER)
    1026      1094495 :                 ORIGINAL_REGNO (last_repl) = regno;
    1027      1114628 :               REG_ATTRS (last_repl) = attr;
    1028      1114628 :               REG_POINTER (last_repl) = reg_ptr;
    1029      1114628 :               last_reg = *chain->loc;
    1030              :             }
    1031      2008563 :           validate_change (chain->insn, chain->loc, last_repl, true);
    1032              :         }
    1033              :     }
    1034              : 
    1035       533680 :   if (!apply_change_group ())
    1036              :     return false;
    1037              : 
    1038       533635 :   mode = GET_MODE (*head->first->loc);
    1039       533635 :   head->renamed = 1;
    1040       533635 :   head->regno = reg;
    1041       533635 :   head->nregs = hard_regno_nregs (reg, mode);
    1042       533635 :   return true;
    1043              : }
    1044              : 
    1045              : 
    1046              : /* True if we found a register with a size mismatch, which means that we
    1047              :    can't track its lifetime accurately.  If so, we abort the current block
    1048              :    without renaming.  */
    1049              : static bool fail_current_block;
    1050              : 
    1051              : /* Return true if OP is a reg for which all bits are set in PSET, false
    1052              :    if all bits are clear.
    1053              :    In other cases, set fail_current_block and return false.  */
    1054              : 
    1055              : static bool
    1056      2581034 : verify_reg_in_set (rtx op, HARD_REG_SET *pset)
    1057              : {
    1058      2581034 :   unsigned regno, nregs;
    1059      2581034 :   bool all_live, all_dead;
    1060      2581034 :   if (!REG_P (op))
    1061              :     return false;
    1062              : 
    1063      2571006 :   regno = REGNO (op);
    1064      2571006 :   nregs = REG_NREGS (op);
    1065      2571006 :   all_live = all_dead = true;
    1066      5142046 :   while (nregs-- > 0)
    1067      2571040 :     if (TEST_HARD_REG_BIT (*pset, regno + nregs))
    1068              :       all_dead = false;
    1069              :     else
    1070      1243406 :       all_live = false;
    1071      2571006 :   if (!all_dead && !all_live)
    1072              :     {
    1073            0 :       fail_current_block = true;
    1074            0 :       return false;
    1075              :     }
    1076              :   return all_live;
    1077              : }
    1078              : 
    1079              : /* Return true if OP is a reg that is being tracked already in some form.
    1080              :    May set fail_current_block if it sees an unhandled case of overlap.  */
    1081              : 
    1082              : static bool
    1083      1325581 : verify_reg_tracked (rtx op)
    1084              : {
    1085      1325581 :   return (verify_reg_in_set (op, &live_hard_regs)
    1086      1325581 :           || verify_reg_in_set (op, &live_in_chains));
    1087              : }
    1088              : 
    1089              : /* Called through note_stores.  DATA points to a rtx_code, either SET or
    1090              :    CLOBBER, which tells us which kind of rtx to look at.  If we have a
    1091              :    match, record the set register in live_hard_regs and in the hard_conflicts
    1092              :    bitmap of open chains.  */
    1093              : 
    1094              : static void
    1095      8569644 : note_sets_clobbers (rtx x, const_rtx set, void *data)
    1096              : {
    1097      8569644 :   enum rtx_code code = *(enum rtx_code *)data;
    1098      8569644 :   class du_head *chain;
    1099              : 
    1100      8569644 :   if (GET_CODE (x) == SUBREG)
    1101            0 :     x = SUBREG_REG (x);
    1102      8569644 :   if (!REG_P (x) || GET_CODE (set) != code)
    1103              :     return;
    1104              :   /* There must not be pseudos at this point.  */
    1105      1004165 :   gcc_assert (HARD_REGISTER_P (x));
    1106      1004165 :   add_to_hard_reg_set (&live_hard_regs, GET_MODE (x), REGNO (x));
    1107      7817322 :   for (chain = open_chains; chain; chain = chain->next_chain)
    1108      6813157 :     add_to_hard_reg_set (&chain->hard_conflicts, GET_MODE (x), REGNO (x));
    1109              : }
    1110              : 
    1111              : static void
    1112     18282596 : scan_rtx_reg (rtx_insn *insn, rtx *loc, enum reg_class cl, enum scan_actions action,
    1113              :               enum op_type type)
    1114              : {
    1115     18282596 :   class du_head **p;
    1116     18282596 :   rtx x = *loc;
    1117     18282596 :   unsigned this_regno = REGNO (x);
    1118     18282596 :   int this_nregs = REG_NREGS (x);
    1119              : 
    1120              :   /* Do not process write actions for the second instruction of
    1121              :      a macro-fused pair of two single_sets.  */
    1122     18282596 :   if ((action == mark_write || action == terminate_write)
    1123     18282596 :         && single_output_fused_pair_p (insn))
    1124              :     return;
    1125              : 
    1126     18282596 :   if (action == mark_write)
    1127              :     {
    1128      1488673 :       if (type == OP_OUT)
    1129              :         {
    1130      1488673 :           du_head_p c;
    1131      1488673 :           rtx pat = PATTERN (insn);
    1132              : 
    1133      1488673 :           c = create_new_chain (this_regno, this_nregs, loc, insn, cl);
    1134              : 
    1135              :           /* We try to tie chains in a move instruction for
    1136              :              a single output.  */
    1137      1488673 :           if (recog_data.n_operands == 2
    1138      1341163 :               && GET_CODE (pat) == SET
    1139      1262270 :               && GET_CODE (SET_DEST (pat)) == REG
    1140      1262270 :               && GET_CODE (SET_SRC (pat)) == REG
    1141       211556 :               && terminated_this_insn
    1142        65310 :               && terminated_this_insn->nregs
    1143        65310 :                  == REG_NREGS (recog_data.operand[1]))
    1144              :             {
    1145        65258 :               gcc_assert (terminated_this_insn->regno
    1146              :                           == REGNO (recog_data.operand[1]));
    1147              : 
    1148        65258 :               c->tied_chain = terminated_this_insn;
    1149        65258 :               terminated_this_insn->tied_chain = c;
    1150              : 
    1151        65258 :               if (dump_file)
    1152            4 :                 fprintf (dump_file, "Tying chain %s (%d) with %s (%d)\n",
    1153            4 :                          reg_names[c->regno], c->id,
    1154              :                          reg_names[terminated_this_insn->regno],
    1155              :                          terminated_this_insn->id);
    1156              :             }
    1157              :         }
    1158              : 
    1159              :       return;
    1160              :     }
    1161              : 
    1162     16793923 :   if ((type == OP_OUT) != (action == terminate_write || action == mark_access)
    1163     18282626 :         && ! (type == OP_OUT && action == mark_read
    1164      1488703 :               && single_output_fused_pair_p (insn)))
    1165              :     return;
    1166              : 
    1167     89119809 :   for (p = &open_chains; *p;)
    1168              :     {
    1169     78699201 :       class du_head *head = *p;
    1170     78699201 :       class du_head *next = head->next_chain;
    1171    157398402 :       int exact_match = (head->regno == this_regno
    1172     78699201 :                          && head->nregs == this_nregs);
    1173    157398402 :       int superset = (this_regno <= head->regno
    1174     78699201 :                       && this_regno + this_nregs >= head->regno + head->nregs);
    1175    157398402 :       int subset = (this_regno >= head->regno
    1176     78699201 :                       && this_regno + this_nregs <= head->regno + head->nregs);
    1177              : 
    1178     78699201 :       if (!bitmap_bit_p (&open_chains_set, head->id)
    1179     78699201 :           || head->regno + head->nregs <= this_regno
    1180    124892504 :           || this_regno + this_nregs <= head->regno)
    1181              :         {
    1182     73073204 :           p = &head->next_chain;
    1183     73073204 :           continue;
    1184              :         }
    1185              : 
    1186      5625997 :       if (action == mark_read || action == mark_access)
    1187              :         {
    1188              :           /* ??? Class NO_REGS can happen if the md file makes use of
    1189              :              EXTRA_CONSTRAINTS to match registers.  Which is arguably
    1190              :              wrong, but there we are.  */
    1191              : 
    1192      3986850 :           if (cl == NO_REGS || (!exact_match && !DEBUG_INSN_P (insn)))
    1193              :             {
    1194         4486 :               if (dump_file)
    1195            0 :                 fprintf (dump_file,
    1196              :                          "Cannot rename chain %s (%d) at insn %d (%s)\n",
    1197            0 :                          reg_names[head->regno], head->id, INSN_UID (insn),
    1198            0 :                          scan_actions_name[(int) action]);
    1199         4486 :               head->cannot_rename = 1;
    1200         4486 :               if (superset)
    1201              :                 {
    1202           25 :                   unsigned nregs = this_nregs;
    1203           25 :                   head->regno = this_regno;
    1204           25 :                   head->nregs = this_nregs;
    1205           66 :                   while (nregs-- > 0)
    1206           41 :                     SET_HARD_REG_BIT (live_in_chains, head->regno + nregs);
    1207           25 :                   if (dump_file)
    1208            0 :                     fprintf (dump_file,
    1209              :                              "Widening register in chain %s (%d) at insn %d\n",
    1210            0 :                              reg_names[head->regno], head->id, INSN_UID (insn));
    1211              :                 }
    1212         4461 :               else if (!subset)
    1213              :                 {
    1214            0 :                   fail_current_block = true;
    1215            0 :                   if (dump_file)
    1216            0 :                     fprintf (dump_file,
    1217              :                              "Failing basic block due to unhandled overlap\n");
    1218              :                 }
    1219              :             }
    1220              :           else
    1221              :             {
    1222      3982364 :               struct du_chain *this_du;
    1223      3982364 :               this_du = XOBNEW (&rename_obstack, struct du_chain);
    1224      3982364 :               this_du->next_use = 0;
    1225      3982364 :               this_du->loc = loc;
    1226      3982364 :               this_du->insn = insn;
    1227      3982364 :               this_du->cl = cl;
    1228      3982364 :               if (head->first == NULL)
    1229       926413 :                 head->first = this_du;
    1230              :               else
    1231      3055951 :                 head->last->next_use = this_du;
    1232      3982364 :               record_operand_use (head, this_du);
    1233      3982364 :               head->last = this_du;
    1234              :             }
    1235              :           /* Avoid adding the same location in a DEBUG_INSN multiple times,
    1236              :              which could happen with non-exact overlap.  */
    1237      3986850 :           if (DEBUG_INSN_P (insn))
    1238              :             return;
    1239              :           /* Otherwise, find any other chains that do not match exactly;
    1240              :              ensure they all get marked unrenamable.  */
    1241      3880933 :           p = &head->next_chain;
    1242      3880933 :           continue;
    1243      3880933 :         }
    1244              : 
    1245              :       /* Whether the terminated chain can be used for renaming
    1246              :          depends on the action and this being an exact match.
    1247              :          In either case, we remove this element from open_chains.  */
    1248              : 
    1249      1639147 :       if ((action == terminate_dead || action == terminate_write)
    1250      1303624 :           && (superset || subset))
    1251              :         {
    1252      1303624 :           unsigned nregs;
    1253              : 
    1254      1303624 :           if (subset && !superset)
    1255         1681 :             head->cannot_rename = 1;
    1256      1303624 :           bitmap_clear_bit (&open_chains_set, head->id);
    1257              : 
    1258      1303624 :           nregs = head->nregs;
    1259      2608929 :           while (nregs-- > 0)
    1260              :             {
    1261      1305305 :               CLEAR_HARD_REG_BIT (live_in_chains, head->regno + nregs);
    1262      1305305 :               if (subset && !superset
    1263         3362 :                   && (head->regno + nregs < this_regno
    1264         2551 :                       || head->regno + nregs >= this_regno + this_nregs))
    1265         1681 :                 SET_HARD_REG_BIT (live_hard_regs, head->regno + nregs);
    1266              :             }
    1267              : 
    1268      1303624 :           if (action == terminate_dead)
    1269      1168930 :             terminated_this_insn = *p;
    1270      1303624 :           *p = next;
    1271      1303624 :           if (dump_file)
    1272          106 :             fprintf (dump_file,
    1273              :                      "Closing chain %s (%d) at insn %d (%s%s)\n",
    1274          106 :                      reg_names[head->regno], head->id, INSN_UID (insn),
    1275          106 :                      scan_actions_name[(int) action],
    1276            0 :                      superset ? ", superset" : subset ? ", subset" : "");
    1277              :         }
    1278            0 :       else if (action == terminate_dead || action == terminate_write)
    1279              :         {
    1280              :           /* In this case, tracking liveness gets too hard.  Fail the
    1281              :              entire basic block.  */
    1282            0 :           if (dump_file)
    1283            0 :             fprintf (dump_file,
    1284              :                      "Failing basic block due to unhandled overlap\n");
    1285            0 :           fail_current_block = true;
    1286            0 :           return;
    1287              :         }
    1288              :       else
    1289              :         {
    1290       335523 :           head->cannot_rename = 1;
    1291       335523 :           if (dump_file)
    1292           14 :             fprintf (dump_file,
    1293              :                      "Cannot rename chain %s (%d) at insn %d (%s)\n",
    1294           14 :                      reg_names[head->regno], head->id, INSN_UID (insn),
    1295           14 :                      scan_actions_name[(int) action]);
    1296       335523 :           p = &head->next_chain;
    1297              :         }
    1298              :     }
    1299              : }
    1300              : 
    1301              : /* A wrapper around base_reg_class which returns ALL_REGS if INSN is a
    1302              :    DEBUG_INSN.  The arguments MODE, AS, CODE and INDEX_CODE are as for
    1303              :    base_reg_class.  */
    1304              : 
    1305              : static reg_class
    1306      6719642 : base_reg_class_for_rename (rtx_insn *insn, machine_mode mode, addr_space_t as,
    1307              :                            rtx_code code, rtx_code index_code)
    1308              : {
    1309            0 :   if (DEBUG_INSN_P (insn))
    1310              :     return ALL_REGS;
    1311      6566603 :   return base_reg_class (mode, as, code, index_code);
    1312              : }
    1313              : 
    1314              : /* Adapted from find_reloads_address_1.  CL is INDEX_REG_CLASS or
    1315              :    BASE_REG_CLASS depending on how the register is being considered.  */
    1316              : 
    1317              : static void
    1318      5144759 : scan_rtx_address (rtx_insn *insn, rtx *loc, enum reg_class cl,
    1319              :                   enum scan_actions action, machine_mode mode,
    1320              :                   addr_space_t as)
    1321              : {
    1322      7851616 :   rtx x = *loc;
    1323      7851616 :   RTX_CODE code = GET_CODE (x);
    1324      7851616 :   const char *fmt;
    1325      7851616 :   int i, j;
    1326              : 
    1327      7851616 :   if (action == mark_write || action == mark_access)
    1328              :     return;
    1329              : 
    1330      7255637 :   switch (code)
    1331              :     {
    1332      2705054 :     case PLUS:
    1333      2705054 :       {
    1334      2705054 :         rtx orig_op0 = XEXP (x, 0);
    1335      2705054 :         rtx orig_op1 = XEXP (x, 1);
    1336      2705054 :         RTX_CODE code0 = GET_CODE (orig_op0);
    1337      2705054 :         RTX_CODE code1 = GET_CODE (orig_op1);
    1338      2705054 :         rtx op0 = orig_op0;
    1339      2705054 :         rtx op1 = orig_op1;
    1340      2705054 :         rtx *locI = NULL;
    1341      2705054 :         rtx *locB = NULL;
    1342      2705054 :         enum rtx_code index_code = SCRATCH;
    1343              : 
    1344      2705054 :         if (GET_CODE (op0) == UNSPEC)
    1345              :           {
    1346              :             /* We have a "segment" unspec; skip it.  */
    1347          874 :             return scan_rtx_address (insn, &XEXP (x, 1), cl, action, mode, as);
    1348              :           }
    1349              : 
    1350      2704180 :         if (GET_CODE (op0) == SUBREG)
    1351              :           {
    1352            0 :             op0 = SUBREG_REG (op0);
    1353            0 :             code0 = GET_CODE (op0);
    1354              :           }
    1355              : 
    1356      2704180 :         if (GET_CODE (op1) == SUBREG)
    1357              :           {
    1358            0 :             op1 = SUBREG_REG (op1);
    1359            0 :             code1 = GET_CODE (op1);
    1360              :           }
    1361              : 
    1362      2704180 :         if (code0 == MULT || code0 == SIGN_EXTEND || code0 == TRUNCATE
    1363      2564209 :             || code0 == ZERO_EXTEND || code1 == MEM)
    1364              :           {
    1365       140180 :             locI = &XEXP (x, 0);
    1366       140180 :             locB = &XEXP (x, 1);
    1367       140180 :             index_code = GET_CODE (*locI);
    1368              :           }
    1369      2564000 :         else if (code1 == MULT || code1 == SIGN_EXTEND || code1 == TRUNCATE
    1370      2563990 :                  || code1 == ZERO_EXTEND || code0 == MEM)
    1371              :           {
    1372          339 :             locI = &XEXP (x, 1);
    1373          339 :             locB = &XEXP (x, 0);
    1374          339 :             index_code = GET_CODE (*locI);
    1375              :           }
    1376      2563661 :         else if (code0 == CONST_INT || code0 == CONST
    1377      2563661 :                  || code0 == SYMBOL_REF || code0 == LABEL_REF)
    1378              :           {
    1379        78433 :             locB = &XEXP (x, 1);
    1380        78433 :             index_code = GET_CODE (XEXP (x, 0));
    1381              :           }
    1382      2485228 :         else if (code1 == CONST_INT || code1 == CONST
    1383              :                  || code1 == SYMBOL_REF || code1 == LABEL_REF)
    1384              :           {
    1385      2261151 :             locB = &XEXP (x, 0);
    1386      2261151 :             index_code = GET_CODE (XEXP (x, 1));
    1387              :           }
    1388       224077 :         else if (code0 == REG && code1 == REG)
    1389              :           {
    1390       195741 :             int index_op;
    1391       195741 :             unsigned regno0 = REGNO (op0), regno1 = REGNO (op1);
    1392              : 
    1393            2 :             if (REGNO_OK_FOR_INDEX_P (regno1)
    1394       195741 :                 && regno_ok_for_base_p (regno0, mode, as, PLUS, REG))
    1395              :               index_op = 1;
    1396            0 :             else if (REGNO_OK_FOR_INDEX_P (regno0)
    1397            2 :                      && regno_ok_for_base_p (regno1, mode, as, PLUS, REG))
    1398              :               index_op = 0;
    1399            0 :             else if (regno_ok_for_base_p (regno0, mode, as, PLUS, REG)
    1400            0 :                      || REGNO_OK_FOR_INDEX_P (regno1))
    1401              :               index_op = 1;
    1402            0 :             else if (regno_ok_for_base_p (regno1, mode, as, PLUS, REG))
    1403              :               index_op = 0;
    1404              :             else
    1405       195739 :               index_op = 1;
    1406              : 
    1407       195741 :             locI = &XEXP (x, index_op);
    1408       195741 :             locB = &XEXP (x, !index_op);
    1409       195741 :             index_code = GET_CODE (*locI);
    1410              :           }
    1411        28336 :         else if (code0 == REG)
    1412              :           {
    1413         4442 :             locI = &XEXP (x, 0);
    1414         4442 :             locB = &XEXP (x, 1);
    1415         4442 :             index_code = GET_CODE (*locI);
    1416              :           }
    1417        23894 :         else if (code1 == REG)
    1418              :           {
    1419        23777 :             locI = &XEXP (x, 1);
    1420        23777 :             locB = &XEXP (x, 0);
    1421        23777 :             index_code = GET_CODE (*locI);
    1422              :           }
    1423              : 
    1424      2704063 :         if (locI)
    1425              :           {
    1426       364479 :             reg_class iclass = DEBUG_INSN_P (insn) ? ALL_REGS : INDEX_REG_CLASS;
    1427       364479 :             scan_rtx_address (insn, locI, iclass, action, mode, as);
    1428              :           }
    1429      2704180 :         if (locB)
    1430              :           {
    1431      5346804 :             reg_class bclass = base_reg_class_for_rename (insn, mode, as, PLUS,
    1432              :                                                           index_code);
    1433              :             scan_rtx_address (insn, locB, bclass, action, mode, as);
    1434              :           }
    1435              :         return;
    1436              :       }
    1437              : 
    1438       137486 :     case POST_INC:
    1439       137486 :     case POST_DEC:
    1440       137486 :     case POST_MODIFY:
    1441       137486 :     case PRE_INC:
    1442       137486 :     case PRE_DEC:
    1443       137486 :     case PRE_MODIFY:
    1444              :       /* If the target doesn't claim to handle autoinc, this must be
    1445              :          something special, like a stack push.  Kill this chain.  */
    1446       137486 :       if (!AUTO_INC_DEC)
    1447       137486 :         action = mark_all_read;
    1448              : 
    1449       137486 :       break;
    1450              : 
    1451         1920 :     case MEM:
    1452         1920 :       {
    1453         1920 :         reg_class bclass = base_reg_class_for_rename (insn, GET_MODE (x),
    1454         1920 :                                                       MEM_ADDR_SPACE (x),
    1455              :                                                       MEM, SCRATCH);
    1456         1920 :         scan_rtx_address (insn, &XEXP (x, 0), bclass, action, GET_MODE (x),
    1457         1920 :                           MEM_ADDR_SPACE (x));
    1458              :       }
    1459         1920 :       return;
    1460              : 
    1461      3296803 :     case REG:
    1462      3296803 :       scan_rtx_reg (insn, loc, cl, action, OP_IN);
    1463      3296803 :       return;
    1464              : 
    1465              :     default:
    1466              :       break;
    1467              :     }
    1468              : 
    1469      1251860 :   fmt = GET_RTX_FORMAT (code);
    1470      2779148 :   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
    1471              :     {
    1472      1527288 :       if (fmt[i] == 'e')
    1473       574986 :         scan_rtx_address (insn, &XEXP (x, i), cl, action, mode, as);
    1474       952302 :       else if (fmt[i] == 'E')
    1475         1492 :         for (j = XVECLEN (x, i) - 1; j >= 0; j--)
    1476          806 :           scan_rtx_address (insn, &XVECEXP (x, i, j), cl, action, mode, as);
    1477              :     }
    1478              : }
    1479              : 
    1480              : static void
    1481     41399276 : scan_rtx (rtx_insn *insn, rtx *loc, enum reg_class cl, enum scan_actions action,
    1482              :           enum op_type type)
    1483              : {
    1484     50182954 :   const char *fmt;
    1485     50182954 :   rtx x = *loc;
    1486     50182954 :   int i, j;
    1487              : 
    1488     50182954 :   enum rtx_code code = GET_CODE (x);
    1489     50182954 :   switch (code)
    1490              :     {
    1491              :     case CONST:
    1492              :     CASE_CONST_ANY:
    1493              :     case SYMBOL_REF:
    1494              :     case LABEL_REF:
    1495              :     case PC:
    1496              :       return;
    1497              : 
    1498     14985793 :     case REG:
    1499     14985793 :       scan_rtx_reg (insn, loc, cl, action, type);
    1500     14985793 :       return;
    1501              : 
    1502      4013659 :     case MEM:
    1503      4013659 :       {
    1504      4013659 :         reg_class bclass = base_reg_class_for_rename (insn, GET_MODE (x),
    1505      4013659 :                                                       MEM_ADDR_SPACE (x),
    1506              :                                                       MEM, SCRATCH);
    1507              : 
    1508      4013659 :         scan_rtx_address (insn, &XEXP (x, 0), bclass, action, GET_MODE (x),
    1509      4013659 :                           MEM_ADDR_SPACE (x));
    1510              :       }
    1511      4013659 :       return;
    1512              : 
    1513      7398254 :     case SET:
    1514      7398254 :       scan_rtx (insn, &SET_SRC (x), cl, action, OP_IN);
    1515     14796508 :       scan_rtx (insn, &SET_DEST (x), cl, action,
    1516      7398254 :                 (GET_CODE (PATTERN (insn)) == COND_EXEC
    1517            0 :                  && verify_reg_tracked (SET_DEST (x))) ? OP_INOUT : OP_OUT);
    1518      7398254 :       return;
    1519              : 
    1520         3924 :     case STRICT_LOW_PART:
    1521         3924 :       scan_rtx (insn, &XEXP (x, 0), cl, action,
    1522         3924 :                 verify_reg_tracked (XEXP (x, 0)) ? OP_INOUT : OP_OUT);
    1523         3924 :       return;
    1524              : 
    1525         5180 :     case ZERO_EXTRACT:
    1526         5180 :     case SIGN_EXTRACT:
    1527         6270 :       scan_rtx (insn, &XEXP (x, 0), cl, action,
    1528              :                 (type == OP_IN ? OP_IN :
    1529         1090 :                  verify_reg_tracked (XEXP (x, 0)) ? OP_INOUT : OP_OUT));
    1530         5180 :       scan_rtx (insn, &XEXP (x, 1), cl, action, OP_IN);
    1531         5180 :       scan_rtx (insn, &XEXP (x, 2), cl, action, OP_IN);
    1532         5180 :       return;
    1533              : 
    1534            0 :     case POST_INC:
    1535            0 :     case PRE_INC:
    1536            0 :     case POST_DEC:
    1537            0 :     case PRE_DEC:
    1538            0 :     case POST_MODIFY:
    1539            0 :     case PRE_MODIFY:
    1540              :       /* Should only happen inside MEM.  */
    1541            0 :       gcc_unreachable ();
    1542              : 
    1543      1176140 :     case CLOBBER:
    1544      2352280 :       scan_rtx (insn, &SET_DEST (x), cl, action,
    1545      1176140 :                 (GET_CODE (PATTERN (insn)) == COND_EXEC
    1546            0 :                  && verify_reg_tracked (SET_DEST (x))) ? OP_INOUT : OP_OUT);
    1547      1176140 :       return;
    1548              : 
    1549       339901 :     case EXPR_LIST:
    1550       339901 :       scan_rtx (insn, &XEXP (x, 0), cl, action, type);
    1551       339901 :       if (XEXP (x, 1))
    1552       200180 :         scan_rtx (insn, &XEXP (x, 1), cl, action, type);
    1553              :       return;
    1554              : 
    1555      7198883 :     default:
    1556      7198883 :       break;
    1557              :     }
    1558              : 
    1559      7198883 :   fmt = GET_RTX_FORMAT (code);
    1560     20185556 :   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
    1561              :     {
    1562     12986673 :       if (fmt[i] == 'e')
    1563     11075919 :         scan_rtx (insn, &XEXP (x, i), cl, action, type);
    1564      1910754 :       else if (fmt[i] == 'E')
    1565      4573362 :         for (j = XVECLEN (x, i) - 1; j >= 0; j--)
    1566      3152412 :           scan_rtx (insn, &XVECEXP (x, i, j), cl, action, type);
    1567              :     }
    1568              : }
    1569              : 
    1570              : /* Hide operands of the current insn (of which there are N_OPS) by
    1571              :    substituting pc for them.
    1572              :    Previous values are stored in the OLD_OPERANDS and OLD_DUPS.
    1573              :    For every bit set in DO_NOT_HIDE, we leave the operand alone.
    1574              :    If INOUT_AND_EC_ONLY is set, we only do this for OP_INOUT type operands
    1575              :    and earlyclobbers.  */
    1576              : 
    1577              : static void
    1578     15155544 : hide_operands (int n_ops, rtx *old_operands, rtx *old_dups,
    1579              :                unsigned HOST_WIDE_INT do_not_hide, bool inout_and_ec_only)
    1580              : {
    1581     15155544 :   int i;
    1582     15155544 :   const operand_alternative *op_alt = which_op_alt ();
    1583     64102468 :   for (i = 0; i < n_ops; i++)
    1584              :     {
    1585     33791380 :       old_operands[i] = recog_data.operand[i];
    1586              :       /* Don't squash match_operator or match_parallel here, since
    1587              :          we don't know that all of the contained registers are
    1588              :          reachable by proper operands.  */
    1589     33791380 :       if (recog_data.constraints[i][0] == '\0')
    1590      5686440 :         continue;
    1591     28104940 :       if (do_not_hide & (1 << i))
    1592         1616 :         continue;
    1593     28103324 :       if (!inout_and_ec_only || recog_data.operand_type[i] == OP_INOUT
    1594      5654866 :           || op_alt[i].earlyclobber)
    1595     22448512 :         *recog_data.operand_loc[i] = pc_rtx;
    1596              :     }
    1597     15572944 :   for (i = 0; i < recog_data.n_dups; i++)
    1598              :     {
    1599       417400 :       int opn = recog_data.dup_num[i];
    1600       417400 :       old_dups[i] = *recog_data.dup_loc[i];
    1601       417400 :       if (do_not_hide & (1 << opn))
    1602            0 :         continue;
    1603       417400 :       if (!inout_and_ec_only || recog_data.operand_type[opn] == OP_INOUT
    1604        54923 :           || op_alt[opn].earlyclobber)
    1605       362477 :         *recog_data.dup_loc[i] = pc_rtx;
    1606              :     }
    1607     15155544 : }
    1608              : 
    1609              : /* Undo the substitution performed by hide_operands.  INSN is the insn we
    1610              :    are processing; the arguments are the same as in hide_operands.  */
    1611              : 
    1612              : static void
    1613     15155544 : restore_operands (rtx_insn *insn, int n_ops, rtx *old_operands, rtx *old_dups)
    1614              : {
    1615     15155544 :   int i;
    1616     15572944 :   for (i = 0; i < recog_data.n_dups; i++)
    1617       417400 :     *recog_data.dup_loc[i] = old_dups[i];
    1618     48946924 :   for (i = 0; i < n_ops; i++)
    1619     33791380 :     *recog_data.operand_loc[i] = old_operands[i];
    1620     15155544 :   if (recog_data.n_dups)
    1621       226152 :     df_insn_rescan (insn);
    1622     15155544 : }
    1623              : 
    1624              : /* For each output operand of INSN, call scan_rtx to create a new
    1625              :    open chain.  Do this only for normal or earlyclobber outputs,
    1626              :    depending on EARLYCLOBBER.  If INSN_INFO is nonnull, use it to
    1627              :    record information about the operands in the insn.  */
    1628              : 
    1629              : static void
    1630      7577772 : record_out_operands (rtx_insn *insn, bool earlyclobber, insn_rr_info *insn_info)
    1631              : {
    1632      7577772 :   int n_ops = recog_data.n_operands;
    1633      7577772 :   const operand_alternative *op_alt = which_op_alt ();
    1634              : 
    1635      7577772 :   int i;
    1636              : 
    1637     32259934 :   for (i = 0; i < n_ops + recog_data.n_dups; i++)
    1638              :     {
    1639     17104390 :       int opn = i < n_ops ? i : recog_data.dup_num[i - n_ops];
    1640     16895690 :       rtx *loc = (i < n_ops
    1641     17104390 :                   ? recog_data.operand_loc[opn]
    1642       208700 :                   : recog_data.dup_loc[i - n_ops]);
    1643     17104390 :       rtx op = *loc;
    1644     17104390 :       enum reg_class cl = alternative_class (op_alt, opn);
    1645              : 
    1646     17104390 :       class du_head *prev_open;
    1647              : 
    1648     17104390 :       if (recog_data.operand_type[opn] != OP_OUT
    1649      4169304 :           || op_alt[opn].earlyclobber != earlyclobber)
    1650     15019738 :         continue;
    1651              : 
    1652      2084652 :       if (insn_info)
    1653            0 :         cur_operand = insn_info->op_info + i;
    1654              : 
    1655      2084652 :       prev_open = open_chains;
    1656      2084652 :       if (earlyclobber)
    1657           54 :         scan_rtx (insn, loc, cl, terminate_write, OP_OUT);
    1658      2084652 :       scan_rtx (insn, loc, cl, mark_write, OP_OUT);
    1659              : 
    1660              :       /* ??? Many targets have output constraints on the SET_DEST
    1661              :          of a call insn, which is stupid, since these are certainly
    1662              :          ABI defined hard registers.  For these, and for asm operands
    1663              :          that originally referenced hard registers, we must record that
    1664              :          the chain cannot be renamed.  */
    1665      2084652 :       if (CALL_P (insn)
    1666      2084652 :           || (asm_noperands (PATTERN (insn)) > 0
    1667          475 :               && REG_P (op)
    1668          267 :               && REGNO (op) == ORIGINAL_REGNO (op)))
    1669              :         {
    1670            0 :           if (prev_open != open_chains)
    1671            0 :             open_chains->cannot_rename = 1;
    1672              :         }
    1673              :     }
    1674      7577772 :   cur_operand = NULL;
    1675      7577772 : }
    1676              : 
    1677              : /* Build def/use chain.  */
    1678              : 
    1679              : static bool
    1680       615927 : build_def_use (basic_block bb)
    1681              : {
    1682       615927 :   rtx_insn *insn;
    1683       615927 :   unsigned HOST_WIDE_INT untracked_operands;
    1684              : 
    1685       615927 :   fail_current_block = false;
    1686              : 
    1687      6202020 :   for (insn = BB_HEAD (bb); ; insn = NEXT_INSN (insn))
    1688              :     {
    1689      6202020 :       if (NONDEBUG_INSN_P (insn))
    1690              :         {
    1691      3788886 :           int n_ops;
    1692      3788886 :           rtx note;
    1693      3788886 :           rtx old_operands[MAX_RECOG_OPERANDS];
    1694      3788886 :           rtx old_dups[MAX_DUP_OPERANDS];
    1695      3788886 :           int i;
    1696      3788886 :           int predicated;
    1697      3788886 :           enum rtx_code set_code = SET;
    1698      3788886 :           enum rtx_code clobber_code = CLOBBER;
    1699      3788886 :           insn_rr_info *insn_info = NULL;
    1700      3788886 :           terminated_this_insn = NULL;
    1701              : 
    1702              :           /* Process the insn, determining its effect on the def-use
    1703              :              chains and live hard registers.  We perform the following
    1704              :              steps with the register references in the insn, simulating
    1705              :              its effect:
    1706              :              (1) Deal with earlyclobber operands and CLOBBERs of non-operands
    1707              :                  by creating chains and marking hard regs live.
    1708              :              (2) Any read outside an operand causes any chain it overlaps
    1709              :                  with to be marked unrenamable.
    1710              :              (3) Any read inside an operand is added if there's already
    1711              :                  an open chain for it.
    1712              :              (4) For any REG_DEAD note we find, close open chains that
    1713              :                  overlap it.
    1714              :              (5) For any non-earlyclobber write we find, close open chains
    1715              :                  that overlap it.
    1716              :              (6) For any non-earlyclobber write we find in an operand, make
    1717              :                  a new chain or mark the hard register as live.
    1718              :              (7) For any REG_UNUSED, close any chains we just opened.
    1719              :              (8) For any REG_CFA_RESTORE or REG_CFA_REGISTER, kill any chain
    1720              :                  containing its dest.
    1721              : 
    1722              :              We cannot deal with situations where we track a reg in one mode
    1723              :              and see a reference in another mode; these will cause the chain
    1724              :              to be marked unrenamable or even cause us to abort the entire
    1725              :              basic block.  */
    1726              : 
    1727      3788886 :           extract_constrain_insn (insn);
    1728      3788886 :           preprocess_constraints (insn);
    1729      3788886 :           const operand_alternative *op_alt = which_op_alt ();
    1730      3788886 :           n_ops = recog_data.n_operands;
    1731      3788886 :           untracked_operands = 0;
    1732              : 
    1733      3788886 :           if (insn_rr.exists ())
    1734              :             {
    1735            0 :               insn_info = &insn_rr[INSN_UID (insn)];
    1736            0 :               insn_info->op_info = XOBNEWVEC (&rename_obstack, operand_rr_info,
    1737              :                                               recog_data.n_operands);
    1738            0 :               memset (insn_info->op_info, 0,
    1739            0 :                       sizeof (operand_rr_info) * recog_data.n_operands);
    1740              :             }
    1741              : 
    1742              :           /* Simplify the code below by promoting OP_OUT to OP_INOUT in
    1743              :              predicated instructions, but only for register operands
    1744              :              that are already tracked, so that we can create a chain
    1745              :              when the first SET makes a register live.  */
    1746              : 
    1747      3788886 :           predicated = GET_CODE (PATTERN (insn)) == COND_EXEC;
    1748     12236731 :           for (i = 0; i < n_ops; ++i)
    1749              :             {
    1750      8447845 :               rtx op = recog_data.operand[i];
    1751      8447845 :               int matches = op_alt[i].matches;
    1752      8447845 :               if (matches >= 0 || op_alt[i].matched >= 0
    1753      7083215 :                   || (predicated && recog_data.operand_type[i] == OP_OUT))
    1754              :                 {
    1755      1364630 :                   recog_data.operand_type[i] = OP_INOUT;
    1756              :                   /* A special case to deal with instruction patterns that
    1757              :                      have matching operands with different modes.  If we're
    1758              :                      not already tracking such a reg, we won't start here,
    1759              :                      and we must instead make sure to make the operand visible
    1760              :                      to the machinery that tracks hard registers.  */
    1761      1364630 :                   machine_mode i_mode = recog_data.operand_mode[i];
    1762      1364630 :                   if (matches >= 0)
    1763              :                     {
    1764       682315 :                       machine_mode matches_mode
    1765              :                         = recog_data.operand_mode[matches];
    1766              : 
    1767       682315 :                       if (maybe_ne (GET_MODE_SIZE (i_mode),
    1768       682315 :                                     GET_MODE_SIZE (matches_mode))
    1769       682315 :                           && !verify_reg_in_set (op, &live_in_chains))
    1770              :                         {
    1771          202 :                           untracked_operands |= 1 << i;
    1772          202 :                           untracked_operands |= 1 << matches;
    1773              :                         }
    1774              :                     }
    1775              :                 }
    1776              : #ifdef STACK_REGS
    1777      8447845 :               if (regstack_completed
    1778            0 :                   && REG_P (op)
    1779      8447845 :                   && IN_RANGE (REGNO (op), FIRST_STACK_REG, LAST_STACK_REG))
    1780            0 :                 untracked_operands |= 1 << i;
    1781              : #endif
    1782              :               /* If there's an in-out operand with a register that is not
    1783              :                  being tracked at all yet, open a chain.  */
    1784      8447845 :               if (recog_data.operand_type[i] == OP_INOUT
    1785      1371369 :                   && !(untracked_operands & (1 << i))
    1786      1371167 :                   && REG_P (op)
    1787      9768412 :                   && !verify_reg_tracked (op))
    1788           35 :                 create_new_chain (REGNO (op), REG_NREGS (op), NULL, NULL,
    1789              :                                   NO_REGS);
    1790              :             }
    1791              : 
    1792      3788886 :           if (fail_current_block)
    1793              :             break;
    1794              : 
    1795              :           /* Step 1a: Mark hard registers that are clobbered in this insn,
    1796              :              outside an operand, as live.  */
    1797      3788886 :           hide_operands (n_ops, old_operands, old_dups, untracked_operands,
    1798              :                          false);
    1799      3788886 :           note_stores (insn, note_sets_clobbers, &clobber_code);
    1800      3788886 :           restore_operands (insn, n_ops, old_operands, old_dups);
    1801              : 
    1802              :           /* Step 1b: Begin new chains for earlyclobbered writes inside
    1803              :              operands.  */
    1804      3788886 :           record_out_operands (insn, true, insn_info);
    1805              : 
    1806              :           /* Step 2: Mark chains for which we have reads outside operands
    1807              :              as unrenamable.
    1808              :              We do this by munging all operands into PC, and closing
    1809              :              everything remaining.  */
    1810              : 
    1811      3788886 :           hide_operands (n_ops, old_operands, old_dups, untracked_operands,
    1812              :                          false);
    1813      3788886 :           scan_rtx (insn, &PATTERN (insn), NO_REGS, mark_all_read, OP_IN);
    1814      3788886 :           restore_operands (insn, n_ops, old_operands, old_dups);
    1815              : 
    1816              :           /* Step 2B: Can't rename function call argument registers.  */
    1817      3788886 :           if (CALL_P (insn) && CALL_INSN_FUNCTION_USAGE (insn))
    1818       139721 :             scan_rtx (insn, &CALL_INSN_FUNCTION_USAGE (insn),
    1819              :                       NO_REGS, mark_all_read, OP_IN);
    1820              : 
    1821              :           /* Step 2C: Can't rename asm operands that were originally
    1822              :              hard registers.  */
    1823      3788886 :           if (asm_noperands (PATTERN (insn)) > 0)
    1824         2724 :             for (i = 0; i < n_ops; i++)
    1825              :               {
    1826         1839 :                 rtx *loc = recog_data.operand_loc[i];
    1827         1839 :                 rtx op = *loc;
    1828              : 
    1829         1839 :                 if (REG_P (op)
    1830         1305 :                     && REGNO (op) == ORIGINAL_REGNO (op)
    1831         1840 :                     && (recog_data.operand_type[i] == OP_IN
    1832            0 :                         || recog_data.operand_type[i] == OP_INOUT))
    1833            1 :                   scan_rtx (insn, loc, NO_REGS, mark_all_read, OP_IN);
    1834              :               }
    1835              : 
    1836              :           /* Step 3: Append to chains for reads inside operands.  */
    1837     12341081 :           for (i = 0; i < n_ops + recog_data.n_dups; i++)
    1838              :             {
    1839      8552195 :               int opn = i < n_ops ? i : recog_data.dup_num[i - n_ops];
    1840      8447845 :               rtx *loc = (i < n_ops
    1841      8552195 :                           ? recog_data.operand_loc[opn]
    1842       104350 :                           : recog_data.dup_loc[i - n_ops]);
    1843      8552195 :               enum reg_class cl = alternative_class (op_alt, opn);
    1844      8552195 :               enum op_type type = recog_data.operand_type[opn];
    1845              : 
    1846              :               /* Don't scan match_operand here, since we've no reg class
    1847              :                  information to pass down.  Any operands that we could
    1848              :                  substitute in will be represented elsewhere.  */
    1849      8552195 :               if (recog_data.constraints[opn][0] == '\0'
    1850      7121145 :                   || untracked_operands & (1 << opn))
    1851      1431454 :                 continue;
    1852              : 
    1853      7120741 :               if (insn_info)
    1854            0 :                 cur_operand = i == opn ? insn_info->op_info + i : NULL;
    1855      7120741 :               if (op_alt[opn].is_address)
    1856       190829 :                 scan_rtx_address (insn, loc, cl, mark_read,
    1857              :                                   VOIDmode, ADDR_SPACE_GENERIC);
    1858              :               else
    1859      6929912 :                 scan_rtx (insn, loc, cl, mark_read, type);
    1860              :             }
    1861      3788886 :           cur_operand = NULL;
    1862              : 
    1863              :           /* Step 3B: Record updates for regs in REG_INC notes, and
    1864              :              source regs in REG_FRAME_RELATED_EXPR notes.  */
    1865      7000169 :           for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
    1866      3211283 :             if (REG_NOTE_KIND (note) == REG_INC
    1867      3211283 :                 || REG_NOTE_KIND (note) == REG_FRAME_RELATED_EXPR)
    1868           30 :               scan_rtx (insn, &XEXP (note, 0), ALL_REGS, mark_read,
    1869              :                         OP_INOUT);
    1870              : 
    1871              :           /* Step 4: Close chains for registers that die here, unless
    1872              :              the register is mentioned in a REG_UNUSED note.  In that
    1873              :              case we keep the chain open until step #7 below to ensure
    1874              :              it conflicts with other output operands of this insn.
    1875              :              See PR 52573.  Arguably the insn should not have both
    1876              :              notes; it has proven difficult to fix that without
    1877              :              other undesirable side effects.  */
    1878      7000169 :           for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
    1879      3211283 :             if (REG_NOTE_KIND (note) == REG_DEAD
    1880      3211283 :                 && !find_regno_note (insn, REG_UNUSED, REGNO (XEXP (note, 0))))
    1881              :               {
    1882      1635941 :                 remove_from_hard_reg_set (&live_hard_regs,
    1883      1635941 :                                           GET_MODE (XEXP (note, 0)),
    1884      1635941 :                                           REGNO (XEXP (note, 0)));
    1885      1635941 :                 scan_rtx (insn, &XEXP (note, 0), NO_REGS, terminate_dead,
    1886              :                           OP_IN);
    1887              :               }
    1888              : 
    1889              :           /* Step 4B: If this is a call, any chain live at this point
    1890              :              requires a caller-saved reg.  */
    1891      3788886 :           if (CALL_P (insn))
    1892              :             {
    1893       150645 :               function_abi callee_abi = insn_callee_abi (insn);
    1894       150645 :               class du_head *p;
    1895       442072 :               for (p = open_chains; p; p = p->next_chain)
    1896              :                 {
    1897       291427 :                   p->call_abis |= (1 << callee_abi.id ());
    1898       291427 :                   p->call_clobber_mask
    1899       291427 :                     |= callee_abi.full_and_partial_reg_clobbers ();
    1900       582854 :                   p->hard_conflicts |= callee_abi.full_reg_clobbers ();
    1901              :                 }
    1902              :             }
    1903              : 
    1904              :           /* Step 5: Close open chains that overlap writes.  Similar to
    1905              :              step 2, we hide in-out operands, since we do not want to
    1906              :              close these chains.  We also hide earlyclobber operands,
    1907              :              since we've opened chains for them in step 1, and earlier
    1908              :              chains they would overlap with must have been closed at
    1909              :              the previous insn at the latest, as such operands cannot
    1910              :              possibly overlap with any input operands.  */
    1911              : 
    1912      3788886 :           hide_operands (n_ops, old_operands, old_dups, untracked_operands,
    1913              :                          true);
    1914      3788886 :           scan_rtx (insn, &PATTERN (insn), NO_REGS, terminate_write, OP_IN);
    1915      3788886 :           restore_operands (insn, n_ops, old_operands, old_dups);
    1916              : 
    1917              :           /* Step 6a: Mark hard registers that are set in this insn,
    1918              :              outside an operand, as live.  */
    1919      3788886 :           hide_operands (n_ops, old_operands, old_dups, untracked_operands,
    1920              :                          false);
    1921      3788886 :           note_stores (insn, note_sets_clobbers, &set_code);
    1922      3788886 :           restore_operands (insn, n_ops, old_operands, old_dups);
    1923              : 
    1924              :           /* Step 6b: Begin new chains for writes inside operands.  */
    1925      3788886 :           record_out_operands (insn, false, insn_info);
    1926              : 
    1927              :           /* Step 6c: Record destination regs in REG_FRAME_RELATED_EXPR
    1928              :              notes for update.  */
    1929      7000169 :           for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
    1930      3211283 :             if (REG_NOTE_KIND (note) == REG_FRAME_RELATED_EXPR)
    1931           30 :               scan_rtx (insn, &XEXP (note, 0), ALL_REGS, mark_access,
    1932              :                         OP_INOUT);
    1933              : 
    1934              :           /* Step 7: Close chains for registers that were never
    1935              :              really used here.  */
    1936      7000169 :           for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
    1937      3211283 :             if (REG_NOTE_KIND (note) == REG_UNUSED)
    1938              :               {
    1939       591066 :                 remove_from_hard_reg_set (&live_hard_regs,
    1940       591066 :                                           GET_MODE (XEXP (note, 0)),
    1941       591066 :                                           REGNO (XEXP (note, 0)));
    1942       591066 :                 scan_rtx (insn, &XEXP (note, 0), NO_REGS, terminate_dead,
    1943              :                           OP_IN);
    1944              :               }
    1945              : 
    1946              :           /* Step 8: Kill the chains involving register restores.  Those
    1947              :              should restore _that_ register.  Similar for REG_CFA_REGISTER.  */
    1948      7000169 :           for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
    1949      3211283 :             if (REG_NOTE_KIND (note) == REG_CFA_RESTORE
    1950      3205822 :                 || REG_NOTE_KIND (note) == REG_CFA_REGISTER)
    1951              :               {
    1952         5461 :                 rtx *x = &XEXP (note, 0);
    1953         5461 :                 if (!*x)
    1954            0 :                   x = &PATTERN (insn);
    1955         5461 :                 if (GET_CODE (*x) == PARALLEL)
    1956            0 :                   x = &XVECEXP (*x, 0, 0);
    1957         5461 :                 if (GET_CODE (*x) == SET)
    1958            0 :                   x = &SET_DEST (*x);
    1959         5461 :                 scan_rtx (insn, x, NO_REGS, mark_all_read, OP_IN);
    1960              :               }
    1961              :         }
    1962       894641 :       else if (DEBUG_BIND_INSN_P (insn)
    1963      3004225 :                && !VAR_LOC_UNKNOWN_P (INSN_VAR_LOCATION_LOC (insn)))
    1964              :         {
    1965       457790 :           scan_rtx (insn, &INSN_VAR_LOCATION_LOC (insn),
    1966              :                     ALL_REGS, mark_read, OP_IN);
    1967              :         }
    1968      6202020 :       if (insn == BB_END (bb))
    1969              :         break;
    1970      5586093 :     }
    1971              : 
    1972       615927 :   if (fail_current_block)
    1973            0 :     return false;
    1974              : 
    1975              :   return true;
    1976              : }
    1977              : 
    1978              : /* Initialize the register renamer.  If INSN_INFO is true, ensure that
    1979              :    insn_rr is nonnull.  */
    1980              : void
    1981        23342 : regrename_init (bool insn_info)
    1982              : {
    1983        23342 :   gcc_obstack_init (&rename_obstack);
    1984        23342 :   insn_rr.create (0);
    1985        23342 :   if (insn_info)
    1986            0 :     insn_rr.safe_grow_cleared (get_max_uid (), true);
    1987        23342 : }
    1988              : 
    1989              : /* Free all global data used by the register renamer.  */
    1990              : void
    1991        23342 : regrename_finish (void)
    1992              : {
    1993        23342 :   insn_rr.release ();
    1994        23342 :   free_chain_data ();
    1995        23342 :   obstack_free (&rename_obstack, NULL);
    1996        23342 : }
    1997              : 
    1998              : /* Perform register renaming on the current function.  */
    1999              : 
    2000              : static unsigned int
    2001        23342 : regrename_optimize (void)
    2002              : {
    2003        23342 :   df_set_flags (DF_LR_RUN_DCE);
    2004        23342 :   df_note_add_problem ();
    2005        23342 :   df_analyze ();
    2006        23342 :   df_set_flags (DF_DEFER_INSN_RESCAN);
    2007              : 
    2008        23342 :   regrename_init (false);
    2009              : 
    2010        23342 :   regrename_analyze (NULL, false);
    2011              : 
    2012        23342 :   rename_chains ();
    2013              : 
    2014        23342 :   regrename_finish ();
    2015              : 
    2016        23342 :   return 0;
    2017              : }
    2018              : 
    2019              : namespace {
    2020              : 
    2021              : const pass_data pass_data_regrename =
    2022              : {
    2023              :   RTL_PASS, /* type */
    2024              :   "rnreg", /* name */
    2025              :   OPTGROUP_NONE, /* optinfo_flags */
    2026              :   TV_RENAME_REGISTERS, /* tv_id */
    2027              :   0, /* properties_required */
    2028              :   0, /* properties_provided */
    2029              :   0, /* properties_destroyed */
    2030              :   0, /* todo_flags_start */
    2031              :   TODO_df_finish, /* todo_flags_finish */
    2032              : };
    2033              : 
    2034              : class pass_regrename : public rtl_opt_pass
    2035              : {
    2036              : public:
    2037       294587 :   pass_regrename (gcc::context *ctxt)
    2038       589174 :     : rtl_opt_pass (pass_data_regrename, ctxt)
    2039              :   {}
    2040              : 
    2041              :   /* opt_pass methods: */
    2042      1511392 :   bool gate (function *) final override
    2043              :     {
    2044      1511392 :       return (optimize > 0 && (flag_rename_registers));
    2045              :     }
    2046              : 
    2047        23342 :   unsigned int execute (function *) final override
    2048              :   {
    2049        23342 :     return regrename_optimize ();
    2050              :   }
    2051              : 
    2052              : }; // class pass_regrename
    2053              : 
    2054              : } // anon namespace
    2055              : 
    2056              : rtl_opt_pass *
    2057       294587 : make_pass_regrename (gcc::context *ctxt)
    2058              : {
    2059       294587 :   return new pass_regrename (ctxt);
    2060              : }
        

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.