LCOV - code coverage report
Current view: top level - gcc - lra.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 89.1 % 1267 1129
Test Date: 2026-03-28 14:25:54 Functions: 97.2 % 71 69
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* LRA (local register allocator) driver and LRA utilities.
       2              :    Copyright (C) 2010-2026 Free Software Foundation, Inc.
       3              :    Contributed by Vladimir Makarov <vmakarov@redhat.com>.
       4              : 
       5              : This file is part of GCC.
       6              : 
       7              : GCC is free software; you can redistribute it and/or modify it under
       8              : the terms of the GNU General Public License as published by the Free
       9              : Software Foundation; either version 3, or (at your option) any later
      10              : version.
      11              : 
      12              : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      13              : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      14              : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      15              : for more details.
      16              : 
      17              : You should have received a copy of the GNU General Public License
      18              : along with GCC; see the file COPYING3.  If not see
      19              : <http://www.gnu.org/licenses/>.    */
      20              : 
      21              : 
      22              : /* The Local Register Allocator (LRA) is a replacement of former
      23              :    reload pass.  It is focused to simplify code solving the reload
      24              :    pass tasks, to make the code maintenance easier, and to implement new
      25              :    perspective optimizations.
      26              : 
      27              :    The major LRA design solutions are:
      28              :      o division small manageable, separated sub-tasks
      29              :      o reflection of all transformations and decisions in RTL as more
      30              :        as possible
      31              :      o insn constraints as a primary source of the info (minimizing
      32              :        number of target-depended macros/hooks)
      33              : 
      34              :    In brief LRA works by iterative insn process with the final goal is
      35              :    to satisfy all insn and address constraints:
      36              :      o New reload insns (in brief reloads) and reload pseudos might be
      37              :        generated;
      38              :      o Some pseudos might be spilled to assign hard registers to
      39              :        new reload pseudos;
      40              :      o Recalculating spilled pseudo values (rematerialization);
      41              :      o Changing spilled pseudos to stack memory or their equivalences;
      42              :      o Allocation stack memory changes the address displacement and
      43              :        new iteration is needed.
      44              : 
      45              :    Here is block diagram of LRA passes:
      46              : 
      47              :                                 ------------------------
      48              :            ---------------     | Undo inheritance for   |     ---------------
      49              :           | Memory-memory |    | spilled pseudos,       |    | New (and old) |
      50              :           | move coalesce |<---| splits for pseudos got |<-- |   pseudos     |
      51              :            ---------------     | the same hard regs,    |    |  assignment   |
      52              :   Start           |            | and optional reloads   |     ---------------
      53              :     |             |             ------------------------            ^
      54              :     V             |              ----------------                   |
      55              :  -----------      V             | Update virtual |                  |
      56              : |  Remove   |----> ------------>|    register    |                  |
      57              : | scratches |     ^             |  displacements |                  |
      58              :  -----------      |              ----------------                   |
      59              :                   |                      |                          |
      60              :                   |                      V         New              |
      61              :                   |                 ------------  pseudos   -------------------
      62              :                   |                |Constraints:| or insns | Inheritance/split |
      63              :                   |                |    RTL     |--------->|  transformations  |
      64              :                   |                | transfor-  |          |    in EBB scope   |
      65              :                   | substi-        |  mations   |           -------------------
      66              :                   | tutions         ------------
      67              :                   |                     | No change
      68              :           ----------------              V
      69              :          | Spilled pseudo |      -------------------
      70              :          |    to memory   |<----| Rematerialization |
      71              :          |  substitution  |      -------------------
      72              :           ----------------
      73              :                   | No susbtitions
      74              :                   V
      75              :       -------------------------
      76              :      | Hard regs substitution, |
      77              :      |  devirtalization, and   |------> Finish
      78              :      | restoring scratches got |
      79              :      |         memory          |
      80              :       -------------------------
      81              : 
      82              :    To speed up the process:
      83              :      o We process only insns affected by changes on previous
      84              :        iterations;
      85              :      o We don't use DFA-infrastructure because it results in much slower
      86              :        compiler speed than a special IR described below does;
      87              :      o We use a special insn representation for quick access to insn
      88              :        info which is always *synchronized* with the current RTL;
      89              :        o Insn IR is minimized by memory.  It is divided on three parts:
      90              :          o one specific for each insn in RTL (only operand locations);
      91              :          o one common for all insns in RTL with the same insn code
      92              :            (different operand attributes from machine descriptions);
      93              :          o one oriented for maintenance of live info (list of pseudos).
      94              :        o Pseudo data:
      95              :          o all insns where the pseudo is referenced;
      96              :          o live info (conflicting hard regs, live ranges, # of
      97              :            references etc);
      98              :          o data used for assigning (preferred hard regs, costs etc).
      99              : 
     100              :    This file contains LRA driver, LRA utility functions and data, and
     101              :    code for dealing with scratches.  */
     102              : 
     103              : #include "config.h"
     104              : #include "system.h"
     105              : #include "coretypes.h"
     106              : #include "backend.h"
     107              : #include "target.h"
     108              : #include "rtl.h"
     109              : #include "rtl-error.h"
     110              : #include "tree.h"
     111              : #include "predict.h"
     112              : #include "df.h"
     113              : #include "memmodel.h"
     114              : #include "tm_p.h"
     115              : #include "optabs.h"
     116              : #include "regs.h"
     117              : #include "ira.h"
     118              : #include "recog.h"
     119              : #include "expr.h"
     120              : #include "cfgrtl.h"
     121              : #include "cfgbuild.h"
     122              : #include "lra.h"
     123              : #include "lra-int.h"
     124              : #include "print-rtl.h"
     125              : #include "function-abi.h"
     126              : 
     127              : /* Dump bitmap SET with TITLE and BB INDEX.  */
     128              : void
     129          364 : lra_dump_bitmap_with_title (const char *title, bitmap set, int index)
     130              : {
     131          364 :   unsigned int i;
     132          364 :   int count;
     133          364 :   bitmap_iterator bi;
     134          364 :   static const int max_nums_on_line = 10;
     135              : 
     136          364 :   if (bitmap_empty_p (set))
     137          266 :     return;
     138           98 :   fprintf (lra_dump_file, "  %s %d:", title, index);
     139           98 :   fprintf (lra_dump_file, "\n");
     140           98 :   count = max_nums_on_line + 1;
     141          476 :   EXECUTE_IF_SET_IN_BITMAP (set, 0, i, bi)
     142              :     {
     143          378 :       if (count > max_nums_on_line)
     144              :         {
     145           98 :           fprintf (lra_dump_file, "\n    ");
     146           98 :           count = 0;
     147              :         }
     148          378 :       fprintf (lra_dump_file, " %4u", i);
     149          378 :       count++;
     150              :     }
     151           98 :   fprintf (lra_dump_file, "\n");
     152              : }
     153              : 
     154              : /* Hard registers currently not available for allocation.  It can
     155              :    changed after some hard  registers become not eliminable.  */
     156              : HARD_REG_SET lra_no_alloc_regs;
     157              : 
     158              : static int get_new_reg_value (void);
     159              : static void expand_reg_info (void);
     160              : static void invalidate_insn_recog_data (int);
     161              : static int get_insn_freq (rtx_insn *);
     162              : static void invalidate_insn_data_regno_info (lra_insn_recog_data_t,
     163              :                                              rtx_insn *, int);
     164              : /* Expand all regno related info needed for LRA.  */
     165              : static void
     166      7361637 : expand_reg_data (int old)
     167              : {
     168      7361637 :   resize_reg_info ();
     169      7361637 :   expand_reg_info ();
     170      7361637 :   ira_expand_reg_equiv ();
     171      7364038 :   for (int i = (int) max_reg_num () - 1; i >= old; i--)
     172         2401 :     lra_change_class (i, ALL_REGS, "      Set", true);
     173      7361637 : }
     174              : 
     175              : /* Create and return a new reg of ORIGINAL mode.  If ORIGINAL is NULL
     176              :    or of VOIDmode, use MD_MODE for the new reg.  Initialize its
     177              :    register class to RCLASS.  Print message about assigning class
     178              :    RCLASS containing new register name TITLE unless it is NULL.  Use
     179              :    attributes of ORIGINAL if it is a register.  The created register
     180              :    will have unique held value.  */
     181              : rtx
     182      7359300 : lra_create_new_reg_with_unique_value (machine_mode md_mode, rtx original,
     183              :                                       enum reg_class rclass,
     184              :                                       HARD_REG_SET *exclude_start_hard_regs,
     185              :                                       const char *title)
     186              : {
     187      7359300 :   machine_mode mode;
     188      7359300 :   rtx new_reg;
     189              : 
     190      7359300 :   if (original == NULL_RTX || (mode = GET_MODE (original)) == VOIDmode)
     191       703237 :     mode = md_mode;
     192      7359300 :   lra_assert (mode != VOIDmode);
     193      7359300 :   new_reg = gen_reg_rtx (mode);
     194      7359300 :   if (original == NULL_RTX || ! REG_P (original))
     195              :     {
     196      2048890 :       if (lra_dump_file != NULL)
     197            1 :         fprintf (lra_dump_file, "      Creating newreg=%i", REGNO (new_reg));
     198              :     }
     199              :   else
     200              :     {
     201      5310410 :       if (ORIGINAL_REGNO (original) >= FIRST_PSEUDO_REGISTER)
     202      5299102 :         ORIGINAL_REGNO (new_reg) = ORIGINAL_REGNO (original);
     203      5310410 :       REG_USERVAR_P (new_reg) = REG_USERVAR_P (original);
     204      5310410 :       REG_POINTER (new_reg) = REG_POINTER (original);
     205      5310410 :       REG_ATTRS (new_reg) = REG_ATTRS (original);
     206      5310410 :       if (lra_dump_file != NULL)
     207           98 :         fprintf (lra_dump_file, "      Creating newreg=%i from oldreg=%i",
     208              :                  REGNO (new_reg), REGNO (original));
     209              :     }
     210      7359300 :   if (lra_dump_file != NULL)
     211              :     {
     212           99 :       if (title != NULL)
     213           99 :         fprintf (lra_dump_file, ", assigning class %s to%s%s r%d",
     214          101 :                  reg_class_names[rclass], *title == '\0' ? "" : " ",
     215              :                  title, REGNO (new_reg));
     216           99 :       fprintf (lra_dump_file, "\n");
     217              :     }
     218      7359300 :   expand_reg_data (max_reg_num ());
     219      7359300 :   setup_reg_classes (REGNO (new_reg), rclass, NO_REGS, rclass);
     220      7359300 :   if (exclude_start_hard_regs != NULL)
     221      5025035 :     lra_reg_info[REGNO (new_reg)].exclude_start_hard_regs
     222      5025035 :       = *exclude_start_hard_regs;
     223      7359300 :   return new_reg;
     224              : }
     225              : 
     226              : /* Analogous to the previous function but also inherits value of
     227              :    ORIGINAL.  */
     228              : rtx
     229      5113395 : lra_create_new_reg (machine_mode md_mode, rtx original, enum reg_class rclass,
     230              :                     HARD_REG_SET *exclude_start_hard_regs, const char *title)
     231              : {
     232      5113395 :   rtx new_reg;
     233              : 
     234      5113395 :   new_reg
     235      5113395 :     = lra_create_new_reg_with_unique_value (md_mode, original, rclass,
     236              :                                             exclude_start_hard_regs, title);
     237      5113395 :   if (original != NULL_RTX && REG_P (original))
     238      3347053 :     lra_assign_reg_val (REGNO (original), REGNO (new_reg));
     239      5113395 :   return new_reg;
     240              : }
     241              : 
     242              : /* Set up for REGNO unique hold value.  */
     243              : void
     244         1686 : lra_set_regno_unique_value (int regno)
     245              : {
     246         1686 :   lra_reg_info[regno].val = get_new_reg_value ();
     247         1686 : }
     248              : 
     249              : /* Invalidate INSN related info used by LRA.  The info should never be
     250              :    used after that.  */
     251              : void
     252     12931837 : lra_invalidate_insn_data (rtx_insn *insn)
     253              : {
     254     12931837 :   lra_invalidate_insn_regno_info (insn);
     255     12931837 :   invalidate_insn_recog_data (INSN_UID (insn));
     256     12931837 : }
     257              : 
     258              : /* Mark INSN deleted and invalidate the insn related info used by
     259              :    LRA.  */
     260              : void
     261      1797574 : lra_set_insn_deleted (rtx_insn *insn)
     262              : {
     263      1797574 :   bitmap_clear_bit (&lra_postponed_insns, INSN_UID (insn));
     264      1797574 :   lra_invalidate_insn_data (insn);
     265      1797574 :   SET_INSN_DELETED (insn);
     266      1797574 : }
     267              : 
     268              : /* Delete an unneeded INSN and any previous insns who sole purpose is
     269              :    loading data that is dead in INSN.  */
     270              : void
     271            0 : lra_delete_dead_insn (rtx_insn *insn)
     272              : {
     273            0 :   rtx_insn *prev = prev_real_insn (insn);
     274            0 :   rtx prev_dest;
     275              : 
     276              :   /* If the previous insn sets a register that dies in our insn,
     277              :      delete it too.  */
     278            0 :   if (prev && GET_CODE (PATTERN (prev)) == SET
     279            0 :       && (prev_dest = SET_DEST (PATTERN (prev)), REG_P (prev_dest))
     280            0 :       && reg_mentioned_p (prev_dest, PATTERN (insn))
     281            0 :       && find_regno_note (insn, REG_DEAD, REGNO (prev_dest))
     282            0 :       && ! side_effects_p (SET_SRC (PATTERN (prev))))
     283            0 :     lra_delete_dead_insn (prev);
     284              : 
     285            0 :   lra_set_insn_deleted (insn);
     286            0 : }
     287              : 
     288              : /* Emit insn x = y + z.  Return NULL if we failed to do it.
     289              :    Otherwise, return the insn.  We don't use gen_add3_insn as it might
     290              :    clobber CC.  */
     291              : static rtx_insn *
     292       618851 : emit_add3_insn (rtx x, rtx y, rtx z)
     293              : {
     294       618851 :   rtx_insn *last;
     295              : 
     296       618851 :   last = get_last_insn ();
     297              : 
     298       618851 :   if (have_addptr3_insn (x, y, z))
     299              :     {
     300            0 :       rtx_insn *insn = gen_addptr3_insn (x, y, z);
     301              : 
     302              :       /* If the target provides an "addptr" pattern it hopefully does
     303              :          for a reason.  So falling back to the normal add would be
     304              :          a bug.  */
     305            0 :       lra_assert (insn != NULL_RTX);
     306            0 :       emit_insn (insn);
     307            0 :       return insn;
     308              :     }
     309              : 
     310       618851 :   rtx_insn *insn = emit_insn (gen_rtx_SET (x, gen_rtx_PLUS (GET_MODE (y),
     311              :                                                             y, z)));
     312       618851 :   if (recog_memoized (insn) < 0)
     313              :     {
     314          132 :       delete_insns_since (last);
     315          132 :       insn = NULL;
     316              :     }
     317              :   return insn;
     318              : }
     319              : 
     320              : /* Emit insn x = x + y.  Return the insn.  We use gen_add2_insn as the
     321              :    last resort.  */
     322              : static rtx_insn *
     323          132 : emit_add2_insn (rtx x, rtx y)
     324              : {
     325          132 :   rtx_insn *insn = emit_add3_insn (x, x, y);
     326          132 :   if (insn == NULL_RTX)
     327              :     {
     328            0 :       insn = gen_add2_insn (x, y);
     329            0 :       if (insn != NULL_RTX)
     330            0 :         emit_insn (insn);
     331              :     }
     332          132 :   return insn;
     333              : }
     334              : 
     335              : /* Target checks operands through operand predicates to recognize an
     336              :    insn.  We should have a special precaution to generate add insns
     337              :    which are frequent results of elimination.
     338              : 
     339              :    Emit insns for x = y + z.  X can be used to store intermediate
     340              :    values and should be not in Y and Z when we use X to store an
     341              :    intermediate value.  Y + Z should form [base] [+ index[ * scale]] [
     342              :    + disp] where base and index are registers, disp and scale are
     343              :    constants.  Y should contain base if it is present, Z should
     344              :    contain disp if any.  index[*scale] can be part of Y or Z.  */
     345              : void
     346       618719 : lra_emit_add (rtx x, rtx y, rtx z)
     347              : {
     348       618719 :   int old;
     349       618719 :   rtx_insn *last;
     350       618719 :   rtx a1, a2, base, index, disp, scale, index_scale;
     351       618719 :   bool ok_p;
     352              : 
     353       618719 :   rtx_insn *add3_insn = emit_add3_insn (x, y, z);
     354       618719 :   old = max_reg_num ();
     355       618719 :   if (add3_insn != NULL)
     356              :     ;
     357              :   else
     358              :     {
     359          132 :       disp = a2 = NULL_RTX;
     360          132 :       if (GET_CODE (y) == PLUS)
     361              :         {
     362            0 :           a1 = XEXP (y, 0);
     363            0 :           a2 = XEXP (y, 1);
     364            0 :           disp = z;
     365              :         }
     366              :       else
     367              :         {
     368          132 :           a1 = y;
     369          132 :           if (CONSTANT_P (z))
     370              :             disp = z;
     371              :           else
     372            0 :             a2 = z;
     373              :         }
     374          132 :       index_scale = scale = NULL_RTX;
     375          132 :       if (GET_CODE (a1) == MULT)
     376              :         {
     377            0 :           index_scale = a1;
     378            0 :           index = XEXP (a1, 0);
     379            0 :           scale = XEXP (a1, 1);
     380            0 :           base = a2;
     381              :         }
     382          132 :       else if (a2 != NULL_RTX && GET_CODE (a2) == MULT)
     383              :         {
     384            0 :           index_scale = a2;
     385            0 :           index = XEXP (a2, 0);
     386            0 :           scale = XEXP (a2, 1);
     387            0 :           base = a1;
     388              :         }
     389              :       else
     390              :         {
     391              :           base = a1;
     392              :           index = a2;
     393              :         }
     394          132 :       if ((base != NULL_RTX && ! (REG_P (base) || GET_CODE (base) == SUBREG))
     395          132 :           || (index != NULL_RTX
     396            0 :               && ! (REG_P (index) || GET_CODE (index) == SUBREG))
     397          132 :           || (disp != NULL_RTX && ! CONSTANT_P (disp))
     398          132 :           || (scale != NULL_RTX && ! CONSTANT_P (scale)))
     399              :         {
     400              :           /* Probably we have no 3 op add.  Last chance is to use 2-op
     401              :              add insn.  To succeed, don't move Z to X as an address
     402              :              segment always comes in Y.  Otherwise, we might fail when
     403              :              adding the address segment to register.  */
     404            0 :           lra_assert (x != y && x != z);
     405            0 :           emit_move_insn (x, y);
     406            0 :           rtx_insn *insn = emit_add2_insn (x, z);
     407            0 :           lra_assert (insn != NULL_RTX);
     408              :         }
     409              :       else
     410              :         {
     411          132 :           if (index_scale == NULL_RTX)
     412          132 :             index_scale = index;
     413          132 :           if (disp == NULL_RTX)
     414              :             {
     415              :               /* Generate x = index_scale; x = x + base.  */
     416            0 :               lra_assert (index_scale != NULL_RTX && base != NULL_RTX);
     417            0 :               emit_move_insn (x, index_scale);
     418            0 :               rtx_insn *insn = emit_add2_insn (x, base);
     419            0 :               lra_assert (insn != NULL_RTX);
     420              :             }
     421          132 :           else if (scale == NULL_RTX)
     422              :             {
     423              :               /* Try x = base + disp.  */
     424          132 :               lra_assert (base != NULL_RTX);
     425          132 :               last = get_last_insn ();
     426          132 :               rtx_insn *move_insn =
     427          132 :                 emit_move_insn (x, gen_rtx_PLUS (GET_MODE (base), base, disp));
     428          132 :               if (recog_memoized (move_insn) < 0)
     429              :                 {
     430          132 :                   delete_insns_since (last);
     431              :                   /* Generate x = disp; x = x + base.  */
     432          132 :                   emit_move_insn (x, disp);
     433          132 :                   rtx_insn *add2_insn = emit_add2_insn (x, base);
     434          132 :                   lra_assert (add2_insn != NULL_RTX);
     435              :                 }
     436              :               /* Generate x = x + index.  */
     437          132 :               if (index != NULL_RTX)
     438              :                 {
     439            0 :                   rtx_insn *insn = emit_add2_insn (x, index);
     440            0 :                   lra_assert (insn != NULL_RTX);
     441              :                 }
     442              :             }
     443              :           else
     444              :             {
     445              :               /* Try x = index_scale; x = x + disp; x = x + base.  */
     446            0 :               last = get_last_insn ();
     447            0 :               rtx_insn *move_insn = emit_move_insn (x, index_scale);
     448            0 :               ok_p = false;
     449            0 :               if (recog_memoized (move_insn) >= 0)
     450              :                 {
     451            0 :                   rtx_insn *insn = emit_add2_insn (x, disp);
     452            0 :                   if (insn != NULL_RTX)
     453              :                     {
     454            0 :                       if (base == NULL_RTX)
     455              :                         ok_p = true;
     456              :                       else
     457              :                         {
     458            0 :                           insn = emit_add2_insn (x, base);
     459            0 :                           if (insn != NULL_RTX)
     460              :                             ok_p = true;
     461              :                         }
     462              :                     }
     463              :                 }
     464              :               if (! ok_p)
     465              :                 {
     466            0 :                   rtx_insn *insn;
     467              : 
     468            0 :                   delete_insns_since (last);
     469              :                   /* Generate x = disp; x = x + base; x = x + index_scale.  */
     470            0 :                   emit_move_insn (x, disp);
     471            0 :                   if (base != NULL_RTX)
     472              :                     {
     473            0 :                       insn = emit_add2_insn (x, base);
     474            0 :                       lra_assert (insn != NULL_RTX);
     475              :                     }
     476            0 :                   insn = emit_add2_insn (x, index_scale);
     477            0 :                   lra_assert (insn != NULL_RTX);
     478              :                 }
     479              :             }
     480              :         }
     481              :     }
     482              :   /* Functions emit_... can create pseudos -- so expand the pseudo
     483              :      data.  */
     484       618719 :   if (old != max_reg_num ())
     485            0 :     expand_reg_data (old);
     486       618719 : }
     487              : 
     488              : /* The number of emitted reload insns so far.  */
     489              : int lra_curr_reload_num;
     490              : 
     491              : static void remove_insn_scratches (rtx_insn *insn);
     492              : 
     493              : /* Emit x := y, processing special case when y = u + v or y = u + v * scale + w
     494              :    through emit_add (Y can be an address which is base + index reg * scale +
     495              :    displacement in general case).  X may be used as intermediate result
     496              :    therefore it should be not in Y.  Set up pointer flag of X if Y is
     497              :    equivalence whose original target has setup pointer flag.  */
     498              : void
     499      8290823 : lra_emit_move (rtx x, rtx y)
     500              : {
     501      8290823 :   int old;
     502      8290823 :   rtx_insn *insn;
     503              : 
     504      8290823 :   if ((REG_P (x) || MEM_P (x)) && lra_pointer_equiv_set_in (y))
     505              :      {
     506              :        /* Set up pointer flag from original equivalence target: */
     507       690913 :        if (REG_P (x))
     508       690913 :          REG_POINTER (x) = 1;
     509              :        else
     510            0 :          MEM_POINTER (x) = 1;
     511              :      }
     512      8290823 :   if (GET_CODE (y) != PLUS)
     513              :     {
     514      7672143 :       if (rtx_equal_p (x, y))
     515              :         return;
     516      7672143 :       old = max_reg_num ();
     517              : 
     518      7672143 :       insn = (GET_CODE (x) != STRICT_LOW_PART
     519      7672143 :               ? emit_move_insn (x, y) : emit_insn (gen_rtx_SET (x, y)));
     520              :       /* The move pattern may require scratch registers, so convert them
     521              :          into real registers now.  */
     522      7672143 :       if (insn != NULL_RTX)
     523      7672143 :         remove_insn_scratches (insn);
     524      7672143 :       if (REG_P (x))
     525      7272584 :         lra_reg_info[ORIGINAL_REGNO (x)].last_reload = ++lra_curr_reload_num;
     526              :       /* Function emit_move can create pseudos -- so expand the pseudo
     527              :          data.  */
     528      7672143 :       if (old != max_reg_num ())
     529         2337 :         expand_reg_data (old);
     530      7672143 :       return;
     531              :     }
     532       618680 :   lra_emit_add (x, XEXP (y, 0), XEXP (y, 1));
     533              : }
     534              : 
     535              : /* Update insn operands which are duplication of operands whose
     536              :    numbers are in array of NOPS (with end marker -1).  The insn is
     537              :    represented by its LRA internal representation ID.  */
     538              : void
     539      1729440 : lra_update_dups (lra_insn_recog_data_t id, signed char *nops)
     540              : {
     541      1729440 :   int i, j, nop;
     542      1729440 :   struct lra_static_insn_data *static_id = id->insn_static_data;
     543              : 
     544      2067397 :   for (i = 0; i < static_id->n_dups; i++)
     545       675914 :     for (j = 0; (nop = nops[j]) >= 0; j++)
     546       337957 :       if (static_id->dup_num[i] == nop)
     547       139552 :         *id->dup_loc[i] = *id->operand_loc[nop];
     548      1729440 : }
     549              : 
     550              : /* Report asm insn error and modify the asm insn.  */
     551              : void
     552           58 : lra_asm_insn_error (rtx_insn *insn)
     553              : {
     554           58 :   lra_asm_error_p = true;
     555           58 :   error_for_asm (insn,
     556              :                  "%<asm%> operand has impossible constraints"
     557              :                  " or there are not enough registers");
     558              :   /* Avoid further trouble with this insn.  */
     559           58 :   if (JUMP_P (insn))
     560              :     {
     561            6 :       ira_nullify_asm_goto (insn);
     562            6 :       lra_invalidate_insn_data (insn);
     563            6 :       bitmap_clear_bit (&lra_postponed_insns, INSN_UID (insn));
     564              :     }
     565              :   else
     566              :     {
     567           52 :       PATTERN (insn) = gen_rtx_USE (VOIDmode, const0_rtx);
     568           52 :       lra_set_insn_deleted (insn);
     569              :     }
     570           58 : }
     571              : 
     572              : 
     573              : 
     574              : /* This page contains code dealing with info about registers in the
     575              :    insns.  */
     576              : 
     577              : /* Pools for insn reg info.  */
     578              : object_allocator<lra_insn_reg> lra_insn_reg_pool ("insn regs");
     579              : 
     580              : /* Create LRA insn related info about a reference to REGNO in INSN
     581              :    with TYPE (in/out/inout), biggest reference mode MODE, flag that it
     582              :    is reference through subreg (SUBREG_P), and reference to the next
     583              :    insn reg info (NEXT).  If REGNO can be early clobbered,
     584              :    alternatives in which it can be early clobbered are given by
     585              :    EARLY_CLOBBER_ALTS.  */
     586              : static struct lra_insn_reg *
     587    285622029 : new_insn_reg (rtx_insn *insn, int regno, enum op_type type,
     588              :               machine_mode mode, bool subreg_p,
     589              :               alternative_mask early_clobber_alts,
     590              :               struct lra_insn_reg *next)
     591              : {
     592    285622029 :   lra_insn_reg *ir = lra_insn_reg_pool.allocate ();
     593    285622029 :   ir->type = type;
     594    285622029 :   ir->biggest_mode = mode;
     595    285622029 :   if (NONDEBUG_INSN_P (insn))
     596    265581328 :     lra_update_biggest_mode (regno, mode);
     597    285622029 :   ir->subreg_p = subreg_p;
     598    285622029 :   ir->early_clobber_alts = early_clobber_alts;
     599    285622029 :   ir->regno = regno;
     600    285622029 :   ir->next = next;
     601    285622029 :   return ir;
     602              : }
     603              : 
     604              : /* Free insn reg info list IR.  */
     605              : static void
     606    145182561 : free_insn_regs (struct lra_insn_reg *ir)
     607              : {
     608    145182561 :   struct lra_insn_reg *next_ir;
     609              : 
     610    278303780 :   for (; ir != NULL; ir = next_ir)
     611              :     {
     612    133121219 :       next_ir = ir->next;
     613    133121219 :       lra_insn_reg_pool.remove (ir);
     614              :     }
     615    145182561 : }
     616              : 
     617              : /* Finish pool for insn reg info.  */
     618              : static void
     619      1480947 : finish_insn_regs (void)
     620              : {
     621            0 :   lra_insn_reg_pool.release ();
     622            0 : }
     623              : 
     624              : 
     625              : 
     626              : /* This page contains code dealing LRA insn info (or in other words
     627              :    LRA internal insn representation).  */
     628              : 
     629              : /* Map INSN_CODE -> the static insn data.  This info is valid during
     630              :    all translation unit.  */
     631              : struct lra_static_insn_data *insn_code_data[NUM_INSN_CODES];
     632              : 
     633              : /* Debug insns are represented as a special insn with one input
     634              :    operand which is RTL expression in var_location.  */
     635              : 
     636              : /* The following data are used as static insn operand data for all
     637              :    debug insns.  If structure lra_operand_data is changed, the
     638              :    initializer should be changed too.  */
     639              : static struct lra_operand_data debug_operand_data =
     640              :   {
     641              :     NULL, /* alternative  */
     642              :     0, /* early_clobber_alts */
     643              :     E_VOIDmode, /* We are not interesting in the operand mode.  */
     644              :     OP_IN,
     645              :     0, 0, 0
     646              :   };
     647              : 
     648              : /* The following data are used as static insn data for all debug
     649              :    bind insns.  If structure lra_static_insn_data is changed, the
     650              :    initializer should be changed too.  */
     651              : static struct lra_static_insn_data debug_bind_static_data =
     652              :   {
     653              :     &debug_operand_data,
     654              :     0,  /* Duplication operands #.  */
     655              :     -1, /* Commutative operand #.  */
     656              :     1,  /* Operands #.  There is only one operand which is debug RTL
     657              :            expression.  */
     658              :     0,  /* Duplications #.  */
     659              :     0,  /* Alternatives #.  We are not interesting in alternatives
     660              :            because we does not proceed debug_insns for reloads.  */
     661              :     NULL, /* Hard registers referenced in machine description.  */
     662              :     NULL  /* Descriptions of operands in alternatives.  */
     663              :   };
     664              : 
     665              : /* The following data are used as static insn data for all debug
     666              :    marker insns.  If structure lra_static_insn_data is changed, the
     667              :    initializer should be changed too.  */
     668              : static struct lra_static_insn_data debug_marker_static_data =
     669              :   {
     670              :     &debug_operand_data,
     671              :     0,  /* Duplication operands #.  */
     672              :     -1, /* Commutative operand #.  */
     673              :     0,  /* Operands #.  There isn't any operand.  */
     674              :     0,  /* Duplications #.  */
     675              :     0,  /* Alternatives #.  We are not interesting in alternatives
     676              :            because we does not proceed debug_insns for reloads.  */
     677              :     NULL, /* Hard registers referenced in machine description.  */
     678              :     NULL  /* Descriptions of operands in alternatives.  */
     679              :   };
     680              : 
     681              : /* Called once per compiler work to initialize some LRA data related
     682              :    to insns.  */
     683              : static void
     684       211466 : init_insn_code_data_once (void)
     685              : {
     686       211466 :   memset (insn_code_data, 0, sizeof (insn_code_data));
     687            0 : }
     688              : 
     689              : /* Called once per compiler work to finalize some LRA data related to
     690              :    insns.  */
     691              : static void
     692       278943 : finish_insn_code_data_once (void)
     693              : {
     694   4231565310 :   for (unsigned int i = 0; i < NUM_INSN_CODES; i++)
     695              :     {
     696   4231286367 :       if (insn_code_data[i] != NULL)
     697              :         {
     698      2402129 :           free (insn_code_data[i]);
     699      2402129 :           insn_code_data[i] = NULL;
     700              :         }
     701              :     }
     702       278943 : }
     703              : 
     704              : /* Return static insn data, allocate and setup if necessary.  Although
     705              :    dup_num is static data (it depends only on icode), to set it up we
     706              :    need to extract insn first.  So recog_data should be valid for
     707              :    normal insn (ICODE >= 0) before the call.  */
     708              : static struct lra_static_insn_data *
     709     95713034 : get_static_insn_data (int icode, int nop, int ndup, int nalt)
     710              : {
     711     95713034 :   struct lra_static_insn_data *data;
     712     95713034 :   size_t n_bytes;
     713              : 
     714     95713034 :   lra_assert (icode < (int) NUM_INSN_CODES);
     715     95713034 :   if (icode >= 0 && (data = insn_code_data[icode]) != NULL)
     716              :     return data;
     717      3439032 :   lra_assert (nop >= 0 && ndup >= 0 && nalt >= 0);
     718      3439032 :   n_bytes = sizeof (struct lra_static_insn_data)
     719      3439032 :             + sizeof (struct lra_operand_data) * nop
     720      3439032 :             + sizeof (int) * ndup;
     721      3439032 :   data = XNEWVAR (struct lra_static_insn_data, n_bytes);
     722      3439032 :   data->operand_alternative = NULL;
     723      3439032 :   data->n_operands = nop;
     724      3439032 :   data->n_dups = ndup;
     725      3439032 :   data->n_alternatives = nalt;
     726      3439032 :   data->operand = ((struct lra_operand_data *)
     727              :                    ((char *) data + sizeof (struct lra_static_insn_data)));
     728      3439032 :   data->dup_num = ((int *) ((char *) data->operand
     729      3439032 :                             + sizeof (struct lra_operand_data) * nop));
     730      3439032 :   if (icode >= 0)
     731              :     {
     732      2402132 :       int i;
     733              : 
     734      2402132 :       insn_code_data[icode] = data;
     735      7952277 :       for (i = 0; i < nop; i++)
     736              :         {
     737      5550145 :           data->operand[i].constraint
     738      5550145 :             = insn_data[icode].operand[i].constraint;
     739      5550145 :           data->operand[i].mode = insn_data[icode].operand[i].mode;
     740      5550145 :           data->operand[i].strict_low = insn_data[icode].operand[i].strict_low;
     741      5550145 :           data->operand[i].is_operator
     742      5550145 :             = insn_data[icode].operand[i].is_operator;
     743      5550145 :           data->operand[i].type
     744      5550145 :             = (data->operand[i].constraint[0] == '=' ? OP_OUT
     745              :                : data->operand[i].constraint[0] == '+' ? OP_INOUT
     746              :                : OP_IN);
     747      5550145 :           data->operand[i].is_address = false;
     748              :         }
     749      2536693 :       for (i = 0; i < ndup; i++)
     750       134561 :         data->dup_num[i] = recog_data.dup_num[i];
     751              :     }
     752              :   return data;
     753              : }
     754              : 
     755              : /* The current length of the following array.  */
     756              : int lra_insn_recog_data_len;
     757              : 
     758              : /* Map INSN_UID -> the insn recog data (NULL if unknown).  */
     759              : lra_insn_recog_data_t *lra_insn_recog_data;
     760              : 
     761              : /* Alloc pool we allocate entries for lra_insn_recog_data from.  */
     762              : static object_allocator<class lra_insn_recog_data>
     763              :   lra_insn_recog_data_pool ("insn recog data pool");
     764              : 
     765              : /* Initialize LRA data about insns.  */
     766              : static void
     767      1480947 : init_insn_recog_data (void)
     768              : {
     769      1480947 :   lra_insn_recog_data_len = 0;
     770      1480947 :   lra_insn_recog_data = NULL;
     771            0 : }
     772              : 
     773              : /* Expand, if necessary, LRA data about insns.  */
     774              : static void
     775    199556254 : check_and_expand_insn_recog_data (int index)
     776              : {
     777    199556254 :   int i, old;
     778              : 
     779    199556254 :   if (lra_insn_recog_data_len > index)
     780              :     return;
     781      1605929 :   old = lra_insn_recog_data_len;
     782      1605929 :   lra_insn_recog_data_len = index * 3U / 2;
     783      1605929 :   if (lra_insn_recog_data_len <= index)
     784            0 :     lra_insn_recog_data_len = index + 1;
     785      1605929 :   lra_insn_recog_data = XRESIZEVEC (lra_insn_recog_data_t,
     786              :                                     lra_insn_recog_data,
     787              :                                     lra_insn_recog_data_len);
     788    283559179 :   for (i = old; i < lra_insn_recog_data_len; i++)
     789    281953250 :     lra_insn_recog_data[i] = NULL;
     790              : }
     791              : 
     792              : /* Finish LRA DATA about insn.  */
     793              : static void
     794    144145661 : free_insn_recog_data (lra_insn_recog_data_t data)
     795              : {
     796    144145661 :   if (data->operand_loc != NULL)
     797    131497503 :     free (data->operand_loc);
     798    144145661 :   if (data->dup_loc != NULL)
     799       519566 :     free (data->dup_loc);
     800    144145661 :   if (data->arg_hard_regs != NULL)
     801      4649846 :     free (data->arg_hard_regs);
     802    144145661 :   if (data->icode < 0 && NONDEBUG_INSN_P (data->insn))
     803              :     {
     804      1036900 :       if (data->insn_static_data->operand_alternative != NULL)
     805        42560 :         free (const_cast <operand_alternative *>
     806              :               (data->insn_static_data->operand_alternative));
     807      1036900 :       free_insn_regs (data->insn_static_data->hard_regs);
     808      1036900 :       free (data->insn_static_data);
     809              :     }
     810    144145661 :   free_insn_regs (data->regs);
     811    144145661 :   data->regs = NULL;
     812    144145661 :   lra_insn_recog_data_pool.remove (data);
     813    144145661 : }
     814              : 
     815              : /* Pools for copies.  */
     816              : static object_allocator<lra_copy> lra_copy_pool ("lra copies");
     817              : 
     818              : /* Finish LRA data about all insns.  */
     819              : static void
     820      1480947 : finish_insn_recog_data (void)
     821              : {
     822      1480947 :   int i;
     823      1480947 :   lra_insn_recog_data_t data;
     824              : 
     825    283434197 :   for (i = 0; i < lra_insn_recog_data_len; i++)
     826    281953250 :     if ((data = lra_insn_recog_data[i]) != NULL)
     827    130999325 :       free_insn_recog_data (data);
     828      1480947 :   finish_insn_regs ();
     829      1480947 :   lra_copy_pool.release ();
     830      1480947 :   lra_insn_reg_pool.release ();
     831      1480947 :   lra_insn_recog_data_pool.release ();
     832      1480947 :   free (lra_insn_recog_data);
     833      1480947 : }
     834              : 
     835              : /* Setup info about operands in alternatives of LRA DATA of insn.  */
     836              : static void
     837      2951469 : setup_operand_alternative (lra_insn_recog_data_t data,
     838              :                            const operand_alternative *op_alt)
     839              : {
     840      2951469 :   int i, j, nop, nalt;
     841      2951469 :   int icode = data->icode;
     842      2951469 :   struct lra_static_insn_data *static_data = data->insn_static_data;
     843              : 
     844      2951469 :   static_data->commutative = -1;
     845      2951469 :   nop = static_data->n_operands;
     846      2951469 :   nalt = static_data->n_alternatives;
     847      2951469 :   static_data->operand_alternative = op_alt;
     848      8633688 :   for (i = 0; i < nop; i++)
     849              :     {
     850      5682219 :       static_data->operand[i].early_clobber_alts = 0;
     851      5682219 :       static_data->operand[i].is_address = false;
     852      5682219 :       if (static_data->operand[i].constraint[0] == '%')
     853              :         {
     854              :           /* We currently only support one commutative pair of operands.  */
     855       363242 :           if (static_data->commutative < 0)
     856       362888 :             static_data->commutative = i;
     857              :           else
     858          354 :             lra_assert (icode < 0); /* Asm  */
     859              :           /* The last operand should not be marked commutative.  */
     860       363242 :           lra_assert (i != nop - 1);
     861              :         }
     862              :     }
     863     18642998 :   for (j = 0; j < nalt; j++)
     864     50895858 :     for (i = 0; i < nop; i++, op_alt++)
     865              :       {
     866     35204329 :         if (op_alt->earlyclobber)
     867        47311 :           static_data->operand[i].early_clobber_alts |= (alternative_mask) 1 << j;
     868     35204329 :         static_data->operand[i].is_address |= op_alt->is_address;
     869              :       }
     870      2951469 : }
     871              : 
     872              : /* Recursively process X and collect info about registers, which are
     873              :    not the insn operands, in X with TYPE (in/out/inout) and flag that
     874              :    it is early clobbered in the insn (EARLY_CLOBBER) and add the info
     875              :    to LIST.  X is a part of insn given by DATA.  Return the result
     876              :    list.  */
     877              : static struct lra_insn_reg *
     878    408450527 : collect_non_operand_hard_regs (rtx_insn *insn, rtx *x,
     879              :                                lra_insn_recog_data_t data,
     880              :                                struct lra_insn_reg *list,
     881              :                                enum op_type type, bool early_clobber)
     882              : {
     883    408450527 :   int i, j, regno, last;
     884    408450527 :   bool subreg_p;
     885    408450527 :   machine_mode mode;
     886    408450527 :   struct lra_insn_reg *curr;
     887    408450527 :   rtx op = *x;
     888    408450527 :   enum rtx_code code = GET_CODE (op);
     889    408450527 :   const char *fmt = GET_RTX_FORMAT (code);
     890              : 
     891   1041950394 :   for (i = 0; i < data->insn_static_data->n_operands; i++)
     892    820085214 :     if (! data->insn_static_data->operand[i].is_operator
     893    764751410 :         && x == data->operand_loc[i])
     894              :       /* It is an operand loc. Stop here.  */
     895              :       return list;
     896    230189274 :   for (i = 0; i < data->insn_static_data->n_dups; i++)
     897      9270275 :     if (x == data->dup_loc[i])
     898              :       /* It is a dup loc. Stop here.  */
     899              :       return list;
     900    220918999 :   mode = GET_MODE (op);
     901    220918999 :   subreg_p = false;
     902    220918999 :   if (code == SUBREG)
     903              :     {
     904         8266 :       mode = wider_subreg_mode (op);
     905         8266 :       if (read_modify_subreg_p (op))
     906              :         subreg_p = true;
     907         8266 :       op = SUBREG_REG (op);
     908         8266 :       code = GET_CODE (op);
     909              :     }
     910    220918999 :   if (REG_P (op))
     911              :     {
     912     24635467 :       if ((regno = REGNO (op)) >= FIRST_PSEUDO_REGISTER)
     913              :         return list;
     914              :       /* Process all regs even unallocatable ones as we need info
     915              :          about all regs for rematerialization pass.  */
     916     49262556 :       for (last = end_hard_regno (mode, regno); regno < last; regno++)
     917              :         {
     918     25201666 :           for (curr = list; curr != NULL; curr = curr->next)
     919       712947 :             if (curr->regno == regno && curr->subreg_p == subreg_p
     920       162591 :                 && curr->biggest_mode == mode)
     921              :               {
     922       142559 :                 if (curr->type != type)
     923       142559 :                   curr->type = OP_INOUT;
     924       142559 :                 if (early_clobber)
     925            0 :                   curr->early_clobber_alts = ALL_ALTERNATIVES;
     926              :                 break;
     927              :               }
     928     24631278 :           if (curr == NULL)
     929              :             {
     930              :               /* This is a new hard regno or the info cannot be
     931              :                  integrated into the found structure.    */
     932              : #ifdef STACK_REGS
     933     24488719 :               early_clobber
     934     24488719 :                 = (early_clobber
     935              :                    /* This clobber is to inform popping floating
     936              :                       point stack only.  */
     937     24488719 :                    && ! (FIRST_STACK_REG <= regno
     938              :                          && regno <= LAST_STACK_REG));
     939              : #endif
     940     24488719 :               list = new_insn_reg (data->insn, regno, type, mode, subreg_p,
     941              :                                    early_clobber ? ALL_ALTERNATIVES : 0, list);
     942              :             }
     943              :         }
     944              :       return list;
     945              :     }
     946    196283532 :   switch (code)
     947              :     {
     948     91207326 :     case SET:
     949     91207326 :       list = collect_non_operand_hard_regs (insn, &SET_DEST (op), data,
     950              :                                             list, OP_OUT, false);
     951     91207326 :       list = collect_non_operand_hard_regs (insn, &SET_SRC (op), data,
     952              :                                             list, OP_IN, false);
     953     91207326 :       break;
     954     10854510 :     case CLOBBER:
     955              :       /* We treat clobber of non-operand hard registers as early clobber.  */
     956     10854510 :       list = collect_non_operand_hard_regs (insn, &XEXP (op, 0), data,
     957              :                                             list, OP_OUT, true);
     958     10854510 :       break;
     959            0 :     case PRE_INC: case PRE_DEC: case POST_INC: case POST_DEC:
     960            0 :       list = collect_non_operand_hard_regs (insn, &XEXP (op, 0), data,
     961              :                                             list, OP_INOUT, false);
     962            0 :       break;
     963            0 :     case PRE_MODIFY: case POST_MODIFY:
     964            0 :       list = collect_non_operand_hard_regs (insn, &XEXP (op, 0), data,
     965              :                                             list, OP_INOUT, false);
     966            0 :       list = collect_non_operand_hard_regs (insn, &XEXP (op, 1), data,
     967              :                                             list, OP_IN, false);
     968            0 :       break;
     969     94221696 :     default:
     970     94221696 :       fmt = GET_RTX_FORMAT (code);
     971    228083004 :       for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
     972              :         {
     973    133861308 :           if (fmt[i] == 'e')
     974     94730570 :             list = collect_non_operand_hard_regs (insn, &XEXP (op, i), data,
     975              :                                                   list, OP_IN, false);
     976     39130738 :           else if (fmt[i] == 'E')
     977     38705663 :             for (j = XVECLEN (op, i) - 1; j >= 0; j--)
     978     25664810 :               list = collect_non_operand_hard_regs (insn, &XVECEXP (op, i, j),
     979              :                                                     data, list, OP_IN, false);
     980              :         }
     981              :     }
     982              :   return list;
     983              : }
     984              : 
     985              : /* Set up and return info about INSN.  Set up the info if it is not set up
     986              :    yet.  */
     987              : lra_insn_recog_data_t
     988    144145661 : lra_set_insn_recog_data (rtx_insn *insn)
     989              : {
     990    144145661 :   lra_insn_recog_data_t data;
     991    144145661 :   int i, n, icode;
     992    144145661 :   rtx **locs;
     993    144145661 :   unsigned int uid = INSN_UID (insn);
     994    144145661 :   struct lra_static_insn_data *insn_static_data;
     995              : 
     996    144145661 :   check_and_expand_insn_recog_data (uid);
     997    144145661 :   if (DEBUG_INSN_P (insn))
     998              :     icode = -1;
     999              :   else
    1000              :     {
    1001     95713034 :       icode = INSN_CODE (insn);
    1002     95713034 :       if (icode < 0)
    1003              :         /* It might be a new simple insn which is not recognized yet.  */
    1004      2396584 :         INSN_CODE (insn) = icode = recog_memoized (insn);
    1005              :     }
    1006    144145661 :   data = lra_insn_recog_data_pool.allocate ();
    1007    144145661 :   lra_insn_recog_data[uid] = data;
    1008    144145661 :   data->insn = insn;
    1009    144145661 :   data->used_insn_alternative = LRA_UNKNOWN_ALT;
    1010    144145661 :   data->asm_reloads_num = 0;
    1011    144145661 :   data->icode = icode;
    1012    144145661 :   data->regs = NULL;
    1013    144145661 :   if (DEBUG_INSN_P (insn))
    1014              :     {
    1015     48432627 :       data->dup_loc = NULL;
    1016     48432627 :       data->arg_hard_regs = NULL;
    1017     48432627 :       data->preferred_alternatives = ALL_ALTERNATIVES;
    1018     48432627 :       if (DEBUG_BIND_INSN_P (insn))
    1019              :         {
    1020     37341405 :           data->insn_static_data = &debug_bind_static_data;
    1021     37341405 :           data->operand_loc = XNEWVEC (rtx *, 1);
    1022     37341405 :           data->operand_loc[0] = &INSN_VAR_LOCATION_LOC (insn);
    1023              :         }
    1024     11091222 :       else if (DEBUG_MARKER_INSN_P (insn))
    1025              :         {
    1026     11091222 :           data->insn_static_data = &debug_marker_static_data;
    1027     11091222 :           data->operand_loc = NULL;
    1028              :         }
    1029     48432627 :       return data;
    1030              :     }
    1031     95713034 :   if (icode < 0)
    1032              :     {
    1033      1036900 :       int nop, nalt;
    1034      1036900 :       machine_mode operand_mode[MAX_RECOG_OPERANDS];
    1035      1036900 :       const char *constraints[MAX_RECOG_OPERANDS];
    1036              : 
    1037      1036900 :       nop = asm_noperands (PATTERN (insn));
    1038      1036900 :       data->operand_loc = data->dup_loc = NULL;
    1039      1036900 :       nalt = 1;
    1040      1036900 :       if (nop < 0)
    1041              :         {
    1042              :           /* It is a special insn like USE or CLOBBER.  We should
    1043              :              recognize any regular insn otherwise LRA can do nothing
    1044              :              with this insn.  */
    1045       929062 :           gcc_assert (GET_CODE (PATTERN (insn)) == USE
    1046              :                       || GET_CODE (PATTERN (insn)) == CLOBBER
    1047              :                       || GET_CODE (PATTERN (insn)) == ASM_INPUT);
    1048      1858124 :           data->insn_static_data = insn_static_data
    1049       929062 :             = get_static_insn_data (-1, 0, 0, nalt);
    1050              :         }
    1051              :       else
    1052              :         {
    1053              :           /* expand_asm_operands makes sure there aren't too many
    1054              :              operands.  */
    1055       107838 :           lra_assert (nop <= MAX_RECOG_OPERANDS);
    1056       107838 :           if (nop != 0)
    1057        42560 :             data->operand_loc = XNEWVEC (rtx *, nop);
    1058              :           /* Now get the operand values and constraints out of the
    1059              :              insn.  */
    1060       107838 :           decode_asm_operands (PATTERN (insn), NULL,
    1061              :                                data->operand_loc,
    1062              :                                constraints, operand_mode, NULL);
    1063       107838 :           if (nop > 0)
    1064       120067 :             for (const char *p =constraints[0]; *p; p++)
    1065        77507 :               nalt += *p == ',';
    1066       215676 :           data->insn_static_data = insn_static_data
    1067       107838 :             = get_static_insn_data (-1, nop, 0, nalt);
    1068       239912 :           for (i = 0; i < nop; i++)
    1069              :             {
    1070       132074 :               insn_static_data->operand[i].mode = operand_mode[i];
    1071       132074 :               insn_static_data->operand[i].constraint = constraints[i];
    1072       132074 :               insn_static_data->operand[i].strict_low = false;
    1073       132074 :               insn_static_data->operand[i].is_operator = false;
    1074       132074 :               insn_static_data->operand[i].is_address = false;
    1075              :             }
    1076              :         }
    1077      1168974 :       for (i = 0; i < insn_static_data->n_operands; i++)
    1078       132074 :         insn_static_data->operand[i].type
    1079       188248 :           = (insn_static_data->operand[i].constraint[0] == '=' ? OP_OUT
    1080              :              : insn_static_data->operand[i].constraint[0] == '+' ? OP_INOUT
    1081              :              : OP_IN);
    1082      1036900 :       data->preferred_alternatives = ALL_ALTERNATIVES;
    1083      1036900 :       if (nop > 0)
    1084              :         {
    1085        42560 :           operand_alternative *op_alt = XCNEWVEC (operand_alternative,
    1086              :                                                   nalt * nop);
    1087        42560 :           preprocess_constraints (nop, nalt, constraints, op_alt,
    1088              :                                   data->operand_loc);
    1089        42560 :           setup_operand_alternative (data, op_alt);
    1090              :         }
    1091              :     }
    1092              :   else
    1093              :     {
    1094     94676134 :       insn_extract (insn);
    1095    189352268 :       data->insn_static_data = insn_static_data
    1096    189352268 :         = get_static_insn_data (icode, insn_data[icode].n_operands,
    1097     94676134 :                                 insn_data[icode].n_dups,
    1098     94676134 :                                 insn_data[icode].n_alternatives);
    1099     94676134 :       n = insn_static_data->n_operands;
    1100     94676134 :       if (n == 0)
    1101              :         locs = NULL;
    1102              :       else
    1103              :         {
    1104     94113538 :           locs = XNEWVEC (rtx *, n);
    1105     94113538 :           memcpy (locs, recog_data.operand_loc, n * sizeof (rtx *));
    1106              :         }
    1107     94676134 :       data->operand_loc = locs;
    1108     94676134 :       n = insn_static_data->n_dups;
    1109     94676134 :       if (n == 0)
    1110              :         locs = NULL;
    1111              :       else
    1112              :         {
    1113       519566 :           locs = XNEWVEC (rtx *, n);
    1114       519566 :           memcpy (locs, recog_data.dup_loc, n * sizeof (rtx *));
    1115              :         }
    1116     94676134 :       data->dup_loc = locs;
    1117     94676134 :       data->preferred_alternatives = get_preferred_alternatives (insn);
    1118     94676134 :       const operand_alternative *op_alt = preprocess_insn_constraints (icode);
    1119     94676134 :       if (!insn_static_data->operand_alternative)
    1120      2908909 :         setup_operand_alternative (data, op_alt);
    1121     91767225 :       else if (op_alt != insn_static_data->operand_alternative)
    1122        45699 :         insn_static_data->operand_alternative = op_alt;
    1123              :     }
    1124     95713034 :   if (GET_CODE (PATTERN (insn)) == CLOBBER || GET_CODE (PATTERN (insn)) == USE)
    1125       927049 :     insn_static_data->hard_regs = NULL;
    1126              :   else
    1127     94785985 :     insn_static_data->hard_regs
    1128     94785985 :       = collect_non_operand_hard_regs (insn, &PATTERN (insn), data,
    1129              :                                        NULL, OP_IN, false);
    1130     95713034 :   data->arg_hard_regs = NULL;
    1131     95713034 :   if (CALL_P (insn))
    1132              :     {
    1133      5958427 :       bool use_p;
    1134      5958427 :       rtx link;
    1135      5958427 :       int n_hard_regs, regno, arg_hard_regs[FIRST_PSEUDO_REGISTER];
    1136              : 
    1137      5958427 :       n_hard_regs = 0;
    1138              :       /* Finding implicit hard register usage.  We believe it will be
    1139              :          not changed whatever transformations are used.  Call insns
    1140              :          are such example.  */
    1141      5958427 :       for (link = CALL_INSN_FUNCTION_USAGE (insn);
    1142     18855438 :            link != NULL_RTX;
    1143     12897011 :            link = XEXP (link, 1))
    1144     12897011 :         if (((use_p = GET_CODE (XEXP (link, 0)) == USE)
    1145       944773 :              || GET_CODE (XEXP (link, 0)) == CLOBBER)
    1146     13694870 :             && REG_P (XEXP (XEXP (link, 0), 0)))
    1147              :           {
    1148     11749825 :             regno = REGNO (XEXP (XEXP (link, 0), 0));
    1149     11749825 :             lra_assert (regno < FIRST_PSEUDO_REGISTER);
    1150              :             /* It is an argument register.  */
    1151     23560134 :             for (i = REG_NREGS (XEXP (XEXP (link, 0), 0)) - 1; i >= 0; i--)
    1152     23620618 :               arg_hard_regs[n_hard_regs++]
    1153     12608168 :                 = regno + i + (use_p ? 0 : FIRST_PSEUDO_REGISTER);
    1154              :           }
    1155              : 
    1156      5958427 :       if (n_hard_regs != 0)
    1157              :         {
    1158      4649846 :           arg_hard_regs[n_hard_regs++] = -1;
    1159      4649846 :           data->arg_hard_regs = XNEWVEC (int, n_hard_regs);
    1160      4649846 :           memcpy (data->arg_hard_regs, arg_hard_regs,
    1161              :                   sizeof (int) * n_hard_regs);
    1162              :         }
    1163              :     }
    1164              :   /* Some output operand can be recognized only from the context not
    1165              :      from the constraints which are empty in this case.  Call insn may
    1166              :      contain a hard register in set destination with empty constraint
    1167              :      and extract_insn treats them as an input.  */
    1168    298599166 :   for (i = 0; i < insn_static_data->n_operands; i++)
    1169              :     {
    1170    202886132 :       int j;
    1171    202886132 :       rtx pat, set;
    1172    202886132 :       struct lra_operand_data *operand = &insn_static_data->operand[i];
    1173              : 
    1174              :       /* ??? Should we treat 'X' the same way.  It looks to me that
    1175              :          'X' means anything and empty constraint means we do not
    1176              :          care.  */
    1177    202886132 :       if (operand->type != OP_IN || *operand->constraint != '\0'
    1178     25482270 :           || operand->is_operator)
    1179    184943280 :         continue;
    1180     17942852 :       pat = PATTERN (insn);
    1181     17942852 :       if (GET_CODE (pat) == SET)
    1182              :         {
    1183     14304251 :           if (data->operand_loc[i] != &SET_DEST (pat))
    1184     14197684 :             continue;
    1185              :         }
    1186      3638601 :       else if (GET_CODE (pat) == PARALLEL)
    1187              :         {
    1188       858572 :           for (j = XVECLEN (pat, 0) - 1; j >= 0; j--)
    1189              :             {
    1190       589213 :               set = XVECEXP (PATTERN (insn), 0, j);
    1191       589213 :               if (GET_CODE (set) == SET
    1192       375699 :                   && &SET_DEST (set) == data->operand_loc[i])
    1193              :                 break;
    1194              :             }
    1195       269669 :           if (j < 0)
    1196       269359 :             continue;
    1197              :         }
    1198              :       else
    1199      3368932 :         continue;
    1200       106877 :       operand->type = OP_OUT;
    1201              :     }
    1202              :   return data;
    1203              : }
    1204              : 
    1205              : /* Return info about insn give by UID.  The info should be already set
    1206              :    up.  */
    1207              : static lra_insn_recog_data_t
    1208       106994 : get_insn_recog_data_by_uid (int uid)
    1209              : {
    1210       106994 :   lra_insn_recog_data_t data;
    1211              : 
    1212       106994 :   data = lra_insn_recog_data[uid];
    1213       106994 :   lra_assert (data != NULL);
    1214       106994 :   return data;
    1215              : }
    1216              : 
    1217              : /* Invalidate all info about insn given by its UID.  */
    1218              : static void
    1219     13146336 : invalidate_insn_recog_data (int uid)
    1220              : {
    1221     13146336 :   lra_insn_recog_data_t data;
    1222              : 
    1223     13146336 :   data = lra_insn_recog_data[uid];
    1224     13146336 :   lra_assert (data != NULL);
    1225     13146336 :   free_insn_recog_data (data);
    1226     13146336 :   lra_insn_recog_data[uid] = NULL;
    1227     13146336 : }
    1228              : 
    1229              : /* Update all the insn info about INSN.  It is usually called when
    1230              :    something in the insn was changed.  Return the updated info.  */
    1231              : lra_insn_recog_data_t
    1232     46063291 : lra_update_insn_recog_data (rtx_insn *insn)
    1233              : {
    1234     46063291 :   lra_insn_recog_data_t data;
    1235     46063291 :   int n;
    1236     46063291 :   unsigned int uid = INSN_UID (insn);
    1237     46063291 :   struct lra_static_insn_data *insn_static_data;
    1238     46063291 :   poly_int64 sp_offset = 0;
    1239              : 
    1240     46063291 :   check_and_expand_insn_recog_data (uid);
    1241     46063291 :   if ((data = lra_insn_recog_data[uid]) != NULL
    1242     46063291 :       && data->icode != INSN_CODE (insn))
    1243              :     {
    1244       214499 :       sp_offset = data->sp_offset;
    1245       214499 :       invalidate_insn_data_regno_info (data, insn, get_insn_freq (insn));
    1246       214499 :       invalidate_insn_recog_data (uid);
    1247       214499 :       data = NULL;
    1248              :     }
    1249     46063291 :   if (data == NULL)
    1250              :     {
    1251       214499 :       data = lra_get_insn_recog_data (insn);
    1252              :       /* Initiate or restore SP offset.  */
    1253       214499 :       data->sp_offset = sp_offset;
    1254       214499 :       return data;
    1255              :     }
    1256     45848792 :   insn_static_data = data->insn_static_data;
    1257     45848792 :   data->used_insn_alternative = LRA_UNKNOWN_ALT;
    1258     45848792 :   if (DEBUG_INSN_P (insn))
    1259              :     return data;
    1260     36278593 :   if (data->icode < 0)
    1261              :     {
    1262        15158 :       int nop;
    1263        15158 :       machine_mode operand_mode[MAX_RECOG_OPERANDS];
    1264        15158 :       const char *constraints[MAX_RECOG_OPERANDS];
    1265              : 
    1266        15158 :       nop = asm_noperands (PATTERN (insn));
    1267        15158 :       if (nop >= 0)
    1268              :         {
    1269        15158 :           lra_assert (nop == data->insn_static_data->n_operands);
    1270              :           /* Now get the operand values and constraints out of the
    1271              :              insn.  */
    1272        15158 :           decode_asm_operands (PATTERN (insn), NULL,
    1273              :                                data->operand_loc,
    1274              :                                constraints, operand_mode, NULL);
    1275              : 
    1276        15158 :           if (flag_checking)
    1277        46776 :             for (int i = 0; i < nop; i++)
    1278        31618 :               lra_assert
    1279              :                 (insn_static_data->operand[i].mode == operand_mode[i]
    1280              :                  && insn_static_data->operand[i].constraint == constraints[i]
    1281              :                  && ! insn_static_data->operand[i].is_operator);
    1282              :         }
    1283              : 
    1284        15158 :       if (flag_checking)
    1285        46776 :         for (int i = 0; i < insn_static_data->n_operands; i++)
    1286        49058 :           lra_assert
    1287              :             (insn_static_data->operand[i].type
    1288              :              == (insn_static_data->operand[i].constraint[0] == '=' ? OP_OUT
    1289              :                  : insn_static_data->operand[i].constraint[0] == '+' ? OP_INOUT
    1290              :                  : OP_IN));
    1291              :     }
    1292              :   else
    1293              :     {
    1294     36263435 :       insn_extract (insn);
    1295     36263435 :       n = insn_static_data->n_operands;
    1296     36263435 :       if (n != 0)
    1297     36263435 :         memcpy (data->operand_loc, recog_data.operand_loc, n * sizeof (rtx *));
    1298     36263435 :       n = insn_static_data->n_dups;
    1299     36263435 :       if (n != 0)
    1300        45519 :         memcpy (data->dup_loc, recog_data.dup_loc, n * sizeof (rtx *));
    1301     36263435 :       lra_assert (check_bool_attrs (insn));
    1302              :     }
    1303              :   return data;
    1304              : }
    1305              : 
    1306              : /* Set up that INSN is using alternative ALT now.  */
    1307              : void
    1308    124752184 : lra_set_used_insn_alternative (rtx_insn *insn, int alt)
    1309              : {
    1310    124752184 :   lra_insn_recog_data_t data;
    1311              : 
    1312    124752184 :   data = lra_get_insn_recog_data (insn);
    1313    124752184 :   data->used_insn_alternative = alt;
    1314    124752184 : }
    1315              : 
    1316              : /* Set up that insn with UID is using alternative ALT now.  The insn
    1317              :    info should be already set up.  */
    1318              : void
    1319      9347302 : lra_set_used_insn_alternative_by_uid (int uid, int alt)
    1320              : {
    1321      9347302 :   lra_insn_recog_data_t data;
    1322              : 
    1323      9347302 :   check_and_expand_insn_recog_data (uid);
    1324      9347302 :   data = lra_insn_recog_data[uid];
    1325      9347302 :   lra_assert (data != NULL);
    1326      9347302 :   data->used_insn_alternative = alt;
    1327      9347302 : }
    1328              : 
    1329              : 
    1330              : 
    1331              : /* This page contains code dealing with common register info and
    1332              :    pseudo copies.  */
    1333              : 
    1334              : /* The size of the following array.  */
    1335              : static int reg_info_size;
    1336              : /* Common info about each register.  */
    1337              : class lra_reg *lra_reg_info;
    1338              : 
    1339              : HARD_REG_SET hard_regs_spilled_into;
    1340              : 
    1341              : /* Last register value.  */
    1342              : static int last_reg_value;
    1343              : 
    1344              : /* Return new register value.  */
    1345              : static int
    1346    309281533 : get_new_reg_value (void)
    1347              : {
    1348    309281533 :   return ++last_reg_value;
    1349              : }
    1350              : 
    1351              : /* Vec referring to pseudo copies.  */
    1352              : static vec<lra_copy_t> copy_vec;
    1353              : 
    1354              : /* Initialize I-th element of lra_reg_info.  */
    1355              : static inline void
    1356    309279847 : initialize_lra_reg_info_element (int i)
    1357              : {
    1358    309279847 :   bitmap_initialize (&lra_reg_info[i].insn_bitmap, &reg_obstack);
    1359              : #ifdef STACK_REGS
    1360    309279847 :   lra_reg_info[i].no_stack_p = false;
    1361              : #endif
    1362   1237119388 :   CLEAR_HARD_REG_SET (lra_reg_info[i].conflict_hard_regs);
    1363    309279847 :   CLEAR_HARD_REG_SET (lra_reg_info[i].exclude_start_hard_regs);
    1364    309279847 :   lra_reg_info[i].preferred_hard_regno1 = -1;
    1365    309279847 :   lra_reg_info[i].preferred_hard_regno2 = -1;
    1366    309279847 :   lra_reg_info[i].preferred_hard_regno_profit1 = 0;
    1367    309279847 :   lra_reg_info[i].preferred_hard_regno_profit2 = 0;
    1368    309279847 :   lra_reg_info[i].biggest_mode = VOIDmode;
    1369    309279847 :   lra_reg_info[i].live_ranges = NULL;
    1370    309279847 :   lra_reg_info[i].nrefs = lra_reg_info[i].freq = 0;
    1371    309279847 :   lra_reg_info[i].last_reload = 0;
    1372    309279847 :   lra_reg_info[i].restore_rtx = NULL_RTX;
    1373    309279847 :   lra_reg_info[i].val = get_new_reg_value ();
    1374    309279847 :   lra_reg_info[i].offset = 0;
    1375    309279847 :   lra_reg_info[i].copies = NULL;
    1376    309279847 : }
    1377              : 
    1378              : /* Initialize common reg info and copies.  */
    1379              : static void
    1380      1480947 : init_reg_info (void)
    1381              : {
    1382      1480947 :   int i;
    1383              : 
    1384      1480947 :   last_reg_value = 0;
    1385      1480947 :   reg_info_size = max_reg_num () * 3 / 2 + 1;
    1386      1480947 :   lra_reg_info = XNEWVEC (class lra_reg, reg_info_size);
    1387    309508005 :   for (i = 0; i < reg_info_size; i++)
    1388    308027058 :     initialize_lra_reg_info_element (i);
    1389      1480947 :   copy_vec.truncate (0);
    1390      1480947 :   CLEAR_HARD_REG_SET (hard_regs_spilled_into);
    1391      1480947 : }
    1392              : 
    1393              : 
    1394              : /* Finish common reg info and copies.  */
    1395              : static void
    1396      1480947 : finish_reg_info (void)
    1397              : {
    1398      1480947 :   int i;
    1399              : 
    1400    310760794 :   for (i = 0; i < reg_info_size; i++)
    1401    309279847 :     bitmap_clear (&lra_reg_info[i].insn_bitmap);
    1402      1480947 :   free (lra_reg_info);
    1403      1480947 :   reg_info_size = 0;
    1404      1480947 : }
    1405              : 
    1406              : /* Expand common reg info if it is necessary.  */
    1407              : static void
    1408    279099649 : expand_reg_info (void)
    1409              : {
    1410    279099649 :   int i, old = reg_info_size;
    1411              : 
    1412    279099649 :   if (reg_info_size > max_reg_num ())
    1413              :     return;
    1414         1271 :   reg_info_size = max_reg_num () * 3 / 2 + 1;
    1415         1271 :   lra_reg_info = XRESIZEVEC (class lra_reg, lra_reg_info, reg_info_size);
    1416      1254060 :   for (i = old; i < reg_info_size; i++)
    1417      1252789 :     initialize_lra_reg_info_element (i);
    1418              : }
    1419              : 
    1420              : /* Free all copies.  */
    1421              : void
    1422      1779741 : lra_free_copies (void)
    1423              : {
    1424      1779741 :   lra_copy_t cp;
    1425              : 
    1426      6648232 :   while (copy_vec.length () != 0)
    1427              :     {
    1428      4868491 :       cp = copy_vec.pop ();
    1429      4868491 :       lra_reg_info[cp->regno1].copies = lra_reg_info[cp->regno2].copies = NULL;
    1430      4868491 :       lra_copy_pool.remove (cp);
    1431              :     }
    1432      1779741 : }
    1433              : 
    1434              : /* Create copy of two pseudos REGNO1 and REGNO2.  The copy execution
    1435              :    frequency is FREQ.  */
    1436              : void
    1437      5899066 : lra_create_copy (int regno1, int regno2, int freq)
    1438              : {
    1439      5899066 :   bool regno1_dest_p;
    1440      5899066 :   lra_copy_t cp;
    1441              : 
    1442      5899066 :   lra_assert (regno1 != regno2);
    1443      5899066 :   regno1_dest_p = true;
    1444      5899066 :   if (regno1 > regno2)
    1445              :     {
    1446      1249599 :       std::swap (regno1, regno2);
    1447      1249599 :       regno1_dest_p = false;
    1448              :     }
    1449      5899066 :   cp = lra_copy_pool.allocate ();
    1450      5899066 :   copy_vec.safe_push (cp);
    1451      5899066 :   cp->regno1_dest_p = regno1_dest_p;
    1452      5899066 :   cp->freq = freq;
    1453      5899066 :   cp->regno1 = regno1;
    1454      5899066 :   cp->regno2 = regno2;
    1455      5899066 :   cp->regno1_next = lra_reg_info[regno1].copies;
    1456      5899066 :   lra_reg_info[regno1].copies = cp;
    1457      5899066 :   cp->regno2_next = lra_reg_info[regno2].copies;
    1458      5899066 :   lra_reg_info[regno2].copies = cp;
    1459      5899066 :   if (lra_dump_file != NULL)
    1460           10 :     fprintf (lra_dump_file, "         Creating copy r%d%sr%d@%d\n",
    1461              :              regno1, regno1_dest_p ? "<-" : "->", regno2, freq);
    1462      5899066 : }
    1463              : 
    1464              : /* Return N-th (0, 1, ...) copy.  If there is no copy, return
    1465              :    NULL.  */
    1466              : lra_copy_t
    1467      4345535 : lra_get_copy (int n)
    1468              : {
    1469      7717489 :   if (n >= (int) copy_vec.length ())
    1470              :     return NULL;
    1471      2795923 :   return copy_vec[n];
    1472              : }
    1473              : 
    1474              : 
    1475              : 
    1476              : /* This page contains code dealing with info about registers in
    1477              :    insns.  */
    1478              : 
    1479              : /* Process X of INSN recursively and add info (operand type is given
    1480              :    by TYPE) about registers in X to the insn DATA.  If X can be early
    1481              :    clobbered, alternatives in which it can be early clobbered are given
    1482              :    by EARLY_CLOBBER_ALTS.  */
    1483              : static void
    1484    575858560 : add_regs_to_insn_regno_info (lra_insn_recog_data_t data, rtx x,
    1485              :                              rtx_insn *insn, enum op_type type,
    1486              :                              alternative_mask early_clobber_alts)
    1487              : {
    1488    595322440 :   int i, j, regno;
    1489    595322440 :   bool subreg_p;
    1490    595322440 :   machine_mode mode;
    1491    595322440 :   const char *fmt;
    1492    595322440 :   enum rtx_code code;
    1493    595322440 :   struct lra_insn_reg *curr;
    1494              : 
    1495    595322440 :   code = GET_CODE (x);
    1496    595322440 :   mode = GET_MODE (x);
    1497    595322440 :   subreg_p = false;
    1498    595322440 :   if (GET_CODE (x) == SUBREG)
    1499              :     {
    1500      4951387 :       mode = wider_subreg_mode (x);
    1501      4951387 :       if (read_modify_subreg_p (x))
    1502              :         subreg_p = true;
    1503      4951387 :       x = SUBREG_REG (x);
    1504      4951387 :       code = GET_CODE (x);
    1505              :     }
    1506    595322440 :   if (REG_P (x))
    1507              :     {
    1508    270257065 :       regno = REGNO (x);
    1509              :       /* Process all regs even unallocatable ones as we need info about
    1510              :          all regs for rematerialization pass.  */
    1511    270257065 :       expand_reg_info ();
    1512    270257065 :       if (bitmap_set_bit (&lra_reg_info[regno].insn_bitmap, INSN_UID (insn)))
    1513              :         {
    1514    261005338 :           data->regs = new_insn_reg (data->insn, regno, type, mode, subreg_p,
    1515              :                                      early_clobber_alts, data->regs);
    1516    261005338 :           return;
    1517              :         }
    1518              :       else
    1519              :         {
    1520     11021332 :           for (curr = data->regs; curr != NULL; curr = curr->next)
    1521     11021332 :             if (curr->regno == regno)
    1522              :               {
    1523      9251727 :                 if (curr->subreg_p != subreg_p || curr->biggest_mode != mode)
    1524              :                   /* The info cannot be integrated into the found
    1525              :                      structure.  */
    1526       127972 :                   data->regs = new_insn_reg (data->insn, regno, type, mode,
    1527              :                                              subreg_p, early_clobber_alts,
    1528              :                                              data->regs);
    1529              :                 else
    1530              :                   {
    1531      9123755 :                     if (curr->type != type)
    1532      5917934 :                       curr->type = OP_INOUT;
    1533      9123755 :                     curr->early_clobber_alts |= early_clobber_alts;
    1534              :                   }
    1535      9251727 :                 return;
    1536              :               }
    1537            0 :           gcc_unreachable ();
    1538              :         }
    1539              :     }
    1540              : 
    1541    325065375 :   switch (code)
    1542              :     {
    1543         2217 :     case SET:
    1544         2217 :       add_regs_to_insn_regno_info (data, SET_DEST (x), insn, OP_OUT, 0);
    1545         2217 :       add_regs_to_insn_regno_info (data, SET_SRC (x), insn, OP_IN, 0);
    1546         2217 :       break;
    1547     16899592 :     case CLOBBER:
    1548              :       /* We treat clobber of non-operand hard registers as early
    1549              :          clobber.  */
    1550     16899592 :       add_regs_to_insn_regno_info (data, XEXP (x, 0), insn, OP_OUT,
    1551              :                                    ALL_ALTERNATIVES);
    1552     16899592 :       break;
    1553      2454887 :     case PRE_INC: case PRE_DEC: case POST_INC: case POST_DEC:
    1554      2454887 :       add_regs_to_insn_regno_info (data, XEXP (x, 0), insn, OP_INOUT, 0);
    1555      2454887 :       break;
    1556       107184 :     case PRE_MODIFY: case POST_MODIFY:
    1557       107184 :       add_regs_to_insn_regno_info (data, XEXP (x, 0), insn, OP_INOUT, 0);
    1558       107184 :       add_regs_to_insn_regno_info (data, XEXP (x, 1), insn, OP_IN, 0);
    1559       107184 :       break;
    1560    305601495 :     default:
    1561    305601495 :       if ((code != PARALLEL && code != EXPR_LIST) || type != OP_OUT)
    1562              :         /* Some targets place small structures in registers for return
    1563              :            values of functions, and those registers are wrapped in
    1564              :            PARALLEL that we may see as the destination of a SET.  Here
    1565              :            is an example:
    1566              : 
    1567              :            (call_insn 13 12 14 2 (set (parallel:BLK [
    1568              :                 (expr_list:REG_DEP_TRUE (reg:DI 0 ax)
    1569              :                     (const_int 0 [0]))
    1570              :                 (expr_list:REG_DEP_TRUE (reg:DI 1 dx)
    1571              :                     (const_int 8 [0x8]))
    1572              :                ])
    1573              :              (call (mem:QI (symbol_ref:DI (...  */
    1574    305571693 :         type = OP_IN;
    1575    305601495 :       fmt = GET_RTX_FORMAT (code);
    1576    822418920 :       for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
    1577              :         {
    1578    516817425 :           if (fmt[i] == 'e')
    1579    218738522 :             add_regs_to_insn_regno_info (data, XEXP (x, i), insn, type, 0);
    1580    298078903 :           else if (fmt[i] == 'E')
    1581              :             {
    1582      3445063 :               for (j = XVECLEN (x, i) - 1; j >= 0; j--)
    1583      2764251 :                 add_regs_to_insn_regno_info (data, XVECEXP (x, i, j), insn,
    1584              :                                              type, 0);
    1585              :             }
    1586              :         }
    1587              :     }
    1588              : }
    1589              : 
    1590              : /* Return execution frequency of INSN.  */
    1591              : static int
    1592    156260293 : get_insn_freq (rtx_insn *insn)
    1593              : {
    1594    156260293 :   basic_block bb = BLOCK_FOR_INSN (insn);
    1595              : 
    1596    156260293 :   gcc_checking_assert (bb != NULL);
    1597    156260293 :   return REG_FREQ_FROM_BB (bb);
    1598              : }
    1599              : 
    1600              : /* Invalidate all reg info of INSN with DATA and execution frequency
    1601              :    FREQ.  Update common info about the invalidated registers.  */
    1602              : static void
    1603    214253542 : invalidate_insn_data_regno_info (lra_insn_recog_data_t data, rtx_insn *insn,
    1604              :                                  int freq)
    1605              : {
    1606    214253542 :   int uid;
    1607    214253542 :   bool debug_p;
    1608    214253542 :   unsigned int i;
    1609    214253542 :   struct lra_insn_reg *ir, *next_ir;
    1610              : 
    1611    214253542 :   uid = INSN_UID (insn);
    1612    214253542 :   debug_p = DEBUG_INSN_P (insn);
    1613    342414899 :   for (ir = data->regs; ir != NULL; ir = next_ir)
    1614              :     {
    1615    128161357 :       i = ir->regno;
    1616    128161357 :       next_ir = ir->next;
    1617    128161357 :       lra_insn_reg_pool.remove (ir);
    1618    128161357 :       bitmap_clear_bit (&lra_reg_info[i].insn_bitmap, uid);
    1619    128161357 :       if (i >= FIRST_PSEUDO_REGISTER && ! debug_p)
    1620              :         {
    1621     82092455 :           lra_reg_info[i].nrefs--;
    1622     82092455 :           lra_reg_info[i].freq -= freq;
    1623     82092455 :           lra_assert (lra_reg_info[i].nrefs >= 0 && lra_reg_info[i].freq >= 0);
    1624              :         }
    1625              :     }
    1626    214253542 :   data->regs = NULL;
    1627    214253542 : }
    1628              : 
    1629              : /* Invalidate all reg info of INSN.  Update common info about the
    1630              :    invalidated registers.  */
    1631              : void
    1632     12931837 : lra_invalidate_insn_regno_info (rtx_insn *insn)
    1633              : {
    1634     12931837 :   invalidate_insn_data_regno_info (lra_get_insn_recog_data (insn), insn,
    1635              :                                    get_insn_freq (insn));
    1636     12931837 : }
    1637              : 
    1638              : /* Update common reg info from reg info of insn given by its DATA and
    1639              :    execution frequency FREQ.  */
    1640              : static void
    1641    143113957 : setup_insn_reg_info (lra_insn_recog_data_t data, int freq)
    1642              : {
    1643    143113957 :   unsigned int i;
    1644    143113957 :   struct lra_insn_reg *ir;
    1645              : 
    1646    384206566 :   for (ir = data->regs; ir != NULL; ir = ir->next)
    1647    241092609 :     if ((i = ir->regno) >= FIRST_PSEUDO_REGISTER)
    1648              :       {
    1649    160951515 :         lra_reg_info[i].nrefs++;
    1650    160951515 :         lra_reg_info[i].freq += freq;
    1651              :       }
    1652    143113957 : }
    1653              : 
    1654              : /* Set up insn reg info of INSN.  Update common reg info from reg info
    1655              :    of INSN.  */
    1656              : void
    1657    201107223 : lra_update_insn_regno_info (rtx_insn *insn)
    1658              : {
    1659    201107223 :   int i, freq;
    1660    201107223 :   lra_insn_recog_data_t data;
    1661    201107223 :   struct lra_static_insn_data *static_data;
    1662    201107223 :   enum rtx_code code;
    1663    201107223 :   rtx link;
    1664              : 
    1665    201107223 :   if (! INSN_P (insn))
    1666              :     return;
    1667    201107206 :   data = lra_get_insn_recog_data (insn);
    1668    201107206 :   static_data = data->insn_static_data;
    1669    201107206 :   freq = NONDEBUG_INSN_P (insn) ? get_insn_freq (insn) : 0;
    1670    201107206 :   invalidate_insn_data_regno_info (data, insn, freq);
    1671    553387009 :   for (i = static_data->n_operands - 1; i >= 0; i--)
    1672    352279803 :     add_regs_to_insn_regno_info (data, *data->operand_loc[i], insn,
    1673    352279803 :                                  static_data->operand[i].type,
    1674    352279803 :                                  static_data->operand[i].early_clobber_alts);
    1675    201107206 :   if ((code = GET_CODE (PATTERN (insn))) == CLOBBER || code == USE)
    1676       938683 :     add_regs_to_insn_regno_info (data, XEXP (PATTERN (insn), 0), insn,
    1677       938683 :                                  code == USE ? OP_IN : OP_OUT, 0);
    1678    201107206 :   if (CALL_P (insn))
    1679              :     /* On some targets call insns can refer to pseudos in memory in
    1680              :        CALL_INSN_FUNCTION_USAGE list.  Process them in order to
    1681              :        consider their occurrences in calls for different
    1682              :        transformations (e.g. inheritance) with given pseudos.  */
    1683      5983672 :     for (link = CALL_INSN_FUNCTION_USAGE (insn);
    1684     18947736 :          link != NULL_RTX;
    1685     12964064 :          link = XEXP (link, 1))
    1686              :       {
    1687     12964064 :         code = GET_CODE (XEXP (link, 0));
    1688     12964064 :         if ((code == USE || code == CLOBBER)
    1689     12817150 :             && MEM_P (XEXP (XEXP (link, 0), 0)))
    1690      1027900 :           add_regs_to_insn_regno_info (data, XEXP (XEXP (link, 0), 0), insn,
    1691      1027900 :                                        code == USE ? OP_IN : OP_OUT, 0);
    1692              :       }
    1693    201107206 :   if (NONDEBUG_INSN_P (insn))
    1694    143113957 :     setup_insn_reg_info (data, freq);
    1695              : }
    1696              : 
    1697              : /* Return reg info of insn given by it UID.  */
    1698              : struct lra_insn_reg *
    1699       106994 : lra_get_insn_regs (int uid)
    1700              : {
    1701       106994 :   lra_insn_recog_data_t data;
    1702              : 
    1703       106994 :   data = get_insn_recog_data_by_uid (uid);
    1704       106994 :   return data->regs;
    1705              : }
    1706              : 
    1707              : 
    1708              : 
    1709              : /* Recursive hash function for RTL X.  */
    1710              : hashval_t
    1711       178081 : lra_rtx_hash (rtx x)
    1712              : {
    1713       178081 :   int i, j;
    1714       178081 :   enum rtx_code code;
    1715       178081 :   const char *fmt;
    1716       178081 :   hashval_t val = 0;
    1717              : 
    1718       178081 :   if (x == 0)
    1719              :     return val;
    1720              : 
    1721       178081 :   code = GET_CODE (x);
    1722       178081 :   val += (int) code + 4095;
    1723              : 
    1724              :   /* Some RTL can be compared nonrecursively.  */
    1725       178081 :   switch (code)
    1726              :     {
    1727            0 :     case REG:
    1728            0 :       return val + REGNO (x);
    1729              : 
    1730          207 :     case LABEL_REF:
    1731          207 :       return iterative_hash_object (XEXP (x, 0), val);
    1732              : 
    1733        13270 :     case SYMBOL_REF:
    1734        13270 :       return iterative_hash_object (XSTR (x, 0), val);
    1735              : 
    1736              :     case SCRATCH:
    1737              :     case CONST_DOUBLE:
    1738              :     case CONST_VECTOR:
    1739              :       return val;
    1740              : 
    1741       147863 :     case CONST_INT:
    1742       147863 :       return val + UINTVAL (x);
    1743              : 
    1744            0 :     case SUBREG:
    1745            0 :       val += lra_rtx_hash (SUBREG_REG (x));
    1746            0 :       for (int i = 0; i < NUM_POLY_INT_COEFFS; ++i)
    1747            0 :         val += SUBREG_BYTE (x).coeffs[i];
    1748              :       return val;
    1749              : 
    1750        13347 :     default:
    1751        13347 :       break;
    1752              :     }
    1753              : 
    1754              :   /* Hash the elements.  */
    1755        13347 :   fmt = GET_RTX_FORMAT (code);
    1756        19847 :   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
    1757              :     {
    1758         6500 :       switch (fmt[i])
    1759              :         {
    1760            0 :         case 'w':
    1761            0 :           val += XWINT (x, i);
    1762            0 :           break;
    1763              : 
    1764           17 :         case 'n':
    1765           17 :         case 'i':
    1766           17 :           val += XINT (x, i);
    1767           17 :           break;
    1768              : 
    1769            0 :         case 'L':
    1770            0 :           val += XLOC (x, i);
    1771            0 :           break;
    1772              : 
    1773           17 :         case 'V':
    1774           17 :         case 'E':
    1775           17 :           val += XVECLEN (x, i);
    1776              : 
    1777           34 :           for (j = 0; j < XVECLEN (x, i); j++)
    1778           17 :             val += lra_rtx_hash (XVECEXP (x, i, j));
    1779              :           break;
    1780              : 
    1781         6466 :         case 'e':
    1782         6466 :           val += lra_rtx_hash (XEXP (x, i));
    1783         6466 :           break;
    1784              : 
    1785            0 :         case 'S':
    1786            0 :         case 's':
    1787            0 :           val += htab_hash_string (XSTR (x, i));
    1788            0 :           break;
    1789              : 
    1790              :         case 'u':
    1791              :         case '0':
    1792              :         case 't':
    1793              :           break;
    1794              : 
    1795              :           /* It is believed that rtx's at this level will never
    1796              :              contain anything but integers and other rtx's, except for
    1797              :              within LABEL_REFs and SYMBOL_REFs.  */
    1798            0 :         default:
    1799            0 :           abort ();
    1800              :         }
    1801              :     }
    1802              :   return val;
    1803              : }
    1804              : 
    1805              : 
    1806              : 
    1807              : /* This page contains code dealing with stack of the insns which
    1808              :    should be processed by the next constraint pass.  */
    1809              : 
    1810              : /* Bitmap used to put an insn on the stack only in one exemplar.  */
    1811              : static sbitmap lra_constraint_insn_stack_bitmap;
    1812              : 
    1813              : /* The stack itself.  */
    1814              : vec<rtx_insn *> lra_constraint_insn_stack;
    1815              : 
    1816              : /* Put INSN on the stack.  If ALWAYS_UPDATE is true, always update the reg
    1817              :    info for INSN, otherwise only update it if INSN is not already on the
    1818              :    stack.  */
    1819              : static inline void
    1820    187572951 : lra_push_insn_1 (rtx_insn *insn, bool always_update)
    1821              : {
    1822    187572951 :   unsigned int uid = INSN_UID (insn);
    1823    187572951 :   if (always_update)
    1824      9450772 :     lra_update_insn_regno_info (insn);
    1825    187572951 :   if (uid >= SBITMAP_SIZE (lra_constraint_insn_stack_bitmap))
    1826       511774 :     lra_constraint_insn_stack_bitmap =
    1827       511774 :       sbitmap_resize (lra_constraint_insn_stack_bitmap, 3 * uid / 2, 0);
    1828    187572951 :   if (bitmap_bit_p (lra_constraint_insn_stack_bitmap, uid))
    1829              :     return;
    1830    159599920 :   bitmap_set_bit (lra_constraint_insn_stack_bitmap, uid);
    1831    159599920 :   if (! always_update)
    1832    154713458 :     lra_update_insn_regno_info (insn);
    1833    159599920 :   lra_constraint_insn_stack.safe_push (insn);
    1834              : }
    1835              : 
    1836              : /* Put INSN on the stack.  */
    1837              : void
    1838    178122179 : lra_push_insn (rtx_insn *insn)
    1839              : {
    1840    178122179 :   lra_push_insn_1 (insn, false);
    1841    178122179 : }
    1842              : 
    1843              : /* Put INSN on the stack and update its reg info.  */
    1844              : void
    1845      9450772 : lra_push_insn_and_update_insn_regno_info (rtx_insn *insn)
    1846              : {
    1847      9450772 :   lra_push_insn_1 (insn, true);
    1848      9450772 : }
    1849              : 
    1850              : /* Put insn with UID on the stack.  */
    1851              : void
    1852      7111230 : lra_push_insn_by_uid (unsigned int uid)
    1853              : {
    1854      7111230 :   lra_push_insn (lra_insn_recog_data[uid]->insn);
    1855      7111230 : }
    1856              : 
    1857              : /* Take the last-inserted insns off the stack and return it.  */
    1858              : rtx_insn *
    1859    159599598 : lra_pop_insn (void)
    1860              : {
    1861    159599598 :   rtx_insn *insn = lra_constraint_insn_stack.pop ();
    1862    159599598 :   bitmap_clear_bit (lra_constraint_insn_stack_bitmap, INSN_UID (insn));
    1863    159599598 :   return insn;
    1864              : }
    1865              : 
    1866              : /* Return the current size of the insn stack.  */
    1867              : unsigned int
    1868    166052918 : lra_insn_stack_length (void)
    1869              : {
    1870    166052918 :   return lra_constraint_insn_stack.length ();
    1871              : }
    1872              : 
    1873              : /* Push insns FROM to TO (excluding it) going in reverse order.  */
    1874              : static void
    1875     10885798 : push_insns (rtx_insn *from, rtx_insn *to)
    1876              : {
    1877     10885798 :   rtx_insn *insn;
    1878              : 
    1879     10885798 :   if (from == NULL_RTX)
    1880              :     return;
    1881    188153145 :   for (insn = from; insn != to; insn = PREV_INSN (insn))
    1882    177267347 :     if (INSN_P (insn))
    1883    143931156 :       lra_push_insn (insn);
    1884              : }
    1885              : 
    1886              : /* Set up and return sp offset for insns in range [FROM, LAST].  The offset is
    1887              :    taken from the BB insn before FROM after simulating its effects,
    1888              :    or zero if there is no such insn.  */
    1889              : static poly_int64
    1890      9404851 : setup_sp_offset (rtx_insn *from, rtx_insn *last)
    1891              : {
    1892      9404851 :   rtx_insn *before = prev_nonnote_nondebug_insn_bb (from);
    1893      9404851 :   poly_int64 offset = 0;
    1894              : 
    1895      9404851 :   if (before && INSN_P (before))
    1896      7885466 :     offset = lra_update_sp_offset (PATTERN (before),
    1897      7885466 :                                    lra_get_insn_recog_data (before)->sp_offset);
    1898              : 
    1899     19180142 :   for (rtx_insn *insn = from; insn != NEXT_INSN (last); insn = NEXT_INSN (insn))
    1900              :     {
    1901      9775291 :       lra_get_insn_recog_data (insn)->sp_offset = offset;
    1902      9775291 :       offset = lra_update_sp_offset (PATTERN (insn), offset);
    1903              :     }
    1904      9404851 :   return offset;
    1905              : }
    1906              : 
    1907              : /* Dump all func insns in a slim form.  */
    1908              : void
    1909            0 : lra_dump_insns (FILE *f)
    1910              : {
    1911            0 :   dump_rtl_slim (f, get_insns (), NULL, -1, 0);
    1912            0 : }
    1913              : 
    1914              : /* Dump all func insns in a slim form with TITLE when the dump file is open and
    1915              :    lra_verbose >=7.  */
    1916              : void
    1917      2270699 : lra_dump_insns_if_possible (const char *title)
    1918              : {
    1919      2270699 :   if (lra_dump_file == NULL || lra_verbose < 7)
    1920              :     return;
    1921            0 :   fprintf (lra_dump_file, "%s:", title);
    1922            0 :   lra_dump_insns (lra_dump_file);
    1923              : }
    1924              : 
    1925              : /* Emit insns BEFORE before INSN and insns AFTER after INSN.  Put the insns
    1926              :    onto the stack.  Print about emitting the insns with TITLE.  Move insn
    1927              :    REG_ARGS_SIZE note to AFTER insns if FIXUP_REG_ARGS_SIZE.  */
    1928              : void
    1929     82025611 : lra_process_new_insns (rtx_insn *insn, rtx_insn *before, rtx_insn *after,
    1930              :                        const char *title, bool fixup_reg_args_size)
    1931              : {
    1932     82025611 :   if (before == NULL_RTX && after == NULL_RTX)
    1933              :     return;
    1934      7650368 :   if (lra_dump_file != NULL)
    1935              :     {
    1936           99 :       dump_insn_slim (lra_dump_file, insn);
    1937           99 :       if (before != NULL_RTX)
    1938              :         {
    1939           88 :           fprintf (lra_dump_file,"    %s before:\n", title);
    1940           88 :           dump_rtl_slim (lra_dump_file, before, NULL, -1, 0);
    1941              :         }
    1942              :     }
    1943      7650357 :   if (before != NULL_RTX)
    1944              :     {
    1945      5389498 :       if (cfun->can_throw_non_call_exceptions)
    1946      1230262 :         copy_reg_eh_region_note_forward (insn, before, NULL);
    1947      5389498 :       emit_insn_before (before, insn);
    1948      5389498 :       poly_int64 old_sp_offset = lra_get_insn_recog_data (insn)->sp_offset;
    1949      5389498 :       poly_int64 new_sp_offset = setup_sp_offset (before, PREV_INSN (insn));
    1950      5389498 :       if (maybe_ne (old_sp_offset, new_sp_offset))
    1951              :         {
    1952            0 :           if (lra_dump_file != NULL)
    1953              :             {
    1954            0 :               fprintf (lra_dump_file, "    Changing sp offset from ");
    1955            0 :               print_dec (old_sp_offset, lra_dump_file);
    1956            0 :               fprintf (lra_dump_file, " to ");
    1957            0 :               print_dec (new_sp_offset, lra_dump_file);
    1958            0 :               fprintf (lra_dump_file, " for insn");
    1959            0 :               dump_rtl_slim (lra_dump_file, insn, NULL, -1, 0);
    1960              :             }
    1961            0 :           lra_get_insn_recog_data (insn)->sp_offset = new_sp_offset;
    1962            0 :           eliminate_regs_in_insn (insn, false, false,
    1963              :                                   old_sp_offset - new_sp_offset);
    1964            0 :           lra_push_insn (insn);
    1965              :         }
    1966      5389498 :       push_insns (PREV_INSN (insn), PREV_INSN (before));
    1967              :     }
    1968      7650368 :   if (after != NULL_RTX)
    1969              :     {
    1970      4015175 :       if (cfun->can_throw_non_call_exceptions)
    1971       905872 :         copy_reg_eh_region_note_forward (insn, after, NULL);
    1972      4015175 :       if (! JUMP_P (insn))
    1973              :         {
    1974      4015054 :           rtx_insn *last;
    1975              : 
    1976      4015054 :           if (lra_dump_file != NULL)
    1977              :             {
    1978           84 :               fprintf (lra_dump_file, "    %s after:\n", title);
    1979           84 :               dump_rtl_slim (lra_dump_file, after, NULL, -1, 0);
    1980              :             }
    1981              :           for (last = after;
    1982      4016719 :                NEXT_INSN (last) != NULL_RTX;
    1983              :                last = NEXT_INSN (last))
    1984              :             ;
    1985      4015054 :           emit_insn_after (after, insn);
    1986      4015054 :           push_insns (last, insn);
    1987      4015054 :           setup_sp_offset (after, last);
    1988      4015054 :           if (fixup_reg_args_size)
    1989              :             {
    1990      2556342 :               rtx note = find_reg_note (insn, REG_ARGS_SIZE, NULL_RTX);
    1991      2556342 :               if (note)
    1992              :                 {
    1993            3 :                   remove_note (insn, note);
    1994            3 :                   fixup_args_size_notes (insn, last,
    1995              :                                          get_args_size (note));
    1996            3 :                   if (lra_dump_file != NULL)
    1997              :                     {
    1998            0 :                       fprintf (lra_dump_file,
    1999              :                                "    fixing up REG_SIZE_NOTE for:\n");
    2000            0 :                       dump_rtl_slim (lra_dump_file, insn, insn, -1, 0);
    2001            0 :                       fprintf (lra_dump_file, "    fixed insns after:\n");
    2002            0 :                       dump_rtl_slim (lra_dump_file,
    2003            0 :                                      NEXT_INSN (insn), last, -1, 0);
    2004              :                     }
    2005              :                 }
    2006              :             }
    2007              :         }
    2008              :       else
    2009              :         {
    2010              :           /* Put output reload insns on successor BBs: */
    2011          121 :           edge_iterator ei;
    2012          121 :           edge e;
    2013              : 
    2014          420 :           FOR_EACH_EDGE (e, ei, BLOCK_FOR_INSN (insn)->succs)
    2015          299 :             if (e->dest != EXIT_BLOCK_PTR_FOR_FN (cfun))
    2016              :               {
    2017              :                 /* We already made the edge no-critical in ira.cc::ira */
    2018          299 :                 lra_assert (!EDGE_CRITICAL_P (e));
    2019          299 :                 rtx_insn *tmp = BB_HEAD (e->dest);
    2020          299 :                 if (LABEL_P (tmp))
    2021          208 :                   tmp = NEXT_INSN (tmp);
    2022          299 :                 if (NOTE_INSN_BASIC_BLOCK_P (tmp))
    2023          299 :                   tmp = NEXT_INSN (tmp);
    2024              :                 /* Do not put reload insns if it is the last BB
    2025              :                    without actual insns.  */
    2026          299 :                 if (tmp == NULL)
    2027            0 :                   continue;
    2028          299 :                 start_sequence ();
    2029          622 :                 for (rtx_insn *curr = after; curr != NULL_RTX; curr = NEXT_INSN (curr))
    2030              :                   {
    2031          323 :                     rtx pat = copy_insn (PATTERN (curr));
    2032          323 :                     rtx_insn *copy = emit_insn (pat);
    2033          323 :                     if (bitmap_bit_p (&lra_postponed_insns, INSN_UID (curr)))
    2034              :                       /* Propagate flags of postponed insns.  */
    2035          323 :                       bitmap_set_bit (&lra_postponed_insns, INSN_UID (copy));
    2036              :                   }
    2037          299 :                 rtx_insn *copy = get_insns (), *last = get_last_insn ();
    2038          299 :                 end_sequence ();
    2039          299 :                 if (lra_dump_file != NULL)
    2040              :                   {
    2041           14 :                     fprintf (lra_dump_file, "    %s after in bb%d:\n", title,
    2042           14 :                              e->dest->index);
    2043           14 :                     dump_rtl_slim (lra_dump_file, copy, NULL, -1, 0);
    2044              :                   }
    2045              :                 /* Use the right emit func for setting up BB_END/BB_HEAD: */
    2046          299 :                 if (BB_END (e->dest) == PREV_INSN (tmp))
    2047            0 :                   emit_insn_after_noloc (copy, PREV_INSN (tmp), e->dest);
    2048              :                 else
    2049          299 :                   emit_insn_before_noloc (copy, tmp, e->dest);
    2050          299 :                 push_insns (last, PREV_INSN (copy));
    2051          299 :                 setup_sp_offset (copy, last);
    2052              :                 /* We can ignore BB live info here as it and reg notes
    2053              :                    will be updated before the next assignment
    2054              :                    sub-pass. */
    2055              :               }
    2056          248 :           for (rtx_insn *curr = after; curr != NULL_RTX; curr = NEXT_INSN (curr))
    2057              :             /* Clear flags of postponed insns which will be absent in the
    2058              :                result code.  */
    2059          127 :             bitmap_clear_bit (&lra_postponed_insns, INSN_UID (curr));
    2060              :         }
    2061              :     }
    2062      7650368 :   if (lra_dump_file != NULL)
    2063           99 :     fprintf (lra_dump_file, "\n");
    2064      7650368 :   if (cfun->can_throw_non_call_exceptions)
    2065              :     {
    2066      1901288 :       rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
    2067      1901288 :       if (note && !insn_could_throw_p (insn))
    2068          338 :         remove_note (insn, note);
    2069              :     }
    2070              : }
    2071              : 
    2072              : 
    2073              : /* Replace all references to register OLD_REGNO in *LOC with pseudo
    2074              :    register NEW_REG.  Try to simplify subreg of constant if SUBREG_P.
    2075              :    DEBUG_P is if LOC is within a DEBUG_INSN.  Return true if any
    2076              :    change was made.  */
    2077              : bool
    2078     27163333 : lra_substitute_pseudo (rtx *loc, int old_regno, rtx new_reg, bool subreg_p,
    2079              :                        bool debug_p)
    2080              : {
    2081     27163333 :   rtx x = *loc;
    2082     27163333 :   bool result = false;
    2083     27163333 :   enum rtx_code code;
    2084     27163333 :   const char *fmt;
    2085     27163333 :   int i, j;
    2086              : 
    2087     27163333 :   if (x == NULL_RTX)
    2088              :     return false;
    2089              : 
    2090     23005982 :   code = GET_CODE (x);
    2091     23005982 :   if (code == SUBREG && subreg_p)
    2092              :     {
    2093            0 :       rtx subst, inner = SUBREG_REG (x);
    2094              :       /* Transform subreg of constant while we still have inner mode
    2095              :          of the subreg.  The subreg internal should not be an insn
    2096              :          operand.  */
    2097            0 :       if (REG_P (inner) && (int) REGNO (inner) == old_regno
    2098            0 :           && CONSTANT_P (new_reg)
    2099            0 :           && (subst = simplify_subreg (GET_MODE (x), new_reg, GET_MODE (inner),
    2100            0 :                                        SUBREG_BYTE (x))) != NULL_RTX)
    2101              :         {
    2102            0 :           *loc = subst;
    2103            0 :           return true;
    2104              :         }
    2105              : 
    2106              :     }
    2107     23005982 :   else if (code == REG && (int) REGNO (x) == old_regno)
    2108              :     {
    2109      5218830 :       machine_mode mode = GET_MODE (x);
    2110      5218830 :       machine_mode inner_mode = GET_MODE (new_reg);
    2111              : 
    2112      5218830 :       if (mode != inner_mode
    2113           99 :           && ! (CONST_SCALAR_INT_P (new_reg) && SCALAR_INT_MODE_P (mode)))
    2114              :         {
    2115           99 :           poly_uint64 offset = 0;
    2116           99 :           if (partial_subreg_p (mode, inner_mode)
    2117           99 :               && SCALAR_INT_MODE_P (inner_mode))
    2118           99 :             offset = subreg_lowpart_offset (mode, inner_mode);
    2119           99 :           if (debug_p)
    2120           99 :             new_reg = gen_rtx_raw_SUBREG (mode, new_reg, offset);
    2121              :           else
    2122            0 :             new_reg = gen_rtx_SUBREG (mode, new_reg, offset);
    2123              :         }
    2124      5218830 :       *loc = new_reg;
    2125      5218830 :       return true;
    2126              :     }
    2127              : 
    2128              :   /* Scan all the operand sub-expressions.  */
    2129     17787152 :   fmt = GET_RTX_FORMAT (code);
    2130     67930180 :   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
    2131              :     {
    2132     50143028 :       if (fmt[i] == 'e')
    2133              :         {
    2134     22584915 :           if (debug_p
    2135     22584915 :               && i == 0
    2136              :               && (code == SUBREG
    2137       394569 :                   || code == ZERO_EXTEND
    2138              :                   || code == SIGN_EXTEND
    2139              :                   || code == FLOAT
    2140              :                   || code == UNSIGNED_FLOAT))
    2141              :             {
    2142        55561 :               rtx y = XEXP (x, 0);
    2143        55561 :               if (lra_substitute_pseudo (&y, old_regno,
    2144              :                                          new_reg, subreg_p, debug_p))
    2145              :                 {
    2146        28823 :                   result = true;
    2147        28823 :                   if (CONST_SCALAR_INT_P (y))
    2148              :                     {
    2149            0 :                       if (code == SUBREG)
    2150            0 :                         y = simplify_subreg (GET_MODE (x), y,
    2151            0 :                                              GET_MODE (SUBREG_REG (x)),
    2152            0 :                                              SUBREG_BYTE (x));
    2153              :                       else
    2154            0 :                         y = simplify_unary_operation (code, GET_MODE (x), y,
    2155            0 :                                                       GET_MODE (XEXP (x, 0)));
    2156            0 :                       if (y)
    2157            0 :                         *loc = y;
    2158              :                       else
    2159            0 :                         *loc = gen_rtx_CLOBBER (GET_MODE (x), const0_rtx);
    2160              :                     }
    2161              :                   else
    2162        28823 :                     XEXP (x, 0) = y;
    2163              :                 }
    2164        55561 :             }
    2165     22529354 :           else if (lra_substitute_pseudo (&XEXP (x, i), old_regno,
    2166              :                                           new_reg, subreg_p, debug_p))
    2167     50143028 :             result = true;
    2168              :         }
    2169     27558113 :       else if (fmt[i] == 'E')
    2170              :         {
    2171       613426 :           for (j = XVECLEN (x, i) - 1; j >= 0; j--)
    2172       421087 :             if (lra_substitute_pseudo (&XVECEXP (x, i, j), old_regno,
    2173              :                                        new_reg, subreg_p, debug_p))
    2174       170366 :               result = true;
    2175              :         }
    2176              :     }
    2177              :   return result;
    2178              : }
    2179              : 
    2180              : /* Call lra_substitute_pseudo within an insn.  Try to simplify subreg
    2181              :    of constant if SUBREG_P.  This won't update the insn ptr, just the
    2182              :    contents of the insn.  */
    2183              : bool
    2184      2612932 : lra_substitute_pseudo_within_insn (rtx_insn *insn, int old_regno,
    2185              :                                    rtx new_reg, bool subreg_p)
    2186              : {
    2187      2612932 :   rtx loc = insn;
    2188      2612932 :   return lra_substitute_pseudo (&loc, old_regno, new_reg, subreg_p,
    2189      2612932 :                                 DEBUG_INSN_P (insn));
    2190              : }
    2191              : 
    2192              : 
    2193              : 
    2194              : /* Return new register of the same mode as ORIGINAL of class ALL_REGS.
    2195              :    Used in ira_remove_scratches.  */
    2196              : static rtx
    2197         8963 : get_scratch_reg (rtx original)
    2198              : {
    2199         8963 :   return lra_create_new_reg (GET_MODE (original), original, ALL_REGS,
    2200         8963 :                              NULL, NULL);
    2201              : }
    2202              : 
    2203              : /* Remove all insn scratches in INSN.  */
    2204              : static void
    2205    141828008 : remove_insn_scratches (rtx_insn *insn)
    2206              : {
    2207    141828008 :   if (ira_remove_insn_scratches (insn, true, lra_dump_file, get_scratch_reg))
    2208         8704 :     df_insn_rescan (insn);
    2209    141828008 : }
    2210              : 
    2211              : /* Remove all insn scratches in the current function.  */
    2212              : static void
    2213      1480947 : remove_scratches (void)
    2214              : {
    2215      1480947 :   basic_block bb;
    2216      1480947 :   rtx_insn *insn;
    2217              : 
    2218     16022362 :   FOR_EACH_BB_FN (bb, cfun)
    2219    175513465 :     FOR_BB_INSNS (bb, insn)
    2220    160972050 :       if (INSN_P (insn))
    2221    134155865 :         remove_insn_scratches (insn);
    2222      1480947 : }
    2223              : 
    2224              : /* Function checks RTL for correctness.  If FINAL_P is true, it is
    2225              :    done at the end of LRA and the check is more rigorous.  */
    2226              : static void
    2227      2961854 : check_rtl (bool final_p)
    2228              : {
    2229      2961854 :   basic_block bb;
    2230      2961854 :   rtx_insn *insn;
    2231              : 
    2232      2961854 :   lra_assert (! final_p || reload_completed);
    2233     32046233 :   FOR_EACH_BB_FN (bb, cfun)
    2234    349669239 :     FOR_BB_INSNS (bb, insn)
    2235    320584860 :     if (NONDEBUG_INSN_P (insn)
    2236    168290093 :         && GET_CODE (PATTERN (insn)) != USE
    2237              :         && GET_CODE (PATTERN (insn)) != CLOBBER
    2238    320584860 :         && GET_CODE (PATTERN (insn)) != ASM_INPUT)
    2239              :       {
    2240    166685601 :         if (final_p)
    2241              :           {
    2242     81769476 :             extract_constrain_insn (insn);
    2243     81769476 :             continue;
    2244              :           }
    2245              :         /* LRA code is based on assumption that all addresses can be
    2246              :            correctly decomposed.  LRA can generate reloads for
    2247              :            decomposable addresses.  The decomposition code checks the
    2248              :            correctness of the addresses.  So we don't need to check
    2249              :            the addresses here.  Don't call insn_invalid_p here, it can
    2250              :            change the code at this stage.  */
    2251     84916125 :         if (recog_memoized (insn) < 0 && asm_noperands (PATTERN (insn)) < 0)
    2252            0 :           fatal_insn_not_found (insn);
    2253              :       }
    2254      2961854 : }
    2255              : 
    2256              : /* Determine if the current function has an exception receiver block
    2257              :    that reaches the exit block via non-exceptional edges  */
    2258              : static bool
    2259          858 : has_nonexceptional_receiver (void)
    2260              : {
    2261          858 :   edge e;
    2262          858 :   edge_iterator ei;
    2263          858 :   basic_block *tos, *worklist, bb;
    2264              : 
    2265              :   /* If we're not optimizing, then just err on the safe side.  */
    2266          858 :   if (!optimize)
    2267              :     return true;
    2268              : 
    2269              :   /* First determine which blocks can reach exit via normal paths.  */
    2270          730 :   tos = worklist = XNEWVEC (basic_block, n_basic_blocks_for_fn (cfun) + 1);
    2271              : 
    2272         5418 :   FOR_EACH_BB_FN (bb, cfun)
    2273         4688 :     bb->flags &= ~BB_REACHABLE;
    2274              : 
    2275              :   /* Place the exit block on our worklist.  */
    2276          730 :   EXIT_BLOCK_PTR_FOR_FN (cfun)->flags |= BB_REACHABLE;
    2277          730 :   *tos++ = EXIT_BLOCK_PTR_FOR_FN (cfun);
    2278              : 
    2279              :   /* Iterate: find everything reachable from what we've already seen.  */
    2280         2943 :   while (tos != worklist)
    2281              :     {
    2282         2784 :       bb = *--tos;
    2283              : 
    2284         5007 :       FOR_EACH_EDGE (e, ei, bb->preds)
    2285         2794 :         if (e->flags & EDGE_ABNORMAL)
    2286              :           {
    2287          571 :             free (worklist);
    2288          571 :             return true;
    2289              :           }
    2290              :         else
    2291              :           {
    2292         2223 :             basic_block src = e->src;
    2293              : 
    2294         2223 :             if (!(src->flags & BB_REACHABLE))
    2295              :               {
    2296         2130 :                 src->flags |= BB_REACHABLE;
    2297         2130 :                 *tos++ = src;
    2298              :               }
    2299              :           }
    2300              :     }
    2301          159 :   free (worklist);
    2302              :   /* No exceptional block reached exit unexceptionally.  */
    2303          159 :   return false;
    2304              : }
    2305              : 
    2306              : /* Remove all REG_DEAD and REG_UNUSED notes and regenerate REG_INC.
    2307              :    We change pseudos by hard registers without notification of DF and
    2308              :    that can make the notes obsolete.  DF-infrastructure does not deal
    2309              :    with REG_INC notes -- so we should regenerate them here.  */
    2310              : static void
    2311      1480947 : update_inc_notes (void)
    2312              : {
    2313      1480947 :   rtx *pnote;
    2314      1480947 :   basic_block bb;
    2315      1480947 :   rtx_insn *insn;
    2316              : 
    2317     16022362 :   FOR_EACH_BB_FN (bb, cfun)
    2318    174154499 :     FOR_BB_INSNS (bb, insn)
    2319    159613084 :     if (NONDEBUG_INSN_P (insn))
    2320              :       {
    2321     82567303 :         pnote = &REG_NOTES (insn);
    2322    169389211 :         while (*pnote != 0)
    2323              :           {
    2324     86821908 :             if (REG_NOTE_KIND (*pnote) == REG_DEAD
    2325     38443277 :                 || REG_NOTE_KIND (*pnote) == REG_UNUSED
    2326     26036738 :                 || REG_NOTE_KIND (*pnote) == REG_INC)
    2327     60785170 :               *pnote = XEXP (*pnote, 1);
    2328              :             else
    2329     26036738 :               pnote = &XEXP (*pnote, 1);
    2330              :           }
    2331              : 
    2332              :         if (AUTO_INC_DEC)
    2333              :           add_auto_inc_notes (insn, PATTERN (insn));
    2334              :       }
    2335      1480947 : }
    2336              : 
    2337              : /* Set to true while in LRA.  */
    2338              : bool lra_in_progress = false;
    2339              : 
    2340              : /* Start of pseudo regnos before the LRA.  */
    2341              : int lra_new_regno_start;
    2342              : 
    2343              : /* Start of reload pseudo regnos before the new spill pass.  */
    2344              : int lra_constraint_new_regno_start;
    2345              : 
    2346              : /* Avoid spilling pseudos with regno more than the following value if
    2347              :    it is possible.  */
    2348              : int lra_bad_spill_regno_start;
    2349              : 
    2350              : /* A pseudo of Pmode.  */
    2351              : rtx lra_pmode_pseudo;
    2352              : 
    2353              : /* Inheritance pseudo regnos before the new spill pass.  */
    2354              : bitmap_head lra_inheritance_pseudos;
    2355              : 
    2356              : /* Split regnos before the new spill pass.  */
    2357              : bitmap_head lra_split_regs;
    2358              : 
    2359              : /* Reload pseudo regnos before the new assignment pass which still can
    2360              :    be spilled after the assignment pass as memory is also accepted in
    2361              :    insns for the reload pseudos.  */
    2362              : bitmap_head lra_optional_reload_pseudos;
    2363              : 
    2364              : /* Pseudo regnos used for subreg reloads before the new assignment
    2365              :    pass.  Such pseudos still can be spilled after the assignment
    2366              :    pass.  */
    2367              : bitmap_head lra_subreg_reload_pseudos;
    2368              : 
    2369              : /* UIDs of reload insns which should be processed after assigning the reload
    2370              :    pseudos.  We need to do this when reload pseudo should be a general reg but
    2371              :    we have different mov insns for different subsets of general regs, e.g. hi
    2372              :    and lo regs of arm thumb.  Such way we can guarantee finding regs for the
    2373              :    reload pseudos of asm insn which can have a lot of operands (general regs in
    2374              :    our example).  */
    2375              : bitmap_head lra_postponed_insns;
    2376              : 
    2377              : /* File used for output of LRA debug information.  */
    2378              : FILE *lra_dump_file;
    2379              : 
    2380              : /* How verbose should be the debug information. */
    2381              : int lra_verbose;
    2382              : 
    2383              : /* True if we split hard reg after the last constraint sub-pass.  */
    2384              : bool lra_hard_reg_split_p;
    2385              : 
    2386              : /* True if we found an asm error.  */
    2387              : bool lra_asm_error_p;
    2388              : 
    2389              : /* True if we should try spill into registers of different classes
    2390              :    instead of memory.  */
    2391              : bool lra_reg_spill_p;
    2392              : 
    2393              : /* Set up value LRA_REG_SPILL_P.  */
    2394              : static void
    2395      1480947 : setup_reg_spill_flag (void)
    2396              : {
    2397      1480947 :   int cl, mode;
    2398              : 
    2399      1480947 :   if (targetm.spill_class != NULL)
    2400     51833145 :     for (cl = 0; cl < (int) LIM_REG_CLASSES; cl++)
    2401   6294024750 :       for (mode = 0; mode < MAX_MACHINE_MODE; mode++)
    2402   6243672552 :         if (targetm.spill_class ((enum reg_class) cl,
    2403              :                                  (machine_mode) mode) != NO_REGS)
    2404              :           {
    2405            0 :             lra_reg_spill_p = true;
    2406            0 :             return;
    2407              :           }
    2408      1480947 :   lra_reg_spill_p = false;
    2409              : }
    2410              : 
    2411              : /* True if the current function is too big to use regular algorithms
    2412              :    in LRA. In other words, we should use simpler and faster algorithms
    2413              :    in LRA.  It also means we should not worry about generation code
    2414              :    for caller saves.  The value is set up in IRA.  */
    2415              : bool lra_simple_p;
    2416              : 
    2417              : /* Major LRA entry function.  F is a file should be used to dump LRA
    2418              :    debug info with given verbosity.  */
    2419              : void
    2420      1480947 : lra (FILE *f, int verbose)
    2421              : {
    2422      1480947 :   int i;
    2423      1480947 :   bool live_p, inserted_p;
    2424              : 
    2425      1480947 :   lra_dump_file = f;
    2426      1480947 :   lra_verbose = verbose;
    2427      1480947 :   lra_asm_error_p = false;
    2428      1607335 :   lra_pmode_pseudo = gen_reg_rtx (Pmode);
    2429              : 
    2430      1480947 :   timevar_push (TV_LRA);
    2431              : 
    2432              :   /* Make sure that the last insn is a note.  Some subsequent passes
    2433              :      need it.  */
    2434      1480947 :   emit_note (NOTE_INSN_DELETED);
    2435              : 
    2436      1480947 :   lra_no_alloc_regs = ira_no_alloc_regs;
    2437              : 
    2438      1480947 :   init_reg_info ();
    2439      1480947 :   expand_reg_info ();
    2440              : 
    2441      1480947 :   init_insn_recog_data ();
    2442              : 
    2443              :   /* Some quick check on RTL generated by previous passes.  */
    2444      1480947 :   if (flag_checking)
    2445      1480927 :     check_rtl (false);
    2446              : 
    2447      1480947 :   lra_in_progress = true;
    2448              : 
    2449      1480947 :   lra_live_range_iter = lra_coalesce_iter = lra_constraint_iter = 0;
    2450      1480947 :   lra_assignment_iter = lra_assignment_iter_after_spill = 0;
    2451      1480947 :   lra_inheritance_iter = lra_undo_inheritance_iter = 0;
    2452      1480947 :   lra_rematerialization_iter = 0;
    2453              : 
    2454      1480947 :   setup_reg_spill_flag ();
    2455              : 
    2456              :   /* Function remove_scratches can creates new pseudos for clobbers --
    2457              :      so set up lra_constraint_new_regno_start before its call to
    2458              :      permit changing reg classes for pseudos created by this
    2459              :      simplification.  */
    2460      1480947 :   lra_constraint_new_regno_start = lra_new_regno_start = max_reg_num ();
    2461      1480947 :   lra_bad_spill_regno_start = INT_MAX;
    2462      1480947 :   remove_scratches ();
    2463              : 
    2464              :   /* A function that has a non-local label that can reach the exit
    2465              :      block via non-exceptional paths must save all call-saved
    2466              :      registers.  */
    2467      1480947 :   if (cfun->has_nonlocal_label && has_nonexceptional_receiver ())
    2468          699 :     crtl->saves_all_registers = 1;
    2469              : 
    2470      1480947 :   if (crtl->saves_all_registers)
    2471        68169 :     for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
    2472        67436 :       if (!crtl->abi->clobbers_full_reg_p (i)
    2473         6561 :           && !fixed_regs[i]
    2474        67436 :           && !LOCAL_REGNO (i))
    2475         4362 :         df_set_regs_ever_live (i, true);
    2476              : 
    2477              :   /* We don't DF from now and avoid its using because it is to
    2478              :      expensive when a lot of RTL changes are made.  */
    2479      1480947 :   df_set_flags (DF_NO_INSN_RESCAN);
    2480      1480947 :   lra_constraint_insn_stack.create (get_max_uid ());
    2481      1480947 :   lra_constraint_insn_stack_bitmap = sbitmap_alloc (get_max_uid ());
    2482      1480947 :   bitmap_clear (lra_constraint_insn_stack_bitmap);
    2483      1480947 :   lra_live_ranges_init ();
    2484      1480947 :   lra_constraints_init ();
    2485      1480947 :   lra_curr_reload_num = 0;
    2486      1480947 :   push_insns (get_last_insn (), NULL);
    2487              :   /* It is needed for the 1st coalescing.  */
    2488      1480947 :   bitmap_initialize (&lra_inheritance_pseudos, &reg_obstack);
    2489      1480947 :   bitmap_initialize (&lra_split_regs, &reg_obstack);
    2490      1480947 :   bitmap_initialize (&lra_optional_reload_pseudos, &reg_obstack);
    2491      1480947 :   bitmap_initialize (&lra_subreg_reload_pseudos, &reg_obstack);
    2492      1480947 :   bitmap_initialize (&lra_postponed_insns, &reg_obstack);
    2493      1480947 :   live_p = false;
    2494      1480947 :   if (maybe_ne (get_frame_size (), 0) && crtl->stack_alignment_needed)
    2495              :     /* If we have a stack frame, we must align it now.  The stack size
    2496              :        may be a part of the offset computation for register
    2497              :        elimination.  */
    2498       598780 :     assign_stack_local (BLKmode, 0, crtl->stack_alignment_needed);
    2499      1480947 :   lra_init_equiv ();
    2500      3226660 :   for (;;)
    2501              :     {
    2502      3226660 :       for (;;)
    2503              :         {
    2504      3226660 :           bool reloads_p = lra_constraints (lra_constraint_iter == 0);
    2505              :           /* Constraint transformations may result in that eliminable
    2506              :              hard regs become uneliminable and pseudos which use them
    2507              :              should be spilled.  It is better to do it before pseudo
    2508              :              assignments.
    2509              : 
    2510              :              For example, rs6000 can make
    2511              :              RS6000_PIC_OFFSET_TABLE_REGNUM uneliminable if we started
    2512              :              to use a constant pool.  */
    2513      3226660 :           lra_eliminate (false, false);
    2514              :           /* We should try to assign hard registers to scratches even
    2515              :              if there were no RTL transformations in lra_constraints.
    2516              :              Also we should check IRA assignments on the first
    2517              :              iteration as they can be wrong because of early clobbers
    2518              :              operands which are ignored in IRA.  */
    2519      3226660 :           if (! reloads_p && lra_constraint_iter > 1)
    2520              :             {
    2521              :               /* Stack is not empty here only when there are changes
    2522              :                  during the elimination sub-pass.  */
    2523      1679247 :               if (bitmap_empty_p (lra_constraint_insn_stack_bitmap))
    2524              :                 break;
    2525              :               else
    2526              :                 /* If there are no reloads but changing due
    2527              :                    elimination, restart the constraint sub-pass
    2528              :                    first.  */
    2529            0 :                 continue;
    2530              :             }
    2531              :           /* Do inheritance only for regular algorithms.  */
    2532      1547413 :           if (! lra_simple_p)
    2533      1547407 :             lra_inheritance ();
    2534      1547413 :           if (live_p)
    2535        66466 :             lra_clear_live_ranges ();
    2536      1547413 :           bool fails_p;
    2537      1547413 :           lra_hard_reg_split_p = false;
    2538      1547413 :           int split_fails_num = 0;
    2539      1549612 :           do
    2540              :             {
    2541              :               /* We need live ranges for lra_assign -- so build them.
    2542              :                  But don't remove dead insns or change global live
    2543              :                  info as we can undo inheritance transformations after
    2544              :                  inheritance pseudo assigning.  */
    2545      1549612 :               lra_create_live_ranges (true, !lra_simple_p);
    2546      1549612 :               live_p = true;
    2547              :               /* If we don't spill non-reload and non-inheritance
    2548              :                  pseudos, there is no sense to run memory-memory move
    2549              :                  coalescing.  If inheritance pseudos were spilled, the
    2550              :                  memory-memory moves involving them will be removed by
    2551              :                  pass undoing inheritance.  */
    2552      1549612 :               if (lra_simple_p || lra_hard_reg_split_p)
    2553         2205 :                 lra_assign (fails_p);
    2554              :               else
    2555              :                 {
    2556      1547407 :                   bool spill_p = !lra_assign (fails_p);
    2557              : 
    2558      1547407 :                   if (lra_undo_inheritance ())
    2559       111038 :                     live_p = false;
    2560      1547407 :                   if (spill_p && ! fails_p)
    2561              :                     {
    2562        26778 :                       if (! live_p)
    2563              :                         {
    2564        12947 :                           lra_create_live_ranges (true, true);
    2565        12947 :                           live_p = true;
    2566              :                         }
    2567        26778 :                       if (lra_coalesce ())
    2568              :                         live_p = false;
    2569              :                     }
    2570      1546678 :                   if (! live_p)
    2571        98820 :                     lra_clear_live_ranges ();
    2572              :                 }
    2573      1549612 :               if (fails_p)
    2574              :                 {
    2575              :                   /* It is a very rare case.  It is the last hope to
    2576              :                      split a hard regno live range for a reload
    2577              :                      pseudo.  */
    2578         2524 :                   if (live_p)
    2579         2521 :                     lra_clear_live_ranges ();
    2580         2524 :                   live_p = false;
    2581              :                   /* See a comment for LRA_MAX_FAILED_SPLITS definition.  */
    2582         2524 :                   bool last_failed_split_p
    2583              :                     = split_fails_num > LRA_MAX_FAILED_SPLITS;
    2584         2524 :                   if (! lra_split_hard_reg_for (last_failed_split_p))
    2585              :                     {
    2586         2426 :                       if (last_failed_split_p)
    2587              :                         break;
    2588         2235 :                       split_fails_num++;
    2589              :                     }
    2590         2333 :                   lra_hard_reg_split_p = true;
    2591              :                 }
    2592              :             }
    2593      1549421 :           while (fails_p && !lra_asm_error_p);
    2594      1547413 :           if (! live_p) {
    2595              :             /* We need the correct reg notes for work of constraint sub-pass.  */
    2596        99142 :             lra_create_live_ranges (true, true);
    2597        99142 :             live_p = true;
    2598              :           }
    2599      1547413 :           bitmap_iterator bi;
    2600      1547413 :           unsigned int uid;
    2601      1559631 :           EXECUTE_IF_SET_IN_BITMAP (&lra_postponed_insns, 0, uid, bi)
    2602        12218 :             lra_push_insn_by_uid (uid);
    2603      1547413 :           bitmap_clear (&lra_postponed_insns);
    2604              :         }
    2605              :       /* Don't clear optional reloads bitmap until all constraints are
    2606              :          satisfied as we need to differ them from regular reloads.  */
    2607      1679247 :       bitmap_clear (&lra_optional_reload_pseudos);
    2608      1679247 :       bitmap_clear (&lra_subreg_reload_pseudos);
    2609      1679247 :       bitmap_clear (&lra_inheritance_pseudos);
    2610      1679247 :       bitmap_clear (&lra_split_regs);
    2611      1679247 :       if (! live_p)
    2612              :         {
    2613              :           /* We need full live info for spilling pseudos into
    2614              :              registers instead of memory.  */
    2615            0 :           lra_create_live_ranges (lra_reg_spill_p, true);
    2616            0 :           live_p = true;
    2617              :         }
    2618              :       /* We should check necessity for spilling here as the above live
    2619              :          range pass can remove spilled pseudos.  */
    2620      1679247 :       if (! lra_need_for_spills_p ())
    2621              :         break;
    2622              :       /* Now we know what pseudos should be spilled.  Try to
    2623              :          rematerialize them first.  */
    2624       198598 :       if (lra_remat ())
    2625              :         {
    2626              :           /* We need full live info -- see the comment above.  We also might
    2627              :              need live info if we have a pseudo assigned to hard frame pointer
    2628              :              reg and will need FP for usual purposes.  */
    2629         3168 :           lra_create_live_ranges (lra_reg_spill_p || lra_fp_pseudo_p (),
    2630              :                                   true);
    2631         1853 :           live_p = true;
    2632         1853 :           if (! lra_need_for_spills_p ())
    2633              :             {
    2634          298 :               if (lra_need_for_scratch_reg_p ())
    2635            0 :                 continue;
    2636              :               break;
    2637              :             }
    2638              :         }
    2639       198300 :       lra_spill ();
    2640              :       /* Assignment of stack slots changes elimination offsets for
    2641              :          some eliminations.  So update the offsets here.  */
    2642       198300 :       lra_eliminate (false, false);
    2643       198300 :       lra_constraint_new_regno_start = max_reg_num ();
    2644       198300 :       if (lra_bad_spill_regno_start == INT_MAX
    2645       198215 :           && lra_inheritance_iter > LRA_MAX_INHERITANCE_PASSES
    2646         1764 :           && lra_rematerialization_iter > LRA_MAX_REMATERIALIZATION_PASSES)
    2647              :         /* After switching off inheritance and rematerialization
    2648              :            passes, avoid spilling reload pseudos will be created to
    2649              :            prevent LRA cycling in some complicated cases.  */
    2650            2 :         lra_bad_spill_regno_start = lra_constraint_new_regno_start;
    2651       198300 :       lra_assignment_iter_after_spill = 0;
    2652              :     }
    2653      1480947 :   ira_restore_scratches (lra_dump_file);
    2654      1480947 :   lra_eliminate (true, false);
    2655      1480947 :   lra_final_code_change ();
    2656      1480947 :   lra_in_progress = false;
    2657      1480947 :   if (live_p)
    2658      1480947 :     lra_clear_live_ranges ();
    2659      1480947 :   lra_live_ranges_finish ();
    2660      1480947 :   lra_constraints_finish ();
    2661      1480947 :   finish_reg_info ();
    2662      1480947 :   sbitmap_free (lra_constraint_insn_stack_bitmap);
    2663      1480947 :   lra_constraint_insn_stack.release ();
    2664      1480947 :   finish_insn_recog_data ();
    2665      1480947 :   lra_finish_equiv ();
    2666      1480947 :   regstat_free_n_sets_and_refs ();
    2667      1480947 :   regstat_free_ri ();
    2668      1480947 :   reload_completed = 1;
    2669      1480947 :   update_inc_notes ();
    2670              : 
    2671      1480947 :   inserted_p = fixup_abnormal_edges ();
    2672              : 
    2673              :   /* Split basic blocks if we've possibly turned single trapping insn
    2674              :      into multiple ones or otherwise the backend requested to do so.  */
    2675      1480947 :   if (cfun->can_throw_non_call_exceptions
    2676      1218078 :       || cfun->split_basic_blocks_after_reload)
    2677              :     {
    2678       262869 :       auto_sbitmap blocks (last_basic_block_for_fn (cfun));
    2679       262869 :       bitmap_ones (blocks);
    2680       262869 :       find_many_sub_basic_blocks (blocks);
    2681       262869 :     }
    2682              : 
    2683      1480947 :   if (inserted_p)
    2684         3238 :     commit_edge_insertions ();
    2685              : 
    2686              :   /* Subsequent passes expect that rtl is unshared, so unshare everything
    2687              :      here.  */
    2688      1480947 :   unshare_all_rtl_again (get_insns ());
    2689              : 
    2690      1480947 :   if (flag_checking)
    2691      1480927 :     check_rtl (true);
    2692              : 
    2693      1480947 :   timevar_pop (TV_LRA);
    2694      1480947 : }
    2695              : 
    2696              : /* Called once per compiler to initialize LRA data once.  */
    2697              : void
    2698       211466 : lra_init_once (void)
    2699              : {
    2700       211466 :   init_insn_code_data_once ();
    2701       211466 : }
    2702              : 
    2703              : /* Called once per compiler to finish LRA data which are initialize
    2704              :    once.  */
    2705              : void
    2706       278943 : lra_finish_once (void)
    2707              : {
    2708       278943 :   finish_insn_code_data_once ();
    2709       278943 : }
        

Generated by: LCOV version 2.4-beta

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