LCOV - code coverage report
Current view: top level - gcc - regrename.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 89.9 % 956 859
Test Date: 2024-03-23 14:05:01 Functions: 91.2 % 34 31
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* Register renaming for the GNU compiler.
       2                 :             :    Copyright (C) 2000-2024 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                 :    85567208 : regrename_chain_from_id (unsigned int id)
     145                 :             : {
     146                 :    85567208 :   du_head_p first_chain = id_to_chain[id];
     147                 :    85567208 :   du_head_p chain = first_chain;
     148                 :   135051822 :   while (chain->id != id)
     149                 :             :     {
     150                 :    49484614 :       id = chain->id;
     151                 :    49484614 :       chain = id_to_chain[id];
     152                 :             :     }
     153                 :    85567208 :   first_chain->id = id;
     154                 :    85567208 :   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                 :         834 :   FOR_EACH_VEC_ELT_FROM (id_to_chain, i, head, from)
     165                 :             :     {
     166                 :         734 :       struct du_chain *this_du = head->first;
     167                 :             : 
     168                 :         734 :       fprintf (dump_file, "Register %s (%d):",
     169                 :         734 :                reg_names[head->regno], head->nregs);
     170                 :        2334 :       while (this_du)
     171                 :             :         {
     172                 :         866 :           fprintf (dump_file, " %d [%s]", INSN_UID (this_du->insn),
     173                 :         866 :                    reg_class_names[this_du->cl]);
     174                 :         866 :           this_du = this_du->next_use;
     175                 :             :         }
     176                 :         734 :       fprintf (dump_file, "\n");
     177                 :         734 :       head = head->next_chain;
     178                 :             :     }
     179                 :         100 : }
     180                 :             : 
     181                 :             : static void
     182                 :       20587 : free_chain_data (void)
     183                 :             : {
     184                 :       20587 :   int i;
     185                 :       20587 :   du_head_p ptr;
     186                 :     4029857 :   for (i = 0; id_to_chain.iterate (i, &ptr); i++)
     187                 :     4009270 :     bitmap_clear (&ptr->conflicts);
     188                 :             : 
     189                 :       20587 :   id_to_chain.release ();
     190                 :       20587 : }
     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                 :     4009270 : mark_conflict (class du_head *chains, unsigned id)
     197                 :             : {
     198                 :    24907738 :   while (chains)
     199                 :             :     {
     200                 :    20898468 :       bitmap_set_bit (&chains->conflicts, id);
     201                 :    20898468 :       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                 :     4843921 : record_operand_use (class du_head *head, struct du_chain *this_du)
     210                 :             : {
     211                 :     4843921 :   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                 :     4009270 : create_new_chain (unsigned this_regno, unsigned this_nregs, rtx *loc,
     229                 :             :                   rtx_insn *insn, enum reg_class cl)
     230                 :             : {
     231                 :     4009270 :   class du_head *head = XOBNEW (&rename_obstack, class du_head);
     232                 :     4009270 :   struct du_chain *this_du;
     233                 :     4009270 :   int nregs;
     234                 :             : 
     235                 :     4009270 :   memset ((void *)head, 0, sizeof *head);
     236                 :     4009270 :   head->next_chain = open_chains;
     237                 :     4009270 :   head->regno = this_regno;
     238                 :     4009270 :   head->nregs = this_nregs;
     239                 :             : 
     240                 :     4009270 :   id_to_chain.safe_push (head);
     241                 :     4009270 :   head->id = current_id++;
     242                 :             : 
     243                 :     4009270 :   bitmap_initialize (&head->conflicts, &bitmap_default_obstack);
     244                 :     4009270 :   bitmap_copy (&head->conflicts, &open_chains_set);
     245                 :     4009270 :   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                 :     4009270 :   nregs = head->nregs;
     251                 :     8020374 :   while (nregs-- > 0)
     252                 :             :     {
     253                 :     4011104 :       SET_HARD_REG_BIT (live_in_chains, head->regno + nregs);
     254                 :     4011104 :       CLEAR_HARD_REG_BIT (live_hard_regs, head->regno + nregs);
     255                 :             :     }
     256                 :             : 
     257                 :     4009270 :   head->hard_conflicts = live_hard_regs;
     258                 :     4009270 :   bitmap_set_bit (&open_chains_set, head->id);
     259                 :             : 
     260                 :     4009270 :   open_chains = head;
     261                 :             : 
     262                 :     4009270 :   if (dump_file)
     263                 :             :     {
     264                 :         734 :       fprintf (dump_file, "Creating chain %s (%d)",
     265                 :         734 :                reg_names[head->regno], head->id);
     266                 :         734 :       if (insn != NULL_RTX)
     267                 :         138 :         fprintf (dump_file, " at insn %d", INSN_UID (insn));
     268                 :         734 :       fprintf (dump_file, "\n");
     269                 :             :     }
     270                 :             : 
     271                 :     4009270 :   if (insn == NULL_RTX)
     272                 :             :     {
     273                 :     2647910 :       head->first = head->last = NULL;
     274                 :     2647910 :       return head;
     275                 :             :     }
     276                 :             : 
     277                 :     1361360 :   this_du = XOBNEW (&rename_obstack, struct du_chain);
     278                 :     1361360 :   head->first = head->last = this_du;
     279                 :             : 
     280                 :     1361360 :   this_du->next_use = 0;
     281                 :     1361360 :   this_du->loc = loc;
     282                 :     1361360 :   this_du->insn = insn;
     283                 :     1361360 :   this_du->cl = cl;
     284                 :     1361360 :   record_operand_use (head, this_du);
     285                 :     1361360 :   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                 :      953574 : merge_overlapping_regs (HARD_REG_SET *pset, class du_head *head)
     293                 :             : {
     294                 :      953574 :   bitmap_iterator bi;
     295                 :      953574 :   unsigned i;
     296                 :      953574 :   *pset |= head->hard_conflicts;
     297                 :    39927956 :   EXECUTE_IF_SET_IN_BITMAP (&head->conflicts, 0, i, bi)
     298                 :             :     {
     299                 :    38974382 :       du_head_p other = regrename_chain_from_id (i);
     300                 :    38974382 :       unsigned j = other->nregs;
     301                 :    38974382 :       gcc_assert (other != head);
     302                 :    77965087 :       while (j-- > 0)
     303                 :    38990705 :         SET_HARD_REG_BIT (*pset, other->regno + j);
     304                 :             :     }
     305                 :      953574 : }
     306                 :             : 
     307                 :             : /* Return true if (reg:MODE REGNO) would be clobbered by a call covered
     308                 :             :    by THIS_HEAD.  */
     309                 :             : 
     310                 :             : static bool
     311                 :    18861293 : call_clobbered_in_chain_p (du_head *this_head, machine_mode mode,
     312                 :             :                            unsigned int regno)
     313                 :             : {
     314                 :    18861293 :   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                 :    84446651 : check_new_reg_p (int reg ATTRIBUTE_UNUSED, int new_reg,
     325                 :             :                  class du_head *this_head, HARD_REG_SET this_unavailable)
     326                 :             : {
     327                 :    84446651 :   int nregs = this_head->nregs;
     328                 :    84446651 :   int i;
     329                 :    84446651 :   struct du_chain *tmp;
     330                 :             : 
     331                 :    89781826 :   for (i = nregs - 1; i >= 0; --i)
     332                 :    84446651 :     if (TEST_HARD_REG_BIT (this_unavailable, new_reg + i)
     333                 :    19081064 :         || fixed_regs[new_reg + i]
     334                 :     6106072 :         || global_regs[new_reg + i]
     335                 :             :         /* Can't use regs which aren't saved by the prologue.  */
     336                 :     6106072 :         || (! df_regs_ever_live_p (new_reg + i)
     337                 :     1090177 :             && ! crtl->abi->clobbers_full_reg_p (new_reg + i))
     338                 :             : #ifdef LEAF_REGISTERS
     339                 :             :         /* We can't use a non-leaf register if we're in a
     340                 :             :            leaf function.  */
     341                 :             :         || (crtl->is_leaf
     342                 :             :             && !LEAF_REGISTERS[new_reg + i])
     343                 :             : #endif
     344                 :    90077940 :         || ! HARD_REGNO_RENAME_OK (reg + i, new_reg + i))
     345                 :    79111476 :       return false;
     346                 :             : 
     347                 :             :   /* See whether it accepts all modes that occur in
     348                 :             :      definition and uses.  */
     349                 :    24336580 :   for (tmp = this_head->first; tmp; tmp = tmp->next_use)
     350                 :             :     {
     351                 :             :       /* Completely ignore DEBUG_INSNs, otherwise we can get
     352                 :             :          -fcompare-debug failures.  */
     353                 :    19001405 :       if (DEBUG_INSN_P (tmp->insn))
     354                 :      140112 :         continue;
     355                 :             : 
     356                 :    18861293 :       if (!targetm.hard_regno_mode_ok (new_reg, GET_MODE (*tmp->loc))
     357                 :    18861293 :           || call_clobbered_in_chain_p (this_head, GET_MODE (*tmp->loc),
     358                 :             :                                         new_reg))
     359                 :           0 :         return false;
     360                 :             :     }
     361                 :             : 
     362                 :             :   return true;
     363                 :             : }
     364                 :             : 
     365                 :             : /* For the chain THIS_HEAD, compute and return the best register to
     366                 :             :    rename to.  SUPER_CLASS is the superunion of register classes in
     367                 :             :    the chain.  UNAVAILABLE is a set of registers that cannot be used.
     368                 :             :    OLD_REG is the register currently used for the chain.  BEST_RENAME
     369                 :             :    controls whether the register chosen must be better than the
     370                 :             :    current one or just respect the given constraint.  */
     371                 :             : 
     372                 :             : int
     373                 :      953574 : find_rename_reg (du_head_p this_head, enum reg_class super_class,
     374                 :             :                  HARD_REG_SET *unavailable, int old_reg, bool best_rename)
     375                 :             : {
     376                 :      953574 :   bool has_preferred_class;
     377                 :      953574 :   enum reg_class preferred_class;
     378                 :      953574 :   int pass;
     379                 :      953574 :   int best_new_reg = old_reg;
     380                 :             : 
     381                 :             :   /* Mark registers that overlap this chain's lifetime as unavailable.  */
     382                 :      953574 :   merge_overlapping_regs (unavailable, this_head);
     383                 :             : 
     384                 :             :   /* Compute preferred rename class of super union of all the classes
     385                 :             :      in the chain.  */
     386                 :      953574 :   preferred_class
     387                 :      953574 :     = (enum reg_class) targetm.preferred_rename_class (super_class);
     388                 :             : 
     389                 :             :   /* Pick and check the register from the tied chain iff the tied chain
     390                 :             :      is not renamed.  */
     391                 :       89061 :   if (this_head->tied_chain && !this_head->tied_chain->renamed
     392                 :     1024265 :       && check_new_reg_p (old_reg, this_head->tied_chain->regno,
     393                 :             :                           this_head, *unavailable))
     394                 :       23670 :     return this_head->tied_chain->regno;
     395                 :             : 
     396                 :             :   /* If the first non-debug insn is a noop move, then do not rename in this
     397                 :             :      chain as doing so would inhibit removal of the noop move.  */
     398                 :      929993 :   for (struct du_chain *tmp = this_head->first; tmp; tmp = tmp->next_use)
     399                 :      929993 :     if (DEBUG_INSN_P (tmp->insn))
     400                 :          89 :       continue;
     401                 :      929904 :     else if (noop_move_p (tmp->insn))
     402                 :             :       return best_new_reg;
     403                 :             :     else
     404                 :             :       break;
     405                 :             : 
     406                 :             :   /* If PREFERRED_CLASS is not NO_REGS, we iterate in the first pass
     407                 :             :      over registers that belong to PREFERRED_CLASS and try to find the
     408                 :             :      best register within the class.  If that failed, we iterate in
     409                 :             :      the second pass over registers that don't belong to the class.
     410                 :             :      If PREFERRED_CLASS is NO_REGS, we iterate over all registers in
     411                 :             :      ascending order without any preference.  */
     412                 :      917130 :   has_preferred_class = (preferred_class != NO_REGS);
     413                 :     2751390 :   for (pass = (has_preferred_class ? 0 : 1); pass < 2; pass++)
     414                 :             :     {
     415                 :             :       int new_reg;
     416                 :    85293090 :       for (new_reg = 0; new_reg < FIRST_PSEUDO_REGISTER; new_reg++)
     417                 :             :         {
     418                 :    84375960 :           if (has_preferred_class
     419                 :    84375960 :               && (pass == 0)
     420                 :           0 :               != TEST_HARD_REG_BIT (reg_class_contents[preferred_class],
     421                 :             :                                     new_reg))
     422                 :           0 :             continue;
     423                 :             : 
     424                 :    84375960 :           if (!check_new_reg_p (old_reg, new_reg, this_head, *unavailable))
     425                 :    79064455 :             continue;
     426                 :             : 
     427                 :     5311505 :           if (!best_rename)
     428                 :           0 :             return new_reg;
     429                 :             : 
     430                 :             :           /* In the first pass, we force the renaming of registers that
     431                 :             :              don't belong to PREFERRED_CLASS to registers that do, even
     432                 :             :              though the latters were used not very long ago.  */
     433                 :     5311505 :           if ((pass == 0
     434                 :           0 :               && !TEST_HARD_REG_BIT (reg_class_contents[preferred_class],
     435                 :             :                                      best_new_reg))
     436                 :     5311505 :               || tick[best_new_reg] > tick[new_reg])
     437                 :             :             best_new_reg = new_reg;
     438                 :             :         }
     439                 :      917130 :       if (pass == 0 && best_new_reg != old_reg)
     440                 :             :         break;
     441                 :             :     }
     442                 :             :   return best_new_reg;
     443                 :             : }
     444                 :             : 
     445                 :             : /* Iterate over elements in the chain HEAD in order to:
     446                 :             :    1. Count number of uses, storing it in *PN_USES.
     447                 :             :    2. Narrow the set of registers we can use for renaming, adding
     448                 :             :       unavailable registers to *PUNAVAILABLE, which must be
     449                 :             :       initialized by the caller.
     450                 :             :    3. Compute the superunion of register classes in this chain
     451                 :             :       and return it.  */
     452                 :             : reg_class
     453                 :     3613948 : regrename_find_superclass (du_head_p head, int *pn_uses,
     454                 :             :                            HARD_REG_SET *punavailable)
     455                 :             : {
     456                 :     3613948 :   int n_uses = 0;
     457                 :     3613948 :   reg_class super_class = NO_REGS;
     458                 :     7900422 :   for (du_chain *tmp = head->first; tmp; tmp = tmp->next_use)
     459                 :             :     {
     460                 :     4286474 :       if (DEBUG_INSN_P (tmp->insn))
     461                 :       72475 :         continue;
     462                 :     4213999 :       n_uses++;
     463                 :     4213999 :       *punavailable |= ~reg_class_contents[tmp->cl];
     464                 :     4213999 :       super_class
     465                 :     4213999 :         = reg_class_superunion[(int) super_class][(int) tmp->cl];
     466                 :             :     }
     467                 :     3613948 :   *pn_uses = n_uses;
     468                 :     3613948 :   return super_class;
     469                 :             : }
     470                 :             : 
     471                 :             : /* Perform register renaming on the current function.  */
     472                 :             : static void
     473                 :       20587 : rename_chains (void)
     474                 :             : {
     475                 :       20587 :   HARD_REG_SET unavailable;
     476                 :       20587 :   du_head_p this_head;
     477                 :       20587 :   int i;
     478                 :             : 
     479                 :       20587 :   memset (tick, 0, sizeof tick);
     480                 :             : 
     481                 :       20587 :   CLEAR_HARD_REG_SET (unavailable);
     482                 :             :   /* Don't clobber traceback for noreturn functions.  */
     483                 :       20587 :   if (frame_pointer_needed)
     484                 :             :     {
     485                 :         737 :       add_to_hard_reg_set (&unavailable, Pmode, FRAME_POINTER_REGNUM);
     486                 :         737 :       if (!HARD_FRAME_POINTER_IS_FRAME_POINTER)
     487                 :         737 :         add_to_hard_reg_set (&unavailable, Pmode, HARD_FRAME_POINTER_REGNUM);
     488                 :             :     }
     489                 :             : 
     490                 :     4029857 :   FOR_EACH_VEC_ELT (id_to_chain, i, this_head)
     491                 :             :     {
     492                 :     4009270 :       int best_new_reg;
     493                 :     4009270 :       int n_uses;
     494                 :     4009270 :       HARD_REG_SET this_unavailable;
     495                 :     4009270 :       int reg = this_head->regno;
     496                 :             : 
     497                 :     4009270 :       if (this_head->cannot_rename)
     498                 :     3507223 :         continue;
     499                 :             : 
     500                 :     3687576 :       if (fixed_regs[reg] || global_regs[reg]
     501                 :     3686132 :           || (!HARD_FRAME_POINTER_IS_FRAME_POINTER && frame_pointer_needed
     502                 :      841008 :               && reg == HARD_FRAME_POINTER_REGNUM)
     503                 :             :           || (HARD_FRAME_POINTER_IS_FRAME_POINTER && frame_pointer_needed
     504                 :             :               && reg == FRAME_POINTER_REGNUM))
     505                 :       73628 :         continue;
     506                 :             : 
     507                 :     3613948 :       this_unavailable = unavailable;
     508                 :             : 
     509                 :     3613948 :       reg_class super_class = regrename_find_superclass (this_head, &n_uses,
     510                 :             :                                                          &this_unavailable);
     511                 :     3613948 :       if (n_uses < 2)
     512                 :     2660374 :         continue;
     513                 :             : 
     514                 :      953574 :       best_new_reg = find_rename_reg (this_head, super_class,
     515                 :             :                                       &this_unavailable, reg, true);
     516                 :             : 
     517                 :      953574 :       if (dump_file)
     518                 :             :         {
     519                 :         114 :           fprintf (dump_file, "Register %s in insn %d",
     520                 :         114 :                    reg_names[reg], INSN_UID (this_head->first->insn));
     521                 :         114 :           if (this_head->call_abis)
     522                 :           4 :             fprintf (dump_file, " crosses a call");
     523                 :             :         }
     524                 :             : 
     525                 :      953574 :       if (best_new_reg == reg)
     526                 :             :         {
     527                 :      451527 :           tick[reg] = ++this_tick;
     528                 :      451527 :           if (dump_file)
     529                 :          44 :             fprintf (dump_file, "; no available better choice\n");
     530                 :      451527 :           continue;
     531                 :             :         }
     532                 :             : 
     533                 :      502047 :       if (regrename_do_replace (this_head, best_new_reg))
     534                 :             :         {
     535                 :      502008 :           if (dump_file)
     536                 :          70 :             fprintf (dump_file, ", renamed as %s\n", reg_names[best_new_reg]);
     537                 :      502008 :           tick[best_new_reg] = ++this_tick;
     538                 :      502008 :           df_set_regs_ever_live (best_new_reg, true);
     539                 :             :         }
     540                 :             :       else
     541                 :             :         {
     542                 :          39 :           if (dump_file)
     543                 :           0 :             fprintf (dump_file, ", renaming as %s failed\n",
     544                 :             :                      reg_names[best_new_reg]);
     545                 :          39 :           tick[reg] = ++this_tick;
     546                 :             :         }
     547                 :             :     }
     548                 :       20587 : }
     549                 :             : 
     550                 :             : /* A structure to record information for each hard register at the start of
     551                 :             :    a basic block.  */
     552                 :             : struct incoming_reg_info {
     553                 :             :   /* Holds the number of registers used in the chain that gave us information
     554                 :             :      about this register.  Zero means no information known yet, while a
     555                 :             :      negative value is used for something that is part of, but not the first
     556                 :             :      register in a multi-register value.  */
     557                 :             :   int nregs;
     558                 :             :   /* Set to true if we have accesses that conflict in the number of registers
     559                 :             :      used.  */
     560                 :             :   bool unusable;
     561                 :             : };
     562                 :             : 
     563                 :             : /* A structure recording information about each basic block.  It is saved
     564                 :             :    and restored around basic block boundaries.
     565                 :             :    A pointer to such a structure is stored in each basic block's aux field
     566                 :             :    during regrename_analyze, except for blocks we know can't be optimized
     567                 :             :    (such as entry and exit blocks).  */
     568                 :             : class bb_rename_info
     569                 :             : {
     570                 :             : public:
     571                 :             :   /* The basic block corresponding to this structure.  */
     572                 :             :   basic_block bb;
     573                 :             :   /* Copies of the global information.  */
     574                 :             :   bitmap_head open_chains_set;
     575                 :             :   bitmap_head incoming_open_chains_set;
     576                 :             :   struct incoming_reg_info incoming[FIRST_PSEUDO_REGISTER];
     577                 :             : };
     578                 :             : 
     579                 :             : /* Initialize a rename_info structure P for basic block BB, which starts a new
     580                 :             :    scan.  */
     581                 :             : static void
     582                 :      487797 : init_rename_info (class bb_rename_info *p, basic_block bb)
     583                 :             : {
     584                 :      487797 :   int i;
     585                 :      487797 :   df_ref def;
     586                 :      487797 :   HARD_REG_SET start_chains_set;
     587                 :             : 
     588                 :      487797 :   p->bb = bb;
     589                 :      487797 :   bitmap_initialize (&p->open_chains_set, &bitmap_default_obstack);
     590                 :      487797 :   bitmap_initialize (&p->incoming_open_chains_set, &bitmap_default_obstack);
     591                 :             : 
     592                 :      487797 :   open_chains = NULL;
     593                 :      487797 :   bitmap_clear (&open_chains_set);
     594                 :             : 
     595                 :     1951188 :   CLEAR_HARD_REG_SET (live_in_chains);
     596                 :      487797 :   REG_SET_TO_HARD_REG_SET (live_hard_regs, df_get_live_in (bb));
     597                 :      975997 :   FOR_EACH_ARTIFICIAL_DEF (def, bb->index)
     598                 :         403 :     if (DF_REF_FLAGS (def) & DF_REF_AT_TOP)
     599                 :         403 :       SET_HARD_REG_BIT (live_hard_regs, DF_REF_REGNO (def));
     600                 :             : 
     601                 :             :   /* Open chains based on information from (at least one) predecessor
     602                 :             :      block.  This gives us a chance later on to combine chains across
     603                 :             :      basic block boundaries.  Inconsistencies (in access sizes) will
     604                 :             :      be caught normally and dealt with conservatively by disabling the
     605                 :             :      chain for renaming, and there is no risk of losing optimization
     606                 :             :      opportunities by opening chains either: if we did not open the
     607                 :             :      chains, we'd have to track the live register as a hard reg, and
     608                 :             :      we'd be unable to rename it in any case.  */
     609                 :    45365121 :   CLEAR_HARD_REG_SET (start_chains_set);
     610                 :    45365121 :   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
     611                 :             :     {
     612                 :    44877324 :       struct incoming_reg_info *iri = p->incoming + i;
     613                 :     3048199 :       if (iri->nregs > 0 && !iri->unusable
     614                 :    50973722 :           && range_in_hard_reg_set_p (live_hard_regs, i, iri->nregs))
     615                 :             :         {
     616                 :     2647902 :           SET_HARD_REG_BIT (start_chains_set, i);
     617                 :     2647902 :           remove_range_from_hard_reg_set (&live_hard_regs, i, iri->nregs);
     618                 :             :         }
     619                 :             :     }
     620                 :    45365121 :   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
     621                 :             :     {
     622                 :    44877324 :       struct incoming_reg_info *iri = p->incoming + i;
     623                 :    44877324 :       if (TEST_HARD_REG_BIT (start_chains_set, i))
     624                 :             :         {
     625                 :     2647902 :           du_head_p chain;
     626                 :     2647902 :           if (dump_file)
     627                 :         596 :             fprintf (dump_file, "opening incoming chain\n");
     628                 :     2647902 :           chain = create_new_chain (i, iri->nregs, NULL, NULL, NO_REGS);
     629                 :     2647902 :           bitmap_set_bit (&p->incoming_open_chains_set, chain->id);
     630                 :             :         }
     631                 :             :     }
     632                 :      487797 : }
     633                 :             : 
     634                 :             : /* Record in RI that the block corresponding to it has an incoming
     635                 :             :    live value, described by CHAIN.  */
     636                 :             : static void
     637                 :     4616142 : set_incoming_from_chain (class bb_rename_info *ri, du_head_p chain)
     638                 :             : {
     639                 :     4616142 :   int i;
     640                 :     4616142 :   int incoming_nregs = ri->incoming[chain->regno].nregs;
     641                 :     4616142 :   int nregs;
     642                 :             : 
     643                 :             :   /* If we've recorded the same information before, everything is fine.  */
     644                 :     4616142 :   if (incoming_nregs == chain->nregs)
     645                 :             :     {
     646                 :     1566285 :       if (dump_file)
     647                 :         288 :         fprintf (dump_file, "reg %d/%d already recorded\n",
     648                 :             :                  chain->regno, chain->nregs);
     649                 :     1566285 :       return;
     650                 :             :     }
     651                 :             : 
     652                 :             :   /* If we have no information for any of the involved registers, update
     653                 :             :      the incoming array.  */
     654                 :             :   nregs = chain->nregs;
     655                 :     6099714 :   while (nregs-- > 0)
     656                 :     3049857 :     if (ri->incoming[chain->regno + nregs].nregs != 0
     657                 :     3049857 :         || ri->incoming[chain->regno + nregs].unusable)
     658                 :             :       break;
     659                 :     3049857 :   if (nregs < 0)
     660                 :             :     {
     661                 :     3049857 :       nregs = chain->nregs;
     662                 :     3049857 :       ri->incoming[chain->regno].nregs = nregs;
     663                 :     3049857 :       while (nregs-- > 1)
     664                 :           0 :         ri->incoming[chain->regno + nregs].nregs = -nregs;
     665                 :     3049857 :       if (dump_file)
     666                 :         708 :         fprintf (dump_file, "recorded reg %d/%d\n",
     667                 :             :                  chain->regno, chain->nregs);
     668                 :     3049857 :       return;
     669                 :             :     }
     670                 :             : 
     671                 :             :   /* There must be some kind of conflict.  Prevent both the old and
     672                 :             :      new ranges from being used.  */
     673                 :           0 :   if (incoming_nregs < 0)
     674                 :           0 :     ri->incoming[chain->regno + incoming_nregs].unusable = true;
     675                 :           0 :   for (i = 0; i < chain->nregs; i++)
     676                 :           0 :     ri->incoming[chain->regno + i].unusable = true;
     677                 :             : }
     678                 :             : 
     679                 :             : /* Merge the two chains C1 and C2 so that all conflict information is
     680                 :             :    recorded and C1, and the id of C2 is changed to that of C1.  */
     681                 :             : static void
     682                 :     3804849 : merge_chains (du_head_p c1, du_head_p c2)
     683                 :             : {
     684                 :     3804849 :   if (c1 == c2)
     685                 :             :     return;
     686                 :             : 
     687                 :     2747030 :   if (c2->first != NULL)
     688                 :             :     {
     689                 :      845815 :       if (c1->first == NULL)
     690                 :       34770 :         c1->first = c2->first;
     691                 :             :       else
     692                 :      811045 :         c1->last->next_use = c2->first;
     693                 :      845815 :       c1->last = c2->last;
     694                 :             :     }
     695                 :             : 
     696                 :     2747030 :   c2->first = c2->last = NULL;
     697                 :     2747030 :   c2->id = c1->id;
     698                 :             : 
     699                 :     2747030 :   c1->hard_conflicts |= c2->hard_conflicts;
     700                 :     2747030 :   bitmap_ior_into (&c1->conflicts, &c2->conflicts);
     701                 :             : 
     702                 :     2747030 :   c1->call_clobber_mask |= c2->call_clobber_mask;
     703                 :     2747030 :   c1->call_abis |= c2->call_abis;
     704                 :     2747030 :   c1->cannot_rename |= c2->cannot_rename;
     705                 :             : }
     706                 :             : 
     707                 :             : /* Analyze the current function and build chains for renaming.
     708                 :             :    If INCLUDE_ALL_BLOCKS_P is set to true, process all blocks,
     709                 :             :    ignoring BB_DISABLE_SCHEDULE.  The default value is true.  */
     710                 :             : 
     711                 :             : void
     712                 :       20587 : regrename_analyze (bitmap bb_mask, bool include_all_block_p)
     713                 :             : {
     714                 :       20587 :   class bb_rename_info *rename_info;
     715                 :       20587 :   int i;
     716                 :       20587 :   basic_block bb;
     717                 :       20587 :   int n_bbs;
     718                 :       20587 :   int *inverse_postorder;
     719                 :             : 
     720                 :       20587 :   inverse_postorder = XNEWVEC (int, last_basic_block_for_fn (cfun));
     721                 :       20587 :   n_bbs = pre_and_rev_post_order_compute (NULL, inverse_postorder, false);
     722                 :             : 
     723                 :             :   /* Gather some information about the blocks in this function.  */
     724                 :       20587 :   rename_info = XCNEWVEC (class bb_rename_info, n_basic_blocks_for_fn (cfun));
     725                 :       20587 :   i = 0;
     726                 :      508384 :   FOR_EACH_BB_FN (bb, cfun)
     727                 :             :     {
     728                 :      487797 :       class bb_rename_info *ri = rename_info + i;
     729                 :      487797 :       ri->bb = bb;
     730                 :      487797 :       if (bb_mask != NULL && !bitmap_bit_p (bb_mask, bb->index))
     731                 :           0 :         bb->aux = NULL;
     732                 :             :       else
     733                 :      487797 :         bb->aux = ri;
     734                 :      487797 :       i++;
     735                 :             :     }
     736                 :             : 
     737                 :       20587 :   current_id = 0;
     738                 :       20587 :   id_to_chain.create (0);
     739                 :       20587 :   bitmap_initialize (&open_chains_set, &bitmap_default_obstack);
     740                 :             : 
     741                 :             :   /* The order in which we visit blocks ensures that whenever
     742                 :             :      possible, we only process a block after at least one of its
     743                 :             :      predecessors, which provides a "seeding" effect to make the logic
     744                 :             :      in set_incoming_from_chain and init_rename_info useful.  */
     745                 :             : 
     746                 :      508384 :   for (i = 0; i < n_bbs; i++)
     747                 :             :     {
     748                 :      487797 :       basic_block bb1 = BASIC_BLOCK_FOR_FN (cfun, inverse_postorder[i]);
     749                 :      487797 :       class bb_rename_info *this_info;
     750                 :      487797 :       bool success;
     751                 :      487797 :       edge e;
     752                 :      487797 :       edge_iterator ei;
     753                 :      487797 :       int old_length = id_to_chain.length ();
     754                 :             : 
     755                 :      487797 :       this_info = (class bb_rename_info *) bb1->aux;
     756                 :      487797 :       if (this_info == NULL)
     757                 :           0 :         continue;
     758                 :             : 
     759                 :      487797 :       if (dump_file)
     760                 :         100 :         fprintf (dump_file, "\nprocessing block %d:\n", bb1->index);
     761                 :             : 
     762                 :      487797 :       if (!include_all_block_p && (bb1->flags & BB_DISABLE_SCHEDULE) != 0)
     763                 :             :         {
     764                 :           0 :           if (dump_file)
     765                 :           0 :             fprintf (dump_file, "avoid disrupting the sms schedule of bb %d\n",
     766                 :             :                      bb1->index);
     767                 :           0 :           continue;
     768                 :             :         }
     769                 :             : 
     770                 :      487797 :       init_rename_info (this_info, bb1);
     771                 :             : 
     772                 :      487797 :       success = build_def_use (bb1);
     773                 :      487797 :       if (!success)
     774                 :             :         {
     775                 :           0 :           if (dump_file)
     776                 :           0 :             fprintf (dump_file, "failed\n");
     777                 :           0 :           bb1->aux = NULL;
     778                 :           0 :           id_to_chain.truncate (old_length);
     779                 :           0 :           current_id = old_length;
     780                 :           0 :           bitmap_clear (&this_info->incoming_open_chains_set);
     781                 :           0 :           open_chains = NULL;
     782                 :           0 :           if (insn_rr.exists ())
     783                 :             :             {
     784                 :           0 :               rtx_insn *insn;
     785                 :           0 :               FOR_BB_INSNS (bb1, insn)
     786                 :             :                 {
     787                 :           0 :                   insn_rr_info *p = &insn_rr[INSN_UID (insn)];
     788                 :           0 :                   p->op_info = NULL;
     789                 :             :                 }
     790                 :             :             }
     791                 :           0 :           continue;
     792                 :           0 :         }
     793                 :             : 
     794                 :      487797 :       if (dump_file)
     795                 :         100 :         dump_def_use_chain (old_length);
     796                 :      487797 :       bitmap_copy (&this_info->open_chains_set, &open_chains_set);
     797                 :             : 
     798                 :             :       /* Add successor blocks to the worklist if necessary, and record
     799                 :             :          data about our own open chains at the end of this block, which
     800                 :             :          will be used to pre-open chains when processing the successors.  */
     801                 :     1237945 :       FOR_EACH_EDGE (e, ei, bb1->succs)
     802                 :             :         {
     803                 :      750148 :           class bb_rename_info *dest_ri;
     804                 :      750148 :           class du_head *chain;
     805                 :             : 
     806                 :      750148 :           if (dump_file)
     807                 :         152 :             fprintf (dump_file, "successor block %d\n", e->dest->index);
     808                 :             : 
     809                 :      750148 :           if (e->flags & (EDGE_EH | EDGE_ABNORMAL))
     810                 :        3181 :             continue;
     811                 :      746967 :           dest_ri = (class bb_rename_info *)e->dest->aux;
     812                 :      746967 :           if (dest_ri == NULL)
     813                 :       20073 :             continue;
     814                 :     5343036 :           for (chain = open_chains; chain; chain = chain->next_chain)
     815                 :     4616142 :             set_incoming_from_chain (dest_ri, chain);
     816                 :             :         }
     817                 :             :     }
     818                 :             : 
     819                 :       20587 :   free (inverse_postorder);
     820                 :             : 
     821                 :             :   /* Now, combine the chains data we have gathered across basic block
     822                 :             :      boundaries.
     823                 :             : 
     824                 :             :      For every basic block, there may be chains open at the start, or at the
     825                 :             :      end.  Rather than exclude them from renaming, we look for open chains
     826                 :             :      with matching registers at the other side of the CFG edge.
     827                 :             : 
     828                 :             :      For a given chain using register R, open at the start of block B, we
     829                 :             :      must find an open chain using R on the other side of every edge leading
     830                 :             :      to B, if the register is live across this edge.  In the code below,
     831                 :             :      N_PREDS_USED counts the number of edges where the register is live, and
     832                 :             :      N_PREDS_JOINED counts those where we found an appropriate chain for
     833                 :             :      joining.
     834                 :             : 
     835                 :             :      We perform the analysis for both incoming and outgoing edges, but we
     836                 :             :      only need to merge once (in the second part, after verifying outgoing
     837                 :             :      edges).  */
     838                 :      508384 :   FOR_EACH_BB_FN (bb, cfun)
     839                 :             :     {
     840                 :      487797 :       class bb_rename_info *bb_ri = (class bb_rename_info *) bb->aux;
     841                 :      487797 :       unsigned j;
     842                 :      487797 :       bitmap_iterator bi;
     843                 :             : 
     844                 :      487797 :       if (bb_ri == NULL)
     845                 :           0 :         continue;
     846                 :             : 
     847                 :      487797 :       if (dump_file)
     848                 :         100 :         fprintf (dump_file, "processing bb %d in edges\n", bb->index);
     849                 :             : 
     850                 :     3135699 :       EXECUTE_IF_SET_IN_BITMAP (&bb_ri->incoming_open_chains_set, 0, j, bi)
     851                 :             :         {
     852                 :     2647902 :           edge e;
     853                 :     2647902 :           edge_iterator ei;
     854                 :     2647902 :           class du_head *chain = regrename_chain_from_id (j);
     855                 :     2647902 :           int n_preds_used = 0, n_preds_joined = 0;
     856                 :             : 
     857                 :     6454089 :           FOR_EACH_EDGE (e, ei, bb->preds)
     858                 :             :             {
     859                 :             :               class bb_rename_info *src_ri;
     860                 :             :               unsigned k;
     861                 :             :               bitmap_iterator bi2;
     862                 :             :               HARD_REG_SET live;
     863                 :    11418561 :               bool success = false;
     864                 :             : 
     865                 :     3806187 :               REG_SET_TO_HARD_REG_SET (live, df_get_live_out (e->src));
     866                 :     7612374 :               if (!range_overlaps_hard_reg_set_p (live, chain->regno,
     867                 :             :                                                   chain->nregs))
     868                 :          73 :                 continue;
     869                 :     3806126 :               n_preds_used++;
     870                 :             : 
     871                 :     3806126 :               if (e->flags & (EDGE_EH | EDGE_ABNORMAL))
     872                 :          12 :                 continue;
     873                 :             : 
     874                 :     3806114 :               src_ri = (class bb_rename_info *)e->src->aux;
     875                 :     3806114 :               if (src_ri == NULL)
     876                 :           0 :                 continue;
     877                 :             : 
     878                 :    21022930 :               EXECUTE_IF_SET_IN_BITMAP (&src_ri->open_chains_set,
     879                 :             :                                         0, k, bi2)
     880                 :             :                 {
     881                 :    21021657 :                   class du_head *outgoing_chain = regrename_chain_from_id (k);
     882                 :             : 
     883                 :    21021657 :                   if (outgoing_chain->regno == chain->regno
     884                 :    21021657 :                       && outgoing_chain->nregs == chain->nregs)
     885                 :             :                     {
     886                 :     3804841 :                       n_preds_joined++;
     887                 :     3804841 :                       success = true;
     888                 :     3804841 :                       break;
     889                 :             :                     }
     890                 :             :                 }
     891                 :     3806114 :               if (!success && dump_file)
     892                 :           0 :                 fprintf (dump_file, "failure to match with pred block %d\n",
     893                 :           0 :                          e->src->index);
     894                 :             :             }
     895                 :     2647902 :           if (n_preds_joined < n_preds_used)
     896                 :             :             {
     897                 :         914 :               if (dump_file)
     898                 :           0 :                 fprintf (dump_file, "cannot rename chain %d\n", j);
     899                 :         914 :               chain->cannot_rename = 1;
     900                 :             :             }
     901                 :             :         }
     902                 :             :     }
     903                 :      508384 :   FOR_EACH_BB_FN (bb, cfun)
     904                 :             :     {
     905                 :      487797 :       class bb_rename_info *bb_ri = (class bb_rename_info *) bb->aux;
     906                 :      487797 :       unsigned j;
     907                 :      487797 :       bitmap_iterator bi;
     908                 :             : 
     909                 :      487797 :       if (bb_ri == NULL)
     910                 :           0 :         continue;
     911                 :             : 
     912                 :      487797 :       if (dump_file)
     913                 :         100 :         fprintf (dump_file, "processing bb %d out edges\n", bb->index);
     914                 :             : 
     915                 :     3296685 :       EXECUTE_IF_SET_IN_BITMAP (&bb_ri->open_chains_set, 0, j, bi)
     916                 :             :         {
     917                 :     2808888 :           edge e;
     918                 :     2808888 :           edge_iterator ei;
     919                 :     2808888 :           class du_head *chain = regrename_chain_from_id (j);
     920                 :     2808888 :           int n_succs_used = 0, n_succs_joined = 0;
     921                 :             : 
     922                 :     7462500 :           FOR_EACH_EDGE (e, ei, bb->succs)
     923                 :             :             {
     924                 :    13960836 :               bool printed = false;
     925                 :             :               class bb_rename_info *dest_ri;
     926                 :             :               unsigned k;
     927                 :             :               bitmap_iterator bi2;
     928                 :             :               HARD_REG_SET live;
     929                 :             : 
     930                 :     4653612 :               REG_SET_TO_HARD_REG_SET (live, df_get_live_in (e->dest));
     931                 :     9307224 :               if (!range_overlaps_hard_reg_set_p (live, chain->regno,
     932                 :             :                                                   chain->nregs))
     933                 :      847975 :                 continue;
     934                 :             :               
     935                 :     3841986 :               n_succs_used++;
     936                 :             : 
     937                 :     3841986 :               dest_ri = (class bb_rename_info *)e->dest->aux;
     938                 :     3841986 :               if (dest_ri == NULL)
     939                 :       36349 :                 continue;
     940                 :             : 
     941                 :    20115167 :               EXECUTE_IF_SET_IN_BITMAP (&dest_ri->incoming_open_chains_set,
     942                 :             :                                         0, k, bi2)
     943                 :             :                 {
     944                 :    20114379 :                   class du_head *incoming_chain = regrename_chain_from_id (k);
     945                 :             : 
     946                 :    20114379 :                   if (incoming_chain->regno == chain->regno
     947                 :    20114379 :                       && incoming_chain->nregs == chain->nregs)
     948                 :             :                     {
     949                 :     3804849 :                       if (dump_file)
     950                 :             :                         {
     951                 :         872 :                           if (!printed)
     952                 :         872 :                             fprintf (dump_file,
     953                 :             :                                      "merging blocks for edge %d -> %d\n",
     954                 :         872 :                                      e->src->index, e->dest->index);
     955                 :         872 :                           printed = true;
     956                 :         872 :                           fprintf (dump_file,
     957                 :             :                                    "  merging chains %d (->%d) and %d (->%d) [%s]\n",
     958                 :             :                                    k, incoming_chain->id, j, chain->id, 
     959                 :         872 :                                    reg_names[incoming_chain->regno]);
     960                 :             :                         }
     961                 :             : 
     962                 :     3804849 :                       merge_chains (chain, incoming_chain);
     963                 :     3804849 :                       n_succs_joined++;
     964                 :     3804849 :                       break;
     965                 :             :                     }
     966                 :             :                 }
     967                 :             :             }
     968                 :     2808888 :           if (n_succs_joined < n_succs_used)
     969                 :             :             {
     970                 :       37080 :               if (dump_file)
     971                 :          10 :                 fprintf (dump_file, "cannot rename chain %d\n",
     972                 :             :                          j);
     973                 :       37080 :               chain->cannot_rename = 1;
     974                 :             :             }
     975                 :             :         }
     976                 :             :     }
     977                 :             : 
     978                 :       20587 :   free (rename_info);
     979                 :             : 
     980                 :      508384 :   FOR_EACH_BB_FN (bb, cfun)
     981                 :      487797 :     bb->aux = NULL;
     982                 :       20587 : }
     983                 :             : 
     984                 :             : /* Attempt to replace all uses of the register in the chain beginning with
     985                 :             :    HEAD with REG.  Returns true on success and false if the replacement is
     986                 :             :    rejected because the insns would not validate.  The latter can happen
     987                 :             :    e.g. if a match_parallel predicate enforces restrictions on register
     988                 :             :    numbering in its subpatterns.  */
     989                 :             : 
     990                 :             : bool
     991                 :      502047 : regrename_do_replace (class du_head *head, int reg)
     992                 :             : {
     993                 :      502047 :   struct du_chain *chain;
     994                 :      502047 :   unsigned int base_regno = head->regno;
     995                 :      502047 :   machine_mode mode;
     996                 :      502047 :   rtx last_reg = NULL_RTX, last_repl = NULL_RTX;
     997                 :             : 
     998                 :     2242731 :   for (chain = head->first; chain; chain = chain->next_use)
     999                 :             :     {
    1000                 :     1740684 :       unsigned int regno = ORIGINAL_REGNO (*chain->loc);
    1001                 :     1740684 :       class reg_attrs *attr = REG_ATTRS (*chain->loc);
    1002                 :     1740684 :       int reg_ptr = REG_POINTER (*chain->loc);
    1003                 :             : 
    1004                 :     1740684 :       if (DEBUG_INSN_P (chain->insn) && REGNO (*chain->loc) != base_regno)
    1005                 :         313 :         validate_change (chain->insn, &(INSN_VAR_LOCATION_LOC (chain->insn)),
    1006                 :             :                          gen_rtx_UNKNOWN_VAR_LOC (), true);
    1007                 :             :       else
    1008                 :             :         {
    1009                 :     1740371 :           if (*chain->loc != last_reg)
    1010                 :             :             {
    1011                 :      972639 :               last_repl = gen_raw_REG (GET_MODE (*chain->loc), reg);
    1012                 :      972639 :               if (regno >= FIRST_PSEUDO_REGISTER)
    1013                 :      954212 :                 ORIGINAL_REGNO (last_repl) = regno;
    1014                 :      972639 :               REG_ATTRS (last_repl) = attr;
    1015                 :      972639 :               REG_POINTER (last_repl) = reg_ptr;
    1016                 :      972639 :               last_reg = *chain->loc;
    1017                 :             :             }
    1018                 :     1740371 :           validate_change (chain->insn, chain->loc, last_repl, true);
    1019                 :             :         }
    1020                 :             :     }
    1021                 :             : 
    1022                 :      502047 :   if (!apply_change_group ())
    1023                 :             :     return false;
    1024                 :             : 
    1025                 :      502008 :   mode = GET_MODE (*head->first->loc);
    1026                 :      502008 :   head->renamed = 1;
    1027                 :      502008 :   head->regno = reg;
    1028                 :      502008 :   head->nregs = hard_regno_nregs (reg, mode);
    1029                 :      502008 :   return true;
    1030                 :             : }
    1031                 :             : 
    1032                 :             : 
    1033                 :             : /* True if we found a register with a size mismatch, which means that we
    1034                 :             :    can't track its lifetime accurately.  If so, we abort the current block
    1035                 :             :    without renaming.  */
    1036                 :             : static bool fail_current_block;
    1037                 :             : 
    1038                 :             : /* Return true if OP is a reg for which all bits are set in PSET, false
    1039                 :             :    if all bits are clear.
    1040                 :             :    In other cases, set fail_current_block and return false.  */
    1041                 :             : 
    1042                 :             : static bool
    1043                 :     2191458 : verify_reg_in_set (rtx op, HARD_REG_SET *pset)
    1044                 :             : {
    1045                 :     2191458 :   unsigned regno, nregs;
    1046                 :     2191458 :   bool all_live, all_dead;
    1047                 :     2191458 :   if (!REG_P (op))
    1048                 :             :     return false;
    1049                 :             : 
    1050                 :     2180550 :   regno = REGNO (op);
    1051                 :     2180550 :   nregs = REG_NREGS (op);
    1052                 :     2180550 :   all_live = all_dead = true;
    1053                 :     4361122 :   while (nregs-- > 0)
    1054                 :     2180572 :     if (TEST_HARD_REG_BIT (*pset, regno + nregs))
    1055                 :             :       all_dead = false;
    1056                 :             :     else
    1057                 :     1054000 :       all_live = false;
    1058                 :     2180550 :   if (!all_dead && !all_live)
    1059                 :             :     {
    1060                 :           0 :       fail_current_block = true;
    1061                 :           0 :       return false;
    1062                 :             :     }
    1063                 :             :   return all_live;
    1064                 :             : }
    1065                 :             : 
    1066                 :             : /* Return true if OP is a reg that is being tracked already in some form.
    1067                 :             :    May set fail_current_block if it sees an unhandled case of overlap.  */
    1068                 :             : 
    1069                 :             : static bool
    1070                 :     1122822 : verify_reg_tracked (rtx op)
    1071                 :             : {
    1072                 :     1122822 :   return (verify_reg_in_set (op, &live_hard_regs)
    1073                 :     1122822 :           || verify_reg_in_set (op, &live_in_chains));
    1074                 :             : }
    1075                 :             : 
    1076                 :             : /* Called through note_stores.  DATA points to a rtx_code, either SET or
    1077                 :             :    CLOBBER, which tells us which kind of rtx to look at.  If we have a
    1078                 :             :    match, record the set register in live_hard_regs and in the hard_conflicts
    1079                 :             :    bitmap of open chains.  */
    1080                 :             : 
    1081                 :             : static void
    1082                 :     7432496 : note_sets_clobbers (rtx x, const_rtx set, void *data)
    1083                 :             : {
    1084                 :     7432496 :   enum rtx_code code = *(enum rtx_code *)data;
    1085                 :     7432496 :   class du_head *chain;
    1086                 :             : 
    1087                 :     7432496 :   if (GET_CODE (x) == SUBREG)
    1088                 :           0 :     x = SUBREG_REG (x);
    1089                 :     7432496 :   if (!REG_P (x) || GET_CODE (set) != code)
    1090                 :             :     return;
    1091                 :             :   /* There must not be pseudos at this point.  */
    1092                 :      844659 :   gcc_assert (HARD_REGISTER_P (x));
    1093                 :      844659 :   add_to_hard_reg_set (&live_hard_regs, GET_MODE (x), REGNO (x));
    1094                 :     6665228 :   for (chain = open_chains; chain; chain = chain->next_chain)
    1095                 :     5820569 :     add_to_hard_reg_set (&chain->hard_conflicts, GET_MODE (x), REGNO (x));
    1096                 :             : }
    1097                 :             : 
    1098                 :             : static void
    1099                 :    16027436 : scan_rtx_reg (rtx_insn *insn, rtx *loc, enum reg_class cl, enum scan_actions action,
    1100                 :             :               enum op_type type)
    1101                 :             : {
    1102                 :    16027436 :   class du_head **p;
    1103                 :    16027436 :   rtx x = *loc;
    1104                 :    16027436 :   unsigned this_regno = REGNO (x);
    1105                 :    16027436 :   int this_nregs = REG_NREGS (x);
    1106                 :             : 
    1107                 :    16027436 :   if (action == mark_write)
    1108                 :             :     {
    1109                 :     1361360 :       if (type == OP_OUT)
    1110                 :             :         {
    1111                 :     1361360 :           du_head_p c;
    1112                 :     1361360 :           rtx pat = PATTERN (insn);
    1113                 :             : 
    1114                 :     1361360 :           c = create_new_chain (this_regno, this_nregs, loc, insn, cl);
    1115                 :             : 
    1116                 :             :           /* We try to tie chains in a move instruction for
    1117                 :             :              a single output.  */
    1118                 :     1361360 :           if (recog_data.n_operands == 2
    1119                 :     1219589 :               && GET_CODE (pat) == SET
    1120                 :     1148730 :               && GET_CODE (SET_DEST (pat)) == REG
    1121                 :     1148730 :               && GET_CODE (SET_SRC (pat)) == REG
    1122                 :      242829 :               && terminated_this_insn
    1123                 :       75577 :               && terminated_this_insn->nregs
    1124                 :       75577 :                  == REG_NREGS (recog_data.operand[1]))
    1125                 :             :             {
    1126                 :       75549 :               gcc_assert (terminated_this_insn->regno
    1127                 :             :                           == REGNO (recog_data.operand[1]));
    1128                 :             : 
    1129                 :       75549 :               c->tied_chain = terminated_this_insn;
    1130                 :       75549 :               terminated_this_insn->tied_chain = c;
    1131                 :             : 
    1132                 :       75549 :               if (dump_file)
    1133                 :           4 :                 fprintf (dump_file, "Tying chain %s (%d) with %s (%d)\n",
    1134                 :           4 :                          reg_names[c->regno], c->id,
    1135                 :             :                          reg_names[terminated_this_insn->regno],
    1136                 :             :                          terminated_this_insn->id);
    1137                 :             :             }
    1138                 :             :         }
    1139                 :             : 
    1140                 :     1361360 :       return;
    1141                 :             :     }
    1142                 :             : 
    1143                 :    14666076 :   if ((type == OP_OUT) != (action == terminate_write || action == mark_access))
    1144                 :             :     return;
    1145                 :             : 
    1146                 :    79836847 :   for (p = &open_chains; *p;)
    1147                 :             :     {
    1148                 :    70730148 :       class du_head *head = *p;
    1149                 :    70730148 :       class du_head *next = head->next_chain;
    1150                 :   141460296 :       int exact_match = (head->regno == this_regno
    1151                 :    70730148 :                          && head->nregs == this_nregs);
    1152                 :   141460296 :       int superset = (this_regno <= head->regno
    1153                 :    70730148 :                       && this_regno + this_nregs >= head->regno + head->nregs);
    1154                 :   141460296 :       int subset = (this_regno >= head->regno
    1155                 :    70730148 :                       && this_regno + this_nregs <= head->regno + head->nregs);
    1156                 :             : 
    1157                 :    70730148 :       if (!bitmap_bit_p (&open_chains_set, head->id)
    1158                 :    70730148 :           || head->regno + head->nregs <= this_regno
    1159                 :   112880232 :           || this_regno + this_nregs <= head->regno)
    1160                 :             :         {
    1161                 :    65752530 :           p = &head->next_chain;
    1162                 :    65752530 :           continue;
    1163                 :             :         }
    1164                 :             : 
    1165                 :     4977618 :       if (action == mark_read || action == mark_access)
    1166                 :             :         {
    1167                 :             :           /* ??? Class NO_REGS can happen if the md file makes use of
    1168                 :             :              EXTRA_CONSTRAINTS to match registers.  Which is arguably
    1169                 :             :              wrong, but there we are.  */
    1170                 :             : 
    1171                 :     3487233 :           if (cl == NO_REGS || (!exact_match && !DEBUG_INSN_P (insn)))
    1172                 :             :             {
    1173                 :        4672 :               if (dump_file)
    1174                 :           0 :                 fprintf (dump_file,
    1175                 :             :                          "Cannot rename chain %s (%d) at insn %d (%s)\n",
    1176                 :           0 :                          reg_names[head->regno], head->id, INSN_UID (insn),
    1177                 :           0 :                          scan_actions_name[(int) action]);
    1178                 :        4672 :               head->cannot_rename = 1;
    1179                 :        4672 :               if (superset)
    1180                 :             :                 {
    1181                 :          25 :                   unsigned nregs = this_nregs;
    1182                 :          25 :                   head->regno = this_regno;
    1183                 :          25 :                   head->nregs = this_nregs;
    1184                 :          60 :                   while (nregs-- > 0)
    1185                 :          35 :                     SET_HARD_REG_BIT (live_in_chains, head->regno + nregs);
    1186                 :          25 :                   if (dump_file)
    1187                 :           0 :                     fprintf (dump_file,
    1188                 :             :                              "Widening register in chain %s (%d) at insn %d\n",
    1189                 :           0 :                              reg_names[head->regno], head->id, INSN_UID (insn));
    1190                 :             :                 }
    1191                 :        4647 :               else if (!subset)
    1192                 :             :                 {
    1193                 :           0 :                   fail_current_block = true;
    1194                 :           0 :                   if (dump_file)
    1195                 :           0 :                     fprintf (dump_file,
    1196                 :             :                              "Failing basic block due to unhandled overlap\n");
    1197                 :             :                 }
    1198                 :             :             }
    1199                 :             :           else
    1200                 :             :             {
    1201                 :     3482561 :               struct du_chain *this_du;
    1202                 :     3482561 :               this_du = XOBNEW (&rename_obstack, struct du_chain);
    1203                 :     3482561 :               this_du->next_use = 0;
    1204                 :     3482561 :               this_du->loc = loc;
    1205                 :     3482561 :               this_du->insn = insn;
    1206                 :     3482561 :               this_du->cl = cl;
    1207                 :     3482561 :               if (head->first == NULL)
    1208                 :      711925 :                 head->first = this_du;
    1209                 :             :               else
    1210                 :     2770636 :                 head->last->next_use = this_du;
    1211                 :     3482561 :               record_operand_use (head, this_du);
    1212                 :     3482561 :               head->last = this_du;
    1213                 :             :             }
    1214                 :             :           /* Avoid adding the same location in a DEBUG_INSN multiple times,
    1215                 :             :              which could happen with non-exact overlap.  */
    1216                 :     3487233 :           if (DEBUG_INSN_P (insn))
    1217                 :             :             return;
    1218                 :             :           /* Otherwise, find any other chains that do not match exactly;
    1219                 :             :              ensure they all get marked unrenamable.  */
    1220                 :     3396100 :           p = &head->next_chain;
    1221                 :     3396100 :           continue;
    1222                 :     3396100 :         }
    1223                 :             : 
    1224                 :             :       /* Whether the terminated chain can be used for renaming
    1225                 :             :          depends on the action and this being an exact match.
    1226                 :             :          In either case, we remove this element from open_chains.  */
    1227                 :             : 
    1228                 :     1490385 :       if ((action == terminate_dead || action == terminate_write)
    1229                 :     1200382 :           && (superset || subset))
    1230                 :             :         {
    1231                 :     1200382 :           unsigned nregs;
    1232                 :             : 
    1233                 :     1200382 :           if (subset && !superset)
    1234                 :        1844 :             head->cannot_rename = 1;
    1235                 :     1200382 :           bitmap_clear_bit (&open_chains_set, head->id);
    1236                 :             : 
    1237                 :     1200382 :           nregs = head->nregs;
    1238                 :     2402608 :           while (nregs-- > 0)
    1239                 :             :             {
    1240                 :     1202226 :               CLEAR_HARD_REG_BIT (live_in_chains, head->regno + nregs);
    1241                 :     1202226 :               if (subset && !superset
    1242                 :        3688 :                   && (head->regno + nregs < this_regno
    1243                 :        2876 :                       || head->regno + nregs >= this_regno + this_nregs))
    1244                 :        1844 :                 SET_HARD_REG_BIT (live_hard_regs, head->regno + nregs);
    1245                 :             :             }
    1246                 :             : 
    1247                 :     1200382 :           if (action == terminate_dead)
    1248                 :     1072633 :             terminated_this_insn = *p;
    1249                 :     1200382 :           *p = next;
    1250                 :     1200382 :           if (dump_file)
    1251                 :         110 :             fprintf (dump_file,
    1252                 :             :                      "Closing chain %s (%d) at insn %d (%s%s)\n",
    1253                 :         110 :                      reg_names[head->regno], head->id, INSN_UID (insn),
    1254                 :         110 :                      scan_actions_name[(int) action],
    1255                 :           0 :                      superset ? ", superset" : subset ? ", subset" : "");
    1256                 :             :         }
    1257                 :           0 :       else if (action == terminate_dead || action == terminate_write)
    1258                 :             :         {
    1259                 :             :           /* In this case, tracking liveness gets too hard.  Fail the
    1260                 :             :              entire basic block.  */
    1261                 :           0 :           if (dump_file)
    1262                 :           0 :             fprintf (dump_file,
    1263                 :             :                      "Failing basic block due to unhandled overlap\n");
    1264                 :           0 :           fail_current_block = true;
    1265                 :           0 :           return;
    1266                 :             :         }
    1267                 :             :       else
    1268                 :             :         {
    1269                 :      290003 :           head->cannot_rename = 1;
    1270                 :      290003 :           if (dump_file)
    1271                 :          10 :             fprintf (dump_file,
    1272                 :             :                      "Cannot rename chain %s (%d) at insn %d (%s)\n",
    1273                 :          10 :                      reg_names[head->regno], head->id, INSN_UID (insn),
    1274                 :          10 :                      scan_actions_name[(int) action]);
    1275                 :      290003 :           p = &head->next_chain;
    1276                 :             :         }
    1277                 :             :     }
    1278                 :             : }
    1279                 :             : 
    1280                 :             : /* A wrapper around base_reg_class which returns ALL_REGS if INSN is a
    1281                 :             :    DEBUG_INSN.  The arguments MODE, AS, CODE and INDEX_CODE are as for
    1282                 :             :    base_reg_class.  */
    1283                 :             : 
    1284                 :             : static reg_class
    1285                 :     5838089 : base_reg_class_for_rename (rtx_insn *insn, machine_mode mode, addr_space_t as,
    1286                 :             :                            rtx_code code, rtx_code index_code)
    1287                 :             : {
    1288                 :           0 :   if (DEBUG_INSN_P (insn))
    1289                 :             :     return ALL_REGS;
    1290                 :     5693340 :   return base_reg_class (mode, as, code, index_code);
    1291                 :             : }
    1292                 :             : 
    1293                 :             : /* Adapted from find_reloads_address_1.  CL is INDEX_REG_CLASS or
    1294                 :             :    BASE_REG_CLASS depending on how the register is being considered.  */
    1295                 :             : 
    1296                 :             : static void
    1297                 :     6793144 : scan_rtx_address (rtx_insn *insn, rtx *loc, enum reg_class cl,
    1298                 :             :                   enum scan_actions action, machine_mode mode,
    1299                 :             :                   addr_space_t as)
    1300                 :             : {
    1301                 :     6793144 :   rtx x = *loc;
    1302                 :     6793144 :   RTX_CODE code = GET_CODE (x);
    1303                 :     6793144 :   const char *fmt;
    1304                 :     6793144 :   int i, j;
    1305                 :             : 
    1306                 :     6793144 :   if (action == mark_write || action == mark_access)
    1307                 :             :     return;
    1308                 :             : 
    1309                 :     6269471 :   switch (code)
    1310                 :             :     {
    1311                 :     2305221 :     case PLUS:
    1312                 :     2305221 :       {
    1313                 :     2305221 :         rtx orig_op0 = XEXP (x, 0);
    1314                 :     2305221 :         rtx orig_op1 = XEXP (x, 1);
    1315                 :     2305221 :         RTX_CODE code0 = GET_CODE (orig_op0);
    1316                 :     2305221 :         RTX_CODE code1 = GET_CODE (orig_op1);
    1317                 :     2305221 :         rtx op0 = orig_op0;
    1318                 :     2305221 :         rtx op1 = orig_op1;
    1319                 :     2305221 :         rtx *locI = NULL;
    1320                 :     2305221 :         rtx *locB = NULL;
    1321                 :     2305221 :         enum rtx_code index_code = SCRATCH;
    1322                 :             : 
    1323                 :     2305221 :         if (GET_CODE (op0) == SUBREG)
    1324                 :             :           {
    1325                 :           0 :             op0 = SUBREG_REG (op0);
    1326                 :           0 :             code0 = GET_CODE (op0);
    1327                 :             :           }
    1328                 :             : 
    1329                 :     2305221 :         if (GET_CODE (op1) == SUBREG)
    1330                 :             :           {
    1331                 :           0 :             op1 = SUBREG_REG (op1);
    1332                 :           0 :             code1 = GET_CODE (op1);
    1333                 :             :           }
    1334                 :             : 
    1335                 :     2305221 :         if (code0 == MULT || code0 == SIGN_EXTEND || code0 == TRUNCATE
    1336                 :     2186606 :             || code0 == ZERO_EXTEND || code1 == MEM)
    1337                 :             :           {
    1338                 :      118686 :             locI = &XEXP (x, 0);
    1339                 :      118686 :             locB = &XEXP (x, 1);
    1340                 :      118686 :             index_code = GET_CODE (*locI);
    1341                 :             :           }
    1342                 :     2186535 :         else if (code1 == MULT || code1 == SIGN_EXTEND || code1 == TRUNCATE
    1343                 :     2186521 :                  || code1 == ZERO_EXTEND || code0 == MEM)
    1344                 :             :           {
    1345                 :         440 :             locI = &XEXP (x, 1);
    1346                 :         440 :             locB = &XEXP (x, 0);
    1347                 :         440 :             index_code = GET_CODE (*locI);
    1348                 :             :           }
    1349                 :     2186095 :         else if (code0 == CONST_INT || code0 == CONST
    1350                 :     2186095 :                  || code0 == SYMBOL_REF || code0 == LABEL_REF)
    1351                 :             :           {
    1352                 :       54182 :             locB = &XEXP (x, 1);
    1353                 :       54182 :             index_code = GET_CODE (XEXP (x, 0));
    1354                 :             :           }
    1355                 :     2131913 :         else if (code1 == CONST_INT || code1 == CONST
    1356                 :             :                  || code1 == SYMBOL_REF || code1 == LABEL_REF)
    1357                 :             :           {
    1358                 :     1942689 :             locB = &XEXP (x, 0);
    1359                 :     1942689 :             index_code = GET_CODE (XEXP (x, 1));
    1360                 :             :           }
    1361                 :      189224 :         else if (code0 == REG && code1 == REG)
    1362                 :             :           {
    1363                 :      166623 :             int index_op;
    1364                 :      166623 :             unsigned regno0 = REGNO (op0), regno1 = REGNO (op1);
    1365                 :             : 
    1366                 :           1 :             if (REGNO_OK_FOR_INDEX_P (regno1)
    1367                 :      166623 :                 && regno_ok_for_base_p (regno0, mode, as, PLUS, REG))
    1368                 :             :               index_op = 1;
    1369                 :           0 :             else if (REGNO_OK_FOR_INDEX_P (regno0)
    1370                 :           1 :                      && regno_ok_for_base_p (regno1, mode, as, PLUS, REG))
    1371                 :             :               index_op = 0;
    1372                 :           0 :             else if (regno_ok_for_base_p (regno0, mode, as, PLUS, REG)
    1373                 :           0 :                      || REGNO_OK_FOR_INDEX_P (regno1))
    1374                 :             :               index_op = 1;
    1375                 :           0 :             else if (regno_ok_for_base_p (regno1, mode, as, PLUS, REG))
    1376                 :             :               index_op = 0;
    1377                 :             :             else
    1378                 :      166622 :               index_op = 1;
    1379                 :             : 
    1380                 :      166623 :             locI = &XEXP (x, index_op);
    1381                 :      166623 :             locB = &XEXP (x, !index_op);
    1382                 :      166623 :             index_code = GET_CODE (*locI);
    1383                 :             :           }
    1384                 :       22601 :         else if (code0 == REG)
    1385                 :             :           {
    1386                 :        4460 :             locI = &XEXP (x, 0);
    1387                 :        4460 :             locB = &XEXP (x, 1);
    1388                 :        4460 :             index_code = GET_CODE (*locI);
    1389                 :             :           }
    1390                 :       18141 :         else if (code1 == REG)
    1391                 :             :           {
    1392                 :       18083 :             locI = &XEXP (x, 1);
    1393                 :       18083 :             locB = &XEXP (x, 0);
    1394                 :       18083 :             index_code = GET_CODE (*locI);
    1395                 :             :           }
    1396                 :             : 
    1397                 :     2305221 :         if (locI)
    1398                 :             :           {
    1399                 :      308292 :             reg_class iclass = DEBUG_INSN_P (insn) ? ALL_REGS : INDEX_REG_CLASS;
    1400                 :      308292 :             scan_rtx_address (insn, locI, iclass, action, mode, as);
    1401                 :             :           }
    1402                 :     2305221 :         if (locB)
    1403                 :             :           {
    1404                 :     2305163 :             reg_class bclass = base_reg_class_for_rename (insn, mode, as, PLUS,
    1405                 :             :                                                           index_code);
    1406                 :     2305163 :             scan_rtx_address (insn, locB, bclass, action, mode, as);
    1407                 :             :           }
    1408                 :             :         return;
    1409                 :             :       }
    1410                 :             : 
    1411                 :      156010 :     case POST_INC:
    1412                 :      156010 :     case POST_DEC:
    1413                 :      156010 :     case POST_MODIFY:
    1414                 :      156010 :     case PRE_INC:
    1415                 :      156010 :     case PRE_DEC:
    1416                 :      156010 :     case PRE_MODIFY:
    1417                 :             :       /* If the target doesn't claim to handle autoinc, this must be
    1418                 :             :          something special, like a stack push.  Kill this chain.  */
    1419                 :      156010 :       if (!AUTO_INC_DEC)
    1420                 :      156010 :         action = mark_all_read;
    1421                 :             : 
    1422                 :      156010 :       break;
    1423                 :             : 
    1424                 :        2395 :     case MEM:
    1425                 :        2395 :       {
    1426                 :        2395 :         reg_class bclass = base_reg_class_for_rename (insn, GET_MODE (x),
    1427                 :        2395 :                                                       MEM_ADDR_SPACE (x),
    1428                 :             :                                                       MEM, SCRATCH);
    1429                 :        2395 :         scan_rtx_address (insn, &XEXP (x, 0), bclass, action, GET_MODE (x),
    1430                 :        2395 :                           MEM_ADDR_SPACE (x));
    1431                 :             :       }
    1432                 :        2395 :       return;
    1433                 :             : 
    1434                 :     2858804 :     case REG:
    1435                 :     2858804 :       scan_rtx_reg (insn, loc, cl, action, OP_IN);
    1436                 :     2858804 :       return;
    1437                 :             : 
    1438                 :             :     default:
    1439                 :             :       break;
    1440                 :             :     }
    1441                 :             : 
    1442                 :     1103051 :   fmt = GET_RTX_FORMAT (code);
    1443                 :     2447083 :   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
    1444                 :             :     {
    1445                 :     1344032 :       if (fmt[i] == 'e')
    1446                 :      509250 :         scan_rtx_address (insn, &XEXP (x, i), cl, action, mode, as);
    1447                 :      834782 :       else if (fmt[i] == 'E')
    1448                 :        3604 :         for (j = XVECLEN (x, i) - 1; j >= 0; j--)
    1449                 :        1968 :           scan_rtx_address (insn, &XVECEXP (x, i, j), cl, action, mode, as);
    1450                 :             :     }
    1451                 :             : }
    1452                 :             : 
    1453                 :             : static void
    1454                 :    35561330 : scan_rtx (rtx_insn *insn, rtx *loc, enum reg_class cl, enum scan_actions action,
    1455                 :             :           enum op_type type)
    1456                 :             : {
    1457                 :    43178981 :   const char *fmt;
    1458                 :    43178981 :   rtx x = *loc;
    1459                 :    43178981 :   int i, j;
    1460                 :             : 
    1461                 :    43178981 :   enum rtx_code code = GET_CODE (x);
    1462                 :    43178981 :   switch (code)
    1463                 :             :     {
    1464                 :             :     case CONST:
    1465                 :             :     CASE_CONST_ANY:
    1466                 :             :     case SYMBOL_REF:
    1467                 :             :     case LABEL_REF:
    1468                 :             :     case PC:
    1469                 :             :       return;
    1470                 :             : 
    1471                 :    13168632 :     case REG:
    1472                 :    13168632 :       scan_rtx_reg (insn, loc, cl, action, type);
    1473                 :    13168632 :       return;
    1474                 :             : 
    1475                 :     3530531 :     case MEM:
    1476                 :     3530531 :       {
    1477                 :     3530531 :         reg_class bclass = base_reg_class_for_rename (insn, GET_MODE (x),
    1478                 :     3530531 :                                                       MEM_ADDR_SPACE (x),
    1479                 :             :                                                       MEM, SCRATCH);
    1480                 :             : 
    1481                 :     3530531 :         scan_rtx_address (insn, &XEXP (x, 0), bclass, action, GET_MODE (x),
    1482                 :     3530531 :                           MEM_ADDR_SPACE (x));
    1483                 :             :       }
    1484                 :     3530531 :       return;
    1485                 :             : 
    1486                 :     6388450 :     case SET:
    1487                 :     6388450 :       scan_rtx (insn, &SET_SRC (x), cl, action, OP_IN);
    1488                 :    12776900 :       scan_rtx (insn, &SET_DEST (x), cl, action,
    1489                 :     6388450 :                 (GET_CODE (PATTERN (insn)) == COND_EXEC
    1490                 :           0 :                  && verify_reg_tracked (SET_DEST (x))) ? OP_INOUT : OP_OUT);
    1491                 :     6388450 :       return;
    1492                 :             : 
    1493                 :        3974 :     case STRICT_LOW_PART:
    1494                 :        3974 :       scan_rtx (insn, &XEXP (x, 0), cl, action,
    1495                 :        3974 :                 verify_reg_tracked (XEXP (x, 0)) ? OP_INOUT : OP_OUT);
    1496                 :        3974 :       return;
    1497                 :             : 
    1498                 :        5289 :     case ZERO_EXTRACT:
    1499                 :        5289 :     case SIGN_EXTRACT:
    1500                 :        6769 :       scan_rtx (insn, &XEXP (x, 0), cl, action,
    1501                 :             :                 (type == OP_IN ? OP_IN :
    1502                 :        1480 :                  verify_reg_tracked (XEXP (x, 0)) ? OP_INOUT : OP_OUT));
    1503                 :        5289 :       scan_rtx (insn, &XEXP (x, 1), cl, action, OP_IN);
    1504                 :        5289 :       scan_rtx (insn, &XEXP (x, 2), cl, action, OP_IN);
    1505                 :        5289 :       return;
    1506                 :             : 
    1507                 :           0 :     case POST_INC:
    1508                 :           0 :     case PRE_INC:
    1509                 :           0 :     case POST_DEC:
    1510                 :           0 :     case PRE_DEC:
    1511                 :           0 :     case POST_MODIFY:
    1512                 :           0 :     case PRE_MODIFY:
    1513                 :             :       /* Should only happen inside MEM.  */
    1514                 :           0 :       gcc_unreachable ();
    1515                 :             : 
    1516                 :     1048094 :     case CLOBBER:
    1517                 :     2096188 :       scan_rtx (insn, &SET_DEST (x), cl, action,
    1518                 :     1048094 :                 (GET_CODE (PATTERN (insn)) == COND_EXEC
    1519                 :           0 :                  && verify_reg_tracked (SET_DEST (x))) ? OP_INOUT : OP_OUT);
    1520                 :     1048094 :       return;
    1521                 :             : 
    1522                 :      289576 :     case EXPR_LIST:
    1523                 :      289576 :       scan_rtx (insn, &XEXP (x, 0), cl, action, type);
    1524                 :      289576 :       if (XEXP (x, 1))
    1525                 :      171844 :         scan_rtx (insn, &XEXP (x, 1), cl, action, type);
    1526                 :             :       return;
    1527                 :             : 
    1528                 :     6010224 :     default:
    1529                 :     6010224 :       break;
    1530                 :             :     }
    1531                 :             : 
    1532                 :     6010224 :   fmt = GET_RTX_FORMAT (code);
    1533                 :    16688022 :   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
    1534                 :             :     {
    1535                 :    10677798 :       if (fmt[i] == 'e')
    1536                 :     8954686 :         scan_rtx (insn, &XEXP (x, i), cl, action, type);
    1537                 :     1723112 :       else if (fmt[i] == 'E')
    1538                 :     4124875 :         for (j = XVECLEN (x, i) - 1; j >= 0; j--)
    1539                 :     2857390 :           scan_rtx (insn, &XVECEXP (x, i, j), cl, action, type);
    1540                 :             :     }
    1541                 :             : }
    1542                 :             : 
    1543                 :             : /* Hide operands of the current insn (of which there are N_OPS) by
    1544                 :             :    substituting pc for them.
    1545                 :             :    Previous values are stored in the OLD_OPERANDS and OLD_DUPS.
    1546                 :             :    For every bit set in DO_NOT_HIDE, we leave the operand alone.
    1547                 :             :    If INOUT_AND_EC_ONLY is set, we only do this for OP_INOUT type operands
    1548                 :             :    and earlyclobbers.  */
    1549                 :             : 
    1550                 :             : static void
    1551                 :    13120704 : hide_operands (int n_ops, rtx *old_operands, rtx *old_dups,
    1552                 :             :                unsigned HOST_WIDE_INT do_not_hide, bool inout_and_ec_only)
    1553                 :             : {
    1554                 :    13120704 :   int i;
    1555                 :    13120704 :   const operand_alternative *op_alt = which_op_alt ();
    1556                 :    55490864 :   for (i = 0; i < n_ops; i++)
    1557                 :             :     {
    1558                 :    29249456 :       old_operands[i] = recog_data.operand[i];
    1559                 :             :       /* Don't squash match_operator or match_parallel here, since
    1560                 :             :          we don't know that all of the contained registers are
    1561                 :             :          reachable by proper operands.  */
    1562                 :    29249456 :       if (recog_data.constraints[i][0] == '\0')
    1563                 :     4597380 :         continue;
    1564                 :    24652076 :       if (do_not_hide & (1 << i))
    1565                 :        1496 :         continue;
    1566                 :    24650580 :       if (!inout_and_ec_only || recog_data.operand_type[i] == OP_INOUT
    1567                 :     4996161 :           || op_alt[i].earlyclobber)
    1568                 :    19654492 :         *recog_data.operand_loc[i] = pc_rtx;
    1569                 :             :     }
    1570                 :    13424404 :   for (i = 0; i < recog_data.n_dups; i++)
    1571                 :             :     {
    1572                 :      303700 :       int opn = recog_data.dup_num[i];
    1573                 :      303700 :       old_dups[i] = *recog_data.dup_loc[i];
    1574                 :      303700 :       if (do_not_hide & (1 << opn))
    1575                 :           0 :         continue;
    1576                 :      303700 :       if (!inout_and_ec_only || recog_data.operand_type[opn] == OP_INOUT
    1577                 :       38733 :           || op_alt[opn].earlyclobber)
    1578                 :      264967 :         *recog_data.dup_loc[i] = pc_rtx;
    1579                 :             :     }
    1580                 :    13120704 : }
    1581                 :             : 
    1582                 :             : /* Undo the substitution performed by hide_operands.  INSN is the insn we
    1583                 :             :    are processing; the arguments are the same as in hide_operands.  */
    1584                 :             : 
    1585                 :             : static void
    1586                 :    13120704 : restore_operands (rtx_insn *insn, int n_ops, rtx *old_operands, rtx *old_dups)
    1587                 :             : {
    1588                 :    13120704 :   int i;
    1589                 :    13424404 :   for (i = 0; i < recog_data.n_dups; i++)
    1590                 :      303700 :     *recog_data.dup_loc[i] = old_dups[i];
    1591                 :    42370160 :   for (i = 0; i < n_ops; i++)
    1592                 :    29249456 :     *recog_data.operand_loc[i] = old_operands[i];
    1593                 :    13120704 :   if (recog_data.n_dups)
    1594                 :      169320 :     df_insn_rescan (insn);
    1595                 :    13120704 : }
    1596                 :             : 
    1597                 :             : /* For each output operand of INSN, call scan_rtx to create a new
    1598                 :             :    open chain.  Do this only for normal or earlyclobber outputs,
    1599                 :             :    depending on EARLYCLOBBER.  If INSN_INFO is nonnull, use it to
    1600                 :             :    record information about the operands in the insn.  */
    1601                 :             : 
    1602                 :             : static void
    1603                 :     6560352 : record_out_operands (rtx_insn *insn, bool earlyclobber, insn_rr_info *insn_info)
    1604                 :             : {
    1605                 :     6560352 :   int n_ops = recog_data.n_operands;
    1606                 :     6560352 :   const operand_alternative *op_alt = which_op_alt ();
    1607                 :             : 
    1608                 :     6560352 :   int i;
    1609                 :             : 
    1610                 :    21336930 :   for (i = 0; i < n_ops + recog_data.n_dups; i++)
    1611                 :             :     {
    1612                 :    14776578 :       int opn = i < n_ops ? i : recog_data.dup_num[i - n_ops];
    1613                 :    29553156 :       rtx *loc = (i < n_ops
    1614                 :    14776578 :                   ? recog_data.operand_loc[opn]
    1615                 :      151850 :                   : recog_data.dup_loc[i - n_ops]);
    1616                 :    14776578 :       rtx op = *loc;
    1617                 :    14776578 :       enum reg_class cl = alternative_class (op_alt, opn);
    1618                 :             : 
    1619                 :    14776578 :       class du_head *prev_open;
    1620                 :             : 
    1621                 :    14776578 :       if (recog_data.operand_type[opn] != OP_OUT
    1622                 :     3770066 :           || op_alt[opn].earlyclobber != earlyclobber)
    1623                 :    12891545 :         continue;
    1624                 :             : 
    1625                 :     1885033 :       if (insn_info)
    1626                 :           0 :         cur_operand = insn_info->op_info + i;
    1627                 :             : 
    1628                 :     1885033 :       prev_open = open_chains;
    1629                 :     1885033 :       if (earlyclobber)
    1630                 :          73 :         scan_rtx (insn, loc, cl, terminate_write, OP_OUT);
    1631                 :     1885033 :       scan_rtx (insn, loc, cl, mark_write, OP_OUT);
    1632                 :             : 
    1633                 :             :       /* ??? Many targets have output constraints on the SET_DEST
    1634                 :             :          of a call insn, which is stupid, since these are certainly
    1635                 :             :          ABI defined hard registers.  For these, and for asm operands
    1636                 :             :          that originally referenced hard registers, we must record that
    1637                 :             :          the chain cannot be renamed.  */
    1638                 :     1885033 :       if (CALL_P (insn)
    1639                 :     1885033 :           || (asm_noperands (PATTERN (insn)) > 0
    1640                 :         485 :               && REG_P (op)
    1641                 :         267 :               && REGNO (op) == ORIGINAL_REGNO (op)))
    1642                 :             :         {
    1643                 :           0 :           if (prev_open != open_chains)
    1644                 :           0 :             open_chains->cannot_rename = 1;
    1645                 :             :         }
    1646                 :             :     }
    1647                 :     6560352 :   cur_operand = NULL;
    1648                 :     6560352 : }
    1649                 :             : 
    1650                 :             : /* Build def/use chain.  */
    1651                 :             : 
    1652                 :             : static bool
    1653                 :      487797 : build_def_use (basic_block bb)
    1654                 :             : {
    1655                 :      487797 :   rtx_insn *insn;
    1656                 :      487797 :   unsigned HOST_WIDE_INT untracked_operands;
    1657                 :             : 
    1658                 :      487797 :   fail_current_block = false;
    1659                 :             : 
    1660                 :     5340381 :   for (insn = BB_HEAD (bb); ; insn = NEXT_INSN (insn))
    1661                 :             :     {
    1662                 :     5340381 :       if (NONDEBUG_INSN_P (insn))
    1663                 :             :         {
    1664                 :     3280176 :           int n_ops;
    1665                 :     3280176 :           rtx note;
    1666                 :     3280176 :           rtx old_operands[MAX_RECOG_OPERANDS];
    1667                 :     3280176 :           rtx old_dups[MAX_DUP_OPERANDS];
    1668                 :     3280176 :           int i;
    1669                 :     3280176 :           int predicated;
    1670                 :     3280176 :           enum rtx_code set_code = SET;
    1671                 :     3280176 :           enum rtx_code clobber_code = CLOBBER;
    1672                 :     3280176 :           insn_rr_info *insn_info = NULL;
    1673                 :     3280176 :           terminated_this_insn = NULL;
    1674                 :             : 
    1675                 :             :           /* Process the insn, determining its effect on the def-use
    1676                 :             :              chains and live hard registers.  We perform the following
    1677                 :             :              steps with the register references in the insn, simulating
    1678                 :             :              its effect:
    1679                 :             :              (1) Deal with earlyclobber operands and CLOBBERs of non-operands
    1680                 :             :                  by creating chains and marking hard regs live.
    1681                 :             :              (2) Any read outside an operand causes any chain it overlaps
    1682                 :             :                  with to be marked unrenamable.
    1683                 :             :              (3) Any read inside an operand is added if there's already
    1684                 :             :                  an open chain for it.
    1685                 :             :              (4) For any REG_DEAD note we find, close open chains that
    1686                 :             :                  overlap it.
    1687                 :             :              (5) For any non-earlyclobber write we find, close open chains
    1688                 :             :                  that overlap it.
    1689                 :             :              (6) For any non-earlyclobber write we find in an operand, make
    1690                 :             :                  a new chain or mark the hard register as live.
    1691                 :             :              (7) For any REG_UNUSED, close any chains we just opened.
    1692                 :             :              (8) For any REG_CFA_RESTORE or REG_CFA_REGISTER, kill any chain
    1693                 :             :                  containing its dest.
    1694                 :             : 
    1695                 :             :              We cannot deal with situations where we track a reg in one mode
    1696                 :             :              and see a reference in another mode; these will cause the chain
    1697                 :             :              to be marked unrenamable or even cause us to abort the entire
    1698                 :             :              basic block.  */
    1699                 :             : 
    1700                 :     3280176 :           extract_constrain_insn (insn);
    1701                 :     3280176 :           preprocess_constraints (insn);
    1702                 :     3280176 :           const operand_alternative *op_alt = which_op_alt ();
    1703                 :     3280176 :           n_ops = recog_data.n_operands;
    1704                 :     3280176 :           untracked_operands = 0;
    1705                 :             : 
    1706                 :     3280176 :           if (insn_rr.exists ())
    1707                 :             :             {
    1708                 :           0 :               insn_info = &insn_rr[INSN_UID (insn)];
    1709                 :           0 :               insn_info->op_info = XOBNEWVEC (&rename_obstack, operand_rr_info,
    1710                 :             :                                               recog_data.n_operands);
    1711                 :           0 :               memset (insn_info->op_info, 0,
    1712                 :           0 :                       sizeof (operand_rr_info) * recog_data.n_operands);
    1713                 :             :             }
    1714                 :             : 
    1715                 :             :           /* Simplify the code below by promoting OP_OUT to OP_INOUT in
    1716                 :             :              predicated instructions, but only for register operands
    1717                 :             :              that are already tracked, so that we can create a chain
    1718                 :             :              when the first SET makes a register live.  */
    1719                 :             : 
    1720                 :     3280176 :           predicated = GET_CODE (PATTERN (insn)) == COND_EXEC;
    1721                 :    10592540 :           for (i = 0; i < n_ops; ++i)
    1722                 :             :             {
    1723                 :     7312364 :               rtx op = recog_data.operand[i];
    1724                 :     7312364 :               int matches = op_alt[i].matches;
    1725                 :     7312364 :               if (matches >= 0 || op_alt[i].matched >= 0
    1726                 :     6152432 :                   || (predicated && recog_data.operand_type[i] == OP_OUT))
    1727                 :             :                 {
    1728                 :     1159932 :                   recog_data.operand_type[i] = OP_INOUT;
    1729                 :             :                   /* A special case to deal with instruction patterns that
    1730                 :             :                      have matching operands with different modes.  If we're
    1731                 :             :                      not already tracking such a reg, we won't start here,
    1732                 :             :                      and we must instead make sure to make the operand visible
    1733                 :             :                      to the machinery that tracks hard registers.  */
    1734                 :     1159932 :                   machine_mode i_mode = recog_data.operand_mode[i];
    1735                 :     1159932 :                   if (matches >= 0)
    1736                 :             :                     {
    1737                 :      579966 :                       machine_mode matches_mode
    1738                 :             :                         = recog_data.operand_mode[matches];
    1739                 :             : 
    1740                 :      579966 :                       if (maybe_ne (GET_MODE_SIZE (i_mode),
    1741                 :      579966 :                                     GET_MODE_SIZE (matches_mode))
    1742                 :      579966 :                           && !verify_reg_in_set (op, &live_in_chains))
    1743                 :             :                         {
    1744                 :         187 :                           untracked_operands |= 1 << i;
    1745                 :         187 :                           untracked_operands |= 1 << matches;
    1746                 :             :                         }
    1747                 :             :                     }
    1748                 :             :                 }
    1749                 :             : #ifdef STACK_REGS
    1750                 :     7312364 :               if (regstack_completed
    1751                 :           0 :                   && REG_P (op)
    1752                 :     7312364 :                   && IN_RANGE (REGNO (op), FIRST_STACK_REG, LAST_STACK_REG))
    1753                 :           0 :                 untracked_operands |= 1 << i;
    1754                 :             : #endif
    1755                 :             :               /* If there's an in-out operand with a register that is not
    1756                 :             :                  being tracked at all yet, open a chain.  */
    1757                 :     7312364 :               if (recog_data.operand_type[i] == OP_INOUT
    1758                 :     1166858 :                   && !(untracked_operands & (1 << i))
    1759                 :     1166671 :                   && REG_P (op)
    1760                 :     8429732 :                   && !verify_reg_tracked (op))
    1761                 :           8 :                 create_new_chain (REGNO (op), REG_NREGS (op), NULL, NULL,
    1762                 :             :                                   NO_REGS);
    1763                 :             :             }
    1764                 :             : 
    1765                 :     3280176 :           if (fail_current_block)
    1766                 :             :             break;
    1767                 :             : 
    1768                 :             :           /* Step 1a: Mark hard registers that are clobbered in this insn,
    1769                 :             :              outside an operand, as live.  */
    1770                 :     3280176 :           hide_operands (n_ops, old_operands, old_dups, untracked_operands,
    1771                 :             :                          false);
    1772                 :     3280176 :           note_stores (insn, note_sets_clobbers, &clobber_code);
    1773                 :     3280176 :           restore_operands (insn, n_ops, old_operands, old_dups);
    1774                 :             : 
    1775                 :             :           /* Step 1b: Begin new chains for earlyclobbered writes inside
    1776                 :             :              operands.  */
    1777                 :     3280176 :           record_out_operands (insn, true, insn_info);
    1778                 :             : 
    1779                 :             :           /* Step 2: Mark chains for which we have reads outside operands
    1780                 :             :              as unrenamable.
    1781                 :             :              We do this by munging all operands into PC, and closing
    1782                 :             :              everything remaining.  */
    1783                 :             : 
    1784                 :     3280176 :           hide_operands (n_ops, old_operands, old_dups, untracked_operands,
    1785                 :             :                          false);
    1786                 :     3280176 :           scan_rtx (insn, &PATTERN (insn), NO_REGS, mark_all_read, OP_IN);
    1787                 :     3280176 :           restore_operands (insn, n_ops, old_operands, old_dups);
    1788                 :             : 
    1789                 :             :           /* Step 2B: Can't rename function call argument registers.  */
    1790                 :     3280176 :           if (CALL_P (insn) && CALL_INSN_FUNCTION_USAGE (insn))
    1791                 :      117732 :             scan_rtx (insn, &CALL_INSN_FUNCTION_USAGE (insn),
    1792                 :             :                       NO_REGS, mark_all_read, OP_IN);
    1793                 :             : 
    1794                 :             :           /* Step 2C: Can't rename asm operands that were originally
    1795                 :             :              hard registers.  */
    1796                 :     3280176 :           if (asm_noperands (PATTERN (insn)) > 0)
    1797                 :        2715 :             for (i = 0; i < n_ops; i++)
    1798                 :             :               {
    1799                 :        1842 :                 rtx *loc = recog_data.operand_loc[i];
    1800                 :        1842 :                 rtx op = *loc;
    1801                 :             : 
    1802                 :        1842 :                 if (REG_P (op)
    1803                 :        1306 :                     && REGNO (op) == ORIGINAL_REGNO (op)
    1804                 :        1843 :                     && (recog_data.operand_type[i] == OP_IN
    1805                 :           0 :                         || recog_data.operand_type[i] == OP_INOUT))
    1806                 :           1 :                   scan_rtx (insn, loc, NO_REGS, mark_all_read, OP_IN);
    1807                 :             :               }
    1808                 :             : 
    1809                 :             :           /* Step 3: Append to chains for reads inside operands.  */
    1810                 :    10668465 :           for (i = 0; i < n_ops + recog_data.n_dups; i++)
    1811                 :             :             {
    1812                 :     7388289 :               int opn = i < n_ops ? i : recog_data.dup_num[i - n_ops];
    1813                 :    14776578 :               rtx *loc = (i < n_ops
    1814                 :     7388289 :                           ? recog_data.operand_loc[opn]
    1815                 :       75925 :                           : recog_data.dup_loc[i - n_ops]);
    1816                 :     7388289 :               enum reg_class cl = alternative_class (op_alt, opn);
    1817                 :     7388289 :               enum op_type type = recog_data.operand_type[opn];
    1818                 :             : 
    1819                 :             :               /* Don't scan match_operand here, since we've no reg class
    1820                 :             :                  information to pass down.  Any operands that we could
    1821                 :             :                  substitute in will be represented elsewhere.  */
    1822                 :     7388289 :               if (recog_data.constraints[opn][0] == '\0'
    1823                 :     6229575 :                   || untracked_operands & (1 << opn))
    1824                 :     1159088 :                 continue;
    1825                 :             : 
    1826                 :     6229201 :               if (insn_info)
    1827                 :           0 :                 cur_operand = i == opn ? insn_info->op_info + i : NULL;
    1828                 :     6229201 :               if (op_alt[opn].is_address)
    1829                 :      135545 :                 scan_rtx_address (insn, loc, cl, mark_read,
    1830                 :             :                                   VOIDmode, ADDR_SPACE_GENERIC);
    1831                 :             :               else
    1832                 :     6093656 :                 scan_rtx (insn, loc, cl, mark_read, type);
    1833                 :             :             }
    1834                 :     3280176 :           cur_operand = NULL;
    1835                 :             : 
    1836                 :             :           /* Step 3B: Record updates for regs in REG_INC notes, and
    1837                 :             :              source regs in REG_FRAME_RELATED_EXPR notes.  */
    1838                 :     6080351 :           for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
    1839                 :     2800175 :             if (REG_NOTE_KIND (note) == REG_INC
    1840                 :     2800175 :                 || REG_NOTE_KIND (note) == REG_FRAME_RELATED_EXPR)
    1841                 :          30 :               scan_rtx (insn, &XEXP (note, 0), ALL_REGS, mark_read,
    1842                 :             :                         OP_INOUT);
    1843                 :             : 
    1844                 :             :           /* Step 4: Close chains for registers that die here, unless
    1845                 :             :              the register is mentioned in a REG_UNUSED note.  In that
    1846                 :             :              case we keep the chain open until step #7 below to ensure
    1847                 :             :              it conflicts with other output operands of this insn.
    1848                 :             :              See PR 52573.  Arguably the insn should not have both
    1849                 :             :              notes; it has proven difficult to fix that without
    1850                 :             :              other undesirable side effects.  */
    1851                 :     6080351 :           for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
    1852                 :     2800175 :             if (REG_NOTE_KIND (note) == REG_DEAD
    1853                 :     2800175 :                 && !find_regno_note (insn, REG_UNUSED, REGNO (XEXP (note, 0))))
    1854                 :             :               {
    1855                 :     1438140 :                 remove_from_hard_reg_set (&live_hard_regs,
    1856                 :     1438140 :                                           GET_MODE (XEXP (note, 0)),
    1857                 :     1438140 :                                           REGNO (XEXP (note, 0)));
    1858                 :     1438140 :                 scan_rtx (insn, &XEXP (note, 0), NO_REGS, terminate_dead,
    1859                 :             :                           OP_IN);
    1860                 :             :               }
    1861                 :             : 
    1862                 :             :           /* Step 4B: If this is a call, any chain live at this point
    1863                 :             :              requires a caller-saved reg.  */
    1864                 :     3280176 :           if (CALL_P (insn))
    1865                 :             :             {
    1866                 :      130513 :               function_abi callee_abi = insn_callee_abi (insn);
    1867                 :      130513 :               class du_head *p;
    1868                 :      430867 :               for (p = open_chains; p; p = p->next_chain)
    1869                 :             :                 {
    1870                 :      300354 :                   p->call_abis |= (1 << callee_abi.id ());
    1871                 :      300354 :                   p->call_clobber_mask
    1872                 :      300354 :                     |= callee_abi.full_and_partial_reg_clobbers ();
    1873                 :      600708 :                   p->hard_conflicts |= callee_abi.full_reg_clobbers ();
    1874                 :             :                 }
    1875                 :             :             }
    1876                 :             : 
    1877                 :             :           /* Step 5: Close open chains that overlap writes.  Similar to
    1878                 :             :              step 2, we hide in-out operands, since we do not want to
    1879                 :             :              close these chains.  We also hide earlyclobber operands,
    1880                 :             :              since we've opened chains for them in step 1, and earlier
    1881                 :             :              chains they would overlap with must have been closed at
    1882                 :             :              the previous insn at the latest, as such operands cannot
    1883                 :             :              possibly overlap with any input operands.  */
    1884                 :             : 
    1885                 :     3280176 :           hide_operands (n_ops, old_operands, old_dups, untracked_operands,
    1886                 :             :                          true);
    1887                 :     3280176 :           scan_rtx (insn, &PATTERN (insn), NO_REGS, terminate_write, OP_IN);
    1888                 :     3280176 :           restore_operands (insn, n_ops, old_operands, old_dups);
    1889                 :             : 
    1890                 :             :           /* Step 6a: Mark hard registers that are set in this insn,
    1891                 :             :              outside an operand, as live.  */
    1892                 :     3280176 :           hide_operands (n_ops, old_operands, old_dups, untracked_operands,
    1893                 :             :                          false);
    1894                 :     3280176 :           note_stores (insn, note_sets_clobbers, &set_code);
    1895                 :     3280176 :           restore_operands (insn, n_ops, old_operands, old_dups);
    1896                 :             : 
    1897                 :             :           /* Step 6b: Begin new chains for writes inside operands.  */
    1898                 :     3280176 :           record_out_operands (insn, false, insn_info);
    1899                 :             : 
    1900                 :             :           /* Step 6c: Record destination regs in REG_FRAME_RELATED_EXPR
    1901                 :             :              notes for update.  */
    1902                 :     6080351 :           for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
    1903                 :     2800175 :             if (REG_NOTE_KIND (note) == REG_FRAME_RELATED_EXPR)
    1904                 :          30 :               scan_rtx (insn, &XEXP (note, 0), ALL_REGS, mark_access,
    1905                 :             :                         OP_INOUT);
    1906                 :             : 
    1907                 :             :           /* Step 7: Close chains for registers that were never
    1908                 :             :              really used here.  */
    1909                 :     6080351 :           for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
    1910                 :     2800175 :             if (REG_NOTE_KIND (note) == REG_UNUSED)
    1911                 :             :               {
    1912                 :      527028 :                 remove_from_hard_reg_set (&live_hard_regs,
    1913                 :      527028 :                                           GET_MODE (XEXP (note, 0)),
    1914                 :      527028 :                                           REGNO (XEXP (note, 0)));
    1915                 :      527028 :                 scan_rtx (insn, &XEXP (note, 0), NO_REGS, terminate_dead,
    1916                 :             :                           OP_IN);
    1917                 :             :               }
    1918                 :             : 
    1919                 :             :           /* Step 8: Kill the chains involving register restores.  Those
    1920                 :             :              should restore _that_ register.  Similar for REG_CFA_REGISTER.  */
    1921                 :     6080351 :           for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
    1922                 :     2800175 :             if (REG_NOTE_KIND (note) == REG_CFA_RESTORE
    1923                 :     2798533 :                 || REG_NOTE_KIND (note) == REG_CFA_REGISTER)
    1924                 :             :               {
    1925                 :        1642 :                 rtx *x = &XEXP (note, 0);
    1926                 :        1642 :                 if (!*x)
    1927                 :           0 :                   x = &PATTERN (insn);
    1928                 :        1642 :                 if (GET_CODE (*x) == PARALLEL)
    1929                 :           0 :                   x = &XVECEXP (*x, 0, 0);
    1930                 :        1642 :                 if (GET_CODE (*x) == SET)
    1931                 :           0 :                   x = &SET_DEST (*x);
    1932                 :        1642 :                 scan_rtx (insn, x, NO_REGS, mark_all_read, OP_IN);
    1933                 :             :               }
    1934                 :             :         }
    1935                 :      807153 :       else if (DEBUG_BIND_INSN_P (insn)
    1936                 :     2581258 :                && !VAR_LOC_UNKNOWN_P (INSN_VAR_LOCATION_LOC (insn)))
    1937                 :             :         {
    1938                 :      436933 :           scan_rtx (insn, &INSN_VAR_LOCATION_LOC (insn),
    1939                 :             :                     ALL_REGS, mark_read, OP_IN);
    1940                 :             :         }
    1941                 :     5340381 :       if (insn == BB_END (bb))
    1942                 :             :         break;
    1943                 :     4852584 :     }
    1944                 :             : 
    1945                 :      487797 :   if (fail_current_block)
    1946                 :           0 :     return false;
    1947                 :             : 
    1948                 :             :   return true;
    1949                 :             : }
    1950                 :             : 
    1951                 :             : /* Initialize the register renamer.  If INSN_INFO is true, ensure that
    1952                 :             :    insn_rr is nonnull.  */
    1953                 :             : void
    1954                 :       20587 : regrename_init (bool insn_info)
    1955                 :             : {
    1956                 :       20587 :   gcc_obstack_init (&rename_obstack);
    1957                 :       20587 :   insn_rr.create (0);
    1958                 :       20587 :   if (insn_info)
    1959                 :           0 :     insn_rr.safe_grow_cleared (get_max_uid (), true);
    1960                 :       20587 : }
    1961                 :             : 
    1962                 :             : /* Free all global data used by the register renamer.  */
    1963                 :             : void
    1964                 :       20587 : regrename_finish (void)
    1965                 :             : {
    1966                 :       20587 :   insn_rr.release ();
    1967                 :       20587 :   free_chain_data ();
    1968                 :       20587 :   obstack_free (&rename_obstack, NULL);
    1969                 :       20587 : }
    1970                 :             : 
    1971                 :             : /* Perform register renaming on the current function.  */
    1972                 :             : 
    1973                 :             : static unsigned int
    1974                 :       20587 : regrename_optimize (void)
    1975                 :             : {
    1976                 :       20587 :   df_set_flags (DF_LR_RUN_DCE);
    1977                 :       20587 :   df_note_add_problem ();
    1978                 :       20587 :   df_analyze ();
    1979                 :       20587 :   df_set_flags (DF_DEFER_INSN_RESCAN);
    1980                 :             : 
    1981                 :       20587 :   regrename_init (false);
    1982                 :             : 
    1983                 :       20587 :   regrename_analyze (NULL, false);
    1984                 :             : 
    1985                 :       20587 :   rename_chains ();
    1986                 :             : 
    1987                 :       20587 :   regrename_finish ();
    1988                 :             : 
    1989                 :       20587 :   return 0;
    1990                 :             : }
    1991                 :             : 
    1992                 :             : namespace {
    1993                 :             : 
    1994                 :             : const pass_data pass_data_regrename =
    1995                 :             : {
    1996                 :             :   RTL_PASS, /* type */
    1997                 :             :   "rnreg", /* name */
    1998                 :             :   OPTGROUP_NONE, /* optinfo_flags */
    1999                 :             :   TV_RENAME_REGISTERS, /* tv_id */
    2000                 :             :   0, /* properties_required */
    2001                 :             :   0, /* properties_provided */
    2002                 :             :   0, /* properties_destroyed */
    2003                 :             :   0, /* todo_flags_start */
    2004                 :             :   TODO_df_finish, /* todo_flags_finish */
    2005                 :             : };
    2006                 :             : 
    2007                 :             : class pass_regrename : public rtl_opt_pass
    2008                 :             : {
    2009                 :             : public:
    2010                 :      285617 :   pass_regrename (gcc::context *ctxt)
    2011                 :      571234 :     : rtl_opt_pass (pass_data_regrename, ctxt)
    2012                 :             :   {}
    2013                 :             : 
    2014                 :             :   /* opt_pass methods: */
    2015                 :     1419745 :   bool gate (function *) final override
    2016                 :             :     {
    2017                 :     1419745 :       return (optimize > 0 && (flag_rename_registers));
    2018                 :             :     }
    2019                 :             : 
    2020                 :       20587 :   unsigned int execute (function *) final override
    2021                 :             :   {
    2022                 :       20587 :     return regrename_optimize ();
    2023                 :             :   }
    2024                 :             : 
    2025                 :             : }; // class pass_regrename
    2026                 :             : 
    2027                 :             : } // anon namespace
    2028                 :             : 
    2029                 :             : rtl_opt_pass *
    2030                 :      285617 : make_pass_regrename (gcc::context *ctxt)
    2031                 :             : {
    2032                 :      285617 :   return new pass_regrename (ctxt);
    2033                 :             : }
        

Generated by: LCOV version 2.0-1

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.