LCOV - code coverage report
Current view: top level - gcc - regrename.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 90.5 % 966 874
Test Date: 2026-02-28 14:20:25 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    103355203 : regrename_chain_from_id (unsigned int id)
     145              : {
     146    103355203 :   du_head_p first_chain = id_to_chain[id];
     147    103355203 :   du_head_p chain = first_chain;
     148    164141809 :   while (chain->id != id)
     149              :     {
     150     60786606 :       id = chain->id;
     151     60786606 :       chain = id_to_chain[id];
     152              :     }
     153    103355203 :   first_chain->id = id;
     154    103355203 :   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        22497 : free_chain_data (void)
     183              : {
     184        22497 :   int i;
     185        22497 :   du_head_p ptr;
     186      4699010 :   for (i = 0; id_to_chain.iterate (i, &ptr); i++)
     187      4676513 :     bitmap_clear (&ptr->conflicts);
     188              : 
     189        22497 :   id_to_chain.release ();
     190        22497 : }
     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      4676513 : mark_conflict (class du_head *chains, unsigned id)
     197              : {
     198     28816662 :   while (chains)
     199              :     {
     200     24140149 :       bitmap_set_bit (&chains->conflicts, id);
     201     24140149 :       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      5246309 : record_operand_use (class du_head *head, struct du_chain *this_du)
     210              : {
     211      5246309 :   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      4676513 : create_new_chain (unsigned this_regno, unsigned this_nregs, rtx *loc,
     229              :                   rtx_insn *insn, enum reg_class cl)
     230              : {
     231      4676513 :   class du_head *head = XOBNEW (&rename_obstack, class du_head);
     232      4676513 :   struct du_chain *this_du;
     233      4676513 :   int nregs;
     234              : 
     235      4676513 :   memset ((void *)head, 0, sizeof *head);
     236      4676513 :   head->next_chain = open_chains;
     237      4676513 :   head->regno = this_regno;
     238      4676513 :   head->nregs = this_nregs;
     239              : 
     240      4676513 :   id_to_chain.safe_push (head);
     241      4676513 :   head->id = current_id++;
     242              : 
     243      4676513 :   bitmap_initialize (&head->conflicts, &bitmap_default_obstack);
     244      4676513 :   bitmap_copy (&head->conflicts, &open_chains_set);
     245      4676513 :   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      4676513 :   nregs = head->nregs;
     251      9354668 :   while (nregs-- > 0)
     252              :     {
     253      4678155 :       SET_HARD_REG_BIT (live_in_chains, head->regno + nregs);
     254      4678155 :       CLEAR_HARD_REG_BIT (live_hard_regs, head->regno + nregs);
     255              :     }
     256              : 
     257      4676513 :   head->hard_conflicts = live_hard_regs;
     258      4676513 :   bitmap_set_bit (&open_chains_set, head->id);
     259              : 
     260      4676513 :   open_chains = head;
     261              : 
     262      4676513 :   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      4676513 :   if (insn == NULL_RTX)
     272              :     {
     273      3225537 :       head->first = head->last = NULL;
     274      3225537 :       return head;
     275              :     }
     276              : 
     277      1450976 :   this_du = XOBNEW (&rename_obstack, struct du_chain);
     278      1450976 :   head->first = head->last = this_du;
     279              : 
     280      1450976 :   this_du->next_use = 0;
     281      1450976 :   this_du->loc = loc;
     282      1450976 :   this_du->insn = insn;
     283      1450976 :   this_du->cl = cl;
     284      1450976 :   record_operand_use (head, this_du);
     285      1450976 :   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       988673 : merge_overlapping_regs (HARD_REG_SET *pset, class du_head *head)
     293              : {
     294       988673 :   bitmap_iterator bi;
     295       988673 :   unsigned i;
     296       988673 :   *pset |= head->hard_conflicts;
     297     46138641 :   EXECUTE_IF_SET_IN_BITMAP (&head->conflicts, 0, i, bi)
     298              :     {
     299     45149968 :       du_head_p other = regrename_chain_from_id (i);
     300     45149968 :       unsigned j = other->nregs;
     301     45149968 :       gcc_assert (other != head);
     302     90313385 :       while (j-- > 0)
     303     45163417 :         SET_HARD_REG_BIT (*pset, other->regno + j);
     304              :     }
     305       988673 : }
     306              : 
     307              : /* Return true if (reg:MODE REGNO) would be clobbered by a call covered
     308              :    by THIS_HEAD.  */
     309              : 
     310              : static bool
     311     21141199 : call_clobbered_in_chain_p (du_head *this_head, machine_mode mode,
     312              :                            unsigned int regno)
     313              : {
     314     21141199 :   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     89156776 : check_new_reg_p (int reg ATTRIBUTE_UNUSED, int new_reg,
     325              :                  class du_head *this_head, HARD_REG_SET this_unavailable)
     326              : {
     327     89156776 :   int nregs = 1;
     328     89156776 :   int i;
     329     89156776 :   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    321367798 :   for (tmp = this_head->first; tmp; tmp = tmp->next_use)
     334              :     {
     335    275768346 :       int n;
     336              :       /* Completely ignore DEBUG_INSNs, otherwise we can get
     337              :          -fcompare-debug failures.  */
     338    275768346 :       if (DEBUG_INSN_P (tmp->insn))
     339      4202506 :         continue;
     340              : 
     341    271565840 :       if (!targetm.hard_regno_mode_ok (new_reg, GET_MODE (*tmp->loc)))
     342              :         return false;
     343    228008516 :       n = hard_regno_nregs (new_reg, GET_MODE (*tmp->loc));
     344    228008516 :       if (n > nregs)
     345    232211022 :         nregs = n;
     346              :     }
     347              : 
     348     51343526 :   for (i = nregs - 1; i >= 0; --i)
     349     45605317 :     if (TEST_HARD_REG_BIT (this_unavailable, new_reg + i)
     350     17406712 :         || fixed_regs[new_reg + i]
     351      6555038 :         || global_regs[new_reg + i]
     352              :         /* Can't use regs which aren't saved by the prologue.  */
     353      6555038 :         || (! df_regs_ever_live_p (new_reg + i)
     354      1276649 :             && ! 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     51551635 :         || ! HARD_REGNO_RENAME_OK (reg + i, new_reg + i))
     362     39861243 :       return false;
     363              : 
     364              :   /* See whether it accepts all modes that occur in
     365              :      definition and uses.  */
     366     27020189 :   for (tmp = this_head->first; tmp; tmp = tmp->next_use)
     367              :     {
     368     21281980 :       if (DEBUG_INSN_P (tmp->insn))
     369       140781 :         continue;
     370              : 
     371     21141199 :       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       988673 : 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       988673 :   bool has_preferred_class;
     390       988673 :   enum reg_class preferred_class;
     391       988673 :   int pass;
     392       988673 :   int best_new_reg = old_reg;
     393              : 
     394              :   /* Mark registers that overlap this chain's lifetime as unavailable.  */
     395       988673 :   merge_overlapping_regs (unavailable, this_head);
     396              : 
     397              :   /* Compute preferred rename class of super union of all the classes
     398              :      in the chain.  */
     399       988673 :   preferred_class
     400       988673 :     = (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        64530 :   if (this_head->tied_chain && !this_head->tied_chain->renamed
     405      1041701 :       && check_new_reg_p (old_reg, this_head->tied_chain->regno,
     406              :                           this_head, *unavailable))
     407        13374 :     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       975322 :   for (struct du_chain *tmp = this_head->first; tmp; tmp = tmp->next_use)
     412       975322 :     if (DEBUG_INSN_P (tmp->insn))
     413           23 :       continue;
     414       975299 :     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       968519 :   has_preferred_class = (preferred_class != NO_REGS);
     426      2905557 :   for (pass = (has_preferred_class ? 0 : 1); pass < 2; pass++)
     427              :     {
     428              :       int new_reg;
     429     90072267 :       for (new_reg = 0; new_reg < FIRST_PSEUDO_REGISTER; new_reg++)
     430              :         {
     431     89103748 :           if (has_preferred_class
     432     89103748 :               && (pass == 0)
     433            0 :               != TEST_HARD_REG_BIT (reg_class_contents[preferred_class],
     434              :                                     new_reg))
     435            0 :             continue;
     436              : 
     437     89103748 :           if (!check_new_reg_p (old_reg, new_reg, this_head, *unavailable))
     438     83378913 :             continue;
     439              : 
     440      5724835 :           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      5724835 :           if ((pass == 0
     447            0 :               && !TEST_HARD_REG_BIT (reg_class_contents[preferred_class],
     448              :                                      best_new_reg))
     449      5724835 :               || tick[best_new_reg] > tick[new_reg])
     450              :             best_new_reg = new_reg;
     451              :         }
     452       968519 :       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      4243798 : regrename_find_superclass (du_head_p head, int *pn_uses,
     467              :                            HARD_REG_SET *punavailable)
     468              : {
     469      4243798 :   int n_uses = 0;
     470      4243798 :   reg_class super_class = NO_REGS;
     471      8911392 :   for (du_chain *tmp = head->first; tmp; tmp = tmp->next_use)
     472              :     {
     473      4667594 :       if (DEBUG_INSN_P (tmp->insn))
     474        72889 :         continue;
     475      4594705 :       n_uses++;
     476      4594705 :       *punavailable |= ~reg_class_contents[tmp->cl];
     477      4594705 :       super_class
     478      4594705 :         = reg_class_superunion[(int) super_class][(int) tmp->cl];
     479              :     }
     480      4243798 :   *pn_uses = n_uses;
     481      4243798 :   return super_class;
     482              : }
     483              : 
     484              : /* Perform register renaming on the current function.  */
     485              : static void
     486        22497 : rename_chains (void)
     487              : {
     488        22497 :   HARD_REG_SET unavailable;
     489        22497 :   du_head_p this_head;
     490        22497 :   int i;
     491              : 
     492        22497 :   memset (tick, 0, sizeof tick);
     493              : 
     494        22497 :   CLEAR_HARD_REG_SET (unavailable);
     495              :   /* Don't clobber traceback for noreturn functions.  */
     496        22497 :   if (frame_pointer_needed)
     497              :     {
     498          784 :       add_to_hard_reg_set (&unavailable, Pmode, FRAME_POINTER_REGNUM);
     499          743 :       if (!HARD_FRAME_POINTER_IS_FRAME_POINTER)
     500          743 :         add_to_hard_reg_set (&unavailable, Pmode, HARD_FRAME_POINTER_REGNUM);
     501              :     }
     502              : 
     503      4699010 :   FOR_EACH_VEC_ELT (id_to_chain, i, this_head)
     504              :     {
     505      4676513 :       int best_new_reg;
     506      4676513 :       int n_uses;
     507      4676513 :       HARD_REG_SET this_unavailable;
     508      4676513 :       int reg = this_head->regno;
     509              : 
     510      4676513 :       if (this_head->cannot_rename)
     511      4155627 :         continue;
     512              : 
     513      4323132 :       if (fixed_regs[reg] || global_regs[reg]
     514      4322028 :           || (!HARD_FRAME_POINTER_IS_FRAME_POINTER && frame_pointer_needed
     515       927488 :               && reg == HARD_FRAME_POINTER_REGNUM)
     516              :           || (HARD_FRAME_POINTER_IS_FRAME_POINTER && frame_pointer_needed
     517              :               && reg == FRAME_POINTER_REGNUM))
     518        79334 :         continue;
     519              : 
     520      4243798 :       this_unavailable = unavailable;
     521              : 
     522      4243798 :       reg_class super_class = regrename_find_superclass (this_head, &n_uses,
     523              :                                                          &this_unavailable);
     524      4243798 :       if (n_uses < 2)
     525      3255125 :         continue;
     526              : 
     527       988673 :       best_new_reg = find_rename_reg (this_head, super_class,
     528              :                                       &this_unavailable, reg, true);
     529              : 
     530       988673 :       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       988673 :       if (best_new_reg == reg)
     539              :         {
     540       467787 :           tick[reg] = ++this_tick;
     541       467787 :           if (dump_file)
     542           50 :             fprintf (dump_file, "; no available better choice\n");
     543       467787 :           continue;
     544              :         }
     545              : 
     546       520886 :       if (regrename_do_replace (this_head, best_new_reg))
     547              :         {
     548       520822 :           if (dump_file)
     549           60 :             fprintf (dump_file, ", renamed as %s\n", reg_names[best_new_reg]);
     550       520822 :           tick[best_new_reg] = ++this_tick;
     551       520822 :           df_set_regs_ever_live (best_new_reg, true);
     552              :         }
     553              :       else
     554              :         {
     555           64 :           if (dump_file)
     556            0 :             fprintf (dump_file, ", renaming as %s failed\n",
     557              :                      reg_names[best_new_reg]);
     558           64 :           tick[reg] = ++this_tick;
     559              :         }
     560              :     }
     561        22497 : }
     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       578146 : init_rename_info (class bb_rename_info *p, basic_block bb)
     596              : {
     597       578146 :   int i;
     598       578146 :   df_ref def;
     599       578146 :   HARD_REG_SET start_chains_set;
     600              : 
     601       578146 :   p->bb = bb;
     602       578146 :   bitmap_initialize (&p->open_chains_set, &bitmap_default_obstack);
     603       578146 :   bitmap_initialize (&p->incoming_open_chains_set, &bitmap_default_obstack);
     604              : 
     605       578146 :   open_chains = NULL;
     606       578146 :   bitmap_clear (&open_chains_set);
     607              : 
     608      2312584 :   CLEAR_HARD_REG_SET (live_in_chains);
     609       578146 :   REG_SET_TO_HARD_REG_SET (live_hard_regs, df_get_live_in (bb));
     610      1156693 :   FOR_EACH_ARTIFICIAL_DEF (def, bb->index)
     611          401 :     if (DF_REF_FLAGS (def) & DF_REF_AT_TOP)
     612          401 :       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     53767578 :   CLEAR_HARD_REG_SET (start_chains_set);
     623     53767578 :   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
     624              :     {
     625     53189432 :       struct incoming_reg_info *iri = p->incoming + i;
     626      3675769 :       if (iri->nregs > 0 && !iri->unusable
     627     60540970 :           && range_in_hard_reg_set_p (live_hard_regs, i, iri->nregs))
     628              :         {
     629      3225528 :           SET_HARD_REG_BIT (start_chains_set, i);
     630      3225528 :           remove_range_from_hard_reg_set (&live_hard_regs, i, iri->nregs);
     631              :         }
     632              :     }
     633     53767578 :   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
     634              :     {
     635     53189432 :       struct incoming_reg_info *iri = p->incoming + i;
     636     53189432 :       if (TEST_HARD_REG_BIT (start_chains_set, i))
     637              :         {
     638      3225528 :           du_head_p chain;
     639      3225528 :           if (dump_file)
     640          728 :             fprintf (dump_file, "opening incoming chain\n");
     641      3225528 :           chain = create_new_chain (i, iri->nregs, NULL, NULL, NO_REGS);
     642      3225528 :           bitmap_set_bit (&p->incoming_open_chains_set, chain->id);
     643              :         }
     644              :     }
     645       578146 : }
     646              : 
     647              : /* Record in RI that the block corresponding to it has an incoming
     648              :    live value, described by CHAIN.  */
     649              : static void
     650      5599911 : set_incoming_from_chain (class bb_rename_info *ri, du_head_p chain)
     651              : {
     652      5599911 :   int i;
     653      5599911 :   int incoming_nregs = ri->incoming[chain->regno].nregs;
     654      5599911 :   int nregs;
     655              : 
     656              :   /* If we've recorded the same information before, everything is fine.  */
     657      5599911 :   if (incoming_nregs == chain->nregs)
     658              :     {
     659      1922365 :       if (dump_file)
     660          358 :         fprintf (dump_file, "reg %d/%d already recorded\n",
     661              :                  chain->regno, chain->nregs);
     662      1922365 :       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      7355092 :   while (nregs-- > 0)
     669      3677546 :     if (ri->incoming[chain->regno + nregs].nregs != 0
     670      3677546 :         || ri->incoming[chain->regno + nregs].unusable)
     671              :       break;
     672      3677546 :   if (nregs < 0)
     673              :     {
     674      3677546 :       nregs = chain->nregs;
     675      3677546 :       ri->incoming[chain->regno].nregs = nregs;
     676      3677546 :       while (nregs-- > 1)
     677            0 :         ri->incoming[chain->regno + nregs].nregs = -nregs;
     678      3677546 :       if (dump_file)
     679          840 :         fprintf (dump_file, "recorded reg %d/%d\n",
     680              :                  chain->regno, chain->nregs);
     681      3677546 :       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      4657341 : merge_chains (du_head_p c1, du_head_p c2)
     696              : {
     697      4657341 :   if (c1 == c2)
     698              :     return;
     699              : 
     700      3355593 :   if (c2->first != NULL)
     701              :     {
     702      1015058 :       if (c1->first == NULL)
     703        45312 :         c1->first = c2->first;
     704              :       else
     705       969746 :         c1->last->next_use = c2->first;
     706      1015058 :       c1->last = c2->last;
     707              :     }
     708              : 
     709      3355593 :   c2->first = c2->last = NULL;
     710      3355593 :   c2->id = c1->id;
     711              : 
     712      3355593 :   c1->hard_conflicts |= c2->hard_conflicts;
     713      3355593 :   bitmap_ior_into (&c1->conflicts, &c2->conflicts);
     714              : 
     715      3355593 :   c1->call_clobber_mask |= c2->call_clobber_mask;
     716      3355593 :   c1->call_abis |= c2->call_abis;
     717      3355593 :   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        22497 : regrename_analyze (bitmap bb_mask, bool include_all_block_p)
     726              : {
     727        22497 :   class bb_rename_info *rename_info;
     728        22497 :   int i;
     729        22497 :   basic_block bb;
     730        22497 :   int n_bbs;
     731        22497 :   int *inverse_postorder;
     732              : 
     733        22497 :   inverse_postorder = XNEWVEC (int, last_basic_block_for_fn (cfun));
     734        22497 :   n_bbs = pre_and_rev_post_order_compute (NULL, inverse_postorder, false);
     735              : 
     736              :   /* Gather some information about the blocks in this function.  */
     737        22497 :   rename_info = XCNEWVEC (class bb_rename_info, n_basic_blocks_for_fn (cfun));
     738        22497 :   i = 0;
     739       600643 :   FOR_EACH_BB_FN (bb, cfun)
     740              :     {
     741       578146 :       class bb_rename_info *ri = rename_info + i;
     742       578146 :       ri->bb = bb;
     743       578146 :       if (bb_mask != NULL && !bitmap_bit_p (bb_mask, bb->index))
     744            0 :         bb->aux = NULL;
     745              :       else
     746       578146 :         bb->aux = ri;
     747       578146 :       i++;
     748              :     }
     749              : 
     750        22497 :   current_id = 0;
     751        22497 :   id_to_chain.create (0);
     752        22497 :   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       600643 :   for (i = 0; i < n_bbs; i++)
     760              :     {
     761       578146 :       basic_block bb1 = BASIC_BLOCK_FOR_FN (cfun, inverse_postorder[i]);
     762       578146 :       class bb_rename_info *this_info;
     763       578146 :       bool success;
     764       578146 :       edge e;
     765       578146 :       edge_iterator ei;
     766       578146 :       int old_length = id_to_chain.length ();
     767              : 
     768       578146 :       this_info = (class bb_rename_info *) bb1->aux;
     769       578146 :       if (this_info == NULL)
     770            0 :         continue;
     771              : 
     772       578146 :       if (dump_file)
     773          100 :         fprintf (dump_file, "\nprocessing block %d:\n", bb1->index);
     774              : 
     775       578146 :       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       578146 :       init_rename_info (this_info, bb1);
     784              : 
     785       578146 :       success = build_def_use (bb1);
     786       578146 :       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       578146 :       if (dump_file)
     808          100 :         dump_def_use_chain (old_length);
     809       578146 :       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      1473854 :       FOR_EACH_EDGE (e, ei, bb1->succs)
     815              :         {
     816       895708 :           class bb_rename_info *dest_ri;
     817       895708 :           class du_head *chain;
     818              : 
     819       895708 :           if (dump_file)
     820          152 :             fprintf (dump_file, "successor block %d\n", e->dest->index);
     821              : 
     822       895708 :           if (e->flags & (EDGE_EH | EDGE_ABNORMAL))
     823         3500 :             continue;
     824       892208 :           dest_ri = (class bb_rename_info *)e->dest->aux;
     825       892208 :           if (dest_ri == NULL)
     826        22091 :             continue;
     827      6470028 :           for (chain = open_chains; chain; chain = chain->next_chain)
     828      5599911 :             set_incoming_from_chain (dest_ri, chain);
     829              :         }
     830              :     }
     831              : 
     832        22497 :   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       600643 :   FOR_EACH_BB_FN (bb, cfun)
     852              :     {
     853       578146 :       class bb_rename_info *bb_ri = (class bb_rename_info *) bb->aux;
     854       578146 :       unsigned j;
     855       578146 :       bitmap_iterator bi;
     856              : 
     857       578146 :       if (bb_ri == NULL)
     858            0 :         continue;
     859              : 
     860       578146 :       if (dump_file)
     861          100 :         fprintf (dump_file, "processing bb %d in edges\n", bb->index);
     862              : 
     863      3803674 :       EXECUTE_IF_SET_IN_BITMAP (&bb_ri->incoming_open_chains_set, 0, j, bi)
     864              :         {
     865      3225528 :           edge e;
     866      3225528 :           edge_iterator ei;
     867      3225528 :           class du_head *chain = regrename_chain_from_id (j);
     868      3225528 :           int n_preds_used = 0, n_preds_joined = 0;
     869              : 
     870      7890948 :           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     13996260 :               bool success = false;
     877              : 
     878      4665420 :               REG_SET_TO_HARD_REG_SET (live, df_get_live_out (e->src));
     879      9330840 :               if (!range_overlaps_hard_reg_set_p (live, chain->regno,
     880              :                                                   chain->nregs))
     881           78 :                 continue;
     882      4665356 :               n_preds_used++;
     883              : 
     884      4665356 :               if (e->flags & (EDGE_EH | EDGE_ABNORMAL))
     885           14 :                 continue;
     886              : 
     887      4665342 :               src_ri = (class bb_rename_info *)e->src->aux;
     888      4665342 :               if (src_ri == NULL)
     889            0 :                 continue;
     890              : 
     891     26408673 :               EXECUTE_IF_SET_IN_BITMAP (&src_ri->open_chains_set,
     892              :                                         0, k, bi2)
     893              :                 {
     894     26400661 :                   class du_head *outgoing_chain = regrename_chain_from_id (k);
     895              : 
     896     26400661 :                   if (outgoing_chain->regno == chain->regno
     897      4657330 :                       && outgoing_chain->nregs == chain->nregs)
     898              :                     {
     899      4657330 :                       n_preds_joined++;
     900      4657330 :                       success = true;
     901      4657330 :                       break;
     902              :                     }
     903              :                 }
     904      4665342 :               if (!success && dump_file)
     905            4 :                 fprintf (dump_file, "failure to match with pred block %d\n",
     906            4 :                          e->src->index);
     907              :             }
     908      3225528 :           if (n_preds_joined < n_preds_used)
     909              :             {
     910         4874 :               if (dump_file)
     911            4 :                 fprintf (dump_file, "cannot rename chain %d\n", j);
     912         4874 :               chain->cannot_rename = 1;
     913              :             }
     914              :         }
     915              :     }
     916       600643 :   FOR_EACH_BB_FN (bb, cfun)
     917              :     {
     918       578146 :       class bb_rename_info *bb_ri = (class bb_rename_info *) bb->aux;
     919       578146 :       unsigned j;
     920       578146 :       bitmap_iterator bi;
     921              : 
     922       578146 :       if (bb_ri == NULL)
     923            0 :         continue;
     924              : 
     925       578146 :       if (dump_file)
     926          100 :         fprintf (dump_file, "processing bb %d out edges\n", bb->index);
     927              : 
     928      3989760 :       EXECUTE_IF_SET_IN_BITMAP (&bb_ri->open_chains_set, 0, j, bi)
     929              :         {
     930      3411614 :           edge e;
     931      3411614 :           edge_iterator ei;
     932      3411614 :           class du_head *chain = regrename_chain_from_id (j);
     933      3411614 :           int n_succs_used = 0, n_succs_joined = 0;
     934              : 
     935      9047580 :           FOR_EACH_EDGE (e, ei, bb->succs)
     936              :             {
     937     16907898 :               bool printed = false;
     938              :               class bb_rename_info *dest_ri;
     939              :               unsigned k;
     940              :               bitmap_iterator bi2;
     941              :               HARD_REG_SET live;
     942              : 
     943      5635966 :               REG_SET_TO_HARD_REG_SET (live, df_get_live_in (e->dest));
     944     11271932 :               if (!range_overlaps_hard_reg_set_p (live, chain->regno,
     945              :                                                   chain->nregs))
     946       977832 :                 continue;
     947              : 
     948      4693294 :               n_succs_used++;
     949              : 
     950      4693294 :               dest_ri = (class bb_rename_info *)e->dest->aux;
     951      4693294 :               if (dest_ri == NULL)
     952        35160 :                 continue;
     953              : 
     954     25168225 :               EXECUTE_IF_SET_IN_BITMAP (&dest_ri->incoming_open_chains_set,
     955              :                                         0, k, bi2)
     956              :                 {
     957     25167432 :                   class du_head *incoming_chain = regrename_chain_from_id (k);
     958              : 
     959     25167432 :                   if (incoming_chain->regno == chain->regno
     960      4657341 :                       && incoming_chain->nregs == chain->nregs)
     961              :                     {
     962      4657341 :                       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      4657341 :                       merge_chains (chain, incoming_chain);
     976      4657341 :                       n_succs_joined++;
     977      4657341 :                       break;
     978              :                     }
     979              :                 }
     980              :             }
     981      3411614 :           if (n_succs_joined < n_succs_used)
     982              :             {
     983        35889 :               if (dump_file)
     984           12 :                 fprintf (dump_file, "cannot rename chain %d\n",
     985              :                          j);
     986        35889 :               chain->cannot_rename = 1;
     987              :             }
     988              :         }
     989              :     }
     990              : 
     991        22497 :   free (rename_info);
     992              : 
     993       600643 :   FOR_EACH_BB_FN (bb, cfun)
     994       578146 :     bb->aux = NULL;
     995        22497 : }
     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       520886 : regrename_do_replace (class du_head *head, int reg)
    1005              : {
    1006       520886 :   struct du_chain *chain;
    1007       520886 :   unsigned int base_regno = head->regno;
    1008       520886 :   machine_mode mode;
    1009       520886 :   rtx last_reg = NULL_RTX, last_repl = NULL_RTX;
    1010              : 
    1011      2412982 :   for (chain = head->first; chain; chain = chain->next_use)
    1012              :     {
    1013      1892096 :       unsigned int regno = ORIGINAL_REGNO (*chain->loc);
    1014      1892096 :       class reg_attrs *attr = REG_ATTRS (*chain->loc);
    1015      1892096 :       int reg_ptr = REG_POINTER (*chain->loc);
    1016              : 
    1017      1892096 :       if (DEBUG_INSN_P (chain->insn) && REGNO (*chain->loc) != base_regno)
    1018          310 :         validate_change (chain->insn, &(INSN_VAR_LOCATION_LOC (chain->insn)),
    1019              :                          gen_rtx_UNKNOWN_VAR_LOC (), true);
    1020              :       else
    1021              :         {
    1022      1891786 :           if (*chain->loc != last_reg)
    1023              :             {
    1024      1031198 :               last_repl = gen_raw_REG (GET_MODE (*chain->loc), reg);
    1025      1031198 :               if (regno >= FIRST_PSEUDO_REGISTER)
    1026      1010863 :                 ORIGINAL_REGNO (last_repl) = regno;
    1027      1031198 :               REG_ATTRS (last_repl) = attr;
    1028      1031198 :               REG_POINTER (last_repl) = reg_ptr;
    1029      1031198 :               last_reg = *chain->loc;
    1030              :             }
    1031      1891786 :           validate_change (chain->insn, chain->loc, last_repl, true);
    1032              :         }
    1033              :     }
    1034              : 
    1035       520886 :   if (!apply_change_group ())
    1036              :     return false;
    1037              : 
    1038       520822 :   mode = GET_MODE (*head->first->loc);
    1039       520822 :   head->renamed = 1;
    1040       520822 :   head->regno = reg;
    1041       520822 :   head->nregs = hard_regno_nregs (reg, mode);
    1042       520822 :   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      2353047 : verify_reg_in_set (rtx op, HARD_REG_SET *pset)
    1057              : {
    1058      2353047 :   unsigned regno, nregs;
    1059      2353047 :   bool all_live, all_dead;
    1060      2353047 :   if (!REG_P (op))
    1061              :     return false;
    1062              : 
    1063      2343131 :   regno = REGNO (op);
    1064      2343131 :   nregs = REG_NREGS (op);
    1065      2343131 :   all_live = all_dead = true;
    1066      4686284 :   while (nregs-- > 0)
    1067      2343153 :     if (TEST_HARD_REG_BIT (*pset, regno + nregs))
    1068              :       all_dead = false;
    1069              :     else
    1070      1129834 :       all_live = false;
    1071      2343131 :   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      1209322 : verify_reg_tracked (rtx op)
    1084              : {
    1085      1209322 :   return (verify_reg_in_set (op, &live_hard_regs)
    1086      1209322 :           || 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      8164412 : note_sets_clobbers (rtx x, const_rtx set, void *data)
    1096              : {
    1097      8164412 :   enum rtx_code code = *(enum rtx_code *)data;
    1098      8164412 :   class du_head *chain;
    1099              : 
    1100      8164412 :   if (GET_CODE (x) == SUBREG)
    1101            0 :     x = SUBREG_REG (x);
    1102      8164412 :   if (!REG_P (x) || GET_CODE (set) != code)
    1103              :     return;
    1104              :   /* There must not be pseudos at this point.  */
    1105       938454 :   gcc_assert (HARD_REGISTER_P (x));
    1106       938454 :   add_to_hard_reg_set (&live_hard_regs, GET_MODE (x), REGNO (x));
    1107      7313748 :   for (chain = open_chains; chain; chain = chain->next_chain)
    1108      6375294 :     add_to_hard_reg_set (&chain->hard_conflicts, GET_MODE (x), REGNO (x));
    1109              : }
    1110              : 
    1111              : static void
    1112     17528634 : scan_rtx_reg (rtx_insn *insn, rtx *loc, enum reg_class cl, enum scan_actions action,
    1113              :               enum op_type type)
    1114              : {
    1115     17528634 :   class du_head **p;
    1116     17528634 :   rtx x = *loc;
    1117     17528634 :   unsigned this_regno = REGNO (x);
    1118     17528634 :   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     17528634 :   if ((action == mark_write || action == terminate_write)
    1123     17528634 :         && single_output_fused_pair_p (insn))
    1124              :     return;
    1125              : 
    1126     17528634 :   if (action == mark_write)
    1127              :     {
    1128      1450976 :       if (type == OP_OUT)
    1129              :         {
    1130      1450976 :           du_head_p c;
    1131      1450976 :           rtx pat = PATTERN (insn);
    1132              : 
    1133      1450976 :           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      1450976 :           if (recog_data.n_operands == 2
    1138      1307099 :               && GET_CODE (pat) == SET
    1139      1228028 :               && GET_CODE (SET_DEST (pat)) == REG
    1140      1228028 :               && GET_CODE (SET_SRC (pat)) == REG
    1141       203401 :               && terminated_this_insn
    1142        60796 :               && terminated_this_insn->nregs
    1143        60796 :                  == REG_NREGS (recog_data.operand[1]))
    1144              :             {
    1145        60756 :               gcc_assert (terminated_this_insn->regno
    1146              :                           == REGNO (recog_data.operand[1]));
    1147              : 
    1148        60756 :               c->tied_chain = terminated_this_insn;
    1149        60756 :               terminated_this_insn->tied_chain = c;
    1150              : 
    1151        60756 :               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      1450976 :       return;
    1160              :     }
    1161              : 
    1162     16077658 :   if ((type == OP_OUT) != (action == terminate_write || action == mark_access)
    1163     17528664 :         && ! (type == OP_OUT && action == mark_read
    1164      1451006 :               && single_output_fused_pair_p (insn)))
    1165      6046280 :     return;
    1166              : 
    1167     85985333 :   for (p = &open_chains; *p;)
    1168              :     {
    1169     76044682 :       class du_head *head = *p;
    1170     76044682 :       class du_head *next = head->next_chain;
    1171    152089364 :       int exact_match = (head->regno == this_regno
    1172     76044682 :                          && head->nregs == this_nregs);
    1173    152089364 :       int superset = (this_regno <= head->regno
    1174     76044682 :                       && this_regno + this_nregs >= head->regno + head->nregs);
    1175    152089364 :       int subset = (this_regno >= head->regno
    1176     76044682 :                       && this_regno + this_nregs <= head->regno + head->nregs);
    1177              : 
    1178     76044682 :       if (!bitmap_bit_p (&open_chains_set, head->id)
    1179     76044682 :           || head->regno + head->nregs <= this_regno
    1180    120793220 :           || this_regno + this_nregs <= head->regno)
    1181              :         {
    1182     70660794 :           p = &head->next_chain;
    1183     70660794 :           continue;
    1184              :         }
    1185              : 
    1186      5383888 :       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      3799457 :           if (cl == NO_REGS || (!exact_match && !DEBUG_INSN_P (insn)))
    1193              :             {
    1194         4124 :               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         4124 :               head->cannot_rename = 1;
    1200         4124 :               if (superset)
    1201              :                 {
    1202           19 :                   unsigned nregs = this_nregs;
    1203           19 :                   head->regno = this_regno;
    1204           19 :                   head->nregs = this_nregs;
    1205           48 :                   while (nregs-- > 0)
    1206           29 :                     SET_HARD_REG_BIT (live_in_chains, head->regno + nregs);
    1207           19 :                   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         4105 :               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      3795333 :               struct du_chain *this_du;
    1223      3795333 :               this_du = XOBNEW (&rename_obstack, struct du_chain);
    1224      3795333 :               this_du->next_use = 0;
    1225      3795333 :               this_du->loc = loc;
    1226      3795333 :               this_du->insn = insn;
    1227      3795333 :               this_du->cl = cl;
    1228      3795333 :               if (head->first == NULL)
    1229       839690 :                 head->first = this_du;
    1230              :               else
    1231      2955643 :                 head->last->next_use = this_du;
    1232      3795333 :               record_operand_use (head, this_du);
    1233      3795333 :               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      3799457 :           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      3708730 :           p = &head->next_chain;
    1242      3708730 :           continue;
    1243      3708730 :         }
    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      1584431 :       if ((action == terminate_dead || action == terminate_write)
    1250      1264899 :           && (superset || subset))
    1251              :         {
    1252      1264899 :           unsigned nregs;
    1253              : 
    1254      1264899 :           if (subset && !superset)
    1255         1652 :             head->cannot_rename = 1;
    1256      1264899 :           bitmap_clear_bit (&open_chains_set, head->id);
    1257              : 
    1258      1264899 :           nregs = head->nregs;
    1259      2531450 :           while (nregs-- > 0)
    1260              :             {
    1261      1266551 :               CLEAR_HARD_REG_BIT (live_in_chains, head->regno + nregs);
    1262      1266551 :               if (subset && !superset
    1263         3304 :                   && (head->regno + nregs < this_regno
    1264         2496 :                       || head->regno + nregs >= this_regno + this_nregs))
    1265         1652 :                 SET_HARD_REG_BIT (live_hard_regs, head->regno + nregs);
    1266              :             }
    1267              : 
    1268      1264899 :           if (action == terminate_dead)
    1269      1129067 :             terminated_this_insn = *p;
    1270      1264899 :           *p = next;
    1271      1264899 :           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       319532 :           head->cannot_rename = 1;
    1291       319532 :           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       319532 :           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      6523738 : 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      6379556 :   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      7733124 : 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      7733124 :   rtx x = *loc;
    1323      7733124 :   RTX_CODE code = GET_CODE (x);
    1324      7733124 :   const char *fmt;
    1325      7733124 :   int i, j;
    1326              : 
    1327      7733124 :   if (action == mark_write || action == mark_access)
    1328              :     return;
    1329              : 
    1330      7148000 :   switch (code)
    1331              :     {
    1332      2640026 :     case PLUS:
    1333      2640026 :       {
    1334      2640026 :         rtx orig_op0 = XEXP (x, 0);
    1335      2640026 :         rtx orig_op1 = XEXP (x, 1);
    1336      2640026 :         RTX_CODE code0 = GET_CODE (orig_op0);
    1337      2640026 :         RTX_CODE code1 = GET_CODE (orig_op1);
    1338      2640026 :         rtx op0 = orig_op0;
    1339      2640026 :         rtx op1 = orig_op1;
    1340      2640026 :         rtx *locI = NULL;
    1341      2640026 :         rtx *locB = NULL;
    1342      2640026 :         enum rtx_code index_code = SCRATCH;
    1343              : 
    1344      2640026 :         if (GET_CODE (op0) == SUBREG)
    1345              :           {
    1346            0 :             op0 = SUBREG_REG (op0);
    1347            0 :             code0 = GET_CODE (op0);
    1348              :           }
    1349              : 
    1350      2640026 :         if (GET_CODE (op1) == SUBREG)
    1351              :           {
    1352            0 :             op1 = SUBREG_REG (op1);
    1353            0 :             code1 = GET_CODE (op1);
    1354              :           }
    1355              : 
    1356      2640026 :         if (code0 == MULT || code0 == SIGN_EXTEND || code0 == TRUNCATE
    1357      2484126 :             || code0 == ZERO_EXTEND || code1 == MEM)
    1358              :           {
    1359       155946 :             locI = &XEXP (x, 0);
    1360       155946 :             locB = &XEXP (x, 1);
    1361       155946 :             index_code = GET_CODE (*locI);
    1362              :           }
    1363      2484080 :         else if (code1 == MULT || code1 == SIGN_EXTEND || code1 == TRUNCATE
    1364      2484073 :                  || code1 == ZERO_EXTEND || code0 == MEM)
    1365              :           {
    1366          391 :             locI = &XEXP (x, 1);
    1367          391 :             locB = &XEXP (x, 0);
    1368          391 :             index_code = GET_CODE (*locI);
    1369              :           }
    1370      2483689 :         else if (code0 == CONST_INT || code0 == CONST
    1371      2483689 :                  || code0 == SYMBOL_REF || code0 == LABEL_REF)
    1372              :           {
    1373        77883 :             locB = &XEXP (x, 1);
    1374        77883 :             index_code = GET_CODE (XEXP (x, 0));
    1375              :           }
    1376      2405806 :         else if (code1 == CONST_INT || code1 == CONST
    1377              :                  || code1 == SYMBOL_REF || code1 == LABEL_REF)
    1378              :           {
    1379      2157130 :             locB = &XEXP (x, 0);
    1380      2157130 :             index_code = GET_CODE (XEXP (x, 1));
    1381              :           }
    1382       248676 :         else if (code0 == REG && code1 == REG)
    1383              :           {
    1384       216991 :             int index_op;
    1385       216991 :             unsigned regno0 = REGNO (op0), regno1 = REGNO (op1);
    1386              : 
    1387            9 :             if (REGNO_OK_FOR_INDEX_P (regno1)
    1388       216991 :                 && regno_ok_for_base_p (regno0, mode, as, PLUS, REG))
    1389              :               index_op = 1;
    1390            0 :             else if (REGNO_OK_FOR_INDEX_P (regno0)
    1391            9 :                      && regno_ok_for_base_p (regno1, mode, as, PLUS, REG))
    1392              :               index_op = 0;
    1393            0 :             else if (regno_ok_for_base_p (regno0, mode, as, PLUS, REG)
    1394            0 :                      || REGNO_OK_FOR_INDEX_P (regno1))
    1395              :               index_op = 1;
    1396            0 :             else if (regno_ok_for_base_p (regno1, mode, as, PLUS, REG))
    1397              :               index_op = 0;
    1398              :             else
    1399       216982 :               index_op = 1;
    1400              : 
    1401       216991 :             locI = &XEXP (x, index_op);
    1402       216991 :             locB = &XEXP (x, !index_op);
    1403       216991 :             index_code = GET_CODE (*locI);
    1404              :           }
    1405        31685 :         else if (code0 == REG)
    1406              :           {
    1407         4475 :             locI = &XEXP (x, 0);
    1408         4475 :             locB = &XEXP (x, 1);
    1409         4475 :             index_code = GET_CODE (*locI);
    1410              :           }
    1411        27210 :         else if (code1 == REG)
    1412              :           {
    1413        27173 :             locI = &XEXP (x, 1);
    1414        27173 :             locB = &XEXP (x, 0);
    1415        27173 :             index_code = GET_CODE (*locI);
    1416              :           }
    1417              : 
    1418      2639989 :         if (locI)
    1419              :           {
    1420       404976 :             reg_class iclass = DEBUG_INSN_P (insn) ? ALL_REGS : INDEX_REG_CLASS;
    1421       404976 :             scan_rtx_address (insn, locI, iclass, action, mode, as);
    1422              :           }
    1423      2640026 :         if (locB)
    1424              :           {
    1425      2639989 :             reg_class bclass = base_reg_class_for_rename (insn, mode, as, PLUS,
    1426              :                                                           index_code);
    1427      2639989 :             scan_rtx_address (insn, locB, bclass, action, mode, as);
    1428              :           }
    1429              :         return;
    1430              :       }
    1431              : 
    1432       127354 :     case POST_INC:
    1433       127354 :     case POST_DEC:
    1434       127354 :     case POST_MODIFY:
    1435       127354 :     case PRE_INC:
    1436       127354 :     case PRE_DEC:
    1437       127354 :     case PRE_MODIFY:
    1438              :       /* If the target doesn't claim to handle autoinc, this must be
    1439              :          something special, like a stack push.  Kill this chain.  */
    1440       127354 :       if (!AUTO_INC_DEC)
    1441       127354 :         action = mark_all_read;
    1442              : 
    1443       127354 :       break;
    1444              : 
    1445         1719 :     case MEM:
    1446         1719 :       {
    1447         1719 :         reg_class bclass = base_reg_class_for_rename (insn, GET_MODE (x),
    1448         1719 :                                                       MEM_ADDR_SPACE (x),
    1449              :                                                       MEM, SCRATCH);
    1450         1719 :         scan_rtx_address (insn, &XEXP (x, 0), bclass, action, GET_MODE (x),
    1451         1719 :                           MEM_ADDR_SPACE (x));
    1452              :       }
    1453         1719 :       return;
    1454              : 
    1455      3239807 :     case REG:
    1456      3239807 :       scan_rtx_reg (insn, loc, cl, action, OP_IN);
    1457      3239807 :       return;
    1458              : 
    1459              :     default:
    1460              :       break;
    1461              :     }
    1462              : 
    1463      1266448 :   fmt = GET_RTX_FORMAT (code);
    1464      2833976 :   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
    1465              :     {
    1466      1567528 :       if (fmt[i] == 'e')
    1467       601299 :         scan_rtx_address (insn, &XEXP (x, i), cl, action, mode, as);
    1468       966229 :       else if (fmt[i] == 'E')
    1469         3552 :         for (j = XVECLEN (x, i) - 1; j >= 0; j--)
    1470         1900 :           scan_rtx_address (insn, &XVECEXP (x, i, j), cl, action, mode, as);
    1471              :     }
    1472              : }
    1473              : 
    1474              : static void
    1475     39346989 : scan_rtx (rtx_insn *insn, rtx *loc, enum reg_class cl, enum scan_actions action,
    1476              :           enum op_type type)
    1477              : {
    1478     47716164 :   const char *fmt;
    1479     47716164 :   rtx x = *loc;
    1480     47716164 :   int i, j;
    1481              : 
    1482     47716164 :   enum rtx_code code = GET_CODE (x);
    1483     47716164 :   switch (code)
    1484              :     {
    1485              :     case CONST:
    1486              :     CASE_CONST_ANY:
    1487              :     case SYMBOL_REF:
    1488              :     case LABEL_REF:
    1489              :     case PC:
    1490              :       return;
    1491              : 
    1492     14288827 :     case REG:
    1493     14288827 :       scan_rtx_reg (insn, loc, cl, action, type);
    1494     14288827 :       return;
    1495              : 
    1496      3882030 :     case MEM:
    1497      3882030 :       {
    1498      3882030 :         reg_class bclass = base_reg_class_for_rename (insn, GET_MODE (x),
    1499      3882030 :                                                       MEM_ADDR_SPACE (x),
    1500              :                                                       MEM, SCRATCH);
    1501              : 
    1502      3882030 :         scan_rtx_address (insn, &XEXP (x, 0), bclass, action, GET_MODE (x),
    1503      3882030 :                           MEM_ADDR_SPACE (x));
    1504              :       }
    1505      3882030 :       return;
    1506              : 
    1507      7062576 :     case SET:
    1508      7062576 :       scan_rtx (insn, &SET_SRC (x), cl, action, OP_IN);
    1509     14125152 :       scan_rtx (insn, &SET_DEST (x), cl, action,
    1510      7062576 :                 (GET_CODE (PATTERN (insn)) == COND_EXEC
    1511            0 :                  && verify_reg_tracked (SET_DEST (x))) ? OP_INOUT : OP_OUT);
    1512      7062576 :       return;
    1513              : 
    1514         3834 :     case STRICT_LOW_PART:
    1515         3834 :       scan_rtx (insn, &XEXP (x, 0), cl, action,
    1516         3834 :                 verify_reg_tracked (XEXP (x, 0)) ? OP_INOUT : OP_OUT);
    1517         3834 :       return;
    1518              : 
    1519         5322 :     case ZERO_EXTRACT:
    1520         5322 :     case SIGN_EXTRACT:
    1521         6446 :       scan_rtx (insn, &XEXP (x, 0), cl, action,
    1522              :                 (type == OP_IN ? OP_IN :
    1523         1124 :                  verify_reg_tracked (XEXP (x, 0)) ? OP_INOUT : OP_OUT));
    1524         5322 :       scan_rtx (insn, &XEXP (x, 1), cl, action, OP_IN);
    1525         5322 :       scan_rtx (insn, &XEXP (x, 2), cl, action, OP_IN);
    1526         5322 :       return;
    1527              : 
    1528            0 :     case POST_INC:
    1529            0 :     case PRE_INC:
    1530            0 :     case POST_DEC:
    1531            0 :     case PRE_DEC:
    1532            0 :     case POST_MODIFY:
    1533            0 :     case PRE_MODIFY:
    1534              :       /* Should only happen inside MEM.  */
    1535            0 :       gcc_unreachable ();
    1536              : 
    1537      1106358 :     case CLOBBER:
    1538      2212716 :       scan_rtx (insn, &SET_DEST (x), cl, action,
    1539      1106358 :                 (GET_CODE (PATTERN (insn)) == COND_EXEC
    1540            0 :                  && verify_reg_tracked (SET_DEST (x))) ? OP_INOUT : OP_OUT);
    1541      1106358 :       return;
    1542              : 
    1543       323056 :     case EXPR_LIST:
    1544       323056 :       scan_rtx (insn, &XEXP (x, 0), cl, action, type);
    1545       323056 :       if (XEXP (x, 1))
    1546       191085 :         scan_rtx (insn, &XEXP (x, 1), cl, action, type);
    1547              :       return;
    1548              : 
    1549      6775180 :     default:
    1550      6775180 :       break;
    1551              :     }
    1552              : 
    1553      6775180 :   fmt = GET_RTX_FORMAT (code);
    1554     18973304 :   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
    1555              :     {
    1556     12198124 :       if (fmt[i] == 'e')
    1557     10378363 :         scan_rtx (insn, &XEXP (x, i), cl, action, type);
    1558      1819761 :       else if (fmt[i] == 'E')
    1559      4347524 :         for (j = XVECLEN (x, i) - 1; j >= 0; j--)
    1560      3011520 :           scan_rtx (insn, &XVECEXP (x, i, j), cl, action, type);
    1561              :     }
    1562              : }
    1563              : 
    1564              : /* Hide operands of the current insn (of which there are N_OPS) by
    1565              :    substituting pc for them.
    1566              :    Previous values are stored in the OLD_OPERANDS and OLD_DUPS.
    1567              :    For every bit set in DO_NOT_HIDE, we leave the operand alone.
    1568              :    If INOUT_AND_EC_ONLY is set, we only do this for OP_INOUT type operands
    1569              :    and earlyclobbers.  */
    1570              : 
    1571              : static void
    1572     14488108 : hide_operands (int n_ops, rtx *old_operands, rtx *old_dups,
    1573              :                unsigned HOST_WIDE_INT do_not_hide, bool inout_and_ec_only)
    1574              : {
    1575     14488108 :   int i;
    1576     14488108 :   const operand_alternative *op_alt = which_op_alt ();
    1577     61172304 :   for (i = 0; i < n_ops; i++)
    1578              :     {
    1579     32196088 :       old_operands[i] = recog_data.operand[i];
    1580              :       /* Don't squash match_operator or match_parallel here, since
    1581              :          we don't know that all of the contained registers are
    1582              :          reachable by proper operands.  */
    1583     32196088 :       if (recog_data.constraints[i][0] == '\0')
    1584      5326988 :         continue;
    1585     26869100 :       if (do_not_hide & (1 << i))
    1586         1528 :         continue;
    1587     26867572 :       if (!inout_and_ec_only || recog_data.operand_type[i] == OP_INOUT
    1588      5460658 :           || op_alt[i].earlyclobber)
    1589     21406996 :         *recog_data.operand_loc[i] = pc_rtx;
    1590              :     }
    1591     14846112 :   for (i = 0; i < recog_data.n_dups; i++)
    1592              :     {
    1593       358004 :       int opn = recog_data.dup_num[i];
    1594       358004 :       old_dups[i] = *recog_data.dup_loc[i];
    1595       358004 :       if (do_not_hide & (1 << opn))
    1596            0 :         continue;
    1597       358004 :       if (!inout_and_ec_only || recog_data.operand_type[opn] == OP_INOUT
    1598        46863 :           || op_alt[opn].earlyclobber)
    1599       311141 :         *recog_data.dup_loc[i] = pc_rtx;
    1600              :     }
    1601     14488108 : }
    1602              : 
    1603              : /* Undo the substitution performed by hide_operands.  INSN is the insn we
    1604              :    are processing; the arguments are the same as in hide_operands.  */
    1605              : 
    1606              : static void
    1607     14488108 : restore_operands (rtx_insn *insn, int n_ops, rtx *old_operands, rtx *old_dups)
    1608              : {
    1609     14488108 :   int i;
    1610     14846112 :   for (i = 0; i < recog_data.n_dups; i++)
    1611       358004 :     *recog_data.dup_loc[i] = old_dups[i];
    1612     46684196 :   for (i = 0; i < n_ops; i++)
    1613     32196088 :     *recog_data.operand_loc[i] = old_operands[i];
    1614     14488108 :   if (recog_data.n_dups)
    1615       196848 :     df_insn_rescan (insn);
    1616     14488108 : }
    1617              : 
    1618              : /* For each output operand of INSN, call scan_rtx to create a new
    1619              :    open chain.  Do this only for normal or earlyclobber outputs,
    1620              :    depending on EARLYCLOBBER.  If INSN_INFO is nonnull, use it to
    1621              :    record information about the operands in the insn.  */
    1622              : 
    1623              : static void
    1624      7244054 : record_out_operands (rtx_insn *insn, bool earlyclobber, insn_rr_info *insn_info)
    1625              : {
    1626      7244054 :   int n_ops = recog_data.n_operands;
    1627      7244054 :   const operand_alternative *op_alt = which_op_alt ();
    1628              : 
    1629      7244054 :   int i;
    1630              : 
    1631     23521100 :   for (i = 0; i < n_ops + recog_data.n_dups; i++)
    1632              :     {
    1633     16277046 :       int opn = i < n_ops ? i : recog_data.dup_num[i - n_ops];
    1634     16098044 :       rtx *loc = (i < n_ops
    1635     16277046 :                   ? recog_data.operand_loc[opn]
    1636       179002 :                   : recog_data.dup_loc[i - n_ops]);
    1637     16277046 :       rtx op = *loc;
    1638     16277046 :       enum reg_class cl = alternative_class (op_alt, opn);
    1639              : 
    1640     16277046 :       class du_head *prev_open;
    1641              : 
    1642     16277046 :       if (recog_data.operand_type[opn] != OP_OUT
    1643      4072200 :           || op_alt[opn].earlyclobber != earlyclobber)
    1644     14240946 :         continue;
    1645              : 
    1646      2036100 :       if (insn_info)
    1647            0 :         cur_operand = insn_info->op_info + i;
    1648              : 
    1649      2036100 :       prev_open = open_chains;
    1650      2036100 :       if (earlyclobber)
    1651           82 :         scan_rtx (insn, loc, cl, terminate_write, OP_OUT);
    1652      2036100 :       scan_rtx (insn, loc, cl, mark_write, OP_OUT);
    1653              : 
    1654              :       /* ??? Many targets have output constraints on the SET_DEST
    1655              :          of a call insn, which is stupid, since these are certainly
    1656              :          ABI defined hard registers.  For these, and for asm operands
    1657              :          that originally referenced hard registers, we must record that
    1658              :          the chain cannot be renamed.  */
    1659      2036100 :       if (CALL_P (insn)
    1660      2036100 :           || (asm_noperands (PATTERN (insn)) > 0
    1661          475 :               && REG_P (op)
    1662          267 :               && REGNO (op) == ORIGINAL_REGNO (op)))
    1663              :         {
    1664            0 :           if (prev_open != open_chains)
    1665            0 :             open_chains->cannot_rename = 1;
    1666              :         }
    1667              :     }
    1668      7244054 :   cur_operand = NULL;
    1669      7244054 : }
    1670              : 
    1671              : /* Build def/use chain.  */
    1672              : 
    1673              : static bool
    1674       578146 : build_def_use (basic_block bb)
    1675              : {
    1676       578146 :   rtx_insn *insn;
    1677       578146 :   unsigned HOST_WIDE_INT untracked_operands;
    1678              : 
    1679       578146 :   fail_current_block = false;
    1680              : 
    1681      5995138 :   for (insn = BB_HEAD (bb); ; insn = NEXT_INSN (insn))
    1682              :     {
    1683      5995138 :       if (NONDEBUG_INSN_P (insn))
    1684              :         {
    1685      3622027 :           int n_ops;
    1686      3622027 :           rtx note;
    1687      3622027 :           rtx old_operands[MAX_RECOG_OPERANDS];
    1688      3622027 :           rtx old_dups[MAX_DUP_OPERANDS];
    1689      3622027 :           int i;
    1690      3622027 :           int predicated;
    1691      3622027 :           enum rtx_code set_code = SET;
    1692      3622027 :           enum rtx_code clobber_code = CLOBBER;
    1693      3622027 :           insn_rr_info *insn_info = NULL;
    1694      3622027 :           terminated_this_insn = NULL;
    1695              : 
    1696              :           /* Process the insn, determining its effect on the def-use
    1697              :              chains and live hard registers.  We perform the following
    1698              :              steps with the register references in the insn, simulating
    1699              :              its effect:
    1700              :              (1) Deal with earlyclobber operands and CLOBBERs of non-operands
    1701              :                  by creating chains and marking hard regs live.
    1702              :              (2) Any read outside an operand causes any chain it overlaps
    1703              :                  with to be marked unrenamable.
    1704              :              (3) Any read inside an operand is added if there's already
    1705              :                  an open chain for it.
    1706              :              (4) For any REG_DEAD note we find, close open chains that
    1707              :                  overlap it.
    1708              :              (5) For any non-earlyclobber write we find, close open chains
    1709              :                  that overlap it.
    1710              :              (6) For any non-earlyclobber write we find in an operand, make
    1711              :                  a new chain or mark the hard register as live.
    1712              :              (7) For any REG_UNUSED, close any chains we just opened.
    1713              :              (8) For any REG_CFA_RESTORE or REG_CFA_REGISTER, kill any chain
    1714              :                  containing its dest.
    1715              : 
    1716              :              We cannot deal with situations where we track a reg in one mode
    1717              :              and see a reference in another mode; these will cause the chain
    1718              :              to be marked unrenamable or even cause us to abort the entire
    1719              :              basic block.  */
    1720              : 
    1721      3622027 :           extract_constrain_insn (insn);
    1722      3622027 :           preprocess_constraints (insn);
    1723      3622027 :           const operand_alternative *op_alt = which_op_alt ();
    1724      3622027 :           n_ops = recog_data.n_operands;
    1725      3622027 :           untracked_operands = 0;
    1726              : 
    1727      3622027 :           if (insn_rr.exists ())
    1728              :             {
    1729            0 :               insn_info = &insn_rr[INSN_UID (insn)];
    1730            0 :               insn_info->op_info = XOBNEWVEC (&rename_obstack, operand_rr_info,
    1731              :                                               recog_data.n_operands);
    1732            0 :               memset (insn_info->op_info, 0,
    1733            0 :                       sizeof (operand_rr_info) * recog_data.n_operands);
    1734              :             }
    1735              : 
    1736              :           /* Simplify the code below by promoting OP_OUT to OP_INOUT in
    1737              :              predicated instructions, but only for register operands
    1738              :              that are already tracked, so that we can create a chain
    1739              :              when the first SET makes a register live.  */
    1740              : 
    1741      3622027 :           predicated = GET_CODE (PATTERN (insn)) == COND_EXEC;
    1742     11671049 :           for (i = 0; i < n_ops; ++i)
    1743              :             {
    1744      8049022 :               rtx op = recog_data.operand[i];
    1745      8049022 :               int matches = op_alt[i].matches;
    1746      8049022 :               if (matches >= 0 || op_alt[i].matched >= 0
    1747      6799082 :                   || (predicated && recog_data.operand_type[i] == OP_OUT))
    1748              :                 {
    1749      1249940 :                   recog_data.operand_type[i] = OP_INOUT;
    1750              :                   /* A special case to deal with instruction patterns that
    1751              :                      have matching operands with different modes.  If we're
    1752              :                      not already tracking such a reg, we won't start here,
    1753              :                      and we must instead make sure to make the operand visible
    1754              :                      to the machinery that tracks hard registers.  */
    1755      1249940 :                   machine_mode i_mode = recog_data.operand_mode[i];
    1756      1249940 :                   if (matches >= 0)
    1757              :                     {
    1758       624970 :                       machine_mode matches_mode
    1759              :                         = recog_data.operand_mode[matches];
    1760              : 
    1761       624970 :                       if (maybe_ne (GET_MODE_SIZE (i_mode),
    1762       624970 :                                     GET_MODE_SIZE (matches_mode))
    1763       624970 :                           && !verify_reg_in_set (op, &live_in_chains))
    1764              :                         {
    1765          191 :                           untracked_operands |= 1 << i;
    1766          191 :                           untracked_operands |= 1 << matches;
    1767              :                         }
    1768              :                     }
    1769              :                 }
    1770              : #ifdef STACK_REGS
    1771      8049022 :               if (regstack_completed
    1772            0 :                   && REG_P (op)
    1773      8049022 :                   && IN_RANGE (REGNO (op), FIRST_STACK_REG, LAST_STACK_REG))
    1774            0 :                 untracked_operands |= 1 << i;
    1775              : #endif
    1776              :               /* If there's an in-out operand with a register that is not
    1777              :                  being tracked at all yet, open a chain.  */
    1778      8049022 :               if (recog_data.operand_type[i] == OP_INOUT
    1779      1256617 :                   && !(untracked_operands & (1 << i))
    1780      1256426 :                   && REG_P (op)
    1781      9253386 :                   && !verify_reg_tracked (op))
    1782            9 :                 create_new_chain (REGNO (op), REG_NREGS (op), NULL, NULL,
    1783              :                                   NO_REGS);
    1784              :             }
    1785              : 
    1786      3622027 :           if (fail_current_block)
    1787              :             break;
    1788              : 
    1789              :           /* Step 1a: Mark hard registers that are clobbered in this insn,
    1790              :              outside an operand, as live.  */
    1791      3622027 :           hide_operands (n_ops, old_operands, old_dups, untracked_operands,
    1792              :                          false);
    1793      3622027 :           note_stores (insn, note_sets_clobbers, &clobber_code);
    1794      3622027 :           restore_operands (insn, n_ops, old_operands, old_dups);
    1795              : 
    1796              :           /* Step 1b: Begin new chains for earlyclobbered writes inside
    1797              :              operands.  */
    1798      3622027 :           record_out_operands (insn, true, insn_info);
    1799              : 
    1800              :           /* Step 2: Mark chains for which we have reads outside operands
    1801              :              as unrenamable.
    1802              :              We do this by munging all operands into PC, and closing
    1803              :              everything remaining.  */
    1804              : 
    1805      3622027 :           hide_operands (n_ops, old_operands, old_dups, untracked_operands,
    1806              :                          false);
    1807      3622027 :           scan_rtx (insn, &PATTERN (insn), NO_REGS, mark_all_read, OP_IN);
    1808      3622027 :           restore_operands (insn, n_ops, old_operands, old_dups);
    1809              : 
    1810              :           /* Step 2B: Can't rename function call argument registers.  */
    1811      3622027 :           if (CALL_P (insn) && CALL_INSN_FUNCTION_USAGE (insn))
    1812       131971 :             scan_rtx (insn, &CALL_INSN_FUNCTION_USAGE (insn),
    1813              :                       NO_REGS, mark_all_read, OP_IN);
    1814              : 
    1815              :           /* Step 2C: Can't rename asm operands that were originally
    1816              :              hard registers.  */
    1817      3622027 :           if (asm_noperands (PATTERN (insn)) > 0)
    1818         2714 :             for (i = 0; i < n_ops; i++)
    1819              :               {
    1820         1834 :                 rtx *loc = recog_data.operand_loc[i];
    1821         1834 :                 rtx op = *loc;
    1822              : 
    1823         1834 :                 if (REG_P (op)
    1824         1305 :                     && REGNO (op) == ORIGINAL_REGNO (op)
    1825         1835 :                     && (recog_data.operand_type[i] == OP_IN
    1826            0 :                         || recog_data.operand_type[i] == OP_INOUT))
    1827            1 :                   scan_rtx (insn, loc, NO_REGS, mark_all_read, OP_IN);
    1828              :               }
    1829              : 
    1830              :           /* Step 3: Append to chains for reads inside operands.  */
    1831     11760550 :           for (i = 0; i < n_ops + recog_data.n_dups; i++)
    1832              :             {
    1833      8138523 :               int opn = i < n_ops ? i : recog_data.dup_num[i - n_ops];
    1834      8049022 :               rtx *loc = (i < n_ops
    1835      8138523 :                           ? recog_data.operand_loc[opn]
    1836        89501 :                           : recog_data.dup_loc[i - n_ops]);
    1837      8138523 :               enum reg_class cl = alternative_class (op_alt, opn);
    1838      8138523 :               enum op_type type = recog_data.operand_type[opn];
    1839              : 
    1840              :               /* Don't scan match_operand here, since we've no reg class
    1841              :                  information to pass down.  Any operands that we could
    1842              :                  substitute in will be represented elsewhere.  */
    1843      8138523 :               if (recog_data.constraints[opn][0] == '\0'
    1844      6797327 :                   || untracked_operands & (1 << opn))
    1845      1341578 :                 continue;
    1846              : 
    1847      6796945 :               if (insn_info)
    1848            0 :                 cur_operand = i == opn ? insn_info->op_info + i : NULL;
    1849      6796945 :               if (op_alt[opn].is_address)
    1850       201211 :                 scan_rtx_address (insn, loc, cl, mark_read,
    1851              :                                   VOIDmode, ADDR_SPACE_GENERIC);
    1852              :               else
    1853      6595734 :                 scan_rtx (insn, loc, cl, mark_read, type);
    1854              :             }
    1855      3622027 :           cur_operand = NULL;
    1856              : 
    1857              :           /* Step 3B: Record updates for regs in REG_INC notes, and
    1858              :              source regs in REG_FRAME_RELATED_EXPR notes.  */
    1859      6662805 :           for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
    1860      3040778 :             if (REG_NOTE_KIND (note) == REG_INC
    1861      3040778 :                 || REG_NOTE_KIND (note) == REG_FRAME_RELATED_EXPR)
    1862           30 :               scan_rtx (insn, &XEXP (note, 0), ALL_REGS, mark_read,
    1863              :                         OP_INOUT);
    1864              : 
    1865              :           /* Step 4: Close chains for registers that die here, unless
    1866              :              the register is mentioned in a REG_UNUSED note.  In that
    1867              :              case we keep the chain open until step #7 below to ensure
    1868              :              it conflicts with other output operands of this insn.
    1869              :              See PR 52573.  Arguably the insn should not have both
    1870              :              notes; it has proven difficult to fix that without
    1871              :              other undesirable side effects.  */
    1872      6662805 :           for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
    1873      3040778 :             if (REG_NOTE_KIND (note) == REG_DEAD
    1874      3040778 :                 && !find_regno_note (insn, REG_UNUSED, REGNO (XEXP (note, 0))))
    1875              :               {
    1876      1563372 :                 remove_from_hard_reg_set (&live_hard_regs,
    1877      1563372 :                                           GET_MODE (XEXP (note, 0)),
    1878      1563372 :                                           REGNO (XEXP (note, 0)));
    1879      1563372 :                 scan_rtx (insn, &XEXP (note, 0), NO_REGS, terminate_dead,
    1880              :                           OP_IN);
    1881              :               }
    1882              : 
    1883              :           /* Step 4B: If this is a call, any chain live at this point
    1884              :              requires a caller-saved reg.  */
    1885      3622027 :           if (CALL_P (insn))
    1886              :             {
    1887       143717 :               function_abi callee_abi = insn_callee_abi (insn);
    1888       143717 :               class du_head *p;
    1889       420563 :               for (p = open_chains; p; p = p->next_chain)
    1890              :                 {
    1891       276846 :                   p->call_abis |= (1 << callee_abi.id ());
    1892       276846 :                   p->call_clobber_mask
    1893       276846 :                     |= callee_abi.full_and_partial_reg_clobbers ();
    1894       553692 :                   p->hard_conflicts |= callee_abi.full_reg_clobbers ();
    1895              :                 }
    1896              :             }
    1897              : 
    1898              :           /* Step 5: Close open chains that overlap writes.  Similar to
    1899              :              step 2, we hide in-out operands, since we do not want to
    1900              :              close these chains.  We also hide earlyclobber operands,
    1901              :              since we've opened chains for them in step 1, and earlier
    1902              :              chains they would overlap with must have been closed at
    1903              :              the previous insn at the latest, as such operands cannot
    1904              :              possibly overlap with any input operands.  */
    1905              : 
    1906      3622027 :           hide_operands (n_ops, old_operands, old_dups, untracked_operands,
    1907              :                          true);
    1908      3622027 :           scan_rtx (insn, &PATTERN (insn), NO_REGS, terminate_write, OP_IN);
    1909      3622027 :           restore_operands (insn, n_ops, old_operands, old_dups);
    1910              : 
    1911              :           /* Step 6a: Mark hard registers that are set in this insn,
    1912              :              outside an operand, as live.  */
    1913      3622027 :           hide_operands (n_ops, old_operands, old_dups, untracked_operands,
    1914              :                          false);
    1915      3622027 :           note_stores (insn, note_sets_clobbers, &set_code);
    1916      3622027 :           restore_operands (insn, n_ops, old_operands, old_dups);
    1917              : 
    1918              :           /* Step 6b: Begin new chains for writes inside operands.  */
    1919      3622027 :           record_out_operands (insn, false, insn_info);
    1920              : 
    1921              :           /* Step 6c: Record destination regs in REG_FRAME_RELATED_EXPR
    1922              :              notes for update.  */
    1923      6662805 :           for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
    1924      3040778 :             if (REG_NOTE_KIND (note) == REG_FRAME_RELATED_EXPR)
    1925           30 :               scan_rtx (insn, &XEXP (note, 0), ALL_REGS, mark_access,
    1926              :                         OP_INOUT);
    1927              : 
    1928              :           /* Step 7: Close chains for registers that were never
    1929              :              really used here.  */
    1930      6662805 :           for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
    1931      3040778 :             if (REG_NOTE_KIND (note) == REG_UNUSED)
    1932              :               {
    1933       555278 :                 remove_from_hard_reg_set (&live_hard_regs,
    1934       555278 :                                           GET_MODE (XEXP (note, 0)),
    1935       555278 :                                           REGNO (XEXP (note, 0)));
    1936       555278 :                 scan_rtx (insn, &XEXP (note, 0), NO_REGS, terminate_dead,
    1937              :                           OP_IN);
    1938              :               }
    1939              : 
    1940              :           /* Step 8: Kill the chains involving register restores.  Those
    1941              :              should restore _that_ register.  Similar for REG_CFA_REGISTER.  */
    1942      6662805 :           for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
    1943      3040778 :             if (REG_NOTE_KIND (note) == REG_CFA_RESTORE
    1944      3035209 :                 || REG_NOTE_KIND (note) == REG_CFA_REGISTER)
    1945              :               {
    1946         5569 :                 rtx *x = &XEXP (note, 0);
    1947         5569 :                 if (!*x)
    1948            0 :                   x = &PATTERN (insn);
    1949         5569 :                 if (GET_CODE (*x) == PARALLEL)
    1950            0 :                   x = &XVECEXP (*x, 0, 0);
    1951         5569 :                 if (GET_CODE (*x) == SET)
    1952            0 :                   x = &SET_DEST (*x);
    1953         5569 :                 scan_rtx (insn, x, NO_REGS, mark_all_read, OP_IN);
    1954              :               }
    1955              :         }
    1956       950874 :       else if (DEBUG_BIND_INSN_P (insn)
    1957      3021518 :                && !VAR_LOC_UNKNOWN_P (INSN_VAR_LOCATION_LOC (insn)))
    1958              :         {
    1959       428609 :           scan_rtx (insn, &INSN_VAR_LOCATION_LOC (insn),
    1960              :                     ALL_REGS, mark_read, OP_IN);
    1961              :         }
    1962      5995138 :       if (insn == BB_END (bb))
    1963              :         break;
    1964      5416992 :     }
    1965              : 
    1966       578146 :   if (fail_current_block)
    1967            0 :     return false;
    1968              : 
    1969              :   return true;
    1970              : }
    1971              : 
    1972              : /* Initialize the register renamer.  If INSN_INFO is true, ensure that
    1973              :    insn_rr is nonnull.  */
    1974              : void
    1975        22497 : regrename_init (bool insn_info)
    1976              : {
    1977        22497 :   gcc_obstack_init (&rename_obstack);
    1978        22497 :   insn_rr.create (0);
    1979        22497 :   if (insn_info)
    1980            0 :     insn_rr.safe_grow_cleared (get_max_uid (), true);
    1981        22497 : }
    1982              : 
    1983              : /* Free all global data used by the register renamer.  */
    1984              : void
    1985        22497 : regrename_finish (void)
    1986              : {
    1987        22497 :   insn_rr.release ();
    1988        22497 :   free_chain_data ();
    1989        22497 :   obstack_free (&rename_obstack, NULL);
    1990        22497 : }
    1991              : 
    1992              : /* Perform register renaming on the current function.  */
    1993              : 
    1994              : static unsigned int
    1995        22497 : regrename_optimize (void)
    1996              : {
    1997        22497 :   df_set_flags (DF_LR_RUN_DCE);
    1998        22497 :   df_note_add_problem ();
    1999        22497 :   df_analyze ();
    2000        22497 :   df_set_flags (DF_DEFER_INSN_RESCAN);
    2001              : 
    2002        22497 :   regrename_init (false);
    2003              : 
    2004        22497 :   regrename_analyze (NULL, false);
    2005              : 
    2006        22497 :   rename_chains ();
    2007              : 
    2008        22497 :   regrename_finish ();
    2009              : 
    2010        22497 :   return 0;
    2011              : }
    2012              : 
    2013              : namespace {
    2014              : 
    2015              : const pass_data pass_data_regrename =
    2016              : {
    2017              :   RTL_PASS, /* type */
    2018              :   "rnreg", /* name */
    2019              :   OPTGROUP_NONE, /* optinfo_flags */
    2020              :   TV_RENAME_REGISTERS, /* tv_id */
    2021              :   0, /* properties_required */
    2022              :   0, /* properties_provided */
    2023              :   0, /* properties_destroyed */
    2024              :   0, /* todo_flags_start */
    2025              :   TODO_df_finish, /* todo_flags_finish */
    2026              : };
    2027              : 
    2028              : class pass_regrename : public rtl_opt_pass
    2029              : {
    2030              : public:
    2031       285722 :   pass_regrename (gcc::context *ctxt)
    2032       571444 :     : rtl_opt_pass (pass_data_regrename, ctxt)
    2033              :   {}
    2034              : 
    2035              :   /* opt_pass methods: */
    2036      1471370 :   bool gate (function *) final override
    2037              :     {
    2038      1471370 :       return (optimize > 0 && (flag_rename_registers));
    2039              :     }
    2040              : 
    2041        22497 :   unsigned int execute (function *) final override
    2042              :   {
    2043        22497 :     return regrename_optimize ();
    2044              :   }
    2045              : 
    2046              : }; // class pass_regrename
    2047              : 
    2048              : } // anon namespace
    2049              : 
    2050              : rtl_opt_pass *
    2051       285722 : make_pass_regrename (gcc::context *ctxt)
    2052              : {
    2053       285722 :   return new pass_regrename (ctxt);
    2054              : }
        

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.