LCOV - code coverage report
Current view: top level - gcc - recog.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 86.7 % 1898 1645
Test Date: 2026-06-20 15:32:29 Functions: 87.0 % 123 107
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Subroutines used by or related to instruction recognition.
       2              :    Copyright (C) 1987-2026 Free Software Foundation, Inc.
       3              : 
       4              : This file is part of GCC.
       5              : 
       6              : GCC is free software; you can redistribute it and/or modify it under
       7              : the terms of the GNU General Public License as published by the Free
       8              : Software Foundation; either version 3, or (at your option) any later
       9              : version.
      10              : 
      11              : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      12              : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      13              : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      14              : for more details.
      15              : 
      16              : You should have received a copy of the GNU General Public License
      17              : along with GCC; see the file COPYING3.  If not see
      18              : <http://www.gnu.org/licenses/>.  */
      19              : 
      20              : 
      21              : #include "config.h"
      22              : #include "system.h"
      23              : #include "coretypes.h"
      24              : #include "backend.h"
      25              : #include "target.h"
      26              : #include "rtl.h"
      27              : #include "tree.h"
      28              : #include "stmt.h"
      29              : #include "cfghooks.h"
      30              : #include "df.h"
      31              : #include "memmodel.h"
      32              : #include "tm_p.h"
      33              : #include "insn-config.h"
      34              : #include "regs.h"
      35              : #include "emit-rtl.h"
      36              : #include "recog.h"
      37              : #include "insn-attr.h"
      38              : #include "addresses.h"
      39              : #include "cfgrtl.h"
      40              : #include "cfgbuild.h"
      41              : #include "cfgcleanup.h"
      42              : #include "reload.h"
      43              : #include "tree-pass.h"
      44              : #include "function-abi.h"
      45              : #include "rtl-iter.h"
      46              : 
      47              : #ifndef STACK_POP_CODE
      48              : #if STACK_GROWS_DOWNWARD
      49              : #define STACK_POP_CODE POST_INC
      50              : #else
      51              : #define STACK_POP_CODE POST_DEC
      52              : #endif
      53              : #endif
      54              : 
      55              : static void validate_replace_rtx_1 (rtx *, rtx, rtx, rtx_insn *, bool);
      56              : static void validate_replace_src_1 (rtx *, void *);
      57              : static rtx_insn *split_insn (rtx_insn *);
      58              : 
      59              : struct target_recog default_target_recog;
      60              : #if SWITCHABLE_TARGET
      61              : struct target_recog *this_target_recog = &default_target_recog;
      62              : #endif
      63              : 
      64              : /* Nonzero means allow operands to be volatile.
      65              :    This should be 0 if you are generating rtl, such as if you are calling
      66              :    the functions in optabs.cc and expmed.cc (most of the time).
      67              :    This should be 1 if all valid insns need to be recognized,
      68              :    such as in reginfo.cc and final.cc and reload.cc.
      69              : 
      70              :    init_recog and init_recog_no_volatile are responsible for setting this.  */
      71              : 
      72              : int volatile_ok;
      73              : 
      74              : struct recog_data_d recog_data;
      75              : 
      76              : /* Contains a vector of operand_alternative structures, such that
      77              :    operand OP of alternative A is at index A * n_operands + OP.
      78              :    Set up by preprocess_constraints.  */
      79              : const operand_alternative *recog_op_alt;
      80              : 
      81              : /* Used to provide recog_op_alt for asms.  */
      82              : static operand_alternative asm_op_alt[MAX_RECOG_OPERANDS
      83              :                                       * MAX_RECOG_ALTERNATIVES];
      84              : 
      85              : /* On return from `constrain_operands', indicate which alternative
      86              :    was satisfied.  */
      87              : 
      88              : int which_alternative;
      89              : 
      90              : /* True for inline asm operands with - constraint modifier.  */
      91              : bool raw_constraint_p;
      92              : 
      93              : /* Nonzero after end of reload pass.
      94              :    Set to 1 or 0 by toplev.cc.
      95              :    Controls the significance of (SUBREG (MEM)).  */
      96              : 
      97              : int reload_completed;
      98              : 
      99              : bool post_ra_split_completed;
     100              : 
     101              : /* Nonzero after thread_prologue_and_epilogue_insns has run.  */
     102              : int epilogue_completed;
     103              : 
     104              : /* Initialize data used by the function `recog'.
     105              :    This must be called once in the compilation of a function
     106              :    before any insn recognition may be done in the function.  */
     107              : 
     108              : void
     109      7820769 : init_recog_no_volatile (void)
     110              : {
     111      7820769 :   volatile_ok = 0;
     112      7820769 : }
     113              : 
     114              : void
     115     11631786 : init_recog (void)
     116              : {
     117     11631786 :   volatile_ok = 1;
     118     11631786 : }
     119              : 
     120              : 
     121              : /* Return true if labels in asm operands BODY are LABEL_REFs.  */
     122              : 
     123              : static bool
     124    103906614 : asm_labels_ok (rtx body)
     125              : {
     126    103906614 :   rtx asmop;
     127    103906614 :   int i;
     128              : 
     129    103906614 :   asmop = extract_asm_operands (body);
     130    103906614 :   if (asmop == NULL_RTX)
     131              :     return true;
     132              : 
     133       812799 :   for (i = 0; i < ASM_OPERANDS_LABEL_LENGTH (asmop); i++)
     134         7548 :     if (GET_CODE (ASM_OPERANDS_LABEL (asmop, i)) != LABEL_REF)
     135              :       return false;
     136              : 
     137              :   return true;
     138              : }
     139              : 
     140              : /* Check that X is an insn-body for an `asm' with operands
     141              :    and that the operands mentioned in it are legitimate.  */
     142              : 
     143              : bool
     144    103906614 : check_asm_operands (rtx x)
     145              : {
     146    103906614 :   int noperands;
     147    103906614 :   rtx *operands;
     148    103906614 :   const char **constraints;
     149    103906614 :   int i;
     150              : 
     151    103906614 :   if (!asm_labels_ok (x))
     152              :     return false;
     153              : 
     154              :   /* Post-reload, be more strict with things.  */
     155    103906614 :   if (reload_completed)
     156              :     {
     157              :       /* ??? Doh!  We've not got the wrapping insn.  Cook one up.  */
     158        32716 :       rtx_insn *insn = make_insn_raw (x);
     159        32716 :       extract_insn (insn);
     160        32716 :       constrain_operands (1, get_enabled_alternatives (insn));
     161        32716 :       return which_alternative >= 0;
     162              :     }
     163              : 
     164    103873898 :   noperands = asm_noperands (x);
     165    103873898 :   if (noperands < 0)
     166              :     return false;
     167       757877 :   if (noperands == 0)
     168              :     return true;
     169              : 
     170       644107 :   operands = XALLOCAVEC (rtx, noperands);
     171       644107 :   constraints = XALLOCAVEC (const char *, noperands);
     172              : 
     173       644107 :   decode_asm_operands (x, operands, NULL, constraints, NULL, NULL);
     174              : 
     175      3107440 :   for (i = 0; i < noperands; i++)
     176              :     {
     177      2747634 :       const char *c = constraints[i];
     178      2747634 :       if (c[0] == '%')
     179        12321 :         c++;
     180      2747634 :       if (! asm_operand_ok (operands[i], c, constraints))
     181              :         return false;
     182              :     }
     183              : 
     184              :   return true;
     185              : }
     186              : 
     187              : /* Static data for the next two routines.  */
     188              : 
     189              : struct change_t
     190              : {
     191              :   rtx object;
     192              :   int old_code;
     193              :   int old_len;
     194              :   bool unshare;
     195              :   rtx *loc;
     196              :   rtx old;
     197              : };
     198              : 
     199              : static change_t *changes;
     200              : static int changes_allocated;
     201              : 
     202              : static int num_changes = 0;
     203              : int undo_recog_changes::s_num_changes = 0;
     204              : 
     205              : /* Validate a proposed change to OBJECT.  LOC is the location in the rtl
     206              :    at which NEW_RTX will be placed.  If NEW_LEN is >= 0, XVECLEN (NEW_RTX, 0)
     207              :    will also be changed to NEW_LEN, which is no greater than the current
     208              :    XVECLEN.  If OBJECT is zero, no validation is done, the change is
     209              :    simply made.
     210              : 
     211              :    Two types of objects are supported:  If OBJECT is a MEM, memory_address_p
     212              :    will be called with the address and mode as parameters.  If OBJECT is
     213              :    an INSN, CALL_INSN, or JUMP_INSN, the insn will be re-recognized with
     214              :    the change in place.
     215              : 
     216              :    IN_GROUP is nonzero if this is part of a group of changes that must be
     217              :    performed as a group.  In that case, the changes will be stored.  The
     218              :    function `apply_change_group' will validate and apply the changes.
     219              : 
     220              :    If IN_GROUP is zero, this is a single change.  Try to recognize the insn
     221              :    or validate the memory reference with the change applied.  If the result
     222              :    is not valid for the machine, suppress the change and return false.
     223              :    Otherwise, perform the change and return true.  */
     224              : 
     225              : static bool
     226   1752687899 : validate_change_1 (rtx object, rtx *loc, rtx new_rtx, bool in_group,
     227              :                    bool unshare, int new_len = -1)
     228              : {
     229   1752687899 :   gcc_assert (!undo_recog_changes::is_active ());
     230   1752687899 :   rtx old = *loc;
     231              : 
     232              :   /* Single-element parallels aren't valid and won't match anything.
     233              :      Replace them with the single element.  */
     234   1752687899 :   if (new_len == 1 && GET_CODE (new_rtx) == PARALLEL)
     235              :     {
     236      6317107 :       new_rtx = XVECEXP (new_rtx, 0, 0);
     237      6317107 :       new_len = -1;
     238              :     }
     239              : 
     240              :   /* When a change is part of a group, callers expect to be able to change
     241              :      INSN_CODE after making the change and have the code reset to its old
     242              :      value by a later cancel_changes.  We therefore need to register group
     243              :      changes even if they're no-ops.  */
     244   1752687899 :   if (!in_group
     245    205597783 :       && (old == new_rtx || rtx_equal_p (old, new_rtx))
     246   1940499242 :       && (new_len < 0 || XVECLEN (new_rtx, 0) == new_len))
     247              :     return true;
     248              : 
     249   1564876556 :   gcc_assert ((in_group != 0 || num_changes == 0)
     250              :               && (new_len < 0 || new_rtx == *loc));
     251              : 
     252   1564876556 :   *loc = new_rtx;
     253              : 
     254              :   /* Save the information describing this change.  */
     255   1564876556 :   if (num_changes >= changes_allocated)
     256              :     {
     257       173545 :       if (changes_allocated == 0)
     258              :         /* This value allows for repeated substitutions inside complex
     259              :            indexed addresses, or changes in up to 5 insns.  */
     260       172286 :         changes_allocated = MAX_RECOG_OPERANDS * 5;
     261              :       else
     262         1259 :         changes_allocated *= 2;
     263              : 
     264       173545 :       changes = XRESIZEVEC (change_t, changes, changes_allocated);
     265              :     }
     266              : 
     267   1564876556 :   changes[num_changes].object = object;
     268   1564876556 :   changes[num_changes].loc = loc;
     269   1564876556 :   changes[num_changes].old = old;
     270   1564876556 :   changes[num_changes].old_len = (new_len >= 0 ? XVECLEN (new_rtx, 0) : -1);
     271   1564876556 :   changes[num_changes].unshare = unshare;
     272              : 
     273   1564876556 :   if (new_len >= 0)
     274     11340273 :     XVECLEN (new_rtx, 0) = new_len;
     275              : 
     276   1564876556 :   if (object && !MEM_P (object))
     277              :     {
     278              :       /* Set INSN_CODE to force rerecognition of insn.  Save old code in
     279              :          case invalid.  */
     280   1541169374 :       changes[num_changes].old_code = INSN_CODE (object);
     281   1541169374 :       INSN_CODE (object) = -1;
     282              :     }
     283              : 
     284   1564876556 :   num_changes++;
     285              : 
     286              :   /* If we are making a group of changes, return 1.  Otherwise, validate the
     287              :      change group we made.  */
     288              : 
     289   1564876556 :   if (in_group)
     290              :     return true;
     291              :   else
     292     17786440 :     return apply_change_group ();
     293              : }
     294              : 
     295              : /* Wrapper for validate_change_1 without the UNSHARE argument defaulting
     296              :    UNSHARE to false.  */
     297              : 
     298              : bool
     299   1453410742 : validate_change (rtx object, rtx *loc, rtx new_rtx, bool in_group)
     300              : {
     301   1453410742 :   return validate_change_1 (object, loc, new_rtx, in_group, false);
     302              : }
     303              : 
     304              : /* Wrapper for validate_change_1 without the UNSHARE argument defaulting
     305              :    UNSHARE to true.  */
     306              : 
     307              : bool
     308    281619777 : validate_unshare_change (rtx object, rtx *loc, rtx new_rtx, bool in_group)
     309              : {
     310    281619777 :   return validate_change_1 (object, loc, new_rtx, in_group, true);
     311              : }
     312              : 
     313              : /* Change XVECLEN (*LOC, 0) to NEW_LEN.  OBJECT, IN_GROUP and the return
     314              :    value are as for validate_change_1.  */
     315              : 
     316              : bool
     317     17657380 : validate_change_xveclen (rtx object, rtx *loc, int new_len, bool in_group)
     318              : {
     319     17657380 :   return validate_change_1 (object, loc, *loc, in_group, false, new_len);
     320              : }
     321              : 
     322              : /* Keep X canonicalized if some changes have made it non-canonical; only
     323              :    modifies the operands of X, not (for example) its code.  Simplifications
     324              :    are not the job of this routine.
     325              : 
     326              :    Return true if anything was changed.  */
     327              : bool
     328      1828215 : canonicalize_change_group (rtx_insn *insn, rtx x)
     329              : {
     330      1828215 :   if (COMMUTATIVE_P (x)
     331      1828215 :       && swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1)))
     332              :     {
     333              :       /* Oops, the caller has made X no longer canonical.
     334              :          Let's redo the changes in the correct order.  */
     335        96038 :       rtx tem = XEXP (x, 0);
     336        96038 :       validate_unshare_change (insn, &XEXP (x, 0), XEXP (x, 1), 1);
     337        96038 :       validate_unshare_change (insn, &XEXP (x, 1), tem, 1);
     338        96038 :       return true;
     339              :     }
     340              :   else
     341      1732177 :     return false;
     342              : }
     343              : 
     344              : /* Check if REG_INC argument in *data overlaps a stored REG.  */
     345              : 
     346              : static void
     347            0 : check_invalid_inc_dec (rtx reg, const_rtx, void *data)
     348              : {
     349            0 :   rtx *pinc = (rtx *) data;
     350            0 :   if (*pinc == NULL_RTX || MEM_P (reg))
     351              :     return;
     352            0 :   if (reg_overlap_mentioned_p (reg, *pinc))
     353            0 :     *pinc = NULL_RTX;
     354              : }
     355              : 
     356              : /* This subroutine of apply_change_group verifies whether the changes to INSN
     357              :    were valid; i.e. whether INSN can still be recognized.
     358              : 
     359              :    If IN_GROUP is true clobbers which have to be added in order to
     360              :    match the instructions will be added to the current change group.
     361              :    Otherwise the changes will take effect immediately.  */
     362              : 
     363              : bool
     364    472752626 : insn_invalid_p (rtx_insn *insn, bool in_group)
     365              : {
     366    472752626 :   rtx pat = PATTERN (insn);
     367    472752626 :   int num_clobbers = 0;
     368              :   /* If we are before reload and the pattern is a SET, see if we can add
     369              :      clobbers.  */
     370    472752626 :   int icode = recog (pat, insn,
     371    472752626 :                      (GET_CODE (pat) == SET
     372    393327122 :                       && ! reload_completed
     373    359809733 :                       && ! reload_in_progress)
     374              :                      ? &num_clobbers : 0);
     375    472752626 :   bool is_asm = icode < 0 && asm_noperands (PATTERN (insn)) >= 0;
     376              : 
     377              : 
     378              :   /* If this is an asm and the operand aren't legal, then fail.  Likewise if
     379              :      this is not an asm and the insn wasn't recognized.  */
     380       561389 :   if ((is_asm && ! check_asm_operands (PATTERN (insn)))
     381    472551992 :       || (!is_asm && icode < 0))
     382     17472630 :     return true;
     383              : 
     384              :   /* If we have to add CLOBBERs, fail if we have to add ones that reference
     385              :      hard registers since our callers can't know if they are live or not.
     386              :      Otherwise, add them.  */
     387    455279996 :   if (num_clobbers > 0)
     388              :     {
     389         1939 :       rtx newpat;
     390              : 
     391         1939 :       if (added_clobbers_hard_reg_p (icode))
     392              :         return true;
     393              : 
     394          643 :       newpat = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (num_clobbers + 1));
     395          643 :       XVECEXP (newpat, 0, 0) = pat;
     396          643 :       add_clobbers (newpat, icode);
     397          643 :       if (in_group)
     398          642 :         validate_change (insn, &PATTERN (insn), newpat, 1);
     399              :       else
     400            1 :         PATTERN (insn) = pat = newpat;
     401              :     }
     402              : 
     403              :   /* After reload, verify that all constraints are satisfied.  */
     404    455278700 :   if (reload_completed)
     405              :     {
     406     33528989 :       extract_insn (insn);
     407              : 
     408     33528989 :       if (! constrain_operands (1, get_preferred_alternatives (insn)))
     409              :         return true;
     410              :     }
     411              : 
     412              :   /* Punt if REG_INC argument overlaps some stored REG.  */
     413    455256098 :   for (rtx link = FIND_REG_INC_NOTE (insn, NULL_RTX);
     414    455256098 :        link; link = XEXP (link, 1))
     415              :     if (REG_NOTE_KIND (link) == REG_INC)
     416              :       {
     417              :         rtx reg = XEXP (link, 0);
     418              :         note_stores (insn, check_invalid_inc_dec, &reg);
     419              :         if (reg == NULL_RTX)
     420              :           return true;
     421              :       }
     422              : 
     423    455256098 :   INSN_CODE (insn) = icode;
     424    455256098 :   return false;
     425              : }
     426              : 
     427              : /* Return number of changes made and not validated yet.  */
     428              : int
     429      4727373 : num_changes_pending (void)
     430              : {
     431      4727373 :   return num_changes;
     432              : }
     433              : 
     434              : /* Tentatively apply the changes numbered NUM and up.
     435              :    Return true if all changes are valid, false otherwise.  */
     436              : 
     437              : bool
     438    742121339 : verify_changes (int num)
     439              : {
     440    742121339 :   int i;
     441    742121339 :   rtx last_validated = NULL_RTX;
     442              : 
     443              :   /* The changes have been applied and all INSN_CODEs have been reset to force
     444              :      rerecognition.
     445              : 
     446              :      The changes are valid if we aren't given an object, or if we are
     447              :      given a MEM and it still is a valid address, or if this is in insn
     448              :      and it is recognized.  In the latter case, if reload has completed,
     449              :      we also require that the operands meet the constraints for
     450              :      the insn.  */
     451              : 
     452   2172832344 :   for (i = num; i < num_changes; i++)
     453              :     {
     454   1445060529 :       rtx object = changes[i].object;
     455              : 
     456              :       /* If there is no object to test or if it is the same as the one we
     457              :          already tested, ignore it.  */
     458   1445060529 :       if (object == 0 || object == last_validated)
     459    748108873 :         continue;
     460              : 
     461    696951656 :       if (MEM_P (object))
     462              :         {
     463        33438 :           if (! memory_address_addr_space_p (GET_MODE (object),
     464              :                                              XEXP (object, 0),
     465        16719 :                                              MEM_ADDR_SPACE (object)))
     466              :             break;
     467              :         }
     468    696934937 :       else if (/* changes[i].old might be zero, e.g. when putting a
     469              :                REG_FRAME_RELATED_EXPR into a previously empty list.  */
     470    696934937 :                changes[i].old
     471    696934937 :                && REG_P (changes[i].old)
     472    226106036 :                && asm_noperands (PATTERN (object)) > 0
     473    697132326 :                && register_asm_p (changes[i].old))
     474              :         {
     475              :           /* Don't allow changes of hard register operands to inline
     476              :              assemblies if they have been defined as register asm ("x").  */
     477              :           break;
     478              :         }
     479    696934936 :       else if (DEBUG_INSN_P (object))
     480    239238536 :         continue;
     481    457696400 :       else if (insn_invalid_p (as_a <rtx_insn *> (object), true))
     482              :         {
     483     16944515 :           rtx pat = PATTERN (object);
     484              : 
     485              :           /* Perhaps we couldn't recognize the insn because there were
     486              :              extra CLOBBERs at the end.  If so, try to re-recognize
     487              :              without the last CLOBBER (later iterations will cause each of
     488              :              them to be eliminated, in turn).  But don't do this if we
     489              :              have an ASM_OPERAND.  */
     490     16944515 :           if (GET_CODE (pat) == PARALLEL
     491      3996005 :               && GET_CODE (XVECEXP (pat, 0, XVECLEN (pat, 0) - 1)) == CLOBBER
     492     19725523 :               && asm_noperands (PATTERN (object)) < 0)
     493              :             {
     494      2582032 :               rtx newpat;
     495              : 
     496      2582032 :               if (XVECLEN (pat, 0) == 2)
     497      2179484 :                 newpat = XVECEXP (pat, 0, 0);
     498              :               else
     499              :                 {
     500       402548 :                   int j;
     501              : 
     502       402548 :                   newpat
     503       402548 :                     = gen_rtx_PARALLEL (VOIDmode,
     504              :                                         rtvec_alloc (XVECLEN (pat, 0) - 1));
     505      1241878 :                   for (j = 0; j < XVECLEN (newpat, 0); j++)
     506       839330 :                     XVECEXP (newpat, 0, j) = XVECEXP (pat, 0, j);
     507              :                 }
     508              : 
     509              :               /* Add a new change to this group to replace the pattern
     510              :                  with this new pattern.  Then consider this change
     511              :                  as having succeeded.  The change we added will
     512              :                  cause the entire call to fail if things remain invalid.
     513              : 
     514              :                  Note that this can lose if a later change than the one
     515              :                  we are processing specified &XVECEXP (PATTERN (object), 0, X)
     516              :                  but this shouldn't occur.  */
     517              : 
     518      2582032 :               validate_change (object, &PATTERN (object), newpat, 1);
     519      2582032 :               continue;
     520      2582032 :             }
     521     14362483 :           else if (GET_CODE (pat) == USE || GET_CODE (pat) == CLOBBER
     522     14349453 :                    || GET_CODE (pat) == VAR_LOCATION)
     523              :             /* If this insn is a CLOBBER or USE, it is always valid, but is
     524              :                never recognized.  */
     525        13030 :             continue;
     526              :           else
     527              :             break;
     528              :         }
     529              :       last_validated = object;
     530              :     }
     531              : 
     532    742121339 :   return (i == num_changes);
     533              : }
     534              : 
     535              : /* A group of changes has previously been issued with validate_change
     536              :    and verified with verify_changes.  Call df_insn_rescan for each of
     537              :    the insn changed and clear num_changes.  */
     538              : 
     539              : void
     540    736740530 : confirm_change_group (void)
     541              : {
     542    736740530 :   int i;
     543    736740530 :   rtx last_object = NULL;
     544              : 
     545    736740530 :   gcc_assert (!undo_recog_changes::is_active ());
     546   2176827906 :   for (i = 0; i < num_changes; i++)
     547              :     {
     548   1440087376 :       rtx object = changes[i].object;
     549              : 
     550   1440087376 :       if (changes[i].unshare)
     551     19305801 :         *changes[i].loc = copy_rtx (*changes[i].loc);
     552              : 
     553              :       /* Avoid unnecessary rescanning when multiple changes to same instruction
     554              :          are made.  */
     555   1440087376 :       if (object)
     556              :         {
     557   1437793408 :           if (object != last_object && last_object && INSN_P (last_object))
     558      7431392 :             df_insn_rescan (as_a <rtx_insn *> (last_object));
     559              :           last_object = object;
     560              :         }
     561              :     }
     562              : 
     563    736740530 :   if (last_object && INSN_P (last_object))
     564    579327941 :     df_insn_rescan (as_a <rtx_insn *> (last_object));
     565    736740530 :   num_changes = 0;
     566    736740530 : }
     567              : 
     568              : /* Apply a group of changes previously issued with `validate_change'.
     569              :    If all changes are valid, call confirm_change_group and return true,
     570              :    otherwise, call cancel_changes and return false.  */
     571              : 
     572              : bool
     573    735136023 : apply_change_group (void)
     574              : {
     575    735136023 :   if (verify_changes (0))
     576              :     {
     577    723510986 :       confirm_change_group ();
     578    723510986 :       return true;
     579              :     }
     580              :   else
     581              :     {
     582     11625037 :       cancel_changes (0);
     583     11625037 :       return false;
     584              :     }
     585              : }
     586              : 
     587              : 
     588              : /* Return the number of changes so far in the current group.  */
     589              : 
     590              : int
     591    721412027 : num_validated_changes (void)
     592              : {
     593    721412027 :   return num_changes;
     594              : }
     595              : 
     596              : /* Retract the changes numbered NUM and up.  */
     597              : 
     598              : void
     599    163061043 : cancel_changes (int num)
     600              : {
     601    163061043 :   gcc_assert (!undo_recog_changes::is_active ());
     602    163061043 :   int i;
     603              : 
     604              :   /* Back out all the changes.  Do this in the opposite order in which
     605              :      they were made.  */
     606    287850223 :   for (i = num_changes - 1; i >= num; i--)
     607              :     {
     608    124789180 :       if (changes[i].old_len >= 0)
     609     10481028 :         XVECLEN (*changes[i].loc, 0) = changes[i].old_len;
     610              :       else
     611    114308152 :         *changes[i].loc = changes[i].old;
     612    124789180 :       if (changes[i].object && !MEM_P (changes[i].object))
     613              :         {
     614    103392615 :           INSN_CODE (changes[i].object) = changes[i].old_code;
     615    103392615 :           if (recog_data.insn == changes[i].object)
     616          197 :             recog_data.insn = nullptr;
     617              :         }
     618              :     }
     619    163061043 :   num_changes = num;
     620    163061043 : }
     621              : 
     622              : /* Swap the status of change NUM from being applied to not being applied,
     623              :    or vice versa.  */
     624              : 
     625              : static void
     626     46579058 : swap_change (int num)
     627              : {
     628     46579058 :   if (changes[num].old_len >= 0)
     629      2091644 :     std::swap (XVECLEN (*changes[num].loc, 0), changes[num].old_len);
     630              :   else
     631     44487414 :     std::swap (*changes[num].loc, changes[num].old);
     632     46579058 :   if (changes[num].object && !MEM_P (changes[num].object))
     633              :     {
     634     46579058 :       std::swap (INSN_CODE (changes[num].object), changes[num].old_code);
     635     46579058 :       if (recog_data.insn == changes[num].object)
     636            9 :         recog_data.insn = nullptr;
     637              :     }
     638     46579058 : }
     639              : 
     640     26900761 : undo_recog_changes::undo_recog_changes (int num)
     641     26900761 :   : m_old_num_changes (s_num_changes)
     642              : {
     643     26900761 :   gcc_assert (num <= num_changes - s_num_changes);
     644     50190290 :   for (int i = num_changes - s_num_changes - 1; i >= num; i--)
     645     23289529 :     swap_change (i);
     646     26900761 :   s_num_changes = num_changes - num;
     647     26900761 : }
     648              : 
     649     26900761 : undo_recog_changes::~undo_recog_changes ()
     650              : {
     651     50190290 :   for (int i = num_changes - s_num_changes;
     652     50190290 :        i < num_changes - m_old_num_changes; ++i)
     653     23289529 :     swap_change (i);
     654     26900761 :   s_num_changes = m_old_num_changes;
     655     26900761 : }
     656              : 
     657              : /* Reduce conditional compilation elsewhere.  */
     658              : /* A subroutine of validate_replace_rtx_1 that tries to simplify the resulting
     659              :    rtx.  */
     660              : 
     661              : static void
     662     12151000 : simplify_while_replacing (rtx *loc, rtx to, rtx_insn *object,
     663              :                           machine_mode op0_mode)
     664              : {
     665     12151000 :   rtx x = *loc;
     666     12151000 :   enum rtx_code code = GET_CODE (x);
     667     12151000 :   rtx new_rtx = NULL_RTX;
     668     12151000 :   scalar_int_mode is_mode;
     669              : 
     670     12151000 :   if (SWAPPABLE_OPERANDS_P (x)
     671     12151000 :       && swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1)))
     672              :     {
     673       434769 :       validate_unshare_change (object, loc,
     674       434769 :                                gen_rtx_fmt_ee (COMMUTATIVE_ARITH_P (x) ? code
     675              :                                                : swap_condition (code),
     676              :                                                GET_MODE (x), XEXP (x, 1),
     677              :                                                XEXP (x, 0)), 1);
     678       434769 :       x = *loc;
     679       434769 :       code = GET_CODE (x);
     680              :     }
     681              : 
     682              :   /* Canonicalize arithmetics with all constant operands.  */
     683     12151000 :   switch (GET_RTX_CLASS (code))
     684              :     {
     685       800101 :     case RTX_UNARY:
     686       800101 :       if (CONSTANT_P (XEXP (x, 0)))
     687       557673 :         new_rtx = simplify_unary_operation (code, GET_MODE (x), XEXP (x, 0),
     688              :                                             op0_mode);
     689              :       break;
     690      6301331 :     case RTX_COMM_ARITH:
     691      6301331 :     case RTX_BIN_ARITH:
     692      6301331 :       if (CONSTANT_P (XEXP (x, 0)) && CONSTANT_P (XEXP (x, 1)))
     693       237562 :         new_rtx = simplify_binary_operation (code, GET_MODE (x), XEXP (x, 0),
     694              :                                              XEXP (x, 1));
     695              :       break;
     696       109483 :     case RTX_COMPARE:
     697       109483 :     case RTX_COMM_COMPARE:
     698       109483 :       if (CONSTANT_P (XEXP (x, 0)) && CONSTANT_P (XEXP (x, 1)))
     699         3207 :         new_rtx = simplify_relational_operation (code, GET_MODE (x), op0_mode,
     700              :                                                  XEXP (x, 0), XEXP (x, 1));
     701              :       break;
     702              :     default:
     703              :       break;
     704              :     }
     705       798442 :   if (new_rtx)
     706              :     {
     707       768456 :       validate_change (object, loc, new_rtx, 1);
     708       768456 :       return;
     709              :     }
     710              : 
     711     11382544 :   switch (code)
     712              :     {
     713      2182619 :     case PLUS:
     714              :       /* If we have a PLUS whose second operand is now a CONST_INT, use
     715              :          simplify_gen_binary to try to simplify it.
     716              :          ??? We may want later to remove this, once simplification is
     717              :          separated from this function.  */
     718      2182619 :       if (CONST_INT_P (XEXP (x, 1)) && XEXP (x, 1) == to)
     719       192502 :         validate_change (object, loc,
     720              :                          simplify_gen_binary
     721       192502 :                          (PLUS, GET_MODE (x), XEXP (x, 0), XEXP (x, 1)), 1);
     722              :       break;
     723       475505 :     case MINUS:
     724       475505 :       if (CONST_SCALAR_INT_P (XEXP (x, 1)))
     725        23116 :         validate_change (object, loc,
     726              :                          simplify_gen_binary
     727        23116 :                          (PLUS, GET_MODE (x), XEXP (x, 0),
     728              :                           simplify_gen_unary (NEG,
     729              :                                               GET_MODE (x), XEXP (x, 1),
     730        23116 :                                               GET_MODE (x))), 1);
     731              :       break;
     732       180245 :     case ZERO_EXTEND:
     733       180245 :     case SIGN_EXTEND:
     734       180245 :       if (GET_MODE (XEXP (x, 0)) == VOIDmode)
     735              :         {
     736            0 :           new_rtx = simplify_gen_unary (code, GET_MODE (x), XEXP (x, 0),
     737              :                                     op0_mode);
     738              :           /* If any of the above failed, substitute in something that
     739              :              we know won't be recognized.  */
     740            0 :           if (!new_rtx)
     741            0 :             new_rtx = gen_rtx_CLOBBER (GET_MODE (x), const0_rtx);
     742            0 :           validate_change (object, loc, new_rtx, 1);
     743              :         }
     744              :       break;
     745       140876 :     case SUBREG:
     746              :       /* All subregs possible to simplify should be simplified.  */
     747       281752 :       new_rtx = simplify_subreg (GET_MODE (x), SUBREG_REG (x), op0_mode,
     748       140876 :                              SUBREG_BYTE (x));
     749              : 
     750              :       /* Subregs of VOIDmode operands are incorrect.  */
     751       140876 :       if (!new_rtx && GET_MODE (SUBREG_REG (x)) == VOIDmode)
     752            2 :         new_rtx = gen_rtx_CLOBBER (GET_MODE (x), const0_rtx);
     753            2 :       if (new_rtx)
     754       124347 :         validate_change (object, loc, new_rtx, 1);
     755              :       break;
     756         5454 :     case ZERO_EXTRACT:
     757         5454 :     case SIGN_EXTRACT:
     758              :       /* If we are replacing a register with memory, try to change the memory
     759              :          to be the mode required for memory in extract operations (this isn't
     760              :          likely to be an insertion operation; if it was, nothing bad will
     761              :          happen, we might just fail in some cases).  */
     762              : 
     763         5454 :       if (MEM_P (XEXP (x, 0))
     764          409 :           && is_a <scalar_int_mode> (GET_MODE (XEXP (x, 0)), &is_mode)
     765          409 :           && CONST_INT_P (XEXP (x, 1))
     766          409 :           && CONST_INT_P (XEXP (x, 2))
     767          287 :           && !mode_dependent_address_p (XEXP (XEXP (x, 0), 0),
     768          305 :                                         MEM_ADDR_SPACE (XEXP (x, 0)))
     769         5741 :           && !MEM_VOLATILE_P (XEXP (x, 0)))
     770              :         {
     771          283 :           int pos = INTVAL (XEXP (x, 2));
     772          283 :           machine_mode new_mode = is_mode;
     773          283 :           if (GET_CODE (x) == ZERO_EXTRACT && targetm.have_extzv ())
     774            0 :             new_mode = insn_data[targetm.code_for_extzv].operand[1].mode;
     775          283 :           else if (GET_CODE (x) == SIGN_EXTRACT && targetm.have_extv ())
     776            0 :             new_mode = insn_data[targetm.code_for_extv].operand[1].mode;
     777          283 :           scalar_int_mode wanted_mode = (new_mode == VOIDmode
     778          283 :                                          ? word_mode
     779          283 :                                          : as_a <scalar_int_mode> (new_mode));
     780              : 
     781              :           /* If we have a narrower mode, we can do something.  */
     782          849 :           if (GET_MODE_SIZE (wanted_mode) < GET_MODE_SIZE (is_mode))
     783              :             {
     784            0 :               int offset = pos / BITS_PER_UNIT;
     785            0 :               rtx newmem;
     786              : 
     787              :               /* If the bytes and bits are counted differently, we
     788              :                  must adjust the offset.  */
     789            0 :               if (BYTES_BIG_ENDIAN != BITS_BIG_ENDIAN)
     790              :                 offset =
     791              :                   (GET_MODE_SIZE (is_mode) - GET_MODE_SIZE (wanted_mode) -
     792              :                    offset);
     793              : 
     794            0 :               gcc_assert (GET_MODE_PRECISION (wanted_mode)
     795              :                           == GET_MODE_BITSIZE (wanted_mode));
     796            0 :               pos %= GET_MODE_BITSIZE (wanted_mode);
     797              : 
     798            0 :               newmem = adjust_address_nv (XEXP (x, 0), wanted_mode, offset);
     799              : 
     800            0 :               validate_change (object, &XEXP (x, 2), GEN_INT (pos), 1);
     801            0 :               validate_change (object, &XEXP (x, 0), newmem, 1);
     802              :             }
     803              :         }
     804              : 
     805              :       break;
     806              : 
     807              :     default:
     808              :       break;
     809              :     }
     810              : }
     811              : 
     812              : /* Replace every occurrence of FROM in X with TO.  Mark each change with
     813              :    validate_change passing OBJECT.  */
     814              : 
     815              : static void
     816     68294871 : validate_replace_rtx_1 (rtx *loc, rtx from, rtx to, rtx_insn *object,
     817              :                         bool simplify)
     818              : {
     819     68294871 :   int i, j;
     820     68294871 :   const char *fmt;
     821     68294871 :   rtx x = *loc;
     822     68294871 :   enum rtx_code code;
     823     68294871 :   machine_mode op0_mode = VOIDmode;
     824     68294871 :   int prev_changes = num_changes;
     825              : 
     826     68294871 :   if (!x)
     827              :     return;
     828              : 
     829     68294871 :   code = GET_CODE (x);
     830     68294871 :   fmt = GET_RTX_FORMAT (code);
     831     68294871 :   if (fmt[0] == 'e')
     832     23506647 :     op0_mode = GET_MODE (XEXP (x, 0));
     833              : 
     834              :   /* X matches FROM if it is the same rtx or they are both referring to the
     835              :      same register in the same mode.  Avoid calling rtx_equal_p unless the
     836              :      operands look similar.  */
     837              : 
     838     68294871 :   if (x == from
     839     52863890 :       || (REG_P (x) && REG_P (from)
     840     15269623 :           && GET_MODE (x) == GET_MODE (from)
     841      8952398 :           && REGNO (x) == REGNO (from))
     842    121158758 :       || (GET_CODE (x) == GET_CODE (from) && GET_MODE (x) == GET_MODE (from)
     843      8952395 :           && rtx_equal_p (x, from)))
     844              :     {
     845     15430984 :       validate_unshare_change (object, loc, to, 1);
     846     15430984 :       return;
     847              :     }
     848              : 
     849              :   /* Call ourself recursively to perform the replacements.
     850              :      We must not replace inside already replaced expression, otherwise we
     851              :      get infinite recursion for replacements like (reg X)->(subreg (reg X))
     852              :      so we must special case shared ASM_OPERANDS.  */
     853              : 
     854     52863887 :   if (GET_CODE (x) == PARALLEL)
     855              :     {
     856      1354804 :       for (j = XVECLEN (x, 0) - 1; j >= 0; j--)
     857              :         {
     858      1000762 :           if (j && GET_CODE (XVECEXP (x, 0, j)) == SET
     859        27759 :               && GET_CODE (SET_SRC (XVECEXP (x, 0, j))) == ASM_OPERANDS)
     860              :             {
     861              :               /* Verify that operands are really shared.  */
     862          275 :               gcc_assert (ASM_OPERANDS_INPUT_VEC (SET_SRC (XVECEXP (x, 0, 0)))
     863              :                           == ASM_OPERANDS_INPUT_VEC (SET_SRC (XVECEXP
     864              :                                                               (x, 0, j))));
     865          275 :               validate_replace_rtx_1 (&SET_DEST (XVECEXP (x, 0, j)),
     866              :                                       from, to, object, simplify);
     867              :             }
     868              :           else
     869      1000487 :             validate_replace_rtx_1 (&XVECEXP (x, 0, j), from, to, object,
     870              :                                     simplify);
     871              :         }
     872              :     }
     873              :   else
     874    134063936 :     for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
     875              :       {
     876     81554091 :         if (fmt[i] == 'e')
     877     40105298 :           validate_replace_rtx_1 (&XEXP (x, i), from, to, object, simplify);
     878     41448793 :         else if (fmt[i] == 'E')
     879      6339499 :           for (j = XVECLEN (x, i) - 1; j >= 0; j--)
     880      3455461 :             validate_replace_rtx_1 (&XVECEXP (x, i, j), from, to, object,
     881              :                                     simplify);
     882              :       }
     883              : 
     884              :   /* If we didn't substitute, there is nothing more to do.  */
     885     52863887 :   if (num_changes == prev_changes)
     886              :     return;
     887              : 
     888              :   /* ??? The regmove is no more, so is this aberration still necessary?  */
     889              :   /* Allow substituted expression to have different mode.  This is used by
     890              :      regmove to change mode of pseudo register.  */
     891     12151071 :   if (fmt[0] == 'e' && GET_MODE (XEXP (x, 0)) != VOIDmode)
     892      9264524 :     op0_mode = GET_MODE (XEXP (x, 0));
     893              : 
     894              :   /* Do changes needed to keep rtx consistent.  Don't do any other
     895              :      simplifications, as it is not our job.  */
     896     12151071 :   if (simplify)
     897     12151000 :     simplify_while_replacing (loc, to, object, op0_mode);
     898              : }
     899              : 
     900              : /* Try replacing every occurrence of FROM in subexpression LOC of INSN
     901              :    with TO.  After all changes have been made, validate by seeing
     902              :    if INSN is still valid.  */
     903              : 
     904              : bool
     905            0 : validate_replace_rtx_subexp (rtx from, rtx to, rtx_insn *insn, rtx *loc)
     906              : {
     907            0 :   validate_replace_rtx_1 (loc, from, to, insn, true);
     908            0 :   return apply_change_group ();
     909              : }
     910              : 
     911              : /* Try replacing every occurrence of FROM in INSN with TO.  After all
     912              :    changes have been made, validate by seeing if INSN is still valid.  */
     913              : 
     914              : bool
     915      1998894 : validate_replace_rtx (rtx from, rtx to, rtx_insn *insn)
     916              : {
     917      1998894 :   validate_replace_rtx_1 (&PATTERN (insn), from, to, insn, true);
     918      1998894 :   return apply_change_group ();
     919              : }
     920              : 
     921              : /* Try replacing every occurrence of FROM in WHERE with TO.  Assume that WHERE
     922              :    is a part of INSN.  After all changes have been made, validate by seeing if
     923              :    INSN is still valid.
     924              :    validate_replace_rtx (from, to, insn) is equivalent to
     925              :    validate_replace_rtx_part (from, to, &PATTERN (insn), insn).  */
     926              : 
     927              : bool
     928            0 : validate_replace_rtx_part (rtx from, rtx to, rtx *where, rtx_insn *insn)
     929              : {
     930            0 :   validate_replace_rtx_1 (where, from, to, insn, true);
     931            0 :   return apply_change_group ();
     932              : }
     933              : 
     934              : /* Same as above, but do not simplify rtx afterwards.  */
     935              : bool
     936           89 : validate_replace_rtx_part_nosimplify (rtx from, rtx to, rtx *where,
     937              :                                       rtx_insn *insn)
     938              : {
     939           89 :   validate_replace_rtx_1 (where, from, to, insn, false);
     940           89 :   return apply_change_group ();
     941              : 
     942              : }
     943              : 
     944              : /* Try replacing every occurrence of FROM in INSN with TO.  This also
     945              :    will replace in REG_EQUAL and REG_EQUIV notes.  */
     946              : 
     947              : void
     948           21 : validate_replace_rtx_group (rtx from, rtx to, rtx_insn *insn)
     949              : {
     950           21 :   rtx note;
     951           21 :   validate_replace_rtx_1 (&PATTERN (insn), from, to, insn, true);
     952           28 :   for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
     953            7 :     if (REG_NOTE_KIND (note) == REG_EQUAL
     954            7 :         || REG_NOTE_KIND (note) == REG_EQUIV)
     955            0 :       validate_replace_rtx_1 (&XEXP (note, 0), from, to, insn, true);
     956           21 : }
     957              : 
     958              : /* Function called by note_uses to replace used subexpressions.  */
     959              : struct validate_replace_src_data
     960              : {
     961              :   rtx from;                     /* Old RTX */
     962              :   rtx to;                       /* New RTX */
     963              :   rtx_insn *insn;               /* Insn in which substitution is occurring.  */
     964              : };
     965              : 
     966              : static void
     967     21734346 : validate_replace_src_1 (rtx *x, void *data)
     968              : {
     969     21734346 :   struct validate_replace_src_data *d
     970              :     = (struct validate_replace_src_data *) data;
     971              : 
     972     21734346 :   validate_replace_rtx_1 (x, d->from, d->to, d->insn, true);
     973     21734346 : }
     974              : 
     975              : /* Try replacing every occurrence of FROM in INSN with TO, avoiding
     976              :    SET_DESTs.  */
     977              : 
     978              : void
     979     15529819 : validate_replace_src_group (rtx from, rtx to, rtx_insn *insn)
     980              : {
     981     15529819 :   struct validate_replace_src_data d;
     982              : 
     983     15529819 :   d.from = from;
     984     15529819 :   d.to = to;
     985     15529819 :   d.insn = insn;
     986     15529819 :   note_uses (&PATTERN (insn), validate_replace_src_1, &d);
     987     15529819 : }
     988              : 
     989              : /* Try simplify INSN.
     990              :    Invoke simplify_rtx () on every SET_SRC and SET_DEST inside the INSN's
     991              :    pattern and return true if something was simplified.  */
     992              : 
     993              : bool
     994            0 : validate_simplify_insn (rtx_insn *insn)
     995              : {
     996            0 :   int i;
     997            0 :   rtx pat = NULL;
     998            0 :   rtx newpat = NULL;
     999              : 
    1000            0 :   pat = PATTERN (insn);
    1001              : 
    1002            0 :   if (GET_CODE (pat) == SET)
    1003              :     {
    1004            0 :       newpat = simplify_rtx (SET_SRC (pat));
    1005            0 :       if (newpat && !rtx_equal_p (SET_SRC (pat), newpat))
    1006            0 :         validate_change (insn, &SET_SRC (pat), newpat, 1);
    1007            0 :       newpat = simplify_rtx (SET_DEST (pat));
    1008            0 :       if (newpat && !rtx_equal_p (SET_DEST (pat), newpat))
    1009            0 :         validate_change (insn, &SET_DEST (pat), newpat, 1);
    1010              :     }
    1011            0 :   else if (GET_CODE (pat) == PARALLEL)
    1012            0 :     for (i = 0; i < XVECLEN (pat, 0); i++)
    1013              :       {
    1014            0 :         rtx s = XVECEXP (pat, 0, i);
    1015              : 
    1016            0 :         if (GET_CODE (XVECEXP (pat, 0, i)) == SET)
    1017              :           {
    1018            0 :             newpat = simplify_rtx (SET_SRC (s));
    1019            0 :             if (newpat && !rtx_equal_p (SET_SRC (s), newpat))
    1020            0 :               validate_change (insn, &SET_SRC (s), newpat, 1);
    1021            0 :             newpat = simplify_rtx (SET_DEST (s));
    1022            0 :             if (newpat && !rtx_equal_p (SET_DEST (s), newpat))
    1023            0 :               validate_change (insn, &SET_DEST (s), newpat, 1);
    1024              :           }
    1025              :       }
    1026            0 :   return ((num_changes_pending () > 0) && (apply_change_group () > 0));
    1027              : }
    1028              : 
    1029              : /* Try to process the address of memory expression MEM.  Return true on
    1030              :    success; leave the caller to clean up on failure.  */
    1031              : 
    1032              : bool
    1033     23857589 : insn_propagation::apply_to_mem_1 (rtx mem)
    1034              : {
    1035     23857589 :   auto old_num_changes = num_validated_changes ();
    1036     23857589 :   mem_depth += 1;
    1037     23857589 :   bool res = apply_to_rvalue_1 (&XEXP (mem, 0));
    1038     23857589 :   mem_depth -= 1;
    1039     23857589 :   if (!res)
    1040              :     return false;
    1041              : 
    1042     23857013 :   if (old_num_changes != num_validated_changes ()
    1043      7723314 :       && should_check_mems
    1044     27176031 :       && !check_mem (old_num_changes, mem))
    1045              :     return false;
    1046              : 
    1047              :   return true;
    1048              : }
    1049              : 
    1050              : /* Try to process the rvalue expression at *LOC.  Return true on success;
    1051              :    leave the caller to clean up on failure.  */
    1052              : 
    1053              : bool
    1054    231997346 : insn_propagation::apply_to_rvalue_1 (rtx *loc)
    1055              : {
    1056    231997346 :   rtx x = *loc;
    1057    231997346 :   enum rtx_code code = GET_CODE (x);
    1058    231997346 :   machine_mode mode = GET_MODE (x);
    1059              : 
    1060    231997346 :   auto old_num_changes = num_validated_changes ();
    1061    231997346 :   if (from
    1062    220740188 :       && GET_CODE (x) == GET_CODE (from)
    1063    322915069 :       && (REG_P (x)
    1064     90917723 :           ? REGNO (x) == REGNO (from)
    1065        23454 :           : rtx_equal_p (x, from)))
    1066              :     {
    1067              :       /* Don't replace register asms in asm statements; we mustn't
    1068              :          change the user's register allocation.  */
    1069     58366010 :       if (REG_P (x)
    1070     58343252 :           && HARD_REGISTER_P (x)
    1071     17950962 :           && register_asm_p (x)
    1072     58368007 :           && asm_noperands (PATTERN (insn)) > 0)
    1073              :         return false;
    1074              : 
    1075     58364182 :       rtx newval = to;
    1076     58364182 :       if (GET_MODE (x) != GET_MODE (from))
    1077              :         {
    1078       667866 :           gcc_assert (REG_P (x) && HARD_REGISTER_P (x));
    1079       667866 :           if (REG_NREGS (x) != REG_NREGS (from)
    1080       667866 :               || !REG_CAN_CHANGE_MODE_P (REGNO (x), GET_MODE (from),
    1081              :                                          GET_MODE (x)))
    1082       339646 :             return false;
    1083              : 
    1084              :           /* If the reference is paradoxical and the replacement
    1085              :              value contains registers, we would need to check that the
    1086              :              simplification below does not increase REG_NREGS for those
    1087              :              registers either.  It seems simpler to punt on nonconstant
    1088              :              values instead.  */
    1089       584174 :           if (paradoxical_subreg_p (GET_MODE (x), GET_MODE (from))
    1090       584174 :               && !CONSTANT_P (to))
    1091              :             return false;
    1092              : 
    1093       564792 :           newval = simplify_subreg (GET_MODE (x), to, GET_MODE (from),
    1094              :                                     subreg_lowpart_offset (GET_MODE (x),
    1095              :                                                            GET_MODE (from)));
    1096       564792 :           if (!newval)
    1097              :             return false;
    1098              : 
    1099              :           /* Check that the simplification didn't just push an explicit
    1100              :              subreg down into subexpressions.  In particular, for a register
    1101              :              R that has a fixed mode, such as the stack pointer, a subreg of:
    1102              : 
    1103              :                (plus:M (reg:M R) (const_int C))
    1104              : 
    1105              :              would be:
    1106              : 
    1107              :                (plus:N (subreg:N (reg:M R) ...) (const_int C'))
    1108              : 
    1109              :              But targets can legitimately assume that subregs of hard registers
    1110              :              will not be created after RA (except in special circumstances,
    1111              :              such as strict_low_part).  */
    1112       330864 :           subrtx_iterator::array_type array;
    1113      1285421 :           FOR_EACH_SUBRTX (iter, array, newval, NONCONST)
    1114       957201 :             if (GET_CODE (*iter) == SUBREG)
    1115         2644 :               return false;
    1116       330864 :         }
    1117              : 
    1118     58024536 :       if (should_unshare)
    1119     58024536 :         validate_unshare_change (insn, loc, newval, 1);
    1120              :       else
    1121            0 :         validate_change (insn, loc, newval, 1);
    1122     58024536 :       if (mem_depth && !REG_P (newval) && !CONSTANT_P (newval))
    1123              :         {
    1124              :           /* We're substituting into an address, but TO will have the
    1125              :              form expected outside an address.  Canonicalize it if
    1126              :              necessary.  */
    1127      3599103 :           insn_propagation subprop (insn);
    1128      3599103 :           subprop.mem_depth += 1;
    1129      3599103 :           if (!subprop.apply_to_rvalue (loc))
    1130            0 :             gcc_unreachable ();
    1131      3599103 :           if (should_unshare
    1132      3599103 :               && num_validated_changes () != old_num_changes + 1)
    1133              :             {
    1134              :               /* TO is owned by someone else, so create a copy and
    1135              :                  return TO to its original form.  */
    1136       303754 :               newval = copy_rtx (*loc);
    1137       303754 :               cancel_changes (old_num_changes);
    1138       303754 :               validate_change (insn, loc, newval, 1);
    1139              :             }
    1140              :         }
    1141     58024536 :       num_replacements += 1;
    1142     58024536 :       should_unshare = true;
    1143     58024536 :       result_flags |= UNSIMPLIFIED;
    1144     58024536 :       return true;
    1145              :     }
    1146              : 
    1147              :   /* Recursively apply the substitution and see if we can simplify
    1148              :      the result.  This specifically shouldn't use simplify_gen_* for
    1149              :      speculative simplifications, since we want to avoid generating new
    1150              :      expressions where possible.  */
    1151    173631336 :   auto old_result_flags = result_flags;
    1152    173631336 :   rtx newx = NULL_RTX;
    1153    173631336 :   bool recurse_p = false;
    1154    173631336 :   switch (GET_RTX_CLASS (code))
    1155              :     {
    1156      3010375 :     case RTX_UNARY:
    1157      3010375 :       {
    1158      3010375 :         machine_mode op0_mode = GET_MODE (XEXP (x, 0));
    1159      3010375 :         if (!apply_to_rvalue_1 (&XEXP (x, 0)))
    1160              :           return false;
    1161      2973009 :         if (from && old_num_changes == num_validated_changes ())
    1162              :           return true;
    1163              : 
    1164      2399359 :         newx = simplify_unary_operation (code, mode, XEXP (x, 0), op0_mode);
    1165      2399359 :         break;
    1166              :       }
    1167              : 
    1168     45149868 :     case RTX_BIN_ARITH:
    1169     45149868 :     case RTX_COMM_ARITH:
    1170     45149868 :       {
    1171     45149868 :         if (!apply_to_rvalue_1 (&XEXP (x, 0))
    1172     45149868 :             || !apply_to_rvalue_1 (&XEXP (x, 1)))
    1173       450271 :           return false;
    1174     44699597 :         if (from && old_num_changes == num_validated_changes ())
    1175              :           return true;
    1176              : 
    1177     34285987 :         if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
    1178     34285987 :             && swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1)))
    1179      2683717 :           newx = simplify_gen_binary (code, mode, XEXP (x, 1), XEXP (x, 0));
    1180              :         else
    1181     31602270 :           newx = simplify_binary_operation (code, mode,
    1182              :                                             XEXP (x, 0), XEXP (x, 1));
    1183              :         break;
    1184              :       }
    1185              : 
    1186      5897593 :     case RTX_COMPARE:
    1187      5897593 :     case RTX_COMM_COMPARE:
    1188      5897593 :       {
    1189     11795313 :         machine_mode op_mode = (GET_MODE (XEXP (x, 0)) != VOIDmode
    1190      5897593 :                                 ? GET_MODE (XEXP (x, 0))
    1191          127 :                                 : GET_MODE (XEXP (x, 1)));
    1192      5897593 :         if (!apply_to_rvalue_1 (&XEXP (x, 0))
    1193      5897593 :             || !apply_to_rvalue_1 (&XEXP (x, 1)))
    1194         4278 :           return false;
    1195      5893315 :         if (from && old_num_changes == num_validated_changes ())
    1196              :           return true;
    1197              : 
    1198      5025501 :         newx = simplify_relational_operation (code, mode, op_mode,
    1199              :                                               XEXP (x, 0), XEXP (x, 1));
    1200      5025501 :         break;
    1201              :       }
    1202              : 
    1203      5387674 :     case RTX_TERNARY:
    1204      5387674 :     case RTX_BITFIELD_OPS:
    1205      5387674 :       {
    1206      5387674 :         machine_mode op0_mode = GET_MODE (XEXP (x, 0));
    1207      5387674 :         if (!apply_to_rvalue_1 (&XEXP (x, 0))
    1208      5380640 :             || !apply_to_rvalue_1 (&XEXP (x, 1))
    1209     10745942 :             || !apply_to_rvalue_1 (&XEXP (x, 2)))
    1210        31689 :           return false;
    1211      5355985 :         if (from && old_num_changes == num_validated_changes ())
    1212              :           return true;
    1213              : 
    1214      5288074 :         newx = simplify_ternary_operation (code, mode, op0_mode,
    1215              :                                            XEXP (x, 0), XEXP (x, 1),
    1216              :                                            XEXP (x, 2));
    1217      5288074 :         break;
    1218              :       }
    1219              : 
    1220     10678338 :     case RTX_EXTRA:
    1221     10678338 :       if (code == SUBREG)
    1222              :         {
    1223      2342158 :           machine_mode inner_mode = GET_MODE (SUBREG_REG (x));
    1224      2342158 :           if (!apply_to_rvalue_1 (&SUBREG_REG (x)))
    1225              :             return false;
    1226      2342142 :           if (from && old_num_changes == num_validated_changes ())
    1227              :             return true;
    1228              : 
    1229      1705607 :           rtx inner = SUBREG_REG (x);
    1230      1705607 :           newx = simplify_subreg (mode, inner, inner_mode, SUBREG_BYTE (x));
    1231              :           /* Reject the same cases that simplify_gen_subreg would.  */
    1232      1705607 :           if (!newx
    1233      1705607 :               && (GET_CODE (inner) == SUBREG
    1234      1061175 :                   || GET_CODE (inner) == CONCAT
    1235      1048771 :                   || GET_MODE (inner) == VOIDmode
    1236      1048770 :                   || !validate_subreg (mode, inner_mode,
    1237      1048770 :                                        inner, SUBREG_BYTE (x))))
    1238              :             {
    1239        12449 :               failure_reason = "would create an invalid subreg";
    1240        12449 :               return false;
    1241              :             }
    1242              :           break;
    1243              :         }
    1244              :       else
    1245              :         recurse_p = true;
    1246              :       break;
    1247              : 
    1248     53146148 :     case RTX_OBJ:
    1249     53146148 :       if (code == LO_SUM)
    1250              :         {
    1251            0 :           if (!apply_to_rvalue_1 (&XEXP (x, 0))
    1252            0 :               || !apply_to_rvalue_1 (&XEXP (x, 1)))
    1253            0 :             return false;
    1254            0 :           if (from && old_num_changes == num_validated_changes ())
    1255              :             return true;
    1256              : 
    1257              :           /* (lo_sum (high x) y) -> y where x and y have the same base.  */
    1258            0 :           rtx op0 = XEXP (x, 0);
    1259            0 :           rtx op1 = XEXP (x, 1);
    1260            0 :           if (GET_CODE (op0) == HIGH)
    1261              :             {
    1262            0 :               rtx base0, base1, offset0, offset1;
    1263            0 :               split_const (XEXP (op0, 0), &base0, &offset0);
    1264            0 :               split_const (op1, &base1, &offset1);
    1265            0 :               if (rtx_equal_p (base0, base1))
    1266            0 :                 newx = op1;
    1267              :             }
    1268              :         }
    1269     53146148 :       else if (code == REG)
    1270              :         {
    1271     36760638 :           if (from && REG_P (from) && reg_overlap_mentioned_p (x, from))
    1272              :             {
    1273        61780 :               failure_reason = "inexact register overlap";
    1274        61780 :               return false;
    1275              :             }
    1276              :         }
    1277     16385510 :       else if (code == MEM)
    1278     12336492 :         return apply_to_mem_1 (x);
    1279              :       else
    1280              :         recurse_p = true;
    1281              :       break;
    1282              : 
    1283              :     case RTX_CONST_OBJ:
    1284              :       break;
    1285              : 
    1286      1430289 :     case RTX_AUTOINC:
    1287      1430289 :       if (from && reg_overlap_mentioned_p (XEXP (x, 0), from))
    1288              :         {
    1289            0 :           failure_reason = "is subject to autoinc";
    1290            0 :           return false;
    1291              :         }
    1292              :       recurse_p = true;
    1293              :       break;
    1294              : 
    1295            0 :     case RTX_MATCH:
    1296            0 :     case RTX_INSN:
    1297            0 :       gcc_unreachable ();
    1298              :     }
    1299              : 
    1300     48692079 :   if (recurse_p)
    1301              :     {
    1302     13815487 :       const char *fmt = GET_RTX_FORMAT (code);
    1303     31317629 :       for (int i = 0; fmt[i]; i++)
    1304     17608876 :         switch (fmt[i])
    1305              :           {
    1306              :           case 'E':
    1307      6013544 :             for (int j = 0; j < XVECLEN (x, i); j++)
    1308      4277500 :               if (!apply_to_rvalue_1 (&XVECEXP (x, i, j)))
    1309              :                 return false;
    1310              :             break;
    1311              : 
    1312     11963270 :           case 'e':
    1313     11963270 :             if (XEXP (x, i) && !apply_to_rvalue_1 (&XEXP (x, i)))
    1314              :               return false;
    1315              :             break;
    1316              :           }
    1317              :     }
    1318    134321988 :   else if (newx && !rtx_equal_p (x, newx))
    1319              :     {
    1320              :       /* All substitutions made by OLD_NUM_CHANGES onwards have been
    1321              :          simplified.  */
    1322     10630271 :       result_flags = ((result_flags & ~UNSIMPLIFIED)
    1323              :                       | (old_result_flags & UNSIMPLIFIED));
    1324              : 
    1325     10630271 :       if (should_note_simplifications)
    1326      3862147 :         note_simplification (old_num_changes, old_result_flags, x, newx);
    1327              : 
    1328              :       /* There's no longer any point unsharing the substitutions made
    1329              :          for subexpressions, since we'll just copy this one instead.  */
    1330              :       bool unshare = false;
    1331     21216172 :       for (int i = old_num_changes; i < num_changes; ++i)
    1332              :         {
    1333     10585901 :           unshare |= changes[i].unshare;
    1334     10585901 :           changes[i].unshare = false;
    1335              :         }
    1336     10630271 :       if (unshare)
    1337     10202853 :         validate_unshare_change (insn, loc, newx, 1);
    1338              :       else
    1339       427418 :         validate_change (insn, loc, newx, 1);
    1340              :     }
    1341              : 
    1342              :   return true;
    1343              : }
    1344              : 
    1345              : /* Try to process the lvalue expression at *LOC.  Return true on success;
    1346              :    leave the caller to clean up on failure.  */
    1347              : 
    1348              : bool
    1349     62014592 : insn_propagation::apply_to_lvalue_1 (rtx dest)
    1350              : {
    1351     62014592 :   rtx old_dest = dest;
    1352     62014592 :   while (GET_CODE (dest) == SUBREG
    1353     62218182 :          || GET_CODE (dest) == ZERO_EXTRACT
    1354     62218182 :          || GET_CODE (dest) == STRICT_LOW_PART)
    1355              :     {
    1356       203590 :       if (GET_CODE (dest) == ZERO_EXTRACT
    1357       203590 :           && (!apply_to_rvalue_1 (&XEXP (dest, 1))
    1358         2535 :               || !apply_to_rvalue_1 (&XEXP (dest, 2))))
    1359            0 :         return false;
    1360       203590 :       dest = XEXP (dest, 0);
    1361              :     }
    1362              : 
    1363     62014592 :   if (MEM_P (dest))
    1364     11521097 :     return apply_to_mem_1 (dest);
    1365              : 
    1366              :   /* Check whether the substitution is safe in the presence of this lvalue.  */
    1367     50493495 :   if (!from
    1368     50493495 :       || dest == old_dest
    1369       199516 :       || !REG_P (dest)
    1370     50693011 :       || !reg_overlap_mentioned_p (dest, from))
    1371     50393304 :     return true;
    1372              : 
    1373       100191 :   if (SUBREG_P (old_dest)
    1374        95754 :       && SUBREG_REG (old_dest) == dest
    1375       195945 :       && !read_modify_subreg_p (old_dest))
    1376              :     return true;
    1377              : 
    1378        99913 :   failure_reason = "is part of a read-write destination";
    1379        99913 :   return false;
    1380              : }
    1381              : 
    1382              : /* Try to process the instruction pattern at *LOC.  Return true on success;
    1383              :    leave the caller to clean up on failure.  */
    1384              : 
    1385              : bool
    1386     65495797 : insn_propagation::apply_to_pattern_1 (rtx *loc)
    1387              : {
    1388     65495797 :   rtx body = *loc;
    1389     65495797 :   switch (GET_CODE (body))
    1390              :     {
    1391            0 :     case COND_EXEC:
    1392            0 :       return (apply_to_rvalue_1 (&COND_EXEC_TEST (body))
    1393            0 :               && apply_to_pattern_1 (&COND_EXEC_CODE (body)));
    1394              : 
    1395              :     case PARALLEL:
    1396     14060996 :       for (int i = 0; i < XVECLEN (body, 0); ++i)
    1397              :         {
    1398      9607398 :           rtx *subloc = &XVECEXP (body, 0, i);
    1399      9607398 :           if (GET_CODE (*subloc) == SET)
    1400              :             {
    1401      5225165 :               if (!apply_to_lvalue_1 (SET_DEST (*subloc)))
    1402              :                 return false;
    1403              :               /* ASM_OPERANDS are shared between SETs in the same PARALLEL.
    1404              :                  Only process them on the first iteration.  */
    1405       731061 :               if ((i == 0 || GET_CODE (SET_SRC (*subloc)) != ASM_OPERANDS)
    1406      5822551 :                   && !apply_to_rvalue_1 (&SET_SRC (*subloc)))
    1407              :                 return false;
    1408              :             }
    1409              :           else
    1410              :             {
    1411      4382233 :               if (!apply_to_pattern_1 (subloc))
    1412              :                 return false;
    1413              :             }
    1414              :         }
    1415              :       return true;
    1416              : 
    1417         8590 :     case ASM_OPERANDS:
    1418        30320 :       for (int i = 0, len = ASM_OPERANDS_INPUT_LENGTH (body); i < len; ++i)
    1419        21950 :         if (!apply_to_rvalue_1 (&ASM_OPERANDS_INPUT (body, i)))
    1420              :           return false;
    1421              :       return true;
    1422              : 
    1423      4203050 :     case CLOBBER:
    1424      4203050 :       return apply_to_lvalue_1 (XEXP (body, 0));
    1425              : 
    1426     52586377 :     case SET:
    1427     52586377 :       return (apply_to_lvalue_1 (SET_DEST (body))
    1428     52586377 :               && apply_to_rvalue_1 (&SET_SRC (body)));
    1429              : 
    1430      4193334 :     default:
    1431              :       /* All the other possibilities never store and can use a normal
    1432              :          rtx walk.  This includes:
    1433              : 
    1434              :          - USE
    1435              :          - TRAP_IF
    1436              :          - PREFETCH
    1437              :          - UNSPEC
    1438              :          - UNSPEC_VOLATILE.  */
    1439      4193334 :       return apply_to_rvalue_1 (loc);
    1440              :     }
    1441              : }
    1442              : 
    1443              : /* Apply this insn_propagation object's simplification or substitution
    1444              :    to the instruction pattern at LOC.  */
    1445              : 
    1446              : bool
    1447     61113564 : insn_propagation::apply_to_pattern (rtx *loc)
    1448              : {
    1449     61113564 :   unsigned int num_changes = num_validated_changes ();
    1450     61113564 :   bool res = apply_to_pattern_1 (loc);
    1451     61113564 :   if (!res)
    1452      2321955 :     cancel_changes (num_changes);
    1453     61113564 :   return res;
    1454              : }
    1455              : 
    1456              : /* Apply this insn_propagation object's simplification or substitution
    1457              :    to the rvalue expression at LOC.  */
    1458              : 
    1459              : bool
    1460      7311682 : insn_propagation::apply_to_rvalue (rtx *loc)
    1461              : {
    1462      7311682 :   unsigned int num_changes = num_validated_changes ();
    1463      7311682 :   bool res = apply_to_rvalue_1 (loc);
    1464      7311682 :   if (!res)
    1465        19119 :     cancel_changes (num_changes);
    1466      7311682 :   return res;
    1467              : }
    1468              : 
    1469              : /* Like apply_to_rvalue, but specifically for the case where *LOC is in
    1470              :    a note.  This never changes the INSN_CODE.  */
    1471              : 
    1472              : bool
    1473       182432 : insn_propagation::apply_to_note (rtx *loc)
    1474              : {
    1475       182432 :   auto old_code = INSN_CODE (insn);
    1476       182432 :   bool res = apply_to_rvalue (loc);
    1477       182432 :   if (INSN_CODE (insn) != old_code)
    1478        87745 :     INSN_CODE (insn) = old_code;
    1479       182432 :   return res;
    1480              : }
    1481              : 
    1482              : /* Check whether INSN matches a specific alternative of an .md pattern.  */
    1483              : 
    1484              : bool
    1485            0 : valid_insn_p (rtx_insn *insn)
    1486              : {
    1487            0 :   recog_memoized (insn);
    1488            0 :   if (INSN_CODE (insn) < 0)
    1489              :     return false;
    1490            0 :   extract_insn (insn);
    1491              :   /* We don't know whether the insn will be in code that is optimized
    1492              :      for size or speed, so consider all enabled alternatives.  */
    1493            0 :   if (!constrain_operands (1, get_enabled_alternatives (insn)))
    1494              :     return false;
    1495              :   return true;
    1496              : }
    1497              : 
    1498              : /* Return true if OP is a valid general operand for machine mode MODE.
    1499              :    This is either a register reference, a memory reference,
    1500              :    or a constant.  In the case of a memory reference, the address
    1501              :    is checked for general validity for the target machine.
    1502              : 
    1503              :    Register and memory references must have mode MODE in order to be valid,
    1504              :    but some constants have no machine mode and are valid for any mode.
    1505              : 
    1506              :    If MODE is VOIDmode, OP is checked for validity for whatever mode
    1507              :    it has.
    1508              : 
    1509              :    The main use of this function is as a predicate in match_operand
    1510              :    expressions in the machine description.  */
    1511              : 
    1512              : bool
    1513   4914592063 : general_operand (rtx op, machine_mode mode)
    1514              : {
    1515   4914592063 :   enum rtx_code code = GET_CODE (op);
    1516              : 
    1517   4914592063 :   if (mode == VOIDmode)
    1518   1262871530 :     mode = GET_MODE (op);
    1519              : 
    1520              :   /* Don't accept CONST_INT or anything similar
    1521              :      if the caller wants something floating.  */
    1522   4914592063 :   if (GET_MODE (op) == VOIDmode && mode != VOIDmode
    1523    218409642 :       && GET_MODE_CLASS (mode) != MODE_INT
    1524         6361 :       && GET_MODE_CLASS (mode) != MODE_PARTIAL_INT)
    1525              :     return false;
    1526              : 
    1527   4914585702 :   if (CONST_INT_P (op)
    1528    267527568 :       && mode != VOIDmode
    1529   5129805156 :       && trunc_int_for_mode (INTVAL (op), mode) != INTVAL (op))
    1530              :     return false;
    1531              : 
    1532   4914585477 :   if (CONSTANT_P (op))
    1533     63474704 :     return ((GET_MODE (op) == VOIDmode || GET_MODE (op) == mode
    1534         7160 :              || mode == VOIDmode)
    1535    331556910 :             && (! flag_pic || LEGITIMATE_PIC_OPERAND_P (op))
    1536    714924606 :             && targetm.legitimate_constant_p (mode == VOIDmode
    1537     52382661 :                                               ? GET_MODE (op)
    1538              :                                               : mode, op));
    1539              : 
    1540              :   /* Except for certain constants with VOIDmode, already checked for,
    1541              :      OP's mode must match MODE if MODE specifies a mode.  */
    1542              : 
    1543   4583021407 :   if (GET_MODE (op) != mode)
    1544              :     return false;
    1545              : 
    1546   4529964019 :   if (code == SUBREG)
    1547              :     {
    1548     33342885 :       rtx sub = SUBREG_REG (op);
    1549              : 
    1550              : #ifdef INSN_SCHEDULING
    1551              :       /* On machines that have insn scheduling, we want all memory
    1552              :          reference to be explicit, so outlaw paradoxical SUBREGs.
    1553              :          However, we must allow them after reload so that they can
    1554              :          get cleaned up by cleanup_subreg_operands.  */
    1555     33293136 :       if (!reload_completed && MEM_P (sub)
    1556     33411635 :           && paradoxical_subreg_p (op))
    1557              :         return false;
    1558              : #endif
    1559              :       /* Avoid memories with nonzero SUBREG_BYTE, as offsetting the memory
    1560              :          may result in incorrect reference.  We should simplify all valid
    1561              :          subregs of MEM anyway.  But allow this after reload because we
    1562              :          might be called from cleanup_subreg_operands.
    1563              : 
    1564              :          ??? This is a kludge.  */
    1565     33274353 :       if (!reload_completed
    1566     33224604 :           && maybe_ne (SUBREG_BYTE (op), 0)
    1567     38393807 :           && MEM_P (sub))
    1568              :         return false;
    1569              : 
    1570     33274353 :       if (REG_P (sub)
    1571     31699520 :           && REGNO (sub) < FIRST_PSEUDO_REGISTER
    1572         5265 :           && !REG_CAN_CHANGE_MODE_P (REGNO (sub), GET_MODE (sub), mode)
    1573            0 :           && GET_MODE_CLASS (GET_MODE (sub)) != MODE_COMPLEX_INT
    1574            0 :           && GET_MODE_CLASS (GET_MODE (sub)) != MODE_COMPLEX_FLOAT
    1575              :           /* LRA can generate some invalid SUBREGS just for matched
    1576              :              operand reload presentation.  LRA needs to treat them as
    1577              :              valid.  */
    1578     33274353 :           && ! LRA_SUBREG_P (op))
    1579              :         return false;
    1580              : 
    1581              :       /* FLOAT_MODE subregs can't be paradoxical.  Combine will occasionally
    1582              :          create such rtl, and we must reject it.  */
    1583     33274353 :       if (SCALAR_FLOAT_MODE_P (GET_MODE (op))
    1584              :           /* LRA can use subreg to store a floating point value in an
    1585              :              integer mode.  Although the floating point and the
    1586              :              integer modes need the same number of hard registers, the
    1587              :              size of floating point mode can be less than the integer
    1588              :              mode.  */
    1589       327172 :           && ! lra_in_progress
    1590     33584660 :           && paradoxical_subreg_p (op))
    1591              :         return false;
    1592              : 
    1593     33274353 :       op = sub;
    1594     33274353 :       code = GET_CODE (op);
    1595              :     }
    1596              : 
    1597   4529895487 :   if (code == REG)
    1598   3691590713 :     return (REGNO (op) >= FIRST_PSEUDO_REGISTER
    1599   3691590713 :             || in_hard_reg_set_p (operand_reg_set, GET_MODE (op), REGNO (op)));
    1600              : 
    1601    838304774 :   if (code == MEM)
    1602              :     {
    1603    747166736 :       rtx y = XEXP (op, 0);
    1604              : 
    1605              :       /* If -ffuse-ops-with-volatile-access is enabled, allow volatile
    1606              :          memory reference.  */
    1607    747166736 :       if (!flag_fuse_ops_with_volatile_access
    1608       152077 :           && !volatile_ok
    1609    747213575 :           && MEM_VOLATILE_P (op))
    1610              :         return false;
    1611              : 
    1612              :       /* Use the mem's mode, since it will be reloaded thus.  LRA can
    1613              :          generate move insn with invalid addresses which is made valid
    1614              :          and efficiently calculated by LRA through further numerous
    1615              :          transformations.  */
    1616    747160694 :       if (lra_in_progress
    1617    802460476 :           || memory_address_addr_space_p (GET_MODE (op), y, MEM_ADDR_SPACE (op)))
    1618    728944981 :         return true;
    1619              :     }
    1620              : 
    1621              :   return false;
    1622              : }
    1623              : 
    1624              : /* Return true if OP is a valid memory address for a memory reference
    1625              :    of mode MODE.
    1626              : 
    1627              :    The main use of this function is as a predicate in match_operand
    1628              :    expressions in the machine description.  */
    1629              : 
    1630              : bool
    1631    111824441 : address_operand (rtx op, machine_mode mode)
    1632              : {
    1633              :   /* Wrong mode for an address expr.  */
    1634    111824441 :   if (GET_MODE (op) != VOIDmode
    1635     99687957 :       && ! SCALAR_INT_MODE_P (GET_MODE (op)))
    1636              :     return false;
    1637              : 
    1638    110966885 :   return memory_address_p (mode, op);
    1639              : }
    1640              : 
    1641              : /* Return true if OP is a register reference of mode MODE.
    1642              :    If MODE is VOIDmode, accept a register in any mode.
    1643              : 
    1644              :    The main use of this function is as a predicate in match_operand
    1645              :    expressions in the machine description.  */
    1646              : 
    1647              : bool
    1648   2637841519 : register_operand (rtx op, machine_mode mode)
    1649              : {
    1650   2637841519 :   if (GET_CODE (op) == SUBREG)
    1651              :     {
    1652     11815717 :       rtx sub = SUBREG_REG (op);
    1653              : 
    1654              :       /* Before reload, we can allow (SUBREG (MEM...)) as a register operand
    1655              :          because it is guaranteed to be reloaded into one.
    1656              :          Just make sure the MEM is valid in itself.
    1657              :          (Ideally, (SUBREG (MEM)...) should not exist after reload,
    1658              :          but currently it does result from (SUBREG (REG)...) where the
    1659              :          reg went on the stack.)  */
    1660     11815717 :       if (!REG_P (sub) && (reload_completed || !MEM_P (sub)))
    1661              :         return false;
    1662              :     }
    1663   2626025802 :   else if (!REG_P (op))
    1664              :     return false;
    1665   1934868368 :   return general_operand (op, mode);
    1666              : }
    1667              : 
    1668              : /* Return true for a register in Pmode; ignore the tested mode.  */
    1669              : 
    1670              : bool
    1671            0 : pmode_register_operand (rtx op, machine_mode mode ATTRIBUTE_UNUSED)
    1672              : {
    1673            0 :   return register_operand (op, Pmode);
    1674              : }
    1675              : 
    1676              : /* Return true if OP should match a MATCH_SCRATCH, i.e., if it is a SCRATCH
    1677              :    or a hard register.  */
    1678              : 
    1679              : bool
    1680       702447 : scratch_operand (rtx op, machine_mode mode)
    1681              : {
    1682       702447 :   if (GET_MODE (op) != mode && mode != VOIDmode)
    1683              :     return false;
    1684              : 
    1685       663954 :   return (GET_CODE (op) == SCRATCH
    1686       663954 :           || (REG_P (op)
    1687        89342 :               && (lra_in_progress
    1688        71855 :                   || (REGNO (op) < FIRST_PSEUDO_REGISTER
    1689        69637 :                       && REGNO_REG_CLASS (REGNO (op)) != NO_REGS))));
    1690              : }
    1691              : 
    1692              : /* Return true if OP is a valid immediate operand for mode MODE.
    1693              : 
    1694              :    The main use of this function is as a predicate in match_operand
    1695              :    expressions in the machine description.  */
    1696              : 
    1697              : bool
    1698    500904082 : immediate_operand (rtx op, machine_mode mode)
    1699              : {
    1700              :   /* Don't accept CONST_INT or anything similar
    1701              :      if the caller wants something floating.  */
    1702    500904082 :   if (GET_MODE (op) == VOIDmode && mode != VOIDmode
    1703    141203417 :       && GET_MODE_CLASS (mode) != MODE_INT
    1704            0 :       && GET_MODE_CLASS (mode) != MODE_PARTIAL_INT)
    1705              :     return false;
    1706              : 
    1707    500904082 :   if (CONST_INT_P (op)
    1708    322675084 :       && mode != VOIDmode
    1709    639112760 :       && trunc_int_for_mode (INTVAL (op), mode) != INTVAL (op))
    1710              :     return false;
    1711              : 
    1712    500685969 :   return (CONSTANT_P (op)
    1713    387418865 :           && (GET_MODE (op) == mode || mode == VOIDmode
    1714    142443768 :               || GET_MODE (op) == VOIDmode)
    1715    384946792 :           && (! flag_pic || LEGITIMATE_PIC_OPERAND_P (op))
    1716   1102502910 :           && targetm.legitimate_constant_p (mode == VOIDmode
    1717    221590218 :                                             ? GET_MODE (op)
    1718              :                                             : mode, op));
    1719              : }
    1720              : 
    1721              : /* Return true if OP is an operand that is a CONST_INT of mode MODE.  */
    1722              : 
    1723              : bool
    1724     38671907 : const_int_operand (rtx op, machine_mode mode)
    1725              : {
    1726     38671907 :   if (!CONST_INT_P (op))
    1727              :     return false;
    1728              : 
    1729     32682271 :   if (mode != VOIDmode
    1730     32682271 :       && trunc_int_for_mode (INTVAL (op), mode) != INTVAL (op))
    1731              :     return false;
    1732              : 
    1733              :   return true;
    1734              : }
    1735              : 
    1736              : #if TARGET_SUPPORTS_WIDE_INT
    1737              : /* Return true if OP is an operand that is a CONST_INT or CONST_WIDE_INT
    1738              :    of mode MODE.  */
    1739              : bool
    1740      2325657 : const_scalar_int_operand (rtx op, machine_mode mode)
    1741              : {
    1742      2325657 :   if (!CONST_SCALAR_INT_P (op))
    1743              :     return false;
    1744              : 
    1745      1949710 :   if (CONST_INT_P (op))
    1746       155833 :     return const_int_operand (op, mode);
    1747              : 
    1748      1793877 :   if (mode != VOIDmode)
    1749              :     {
    1750      1793877 :       scalar_int_mode int_mode = as_a <scalar_int_mode> (mode);
    1751      1793877 :       int prec = GET_MODE_PRECISION (int_mode);
    1752      1793877 :       int bitsize = GET_MODE_BITSIZE (int_mode);
    1753              : 
    1754      1793877 :       if (CONST_WIDE_INT_NUNITS (op) * HOST_BITS_PER_WIDE_INT > bitsize)
    1755              :         return false;
    1756              : 
    1757      1793877 :       if (prec == bitsize)
    1758              :         return true;
    1759              :       else
    1760              :         {
    1761              :           /* Multiword partial int.  */
    1762         5496 :           HOST_WIDE_INT x
    1763         5496 :             = CONST_WIDE_INT_ELT (op, CONST_WIDE_INT_NUNITS (op) - 1);
    1764         5496 :           return (sext_hwi (x, prec & (HOST_BITS_PER_WIDE_INT - 1)) == x);
    1765              :         }
    1766              :     }
    1767              :   return true;
    1768              : }
    1769              : 
    1770              : /* Return true if OP is an operand that is a constant integer or constant
    1771              :    floating-point number of MODE.  */
    1772              : 
    1773              : bool
    1774            0 : const_double_operand (rtx op, machine_mode mode)
    1775              : {
    1776            0 :   return (GET_CODE (op) == CONST_DOUBLE)
    1777            0 :           && (GET_MODE (op) == mode || mode == VOIDmode);
    1778              : }
    1779              : #else
    1780              : /* Return true if OP is an operand that is a constant integer or constant
    1781              :    floating-point number of MODE.  */
    1782              : 
    1783              : bool
    1784              : const_double_operand (rtx op, machine_mode mode)
    1785              : {
    1786              :   /* Don't accept CONST_INT or anything similar
    1787              :      if the caller wants something floating.  */
    1788              :   if (GET_MODE (op) == VOIDmode && mode != VOIDmode
    1789              :       && GET_MODE_CLASS (mode) != MODE_INT
    1790              :       && GET_MODE_CLASS (mode) != MODE_PARTIAL_INT)
    1791              :     return false;
    1792              : 
    1793              :   return ((CONST_DOUBLE_P (op) || CONST_INT_P (op))
    1794              :           && (mode == VOIDmode || GET_MODE (op) == mode
    1795              :               || GET_MODE (op) == VOIDmode));
    1796              : }
    1797              : #endif
    1798              : /* Return true if OP is a general operand that is not an immediate
    1799              :    operand of mode MODE.  */
    1800              : 
    1801              : bool
    1802   1917133064 : nonimmediate_operand (rtx op, machine_mode mode)
    1803              : {
    1804   1917133064 :   return (general_operand (op, mode) && ! CONSTANT_P (op));
    1805              : }
    1806              : 
    1807              : /* Return true if OP is a register reference or
    1808              :    immediate value of mode MODE.  */
    1809              : 
    1810              : bool
    1811    534810210 : nonmemory_operand (rtx op, machine_mode mode)
    1812              : {
    1813    534810210 :   if (CONSTANT_P (op))
    1814     31619017 :     return immediate_operand (op, mode);
    1815    503191193 :   return register_operand (op, mode);
    1816              : }
    1817              : 
    1818              : /* Return true if OP is a valid operand that stands for pushing a
    1819              :    value of mode MODE onto the stack.
    1820              : 
    1821              :    The main use of this function is as a predicate in match_operand
    1822              :    expressions in the machine description.  */
    1823              : 
    1824              : bool
    1825    854622596 : push_operand (rtx op, machine_mode mode)
    1826              : {
    1827    854622596 :   if (!MEM_P (op))
    1828              :     return false;
    1829              : 
    1830    258689636 :   if (mode != VOIDmode && GET_MODE (op) != mode)
    1831              :     return false;
    1832              : 
    1833    491015672 :   poly_int64 rounded_size = GET_MODE_SIZE (mode);
    1834              : 
    1835              : #ifdef PUSH_ROUNDING
    1836    245507836 :   rounded_size = PUSH_ROUNDING (MACRO_INT (rounded_size));
    1837              : #endif
    1838              : 
    1839    245507836 :   op = XEXP (op, 0);
    1840              : 
    1841    491015672 :   if (known_eq (rounded_size, GET_MODE_SIZE (mode)))
    1842              :     {
    1843    209356557 :       if (GET_CODE (op) != STACK_PUSH_CODE)
    1844              :         return false;
    1845              :     }
    1846              :   else
    1847              :     {
    1848     36151279 :       poly_int64 offset;
    1849     36151279 :       if (GET_CODE (op) != PRE_MODIFY
    1850      1198553 :           || GET_CODE (XEXP (op, 1)) != PLUS
    1851      1198553 :           || XEXP (XEXP (op, 1), 0) != XEXP (op, 0)
    1852      1198553 :           || !poly_int_rtx_p (XEXP (XEXP (op, 1), 1), &offset)
    1853     36151279 :           || (STACK_GROWS_DOWNWARD
    1854      1198553 :               ? maybe_ne (offset, -rounded_size)
    1855              :               : maybe_ne (offset, rounded_size)))
    1856    810191821 :         return false;
    1857              :     }
    1858              : 
    1859     44430775 :   return XEXP (op, 0) == stack_pointer_rtx;
    1860              : }
    1861              : 
    1862              : /* Return true if OP is a valid operand that stands for popping a
    1863              :    value of mode MODE off the stack.
    1864              : 
    1865              :    The main use of this function is as a predicate in match_operand
    1866              :    expressions in the machine description.  */
    1867              : 
    1868              : bool
    1869    304550673 : pop_operand (rtx op, machine_mode mode)
    1870              : {
    1871    304550673 :   if (!MEM_P (op))
    1872              :     return false;
    1873              : 
    1874     75234562 :   if (mode != VOIDmode && GET_MODE (op) != mode)
    1875              :     return false;
    1876              : 
    1877     75234562 :   op = XEXP (op, 0);
    1878              : 
    1879     75234562 :   if (GET_CODE (op) != STACK_POP_CODE)
    1880              :     return false;
    1881              : 
    1882      1379018 :   return XEXP (op, 0) == stack_pointer_rtx;
    1883              : }
    1884              : 
    1885              : /* Return true if ADDR is a valid memory address
    1886              :    for mode MODE in address space AS.  */
    1887              : 
    1888              : bool
    1889   1482004733 : memory_address_addr_space_p (machine_mode mode ATTRIBUTE_UNUSED, rtx addr,
    1890              :                              addr_space_t as, code_helper ch ATTRIBUTE_UNUSED)
    1891              : {
    1892              : #ifdef GO_IF_LEGITIMATE_ADDRESS
    1893              :   gcc_assert (ADDR_SPACE_GENERIC_P (as));
    1894              :   GO_IF_LEGITIMATE_ADDRESS (mode, addr, win);
    1895              :   return false;
    1896              : 
    1897              :  win:
    1898              :   return true;
    1899              : #else
    1900   1482004733 :   return targetm.addr_space.legitimate_address_p (mode, addr, 0, as, ch);
    1901              : #endif
    1902              : }
    1903              : 
    1904              : /* Return true if OP is a valid memory reference with mode MODE,
    1905              :    including a valid address.
    1906              : 
    1907              :    The main use of this function is as a predicate in match_operand
    1908              :    expressions in the machine description.  */
    1909              : 
    1910              : bool
    1911   1215639481 : memory_operand (rtx op, machine_mode mode)
    1912              : {
    1913   1215639481 :   rtx inner;
    1914              : 
    1915   1215639481 :   if (! reload_completed)
    1916              :     /* Note that no SUBREG is a memory operand before end of reload pass,
    1917              :        because (SUBREG (MEM...)) forces reloading into a register.  */
    1918    122970499 :     return MEM_P (op) && general_operand (op, mode);
    1919              : 
    1920   1092668982 :   if (mode != VOIDmode && GET_MODE (op) != mode)
    1921              :     return false;
    1922              : 
    1923    799509002 :   inner = op;
    1924    799509002 :   if (GET_CODE (inner) == SUBREG)
    1925         7746 :     inner = SUBREG_REG (inner);
    1926              : 
    1927    799509002 :   return (MEM_P (inner) && general_operand (op, mode));
    1928              : }
    1929              : 
    1930              : /* Return true if OP is a valid indirect memory reference with mode MODE;
    1931              :    that is, a memory reference whose address is a general_operand.  */
    1932              : 
    1933              : bool
    1934            0 : indirect_operand (rtx op, machine_mode mode)
    1935              : {
    1936              :   /* Before reload, a SUBREG isn't in memory (see memory_operand, above).  */
    1937            0 :   if (! reload_completed
    1938            0 :       && GET_CODE (op) == SUBREG && MEM_P (SUBREG_REG (op)))
    1939              :     {
    1940            0 :       if (mode != VOIDmode && GET_MODE (op) != mode)
    1941              :         return false;
    1942              : 
    1943              :       /* The only way that we can have a general_operand as the resulting
    1944              :          address is if OFFSET is zero and the address already is an operand
    1945              :          or if the address is (plus Y (const_int -OFFSET)) and Y is an
    1946              :          operand.  */
    1947            0 :       poly_int64 offset;
    1948            0 :       rtx addr = strip_offset (XEXP (SUBREG_REG (op), 0), &offset);
    1949            0 :       return (known_eq (offset + SUBREG_BYTE (op), 0)
    1950            0 :               && general_operand (addr, Pmode));
    1951              :     }
    1952              : 
    1953            0 :   return (MEM_P (op)
    1954            0 :           && memory_operand (op, mode)
    1955            0 :           && general_operand (XEXP (op, 0), Pmode));
    1956              : }
    1957              : 
    1958              : /* Return true if this is an ordered comparison operator (not including
    1959              :    ORDERED and UNORDERED).  */
    1960              : 
    1961              : bool
    1962     28109221 : ordered_comparison_operator (rtx op, machine_mode mode)
    1963              : {
    1964     28109221 :   if (mode != VOIDmode && GET_MODE (op) != mode)
    1965              :     return false;
    1966     28109221 :   switch (GET_CODE (op))
    1967              :     {
    1968              :     case EQ:
    1969              :     case NE:
    1970              :     case LT:
    1971              :     case LTU:
    1972              :     case LE:
    1973              :     case LEU:
    1974              :     case GT:
    1975              :     case GTU:
    1976              :     case GE:
    1977              :     case GEU:
    1978              :       return true;
    1979              :     default:
    1980              :       return false;
    1981              :     }
    1982              : }
    1983              : 
    1984              : /* Return true if this is a comparison operator.  This allows the use of
    1985              :    MATCH_OPERATOR to recognize all the branch insns.  */
    1986              : 
    1987              : bool
    1988    113003437 : comparison_operator (rtx op, machine_mode mode)
    1989              : {
    1990      4527266 :   return ((mode == VOIDmode || GET_MODE (op) == mode)
    1991    117141990 :           && COMPARISON_P (op));
    1992              : }
    1993              : 
    1994              : /* If BODY is an insn body that uses ASM_OPERANDS, return it.  */
    1995              : 
    1996              : rtx
    1997   2037444612 : extract_asm_operands (rtx body)
    1998              : {
    1999   2037444612 :   rtx tmp;
    2000   2037444612 :   switch (GET_CODE (body))
    2001              :     {
    2002              :     case ASM_OPERANDS:
    2003              :       return body;
    2004              : 
    2005   1568418660 :     case SET:
    2006              :       /* Single output operand: BODY is (set OUTPUT (asm_operands ...)).  */
    2007   1568418660 :       tmp = SET_SRC (body);
    2008   1568418660 :       if (GET_CODE (tmp) == ASM_OPERANDS)
    2009              :         return tmp;
    2010              :       break;
    2011              : 
    2012    340194124 :     case PARALLEL:
    2013    340194124 :       tmp = XVECEXP (body, 0, 0);
    2014    340194124 :       if (GET_CODE (tmp) == ASM_OPERANDS)
    2015              :         return tmp;
    2016    337925586 :       if (GET_CODE (tmp) == SET)
    2017              :         {
    2018    333579398 :           tmp = SET_SRC (tmp);
    2019    333579398 :           if (GET_CODE (tmp) == ASM_OPERANDS)
    2020              :             return tmp;
    2021              :         }
    2022              :       break;
    2023              : 
    2024              :     default:
    2025              :       break;
    2026              :     }
    2027   2031559768 :   return NULL;
    2028              : }
    2029              : 
    2030              : /* If BODY is an insn body that uses ASM_OPERANDS,
    2031              :    return the number of operands (both input and output) in the insn.
    2032              :    If BODY is an insn body that uses ASM_INPUT with CLOBBERS in PARALLEL,
    2033              :    return 0.
    2034              :    Otherwise return -1.  */
    2035              : 
    2036              : int
    2037   1577875891 : asm_noperands (const_rtx body)
    2038              : {
    2039   1577875891 :   rtx asm_op = extract_asm_operands (const_cast<rtx> (body));
    2040   1577875891 :   int i, n_sets = 0;
    2041              : 
    2042   1577875891 :   if (asm_op == NULL)
    2043              :     {
    2044   1573137722 :       if (GET_CODE (body) == PARALLEL && XVECLEN (body, 0) >= 2
    2045    249436473 :           && GET_CODE (XVECEXP (body, 0, 0)) == ASM_INPUT)
    2046              :         {
    2047              :           /* body is [(asm_input ...) (clobber (reg ...))...].  */
    2048        76260 :           for (i = XVECLEN (body, 0) - 1; i > 0; i--)
    2049        50840 :             if (GET_CODE (XVECEXP (body, 0, i)) != CLOBBER)
    2050              :               return -1;
    2051              :           return 0;
    2052              :         }
    2053              :       return -1;
    2054              :     }
    2055              : 
    2056      4738169 :   if (GET_CODE (body) == SET)
    2057              :     n_sets = 1;
    2058      4730424 :   else if (GET_CODE (body) == PARALLEL)
    2059              :     {
    2060      4720253 :       if (GET_CODE (XVECEXP (body, 0, 0)) == SET)
    2061              :         {
    2062              :           /* Multiple output operands, or 1 output plus some clobbers:
    2063              :              body is
    2064              :              [(set OUTPUT (asm_operands ...))...
    2065              :               (use (reg ...))...
    2066              :               (clobber (reg ...))...].  */
    2067              :           /* Count backwards through USEs and CLOBBERs to determine
    2068              :              number of SETs.  */
    2069      5718082 :           for (i = XVECLEN (body, 0); i > 0; i--)
    2070              :             {
    2071      5718082 :               if (GET_CODE (XVECEXP (body, 0, i - 1)) == SET)
    2072              :                 break;
    2073      2881027 :               if (GET_CODE (XVECEXP (body, 0, i - 1)) != USE
    2074      2881027 :                   && GET_CODE (XVECEXP (body, 0, i - 1)) != CLOBBER)
    2075              :                 return -1;
    2076              :             }
    2077              : 
    2078              :           /* N_SETS is now number of output operands.  */
    2079     10964077 :           n_sets = i;
    2080              : 
    2081              :           /* Verify that all the SETs we have
    2082              :              came from a single original asm_operands insn
    2083              :              (so that invalid combinations are blocked).  */
    2084     10964077 :           for (i = 0; i < n_sets; i++)
    2085              :             {
    2086      8166299 :               rtx elt = XVECEXP (body, 0, i);
    2087      8166299 :               if (GET_CODE (elt) != SET)
    2088              :                 return -1;
    2089      8161073 :               if (GET_CODE (SET_SRC (elt)) != ASM_OPERANDS)
    2090              :                 return -1;
    2091              :               /* If these ASM_OPERANDS rtx's came from different original insns
    2092              :                  then they aren't allowed together.  */
    2093      8145151 :               if (ASM_OPERANDS_INPUT_VEC (SET_SRC (elt))
    2094      8145151 :                   != ASM_OPERANDS_INPUT_VEC (asm_op))
    2095              :                 return -1;
    2096              :             }
    2097              :         }
    2098              :       else
    2099              :         {
    2100              :           /* 0 outputs, but some clobbers:
    2101              :              body is [(asm_operands ...)
    2102              :                       (use (reg ...))...
    2103              :                       (clobber (reg ...))...].  */
    2104              :           /* Make sure all the other parallel things really are clobbers.  */
    2105      5797422 :           for (i = XVECLEN (body, 0) - 1; i > 0; i--)
    2106      3916604 :             if (GET_CODE (XVECEXP (body, 0, i)) != USE
    2107      3916604 :                 && GET_CODE (XVECEXP (body, 0, i)) != CLOBBER)
    2108              :               return -1;
    2109              :         }
    2110              :     }
    2111              : 
    2112      4696512 :   return (ASM_OPERANDS_INPUT_LENGTH (asm_op)
    2113      4696512 :           + ASM_OPERANDS_LABEL_LENGTH (asm_op) + n_sets);
    2114              : }
    2115              : 
    2116              : /* Assuming BODY is an insn body that uses ASM_OPERANDS,
    2117              :    copy its operands (both input and output) into the vector OPERANDS,
    2118              :    the locations of the operands within the insn into the vector OPERAND_LOCS,
    2119              :    and the constraints for the operands into CONSTRAINTS.
    2120              :    Write the modes of the operands into MODES.
    2121              :    Write the location info into LOC.
    2122              :    Return the assembler-template.
    2123              :    If BODY is an insn body that uses ASM_INPUT with CLOBBERS in PARALLEL,
    2124              :    return the basic assembly string.
    2125              : 
    2126              :    If LOC, MODES, OPERAND_LOCS, CONSTRAINTS or OPERANDS is 0,
    2127              :    we don't store that info.  */
    2128              : 
    2129              : const char *
    2130      2200654 : decode_asm_operands (rtx body, rtx *operands, rtx **operand_locs,
    2131              :                      const char **constraints, machine_mode *modes,
    2132              :                      location_t *loc)
    2133              : {
    2134      2200654 :   int nbase = 0, n, i;
    2135      2200654 :   rtx asmop;
    2136              : 
    2137      2200654 :   switch (GET_CODE (body))
    2138              :     {
    2139              :     case ASM_OPERANDS:
    2140              :       /* Zero output asm: BODY is (asm_operands ...).  */
    2141              :       asmop = body;
    2142              :       break;
    2143              : 
    2144         3658 :     case SET:
    2145              :       /* Single output asm: BODY is (set OUTPUT (asm_operands ...)).  */
    2146         3658 :       asmop = SET_SRC (body);
    2147              : 
    2148              :       /* The output is in the SET.
    2149              :          Its constraint is in the ASM_OPERANDS itself.  */
    2150         3658 :       if (operands)
    2151         3548 :         operands[0] = SET_DEST (body);
    2152         3658 :       if (operand_locs)
    2153          455 :         operand_locs[0] = &SET_DEST (body);
    2154         3658 :       if (constraints)
    2155         3548 :         constraints[0] = ASM_OPERANDS_OUTPUT_CONSTRAINT (asmop);
    2156         3658 :       if (modes)
    2157          455 :         modes[0] = GET_MODE (SET_DEST (body));
    2158              :       nbase = 1;
    2159              :       break;
    2160              : 
    2161      2192710 :     case PARALLEL:
    2162      2192710 :       {
    2163      2192710 :         int nparallel = XVECLEN (body, 0); /* Includes CLOBBERs.  */
    2164              : 
    2165      2192710 :         asmop = XVECEXP (body, 0, 0);
    2166      2192710 :         if (GET_CODE (asmop) == SET)
    2167              :           {
    2168      1175329 :             asmop = SET_SRC (asmop);
    2169              : 
    2170              :             /* At least one output, plus some CLOBBERs.  The outputs are in
    2171              :                the SETs.  Their constraints are in the ASM_OPERANDS itself.  */
    2172      4347520 :             for (i = 0; i < nparallel; i++)
    2173              :               {
    2174      4326303 :                 if (GET_CODE (XVECEXP (body, 0, i)) == USE
    2175      4326303 :                     || GET_CODE (XVECEXP (body, 0, i)) == CLOBBER)
    2176              :                   break;                /* Past last SET */
    2177      3172191 :                 gcc_assert (GET_CODE (XVECEXP (body, 0, i)) == SET);
    2178      3172191 :                 if (operands)
    2179      3001642 :                   operands[i] = SET_DEST (XVECEXP (body, 0, i));
    2180      3172191 :                 if (operand_locs)
    2181      1154905 :                   operand_locs[i] = &SET_DEST (XVECEXP (body, 0, i));
    2182      3172191 :                 if (constraints)
    2183      3016269 :                   constraints[i] = XSTR (SET_SRC (XVECEXP (body, 0, i)), 1);
    2184      3172191 :                 if (modes)
    2185      1154905 :                   modes[i] = GET_MODE (SET_DEST (XVECEXP (body, 0, i)));
    2186              :               }
    2187              :             nbase = i;
    2188              :           }
    2189      1017381 :         else if (GET_CODE (asmop) == ASM_INPUT)
    2190              :           {
    2191        12911 :             if (loc)
    2192            0 :               *loc = ASM_INPUT_SOURCE_LOCATION (asmop);
    2193        12911 :             return XSTR (asmop, 0);
    2194              :           }
    2195              :         break;
    2196              :       }
    2197              : 
    2198            0 :     default:
    2199            0 :       gcc_unreachable ();
    2200              :     }
    2201              : 
    2202      2187743 :   n = ASM_OPERANDS_INPUT_LENGTH (asmop);
    2203      4168928 :   for (i = 0; i < n; i++)
    2204              :     {
    2205      1981185 :       if (operand_locs)
    2206       845115 :         operand_locs[nbase + i] = &ASM_OPERANDS_INPUT (asmop, i);
    2207      1981185 :       if (operands)
    2208      1846910 :         operands[nbase + i] = ASM_OPERANDS_INPUT (asmop, i);
    2209      1981185 :       if (constraints)
    2210      1865206 :         constraints[nbase + i] = ASM_OPERANDS_INPUT_CONSTRAINT (asmop, i);
    2211      1981185 :       if (modes)
    2212       845115 :         modes[nbase + i] = ASM_OPERANDS_INPUT_MODE (asmop, i);
    2213              :     }
    2214      2187743 :   nbase += n;
    2215              : 
    2216      2187743 :   n = ASM_OPERANDS_LABEL_LENGTH (asmop);
    2217      2208322 :   for (i = 0; i < n; i++)
    2218              :     {
    2219        20579 :       if (operand_locs)
    2220        11471 :         operand_locs[nbase + i] = &ASM_OPERANDS_LABEL (asmop, i);
    2221        20579 :       if (operands)
    2222        18698 :         operands[nbase + i] = ASM_OPERANDS_LABEL (asmop, i);
    2223        20579 :       if (constraints)
    2224        18770 :         constraints[nbase + i] = "";
    2225        20579 :       if (modes)
    2226        11471 :         modes[nbase + i] = Pmode;
    2227              :     }
    2228              : 
    2229      2187743 :   if (loc)
    2230       107052 :     *loc = ASM_OPERANDS_SOURCE_LOCATION (asmop);
    2231              : 
    2232      2187743 :   return ASM_OPERANDS_TEMPLATE (asmop);
    2233              : }
    2234              : 
    2235              : /* Parse inline assembly string STRING and determine which operands are
    2236              :    referenced by % markers.  For the first NOPERANDS operands, set USED[I]
    2237              :    to true if operand I is referenced.
    2238              : 
    2239              :    This is intended to distinguish barrier-like asms such as:
    2240              : 
    2241              :       asm ("" : "=m" (...));
    2242              : 
    2243              :    from real references such as:
    2244              : 
    2245              :       asm ("sw\t$0, %0" : "=m" (...));  */
    2246              : 
    2247              : void
    2248            0 : get_referenced_operands (const char *string, bool *used,
    2249              :                          unsigned int noperands)
    2250              : {
    2251            0 :   memset (used, 0, sizeof (bool) * noperands);
    2252            0 :   const char *p = string;
    2253            0 :   while (*p)
    2254            0 :     switch (*p)
    2255              :       {
    2256            0 :       case '%':
    2257            0 :         p += 1;
    2258              :         /* A letter followed by a digit indicates an operand number.  */
    2259            0 :         if (ISALPHA (p[0]) && ISDIGIT (p[1]))
    2260            0 :           p += 1;
    2261            0 :         if (ISDIGIT (*p))
    2262              :           {
    2263            0 :             char *endptr;
    2264            0 :             unsigned long opnum = strtoul (p, &endptr, 10);
    2265            0 :             if (endptr != p && opnum < noperands)
    2266            0 :               used[opnum] = true;
    2267            0 :             p = endptr;
    2268              :           }
    2269              :         else
    2270            0 :           p += 1;
    2271              :         break;
    2272              : 
    2273            0 :       default:
    2274            0 :         p++;
    2275            0 :         break;
    2276              :       }
    2277            0 : }
    2278              : 
    2279              : /* Check if an asm_operand matches its constraints.
    2280              :    Return > 0 if ok, = 0 if bad, < 0 if inconclusive.  */
    2281              : 
    2282              : int
    2283      3448425 : asm_operand_ok (rtx op, const char *constraint, const char **constraints)
    2284              : {
    2285      3448425 :   int result = 0;
    2286      3448425 :   bool incdec_ok = false;
    2287              : 
    2288              :   /* Use constrain_operands after reload.  */
    2289      3448425 :   gcc_assert (!reload_completed);
    2290              : 
    2291              :   /* Empty constraint string is the same as "X,...,X", i.e. X for as
    2292              :      many alternatives as required to match the other operands.  */
    2293      3448425 :   if (*constraint == '\0')
    2294         3822 :     result = 1;
    2295              : 
    2296      9517937 :   while (*constraint)
    2297              :     {
    2298      6069514 :       enum constraint_num cn;
    2299      6069514 :       char c = *constraint;
    2300      6069514 :       int len;
    2301      6069514 :       switch (c)
    2302              :         {
    2303        11497 :         case ',':
    2304        11497 :           raw_constraint_p = false;
    2305        11497 :           constraint++;
    2306        11497 :           continue;
    2307              : 
    2308       644896 :         case '0': case '1': case '2': case '3': case '4':
    2309       644896 :         case '5': case '6': case '7': case '8': case '9':
    2310              :           /* If caller provided constraints pointer, look up
    2311              :              the matching constraint.  Otherwise, our caller should have
    2312              :              given us the proper matching constraint, but we can't
    2313              :              actually fail the check if they didn't.  Indicate that
    2314              :              results are inconclusive.  */
    2315       644896 :           if (constraints)
    2316              :             {
    2317       644695 :               char *end;
    2318       644695 :               unsigned long match;
    2319              : 
    2320       644695 :               match = strtoul (constraint, &end, 10);
    2321       644695 :               if (!result)
    2322       644434 :                 result = asm_operand_ok (op, constraints[match], NULL);
    2323       644695 :               constraint = (const char *) end;
    2324              :             }
    2325              :           else
    2326              :             {
    2327          225 :               do
    2328          225 :                 constraint++;
    2329          225 :               while (ISDIGIT (*constraint));
    2330          201 :               if (! result)
    2331          174 :                 result = -1;
    2332              :             }
    2333       644896 :           continue;
    2334              : 
    2335              :           /* The rest of the compiler assumes that reloading the address
    2336              :              of a MEM into a register will make it fit an 'o' constraint.
    2337              :              That is, if it sees a MEM operand for an 'o' constraint,
    2338              :              it assumes that (mem (base-reg)) will fit.
    2339              : 
    2340              :              That assumption fails on targets that don't have offsettable
    2341              :              addresses at all.  We therefore need to treat 'o' asm
    2342              :              constraints as a special case and only accept operands that
    2343              :              are already offsettable, thus proving that at least one
    2344              :              offsettable address exists.  */
    2345           36 :         case 'o': /* offsettable */
    2346           36 :           if (offsettable_nonstrict_memref_p (op))
    2347      2335294 :             result = 1;
    2348              :           break;
    2349              : 
    2350       116115 :         case 'g':
    2351       116115 :           if (general_operand (op, VOIDmode))
    2352      2335294 :             result = 1;
    2353              :           break;
    2354              : 
    2355           32 :         case '-':
    2356           32 :           raw_constraint_p = true;
    2357           32 :           constraint++;
    2358           32 :           continue;
    2359              : 
    2360              :         case '<':
    2361              :         case '>':
    2362              :           /* ??? Before auto-inc-dec, auto inc/dec insns are not supposed
    2363              :              to exist, excepting those that expand_call created.  Further,
    2364              :              on some machines which do not have generalized auto inc/dec,
    2365              :              an inc/dec is not a memory_operand.
    2366              : 
    2367              :              Match any memory and hope things are resolved after reload.  */
    2368      5296938 :           incdec_ok = true;
    2369              :           /* FALLTHRU */
    2370      5296938 :         default:
    2371      5296938 :           cn = lookup_constraint (constraint);
    2372      5296938 :           rtx mem = NULL;
    2373      5296938 :           switch (get_constraint_type (cn))
    2374              :             {
    2375      5117441 :             case CT_REGISTER:
    2376      5117441 :               if (!result
    2377      2533229 :                   && (reg_class_for_constraint (cn) != NO_REGS
    2378      2582243 :                       || constraint[0] == '{')
    2379      2533887 :                   && GET_MODE (op) != BLKmode
    2380      7651293 :                   && register_operand (op, VOIDmode))
    2381              :                 result = 1;
    2382              :               break;
    2383              : 
    2384            4 :             case CT_CONST_INT:
    2385            4 :               if (!result
    2386            4 :                   && CONST_INT_P (op)
    2387            6 :                   && insn_const_int_ok_for_constraint (INTVAL (op), cn))
    2388              :                 result = 1;
    2389              :               break;
    2390              : 
    2391       156107 :             case CT_MEMORY:
    2392       156107 :             case CT_RELAXED_MEMORY:
    2393       156107 :               mem = op;
    2394              :               /* Fall through.  */
    2395       156107 :             case CT_SPECIAL_MEMORY:
    2396              :               /* Every memory operand can be reloaded to fit.  */
    2397       156107 :               if (!mem)
    2398            0 :                 mem = extract_mem_from_operand (op);
    2399       156107 :               result = result || memory_operand (mem, VOIDmode);
    2400       156107 :               break;
    2401              : 
    2402          143 :             case CT_ADDRESS:
    2403              :               /* Every address operand can be reloaded to fit.  */
    2404          143 :               result = result || address_operand (op, VOIDmode);
    2405          143 :               break;
    2406              : 
    2407        23243 :             case CT_FIXED_FORM:
    2408        23243 :               result = result || constraint_satisfied_p (op, cn);
    2409        23243 :               break;
    2410              :             }
    2411              :           break;
    2412       656425 :         }
    2413      5413089 :       len = CONSTRAINT_LEN (c, constraint);
    2414      5417168 :       do
    2415      5417168 :         constraint++;
    2416     10830257 :       while (--len && *constraint && *constraint != ',');
    2417      5413089 :       if (len)
    2418              :         {
    2419            2 :           raw_constraint_p = false;
    2420            2 :           return 0;
    2421              :         }
    2422              :     }
    2423      3448423 :   raw_constraint_p = false;
    2424              : 
    2425              :   /* For operands without < or > constraints reject side-effects.  */
    2426      3448423 :   if (AUTO_INC_DEC && !incdec_ok && result && MEM_P (op))
    2427              :     switch (GET_CODE (XEXP (op, 0)))
    2428              :       {
    2429              :       case PRE_INC:
    2430              :       case POST_INC:
    2431              :       case PRE_DEC:
    2432              :       case POST_DEC:
    2433              :       case PRE_MODIFY:
    2434              :       case POST_MODIFY:
    2435              :         return 0;
    2436              :       default:
    2437              :         break;
    2438              :       }
    2439              : 
    2440      3448423 :   return result;
    2441              : }
    2442              : 
    2443              : /* Given an rtx *P, if it is a sum containing an integer constant term,
    2444              :    return the location (type rtx *) of the pointer to that constant term.
    2445              :    Otherwise, return a null pointer.  */
    2446              : 
    2447              : rtx *
    2448     41204334 : find_constant_term_loc (rtx *p)
    2449              : {
    2450     41204334 :   rtx *tem;
    2451     41204334 :   enum rtx_code code = GET_CODE (*p);
    2452              : 
    2453              :   /* If *P IS such a constant term, P is its location.  */
    2454              : 
    2455     41204334 :   if (code == CONST_INT || code == SYMBOL_REF || code == LABEL_REF
    2456     29412428 :       || code == CONST)
    2457              :     return p;
    2458              : 
    2459              :   /* Otherwise, if not a sum, it has no constant term.  */
    2460              : 
    2461     29365333 :   if (GET_CODE (*p) != PLUS)
    2462              :     return 0;
    2463              : 
    2464              :   /* If one of the summands is constant, return its location.  */
    2465              : 
    2466     13758599 :   if (XEXP (*p, 0) && CONSTANT_P (XEXP (*p, 0))
    2467            0 :       && XEXP (*p, 1) && CONSTANT_P (XEXP (*p, 1)))
    2468              :     return p;
    2469              : 
    2470              :   /* Otherwise, check each summand for containing a constant term.  */
    2471              : 
    2472     13758599 :   if (XEXP (*p, 0) != 0)
    2473              :     {
    2474     13758599 :       tem = find_constant_term_loc (&XEXP (*p, 0));
    2475     13758599 :       if (tem != 0)
    2476              :         return tem;
    2477              :     }
    2478              : 
    2479     13758599 :   if (XEXP (*p, 1) != 0)
    2480              :     {
    2481     13758599 :       tem = find_constant_term_loc (&XEXP (*p, 1));
    2482     13758599 :       if (tem != 0)
    2483              :         return tem;
    2484              :     }
    2485              : 
    2486              :   return 0;
    2487              : }
    2488              : 
    2489              : /* Return true if OP is a memory reference whose address contains
    2490              :    no side effects and remains valid after the addition of a positive
    2491              :    integer less than the size of the object being referenced.
    2492              : 
    2493              :    We assume that the original address is valid and do not check it.
    2494              : 
    2495              :    This uses strict_memory_address_p as a subroutine, so
    2496              :    don't use it before reload.  */
    2497              : 
    2498              : bool
    2499      5581152 : offsettable_memref_p (rtx op)
    2500              : {
    2501      5581152 :   return ((MEM_P (op))
    2502     11156832 :           && offsettable_address_addr_space_p (1, GET_MODE (op), XEXP (op, 0),
    2503      5575680 :                                                MEM_ADDR_SPACE (op)));
    2504              : }
    2505              : 
    2506              : /* Similar, but don't require a strictly valid mem ref:
    2507              :    consider pseudo-regs valid as index or base regs.  */
    2508              : 
    2509              : bool
    2510     12116255 : offsettable_nonstrict_memref_p (rtx op)
    2511              : {
    2512     12116255 :   return ((MEM_P (op))
    2513     24232476 :           && offsettable_address_addr_space_p (0, GET_MODE (op), XEXP (op, 0),
    2514     12116221 :                                                MEM_ADDR_SPACE (op)));
    2515              : }
    2516              : 
    2517              : /* Return true if Y is a memory address which contains no side effects
    2518              :    and would remain valid for address space AS after the addition of
    2519              :    a positive integer less than the size of that mode.
    2520              : 
    2521              :    We assume that the original address is valid and do not check it.
    2522              :    We do check that it is valid for narrower modes.
    2523              : 
    2524              :    If STRICTP is nonzero, we require a strictly valid address,
    2525              :    for the sake of use in reload.cc.  */
    2526              : 
    2527              : bool
    2528     17691901 : offsettable_address_addr_space_p (int strictp, machine_mode mode, rtx y,
    2529              :                                   addr_space_t as)
    2530              : {
    2531     17691901 :   enum rtx_code ycode = GET_CODE (y);
    2532     17691901 :   rtx z;
    2533     17691901 :   rtx y1 = y;
    2534     17691901 :   rtx *y2;
    2535     12116221 :   bool (*addressp) (machine_mode, rtx, addr_space_t, code_helper) =
    2536     17691901 :     (strictp ? strict_memory_address_addr_space_p
    2537              :              : memory_address_addr_space_p);
    2538     35383802 :   poly_int64 mode_sz = GET_MODE_SIZE (mode);
    2539              : 
    2540     17691901 :   if (CONSTANT_ADDRESS_P (y))
    2541              :     return true;
    2542              : 
    2543              :   /* Adjusting an offsettable address involves changing to a narrower mode.
    2544              :      Make sure that's OK.  */
    2545              : 
    2546     15010148 :   if (mode_dependent_address_p (y, as))
    2547              :     return false;
    2548              : 
    2549     14826178 :   machine_mode address_mode = GET_MODE (y);
    2550     14826178 :   if (address_mode == VOIDmode)
    2551            0 :     address_mode = targetm.addr_space.address_mode (as);
    2552              : #ifdef POINTERS_EXTEND_UNSIGNED
    2553     14826178 :   machine_mode pointer_mode = targetm.addr_space.pointer_mode (as);
    2554              : #endif
    2555              : 
    2556              :   /* ??? How much offset does an offsettable BLKmode reference need?
    2557              :      Clearly that depends on the situation in which it's being used.
    2558              :      However, the current situation in which we test 0xffffffff is
    2559              :      less than ideal.  Caveat user.  */
    2560     14826178 :   if (known_eq (mode_sz, 0))
    2561            0 :     mode_sz = BIGGEST_ALIGNMENT / BITS_PER_UNIT;
    2562              : 
    2563              :   /* If the expression contains a constant term,
    2564              :      see if it remains valid when max possible offset is added.  */
    2565              : 
    2566     14826178 :   if ((ycode == PLUS) && (y2 = find_constant_term_loc (&y1)))
    2567              :     {
    2568     11839001 :       bool good;
    2569              : 
    2570     11839001 :       y1 = *y2;
    2571     11839001 :       *y2 = plus_constant (address_mode, *y2, mode_sz - 1);
    2572              :       /* Use QImode because an odd displacement may be automatically invalid
    2573              :          for any wider mode.  But it should be valid for a single byte.  */
    2574     11839001 :       good = (*addressp) (QImode, y, as, ERROR_MARK);
    2575              : 
    2576              :       /* In any case, restore old contents of memory.  */
    2577     11839001 :       *y2 = y1;
    2578     11839001 :       return good;
    2579              :     }
    2580              : 
    2581      2987177 :   if (GET_RTX_CLASS (ycode) == RTX_AUTOINC)
    2582              :     return false;
    2583              : 
    2584              :   /* The offset added here is chosen as the maximum offset that
    2585              :      any instruction could need to add when operating on something
    2586              :      of the specified mode.  We assume that if Y and Y+c are
    2587              :      valid addresses then so is Y+d for all 0<d<c.  adjust_address will
    2588              :      go inside a LO_SUM here, so we do so as well.  */
    2589      2987177 :   if (GET_CODE (y) == LO_SUM
    2590            0 :       && mode != BLKmode
    2591      2987177 :       && known_le (mode_sz, GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT))
    2592            0 :     z = gen_rtx_LO_SUM (address_mode, XEXP (y, 0),
    2593              :                         plus_constant (address_mode, XEXP (y, 1),
    2594              :                                        mode_sz - 1));
    2595              : #ifdef POINTERS_EXTEND_UNSIGNED
    2596              :   /* Likewise for a ZERO_EXTEND from pointer_mode.  */
    2597      2987177 :   else if (POINTERS_EXTEND_UNSIGNED > 0
    2598      2987177 :            && GET_CODE (y) == ZERO_EXTEND
    2599           13 :            && GET_MODE (XEXP (y, 0)) == pointer_mode)
    2600            7 :     z = gen_rtx_ZERO_EXTEND (address_mode,
    2601              :                              plus_constant (pointer_mode, XEXP (y, 0),
    2602              :                                             mode_sz - 1));
    2603              : #endif
    2604              :   else
    2605      2987170 :     z = plus_constant (address_mode, y, mode_sz - 1);
    2606              : 
    2607              :   /* Use QImode because an odd displacement may be automatically invalid
    2608              :      for any wider mode.  But it should be valid for a single byte.  */
    2609      2987177 :   return (*addressp) (QImode, z, as, ERROR_MARK);
    2610              : }
    2611              : 
    2612              : /* Return true if ADDR is an address-expression whose effect depends
    2613              :    on the mode of the memory reference it is used in.
    2614              : 
    2615              :    ADDRSPACE is the address space associated with the address.
    2616              : 
    2617              :    Autoincrement addressing is a typical example of mode-dependence
    2618              :    because the amount of the increment depends on the mode.  */
    2619              : 
    2620              : bool
    2621     40054095 : mode_dependent_address_p (rtx addr, addr_space_t addrspace)
    2622              : {
    2623              :   /* Auto-increment addressing with anything other than post_modify
    2624              :      or pre_modify always introduces a mode dependency.  Catch such
    2625              :      cases now instead of deferring to the target.  */
    2626     40054095 :   if (GET_CODE (addr) == PRE_INC
    2627     40054095 :       || GET_CODE (addr) == POST_INC
    2628     40054089 :       || GET_CODE (addr) == PRE_DEC
    2629     36275674 :       || GET_CODE (addr) == POST_DEC)
    2630              :     return true;
    2631              : 
    2632     36275674 :   return targetm.mode_dependent_address_p (addr, addrspace);
    2633              : }
    2634              : 
    2635              : /* Return true if boolean attribute ATTR is supported.  */
    2636              : 
    2637              : static bool
    2638   1631527623 : have_bool_attr (bool_attr attr)
    2639              : {
    2640   1631527623 :   switch (attr)
    2641              :     {
    2642              :     case BA_ENABLED:
    2643              :       return HAVE_ATTR_enabled;
    2644              :     case BA_PREFERRED_FOR_SIZE:
    2645              :       return HAVE_ATTR_enabled || HAVE_ATTR_preferred_for_size;
    2646              :     case BA_PREFERRED_FOR_SPEED:
    2647              :       return HAVE_ATTR_enabled || HAVE_ATTR_preferred_for_speed;
    2648              :     }
    2649            0 :   gcc_unreachable ();
    2650              : }
    2651              : 
    2652              : /* Return the value of ATTR for instruction INSN.  */
    2653              : 
    2654              : static bool
    2655   1709480510 : get_bool_attr (rtx_insn *insn, bool_attr attr)
    2656              : {
    2657   1709480510 :   switch (attr)
    2658              :     {
    2659    727129542 :     case BA_ENABLED:
    2660    727129542 :       return get_attr_enabled (insn);
    2661    350890022 :     case BA_PREFERRED_FOR_SIZE:
    2662    350890022 :       return get_attr_enabled (insn) && get_attr_preferred_for_size (insn);
    2663    631460946 :     case BA_PREFERRED_FOR_SPEED:
    2664    631460946 :       return get_attr_enabled (insn) && get_attr_preferred_for_speed (insn);
    2665              :     }
    2666            0 :   gcc_unreachable ();
    2667              : }
    2668              : 
    2669              : /* Like get_bool_attr_mask, but don't use the cache.  */
    2670              : 
    2671              : static alternative_mask
    2672    102268031 : get_bool_attr_mask_uncached (rtx_insn *insn, bool_attr attr)
    2673              : {
    2674              :   /* Temporarily install enough information for get_attr_<foo> to assume
    2675              :      that the insn operands are already cached.  As above, the attribute
    2676              :      mustn't depend on the values of operands, so we don't provide their
    2677              :      real values here.  */
    2678    102268031 :   rtx_insn *old_insn = recog_data.insn;
    2679    102268031 :   int old_alternative = which_alternative;
    2680              : 
    2681    102268031 :   recog_data.insn = insn;
    2682    102268031 :   alternative_mask mask = ALL_ALTERNATIVES;
    2683    102268031 :   int n_alternatives = insn_data[INSN_CODE (insn)].n_alternatives;
    2684   1811748541 :   for (int i = 0; i < n_alternatives; i++)
    2685              :     {
    2686   1709480510 :       which_alternative = i;
    2687   1709480510 :       if (!get_bool_attr (insn, attr))
    2688    517523373 :         mask &= ~ALTERNATIVE_BIT (i);
    2689              :     }
    2690              : 
    2691    102268031 :   recog_data.insn = old_insn;
    2692    102268031 :   which_alternative = old_alternative;
    2693    102268031 :   return mask;
    2694              : }
    2695              : 
    2696              : /* Return the mask of operand alternatives that are allowed for INSN
    2697              :    by boolean attribute ATTR.  This mask depends only on INSN and on
    2698              :    the current target; it does not depend on things like the values of
    2699              :    operands.  */
    2700              : 
    2701              : static alternative_mask
    2702   1633830625 : get_bool_attr_mask (rtx_insn *insn, bool_attr attr)
    2703              : {
    2704              :   /* Quick exit for asms and for targets that don't use these attributes.  */
    2705   1633830625 :   int code = INSN_CODE (insn);
    2706   1633830625 :   if (code < 0 || !have_bool_attr (attr))
    2707              :     return ALL_ALTERNATIVES;
    2708              : 
    2709              :   /* Calling get_attr_<foo> can be expensive, so cache the mask
    2710              :      for speed.  */
    2711   1631527623 :   if (!this_target_recog->x_bool_attr_masks[code][attr])
    2712     13138000 :     this_target_recog->x_bool_attr_masks[code][attr]
    2713     13138000 :       = get_bool_attr_mask_uncached (insn, attr);
    2714   1631527623 :   return this_target_recog->x_bool_attr_masks[code][attr];
    2715              : }
    2716              : 
    2717              : /* Return the set of alternatives of INSN that are allowed by the current
    2718              :    target.  */
    2719              : 
    2720              : alternative_mask
    2721   1170842528 : get_enabled_alternatives (rtx_insn *insn)
    2722              : {
    2723   1170842528 :   return get_bool_attr_mask (insn, BA_ENABLED);
    2724              : }
    2725              : 
    2726              : /* Return the set of alternatives of INSN that are allowed by the current
    2727              :    target and are preferred for the current size/speed optimization
    2728              :    choice.  */
    2729              : 
    2730              : alternative_mask
    2731    462901112 : get_preferred_alternatives (rtx_insn *insn)
    2732              : {
    2733    462901112 :   if (optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn)))
    2734    406712589 :     return get_bool_attr_mask (insn, BA_PREFERRED_FOR_SPEED);
    2735              :   else
    2736     56188523 :     return get_bool_attr_mask (insn, BA_PREFERRED_FOR_SIZE);
    2737              : }
    2738              : 
    2739              : /* Return the set of alternatives of INSN that are allowed by the current
    2740              :    target and are preferred for the size/speed optimization choice
    2741              :    associated with BB.  Passing a separate BB is useful if INSN has not
    2742              :    been emitted yet or if we are considering moving it to a different
    2743              :    block.  */
    2744              : 
    2745              : alternative_mask
    2746        86985 : get_preferred_alternatives (rtx_insn *insn, basic_block bb)
    2747              : {
    2748        86985 :   if (optimize_bb_for_speed_p (bb))
    2749        82102 :     return get_bool_attr_mask (insn, BA_PREFERRED_FOR_SPEED);
    2750              :   else
    2751         4883 :     return get_bool_attr_mask (insn, BA_PREFERRED_FOR_SIZE);
    2752              : }
    2753              : 
    2754              : /* Assert that the cached boolean attributes for INSN are still accurate.
    2755              :    The backend is required to define these attributes in a way that only
    2756              :    depends on the current target (rather than operands, compiler phase,
    2757              :    etc.).  */
    2758              : 
    2759              : bool
    2760     36118585 : check_bool_attrs (rtx_insn *insn)
    2761              : {
    2762     36118585 :   int code = INSN_CODE (insn);
    2763     36118585 :   if (code >= 0)
    2764    144474340 :     for (int i = 0; i <= BA_LAST; ++i)
    2765              :       {
    2766    108355755 :         enum bool_attr attr = (enum bool_attr) i;
    2767    108355755 :         if (this_target_recog->x_bool_attr_masks[code][attr])
    2768     89130031 :           gcc_assert (this_target_recog->x_bool_attr_masks[code][attr]
    2769              :                       == get_bool_attr_mask_uncached (insn, attr));
    2770              :       }
    2771     36118585 :   return true;
    2772              : }
    2773              : 
    2774              : /* Like extract_insn, but save insn extracted and don't extract again, when
    2775              :    called again for the same insn expecting that recog_data still contain the
    2776              :    valid information.  This is used primary by gen_attr infrastructure that
    2777              :    often does extract insn again and again.  */
    2778              : void
    2779  10345123826 : extract_insn_cached (rtx_insn *insn)
    2780              : {
    2781  10345123826 :   if (recog_data.insn == insn && INSN_CODE (insn) >= 0)
    2782              :     return;
    2783    760570920 :   extract_insn (insn);
    2784    760570920 :   recog_data.insn = insn;
    2785              : }
    2786              : 
    2787              : /* Do uncached extract_insn, constrain_operands and complain about failures.
    2788              :    This should be used when extracting a pre-existing constrained instruction
    2789              :    if the caller wants to know which alternative was chosen.  */
    2790              : void
    2791    262067060 : extract_constrain_insn (rtx_insn *insn)
    2792              : {
    2793    262067060 :   extract_insn (insn);
    2794    262067060 :   if (!constrain_operands (reload_completed, get_enabled_alternatives (insn)))
    2795            0 :     fatal_insn_not_found (insn);
    2796    262067060 : }
    2797              : 
    2798              : /* Do cached extract_insn, constrain_operands and complain about failures.
    2799              :    Used by insn_attrtab.  */
    2800              : void
    2801   9150225074 : extract_constrain_insn_cached (rtx_insn *insn)
    2802              : {
    2803   9150225074 :   extract_insn_cached (insn);
    2804   9150225074 :   if (which_alternative == -1
    2805   9150225074 :       && !constrain_operands (reload_completed,
    2806              :                               get_enabled_alternatives (insn)))
    2807            0 :     fatal_insn_not_found (insn);
    2808   9150225074 : }
    2809              : 
    2810              : /* Do cached constrain_operands on INSN and complain about failures.  */
    2811              : bool
    2812    335216752 : constrain_operands_cached (rtx_insn *insn, int strict)
    2813              : {
    2814    335216752 :   if (which_alternative == -1)
    2815     92212207 :     return constrain_operands (strict, get_enabled_alternatives (insn));
    2816              :   else
    2817              :     return true;
    2818              : }
    2819              : 
    2820              : /* Analyze INSN and fill in recog_data.  */
    2821              : 
    2822              : void
    2823   2428943664 : extract_insn (rtx_insn *insn)
    2824              : {
    2825   2428943664 :   int i;
    2826   2428943664 :   int icode;
    2827   2428943664 :   int noperands;
    2828   2428943664 :   rtx body = PATTERN (insn);
    2829              : 
    2830   2428943664 :   recog_data.n_operands = 0;
    2831   2428943664 :   recog_data.n_alternatives = 0;
    2832   2428943664 :   recog_data.n_dups = 0;
    2833   2428943664 :   recog_data.is_asm = false;
    2834              : 
    2835   2428943664 :   switch (GET_CODE (body))
    2836              :     {
    2837              :     case USE:
    2838              :     case CLOBBER:
    2839              :     case ASM_INPUT:
    2840              :     case ADDR_VEC:
    2841              :     case ADDR_DIFF_VEC:
    2842              :     case VAR_LOCATION:
    2843              :     case DEBUG_MARKER:
    2844              :       return;
    2845              : 
    2846   1810602482 :     case SET:
    2847   1810602482 :       if (GET_CODE (SET_SRC (body)) == ASM_OPERANDS)
    2848          400 :         goto asm_insn;
    2849              :       else
    2850   1810602082 :         goto normal_insn;
    2851    243538820 :     case PARALLEL:
    2852    243538820 :       if ((GET_CODE (XVECEXP (body, 0, 0)) == SET
    2853    238933973 :            && GET_CODE (SET_SRC (XVECEXP (body, 0, 0))) == ASM_OPERANDS)
    2854    243066858 :           || GET_CODE (XVECEXP (body, 0, 0)) == ASM_OPERANDS
    2855    242339147 :           || GET_CODE (XVECEXP (body, 0, 0)) == ASM_INPUT)
    2856      1210487 :         goto asm_insn;
    2857              :       else
    2858    242328333 :         goto normal_insn;
    2859      1211027 :     case ASM_OPERANDS:
    2860      1211027 :     asm_insn:
    2861      1211027 :       recog_data.n_operands = noperands = asm_noperands (body);
    2862      1211027 :       if (noperands >= 0)
    2863              :         {
    2864              :           /* This insn is an `asm' with operands.  */
    2865              : 
    2866              :           /* expand_asm_operands makes sure there aren't too many operands.  */
    2867      1211027 :           gcc_assert (noperands <= MAX_RECOG_OPERANDS);
    2868              : 
    2869              :           /* Now get the operand values and constraints out of the insn.  */
    2870      1211027 :           decode_asm_operands (body, recog_data.operand,
    2871              :                                recog_data.operand_loc,
    2872              :                                recog_data.constraints,
    2873              :                                recog_data.operand_mode, NULL);
    2874      1211027 :           memset (recog_data.is_operator, 0, sizeof recog_data.is_operator);
    2875      1211027 :           if (noperands > 0)
    2876              :             {
    2877       578051 :               const char *p =  recog_data.constraints[0];
    2878       578051 :               recog_data.n_alternatives = 1;
    2879      1631832 :               while (*p)
    2880      1053781 :                 recog_data.n_alternatives += (*p++ == ',');
    2881              :             }
    2882      1211027 :           recog_data.is_asm = true;
    2883      1211027 :           break;
    2884              :         }
    2885            0 :       fatal_insn_not_found (insn);
    2886              : 
    2887   2114762094 :     default:
    2888   2114762094 :     normal_insn:
    2889              :       /* Ordinary insn: recognize it, get the operands via insn_extract
    2890              :          and get the constraints.  */
    2891              : 
    2892   2114762094 :       icode = recog_memoized (insn);
    2893   2114762094 :       if (icode < 0)
    2894            0 :         fatal_insn_not_found (insn);
    2895              : 
    2896   2114762094 :       recog_data.n_operands = noperands = insn_data[icode].n_operands;
    2897   2114762094 :       recog_data.n_alternatives = insn_data[icode].n_alternatives;
    2898   2114762094 :       recog_data.n_dups = insn_data[icode].n_dups;
    2899              : 
    2900   2114762094 :       insn_extract (insn);
    2901              : 
    2902   8755893911 :       for (i = 0; i < noperands; i++)
    2903              :         {
    2904   4526369723 :           recog_data.constraints[i] = insn_data[icode].operand[i].constraint;
    2905   4526369723 :           recog_data.is_operator[i] = insn_data[icode].operand[i].is_operator;
    2906   4526369723 :           recog_data.operand_mode[i] = insn_data[icode].operand[i].mode;
    2907              :           /* VOIDmode match_operands gets mode from their real operand.  */
    2908   4526369723 :           if (recog_data.operand_mode[i] == VOIDmode)
    2909    457698758 :             recog_data.operand_mode[i] = GET_MODE (recog_data.operand[i]);
    2910              :         }
    2911              :     }
    2912   6644188825 :   for (i = 0; i < noperands; i++)
    2913   4528215704 :     recog_data.operand_type[i]
    2914   7354806007 :       = (recog_data.constraints[i][0] == '=' ? OP_OUT
    2915   2826590303 :          : recog_data.constraints[i][0] == '+' ? OP_INOUT
    2916              :          : OP_IN);
    2917              : 
    2918   2115973121 :   gcc_assert (recog_data.n_alternatives <= MAX_RECOG_ALTERNATIVES);
    2919              : 
    2920   2115973121 :   recog_data.insn = NULL;
    2921   2115973121 :   which_alternative = -1;
    2922              : }
    2923              : 
    2924              : /* Fill in OP_ALT_BASE for an instruction that has N_OPERANDS
    2925              :    operands, N_ALTERNATIVES alternatives and constraint strings
    2926              :    CONSTRAINTS.  OP_ALT_BASE has N_ALTERNATIVES * N_OPERANDS entries
    2927              :    and CONSTRAINTS has N_OPERANDS entries.  OPLOC should be passed in
    2928              :    if the insn is an asm statement and preprocessing should take the
    2929              :    asm operands into account, e.g. to determine whether they could be
    2930              :    addresses in constraints that require addresses; it should then
    2931              :    point to an array of pointers to each operand.  */
    2932              : 
    2933              : void
    2934      4774844 : preprocess_constraints (int n_operands, int n_alternatives,
    2935              :                         const char **constraints,
    2936              :                         operand_alternative *op_alt_base,
    2937              :                         rtx **oploc)
    2938              : {
    2939     12313762 :   for (int i = 0; i < n_operands; i++)
    2940              :     {
    2941      7538918 :       int j;
    2942      7538918 :       struct operand_alternative *op_alt;
    2943      7538918 :       const char *p = constraints[i];
    2944              : 
    2945      7538918 :       op_alt = op_alt_base;
    2946              : 
    2947     49287816 :       for (j = 0; j < n_alternatives; j++, op_alt += n_operands)
    2948              :         {
    2949     41748898 :           op_alt[i].cl = NO_REGS;
    2950     41748898 :           op_alt[i].register_filters = 0;
    2951     41748898 :           op_alt[i].constraint = p;
    2952     41748898 :           op_alt[i].matches = -1;
    2953     41748898 :           op_alt[i].matched = -1;
    2954              : 
    2955     41748898 :           if (*p == '\0' || *p == ',')
    2956              :             {
    2957      1771471 :               op_alt[i].anything_ok = 1;
    2958      1771471 :               continue;
    2959              :             }
    2960              : 
    2961    104735704 :           for (;;)
    2962              :             {
    2963    104735704 :               char c = *p;
    2964    104735704 :               if (c == '#')
    2965            0 :                 do
    2966            0 :                   c = *++p;
    2967            0 :                 while (c != ',' && c != '\0');
    2968    104735704 :               if (c == ',' || c == '\0')
    2969              :                 {
    2970     39977427 :                   p++;
    2971     39977427 :                   break;
    2972              :                 }
    2973              : 
    2974     64758277 :               switch (c)
    2975              :                 {
    2976      5812689 :                 case '?':
    2977      5812689 :                   op_alt[i].reject += 6;
    2978      5812689 :                   break;
    2979       405902 :                 case '!':
    2980       405902 :                   op_alt[i].reject += 600;
    2981       405902 :                   break;
    2982        60238 :                 case '&':
    2983        60238 :                   op_alt[i].earlyclobber = 1;
    2984        60238 :                   break;
    2985              : 
    2986      2047470 :                 case '0': case '1': case '2': case '3': case '4':
    2987      2047470 :                 case '5': case '6': case '7': case '8': case '9':
    2988      2047470 :                   {
    2989      2047470 :                     char *end;
    2990      2047470 :                     op_alt[i].matches = strtoul (p, &end, 10);
    2991      2047470 :                     op_alt[op_alt[i].matches].matched = i;
    2992      2047470 :                     p = end;
    2993              :                   }
    2994      2047470 :                   continue;
    2995              : 
    2996        31486 :                 case 'X':
    2997        31486 :                   op_alt[i].anything_ok = 1;
    2998        31486 :                   break;
    2999              : 
    3000       210663 :                 case 'g':
    3001       210663 :                   op_alt[i].cl =
    3002       210663 :                    reg_class_subunion[(int) op_alt[i].cl][(int) GENERAL_REGS];
    3003       210663 :                   break;
    3004              : 
    3005     56189829 :                 default:
    3006     56189829 :                   enum constraint_num cn = lookup_constraint (p);
    3007     56189829 :                   enum reg_class cl;
    3008     56189829 :                   switch (get_constraint_type (cn))
    3009              :                     {
    3010     40171511 :                     case CT_REGISTER:
    3011     40171511 :                       cl = reg_class_for_constraint (cn);
    3012     29173200 :                       if (cl != NO_REGS)
    3013              :                         {
    3014     25552130 :                           op_alt[i].cl = reg_class_subunion[op_alt[i].cl][cl];
    3015     25552130 :                           auto filter_id = get_register_filter_id (cn);
    3016     25552130 :                           if (filter_id >= 0)
    3017              :                             op_alt[i].register_filters |= 1U << filter_id;
    3018              :                         }
    3019              :                       break;
    3020              : 
    3021              :                     case CT_CONST_INT:
    3022              :                       break;
    3023              : 
    3024      7942419 :                     case CT_MEMORY:
    3025      7942419 :                     case CT_SPECIAL_MEMORY:
    3026      7942419 :                     case CT_RELAXED_MEMORY:
    3027      7942419 :                       op_alt[i].memory_ok = 1;
    3028      7942419 :                       break;
    3029              : 
    3030        87977 :                     case CT_ADDRESS:
    3031        87977 :                       if (oploc && !address_operand (*oploc[i], VOIDmode))
    3032              :                         break;
    3033              : 
    3034        87958 :                       op_alt[i].is_address = 1;
    3035        87958 :                       op_alt[i].cl
    3036        87958 :                         = (reg_class_subunion
    3037        87958 :                            [(int) op_alt[i].cl]
    3038        87958 :                            [(int) base_reg_class (VOIDmode, ADDR_SPACE_GENERIC,
    3039        87958 :                                                   ADDRESS, SCRATCH)]);
    3040        87958 :                       break;
    3041              : 
    3042              :                     case CT_FIXED_FORM:
    3043              :                       break;
    3044              :                     }
    3045              :                   break;
    3046      2047470 :                 }
    3047     62710807 :               p += CONSTRAINT_LEN (c, p);
    3048              :             }
    3049              :         }
    3050              :     }
    3051      4774844 : }
    3052              : 
    3053              : /* Return an array of operand_alternative instructions for
    3054              :    instruction ICODE.  */
    3055              : 
    3056              : const operand_alternative *
    3057    289488893 : preprocess_insn_constraints (unsigned int icode)
    3058              : {
    3059    289488893 :   gcc_checking_assert (IN_RANGE (icode, 0, NUM_INSN_CODES - 1));
    3060    289488893 :   if (this_target_recog->x_op_alt[icode])
    3061              :     return this_target_recog->x_op_alt[icode];
    3062              : 
    3063      5476873 :   int n_operands = insn_data[icode].n_operands;
    3064      5476873 :   if (n_operands == 0)
    3065              :     return 0;
    3066              :   /* Always provide at least one alternative so that which_op_alt ()
    3067              :      works correctly.  If the instruction has 0 alternatives (i.e. all
    3068              :      constraint strings are empty) then each operand in this alternative
    3069              :      will have anything_ok set.  */
    3070      2967367 :   int n_alternatives = MAX (insn_data[icode].n_alternatives, 1);
    3071      2967367 :   int n_entries = n_operands * n_alternatives;
    3072              : 
    3073      2967367 :   operand_alternative *op_alt = XCNEWVEC (operand_alternative, n_entries);
    3074      2967367 :   const char **constraints = XALLOCAVEC (const char *, n_operands);
    3075              : 
    3076     10068561 :   for (int i = 0; i < n_operands; ++i)
    3077      7101194 :     constraints[i] = insn_data[icode].operand[i].constraint;
    3078      2967367 :   preprocess_constraints (n_operands, n_alternatives, constraints, op_alt,
    3079              :                           NULL);
    3080              : 
    3081      2967367 :   this_target_recog->x_op_alt[icode] = op_alt;
    3082      2967367 :   return op_alt;
    3083              : }
    3084              : 
    3085              : /* After calling extract_insn, you can use this function to extract some
    3086              :    information from the constraint strings into a more usable form.
    3087              :    The collected data is stored in recog_op_alt.  */
    3088              : 
    3089              : void
    3090    197142027 : preprocess_constraints (rtx_insn *insn)
    3091              : {
    3092    197142027 :   int icode = INSN_CODE (insn);
    3093    197142027 :   if (icode >= 0)
    3094    195377569 :     recog_op_alt = preprocess_insn_constraints (icode);
    3095              :   else
    3096              :     {
    3097      1764458 :       int n_operands = recog_data.n_operands;
    3098      1764458 :       int n_alternatives = recog_data.n_alternatives;
    3099      1764458 :       int n_entries = n_operands * n_alternatives;
    3100      1764458 :       memset (asm_op_alt, 0, n_entries * sizeof (operand_alternative));
    3101      1764458 :       preprocess_constraints (n_operands, n_alternatives,
    3102              :                               recog_data.constraints, asm_op_alt,
    3103              :                               NULL);
    3104      1764458 :       recog_op_alt = asm_op_alt;
    3105              :     }
    3106    197142027 : }
    3107              : 
    3108              : /* Check the operands of an insn against the insn's operand constraints
    3109              :    and return 1 if they match any of the alternatives in ALTERNATIVES.
    3110              : 
    3111              :    The information about the insn's operands, constraints, operand modes
    3112              :    etc. is obtained from the global variables set up by extract_insn.
    3113              : 
    3114              :    WHICH_ALTERNATIVE is set to a number which indicates which
    3115              :    alternative of constraints was matched: 0 for the first alternative,
    3116              :    1 for the next, etc.
    3117              : 
    3118              :    In addition, when two operands are required to match
    3119              :    and it happens that the output operand is (reg) while the
    3120              :    input operand is --(reg) or ++(reg) (a pre-inc or pre-dec),
    3121              :    make the output operand look like the input.
    3122              :    This is because the output operand is the one the template will print.
    3123              : 
    3124              :    This is used in final, just before printing the assembler code and by
    3125              :    the routines that determine an insn's attribute.
    3126              : 
    3127              :    If STRICT is a positive nonzero value, it means that we have been
    3128              :    called after reload has been completed.  In that case, we must
    3129              :    do all checks strictly.  If it is zero, it means that we have been called
    3130              :    before reload has completed.  In that case, we first try to see if we can
    3131              :    find an alternative that matches strictly.  If not, we try again, this
    3132              :    time assuming that reload will fix up the insn.  This provides a "best
    3133              :    guess" for the alternative and is used to compute attributes of insns prior
    3134              :    to reload.  A negative value of STRICT is used for this internal call.  */
    3135              : 
    3136              : struct funny_match
    3137              : {
    3138              :   int this_op, other;
    3139              : };
    3140              : 
    3141              : bool
    3142   1135773095 : constrain_operands (int strict, alternative_mask alternatives)
    3143              : {
    3144   1136655606 :   const char *constraints[MAX_RECOG_OPERANDS];
    3145   1136655606 :   int matching_operands[MAX_RECOG_OPERANDS];
    3146   1136655606 :   int earlyclobber[MAX_RECOG_OPERANDS];
    3147   1136655606 :   int c;
    3148              : 
    3149   1136655606 :   struct funny_match funny_match[MAX_RECOG_OPERANDS];
    3150   1136655606 :   int funny_match_index;
    3151              : 
    3152   1136655606 :   which_alternative = 0;
    3153   1136655606 :   if (recog_data.n_operands == 0 || recog_data.n_alternatives == 0)
    3154              :     return true;
    3155              : 
    3156   3377895259 :   for (c = 0; c < recog_data.n_operands; c++)
    3157   2300397033 :     constraints[c] = recog_data.constraints[c];
    3158              : 
    3159   4068563396 :   do
    3160              :     {
    3161   4068563396 :       int seen_earlyclobber_at = -1;
    3162   4068563396 :       int opno;
    3163   4068563396 :       bool lose = false;
    3164   4068563396 :       funny_match_index = 0;
    3165              : 
    3166   4068563396 :       if (!TEST_BIT (alternatives, which_alternative))
    3167              :         {
    3168              :           int i;
    3169              : 
    3170   2746174812 :           for (i = 0; i < recog_data.n_operands; i++)
    3171   3686102492 :             constraints[i] = skip_alternative (constraints[i]);
    3172              : 
    3173    903123566 :           which_alternative++;
    3174    903123566 :           continue;
    3175    903123566 :         }
    3176              : 
    3177   9726894018 :       for (opno = 0; opno < recog_data.n_operands; opno++)
    3178   6561454188 :         matching_operands[opno] = -1;
    3179              : 
    3180   9726894018 :       for (opno = 0; opno < recog_data.n_operands; opno++)
    3181              :         {
    3182   6561454188 :           rtx op = recog_data.operand[opno];
    3183   6561454188 :           machine_mode mode = GET_MODE (op);
    3184   6561454188 :           const char *p = constraints[opno];
    3185   6561454188 :           int offset = 0;
    3186   6561454188 :           bool win = false;
    3187   6561454188 :           int val;
    3188   6561454188 :           int len;
    3189              : 
    3190   6561454188 :           earlyclobber[opno] = 0;
    3191              : 
    3192   6561454188 :           if (GET_CODE (op) == SUBREG)
    3193              :             {
    3194      1461011 :               if (REG_P (SUBREG_REG (op))
    3195      1461011 :                   && REGNO (SUBREG_REG (op)) < FIRST_PSEUDO_REGISTER)
    3196          412 :                 offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
    3197          412 :                                               GET_MODE (SUBREG_REG (op)),
    3198          412 :                                               SUBREG_BYTE (op),
    3199              :                                               GET_MODE (op));
    3200      1461011 :               op = SUBREG_REG (op);
    3201              :             }
    3202              : 
    3203              :           /* An empty constraint or empty alternative
    3204              :              allows anything which matched the pattern.  */
    3205   6561454188 :           if (*p == 0 || *p == ',')
    3206     94317560 :             win = true;
    3207              : 
    3208  16578330526 :           do
    3209  16578330526 :             switch (c = *p, len = CONSTRAINT_LEN (c, p), c)
    3210              :               {
    3211              :               case '\0':
    3212              :                 len = 0;
    3213              :                 break;
    3214   6217724227 :               case ',':
    3215   6217724227 :                 c = '\0';
    3216   6217724227 :                 break;
    3217           32 :               case '-':
    3218           32 :                 raw_constraint_p = true;
    3219           32 :                 break;
    3220              : 
    3221            0 :               case '#':
    3222              :                 /* Ignore rest of this alternative as far as
    3223              :                    constraint checking is concerned.  */
    3224            0 :                 do
    3225            0 :                   p++;
    3226            0 :                 while (*p && *p != ',');
    3227              :                 len = 0;
    3228              :                 break;
    3229              : 
    3230       421883 :               case '&':
    3231       421883 :                 earlyclobber[opno] = 1;
    3232       421883 :                 if (seen_earlyclobber_at < 0)
    3233       403502 :                   seen_earlyclobber_at = opno;
    3234              :                 break;
    3235              : 
    3236    186759186 :               case '0':  case '1':  case '2':  case '3':  case '4':
    3237    186759186 :               case '5':  case '6':  case '7':  case '8':  case '9':
    3238    186759186 :                 {
    3239              :                   /* This operand must be the same as a previous one.
    3240              :                      This kind of constraint is used for instructions such
    3241              :                      as add when they take only two operands.
    3242              : 
    3243              :                      Note that the lower-numbered operand is passed first.
    3244              : 
    3245              :                      If we are not testing strictly, assume that this
    3246              :                      constraint will be satisfied.  */
    3247              : 
    3248    186759186 :                   char *end;
    3249    186759186 :                   int match;
    3250              : 
    3251    186759186 :                   match = strtoul (p, &end, 10);
    3252    186759186 :                   p = end;
    3253              : 
    3254    186759186 :                   if (strict < 0)
    3255              :                     val = 1;
    3256              :                   else
    3257              :                     {
    3258    185855987 :                       rtx op1 = recog_data.operand[match];
    3259    185855987 :                       rtx op2 = recog_data.operand[opno];
    3260    185855987 :                       val = operands_match_p (op1, op2);
    3261              :                     }
    3262              : 
    3263    186759186 :                   matching_operands[opno] = match;
    3264    186759186 :                   matching_operands[match] = opno;
    3265              : 
    3266    186759186 :                   if (val != 0)
    3267    154235881 :                     win = true;
    3268              : 
    3269              :                   /* If output is *x and input is *--x, arrange later
    3270              :                      to change the output to *--x as well, since the
    3271              :                      output op is the one that will be printed.  */
    3272    186759186 :                   if (val == 2 && strict > 0)
    3273              :                     {
    3274            0 :                       funny_match[funny_match_index].this_op = opno;
    3275            0 :                       funny_match[funny_match_index++].other = match;
    3276              :                     }
    3277              :                 }
    3278    186759186 :                 len = 0;
    3279    186759186 :                 break;
    3280              : 
    3281       267455 :               case 'p':
    3282              :                 /* p is used for address_operands.  When we are called by
    3283              :                    gen_reload, no one will have checked that the address is
    3284              :                    strictly valid, i.e., that all pseudos requiring hard regs
    3285              :                    have gotten them.  We also want to make sure we have a
    3286              :                    valid mode.  */
    3287       267455 :                 {
    3288       267368 :                   auto mem_mode = (recog_data.is_asm
    3289       267455 :                                    ? VOIDmode
    3290              :                                    : recog_data.operand_mode[opno]);
    3291       267455 :                   if ((GET_MODE (op) == VOIDmode
    3292       267455 :                        || SCALAR_INT_MODE_P (GET_MODE (op)))
    3293       534884 :                       && (strict <= 0
    3294       267455 :                           || strict_memory_address_p (mem_mode, op)))
    3295       267389 :                     win = true;
    3296              :                   break;
    3297              :                 }
    3298              : 
    3299              :                 /* No need to check general_operand again;
    3300              :                    it was done in insn-recog.cc.  Well, except that reload
    3301              :                    doesn't check the validity of its replacements, but
    3302              :                    that should only matter when there's a bug.  */
    3303    125559992 :               case 'g':
    3304              :                 /* Anything goes unless it is a REG and really has a hard reg
    3305              :                    but the hard reg is not in the class GENERAL_REGS.  */
    3306    125559992 :                 if (REG_P (op))
    3307              :                   {
    3308     47857325 :                     if (strict < 0
    3309              :                         || GENERAL_REGS == ALL_REGS
    3310     47857273 :                         || (reload_in_progress
    3311            0 :                             && REGNO (op) >= FIRST_PSEUDO_REGISTER)
    3312     95714598 :                         || reg_fits_class_p (op, GENERAL_REGS, offset, mode))
    3313              :                       win = true;
    3314              :                   }
    3315     77702667 :                 else if (strict < 0 || general_operand (op, mode))
    3316              :                   win = true;
    3317              :                 break;
    3318              : 
    3319          255 :               case '{':
    3320          247 :                 if ((REG_P (op) && HARD_REGISTER_P (op)
    3321          247 :                      && (int) REGNO (op) == decode_hard_reg_constraint (p))
    3322          269 :                     || !reload_completed)
    3323              :                   win = true;
    3324              :                 break;
    3325              : 
    3326   9703867535 :               default:
    3327   9703867535 :                 {
    3328   9703867535 :                   enum constraint_num cn = lookup_constraint (p);
    3329   9703867535 :                   enum reg_class cl = reg_class_for_constraint (cn);
    3330   4492674120 :                   if (cl != NO_REGS)
    3331              :                     {
    3332   4313065627 :                       auto *filter = get_register_filter (cn);
    3333   4313065627 :                       if (strict < 0
    3334   4311418827 :                           || (strict == 0
    3335     22017983 :                               && REG_P (op)
    3336     16175933 :                               && REGNO (op) >= FIRST_PSEUDO_REGISTER)
    3337      5918559 :                           || (strict == 0 && GET_CODE (op) == SCRATCH)
    3338   8608368284 :                           || (REG_P (op)
    3339   3096884047 :                               && reg_fits_class_p (op, cl, offset, mode)
    3340              :                               && (!filter
    3341              :                                   || TEST_HARD_REG_BIT (*filter,
    3342              :                                                         REGNO (op) + offset))))
    3343              :                         win = true;
    3344              :                     }
    3345              : 
    3346   5390801908 :                   else if (constraint_satisfied_p (op, cn))
    3347              :                     win = true;
    3348              : 
    3349   4509020425 :                   else if ((insn_extra_memory_constraint (cn)
    3350              :                             || insn_extra_relaxed_memory_constraint (cn))
    3351              :                            /* Every memory operand can be reloaded to fit.  */
    3352   4509020425 :                            && ((strict < 0 && MEM_P (op))
    3353              :                                /* Before reload, accept what reload can turn
    3354              :                                   into a mem.  */
    3355       676213 :                                || (strict < 0 && CONSTANT_P (op))
    3356              :                                /* Before reload, accept a pseudo or hard register,
    3357              :                                   since LRA can turn it into a mem.  */
    3358       675851 :                                || (strict < 0 && targetm.lra_p () && REG_P (op))
    3359              :                                /* During reload, accept a pseudo  */
    3360    943238115 :                                || (reload_in_progress && REG_P (op)
    3361            0 :                                    && REGNO (op) >= FIRST_PSEUDO_REGISTER)))
    3362              :                     win = true;
    3363   4508344212 :                   else if (insn_extra_address_constraint (cn)
    3364              :                            /* Every address operand can be reloaded to fit.  */
    3365   4508344212 :                            && strict < 0)
    3366              :                     win = true;
    3367              :                   /* Cater to architectures like IA-64 that define extra memory
    3368              :                      constraints without using define_memory_constraint.  */
    3369   4508344212 :                   else if (reload_in_progress
    3370            0 :                            && REG_P (op)
    3371            0 :                            && REGNO (op) >= FIRST_PSEUDO_REGISTER
    3372            0 :                            && reg_renumber[REGNO (op)] < 0
    3373            0 :                            && reg_equiv_mem (REGNO (op)) != 0
    3374   4508344212 :                            && constraint_satisfied_p
    3375            0 :                               (reg_equiv_mem (REGNO (op)), cn))
    3376              :                     win = true;
    3377              :                   break;
    3378              :                 }
    3379              :               }
    3380  16578330526 :           while (p += len, c);
    3381              : 
    3382   6561454188 :           raw_constraint_p = false;
    3383   6561454188 :           constraints[opno] = p;
    3384              :           /* If this operand did not win somehow,
    3385              :              this alternative loses.  */
    3386   6561454188 :           if (! win)
    3387   3188976391 :             lose = true;
    3388              :         }
    3389              :       /* This alternative won; the operands are ok.
    3390              :          Change whichever operands this alternative says to change.  */
    3391   3165439830 :       if (! lose)
    3392              :         {
    3393   1073228731 :           int opno, eopno;
    3394              : 
    3395              :           /* See if any earlyclobber operand conflicts with some other
    3396              :              operand.  */
    3397              : 
    3398   1073228731 :           if (strict > 0  && seen_earlyclobber_at >= 0)
    3399      1026878 :             for (eopno = seen_earlyclobber_at;
    3400      1355677 :                  eopno < recog_data.n_operands;
    3401              :                  eopno++)
    3402              :               /* Ignore earlyclobber operands now in memory,
    3403              :                  because we would often report failure when we have
    3404              :                  two memory operands, one of which was formerly a REG.  */
    3405      1026878 :               if (earlyclobber[eopno]
    3406       345305 :                   && REG_P (recog_data.operand[eopno]))
    3407      1759631 :                 for (opno = 0; opno < recog_data.n_operands; opno++)
    3408      1414326 :                   if ((MEM_P (recog_data.operand[opno])
    3409      1272583 :                        || recog_data.operand_type[opno] != OP_OUT)
    3410       838429 :                       && opno != eopno
    3411              :                       /* Ignore things like match_operator operands.  */
    3412       837869 :                       && *recog_data.constraints[opno] != 0
    3413       866614 :                       && ! (matching_operands[opno] == eopno
    3414        97948 :                             && operands_match_p (recog_data.operand[opno],
    3415              :                                                  recog_data.operand[eopno]))
    3416      2087192 :                       && ! safe_from_earlyclobber (recog_data.operand[opno],
    3417              :                                                    recog_data.operand[eopno]))
    3418              :                     lose = true;
    3419              : 
    3420   1073228731 :           if (! lose)
    3421              :             {
    3422   1073227741 :               while (--funny_match_index >= 0)
    3423              :                 {
    3424            0 :                   recog_data.operand[funny_match[funny_match_index].other]
    3425            0 :                     = recog_data.operand[funny_match[funny_match_index].this_op];
    3426              :                 }
    3427              : 
    3428              :               /* For operands without < or > constraints reject side-effects.  */
    3429              :               if (AUTO_INC_DEC && recog_data.is_asm)
    3430              :                 {
    3431              :                   for (opno = 0; opno < recog_data.n_operands; opno++)
    3432              :                     if (MEM_P (recog_data.operand[opno]))
    3433              :                       switch (GET_CODE (XEXP (recog_data.operand[opno], 0)))
    3434              :                         {
    3435              :                         case PRE_INC:
    3436              :                         case POST_INC:
    3437              :                         case PRE_DEC:
    3438              :                         case POST_DEC:
    3439              :                         case PRE_MODIFY:
    3440              :                         case POST_MODIFY:
    3441              :                           if (strchr (recog_data.constraints[opno], '<') == NULL
    3442              :                               && strchr (recog_data.constraints[opno], '>')
    3443              :                                  == NULL)
    3444              :                             return false;
    3445              :                           break;
    3446              :                         default:
    3447              :                           break;
    3448              :                         }
    3449              :                 }
    3450              : 
    3451              :               return true;
    3452              :             }
    3453              :         }
    3454              : 
    3455   2092212089 :       which_alternative++;
    3456              :     }
    3457   2995335655 :   while (which_alternative < recog_data.n_alternatives);
    3458              : 
    3459      4270485 :   which_alternative = -1;
    3460              :   /* If we are about to reject this, but we are not to test strictly,
    3461              :      try a very loose test.  Only return failure if it fails also.  */
    3462      4270485 :   if (strict == 0)
    3463              :     return constrain_operands (-1, alternatives);
    3464              :   else
    3465              :     return false;
    3466              : }
    3467              : 
    3468              : /* Return true iff OPERAND (assumed to be a REG rtx)
    3469              :    is a hard reg in class CLASS when its regno is offset by OFFSET
    3470              :    and changed to mode MODE.
    3471              :    If REG occupies multiple hard regs, all of them must be in CLASS.  */
    3472              : 
    3473              : bool
    3474   3390277315 : reg_fits_class_p (const_rtx operand, reg_class_t cl, int offset,
    3475              :                   machine_mode mode)
    3476              : {
    3477   3390277315 :   unsigned int regno = REGNO (operand);
    3478              : 
    3479   3390277315 :   if (cl == NO_REGS)
    3480              :     return false;
    3481              : 
    3482              :   /* Regno must not be a pseudo register.  Offset may be negative.  */
    3483   3294112509 :   return (HARD_REGISTER_NUM_P (regno)
    3484   3294037629 :           && HARD_REGISTER_NUM_P (regno + offset)
    3485   6588150138 :           && in_hard_reg_set_p (reg_class_contents[(int) cl], mode,
    3486              :                                 regno + offset));
    3487              : }
    3488              : 
    3489              : /* Split single instruction.  Helper function for split_all_insns and
    3490              :    split_all_insns_noflow.  Return last insn in the sequence if successful,
    3491              :    or NULL if unsuccessful.  */
    3492              : 
    3493              : static rtx_insn *
    3494    372526164 : split_insn (rtx_insn *insn)
    3495              : {
    3496              :   /* Split insns here to get max fine-grain parallelism.  */
    3497    372526164 :   rtx_insn *first = PREV_INSN (insn);
    3498    372526164 :   rtx_insn *last = try_split (PATTERN (insn), insn, 1);
    3499    372526164 :   rtx insn_set, last_set, note;
    3500              : 
    3501    372526164 :   if (last == insn)
    3502              :     return NULL;
    3503              : 
    3504              :   /* If the original instruction was a single set that was known to be
    3505              :      equivalent to a constant, see if we can say the same about the last
    3506              :      instruction in the split sequence.  The two instructions must set
    3507              :      the same destination.  */
    3508      6136928 :   insn_set = single_set (insn);
    3509      6136928 :   if (insn_set)
    3510              :     {
    3511      6028590 :       last_set = single_set (last);
    3512      6028590 :       if (last_set && rtx_equal_p (SET_DEST (last_set), SET_DEST (insn_set)))
    3513              :         {
    3514      2847766 :           note = find_reg_equal_equiv_note (insn);
    3515      2847766 :           if (note && CONSTANT_P (XEXP (note, 0)))
    3516        84830 :             set_unique_reg_note (last, REG_EQUAL, XEXP (note, 0));
    3517      2762936 :           else if (CONSTANT_P (SET_SRC (insn_set)))
    3518        34246 :             set_unique_reg_note (last, REG_EQUAL,
    3519              :                                  copy_rtx (SET_SRC (insn_set)));
    3520              :         }
    3521              :     }
    3522              : 
    3523              :   /* try_split returns the NOTE that INSN became.  */
    3524      6136928 :   SET_INSN_DELETED (insn);
    3525              : 
    3526              :   /* ??? Coddle to md files that generate subregs in post-reload
    3527              :      splitters instead of computing the proper hard register.  */
    3528      6136928 :   if (reload_completed && first != last)
    3529              :     {
    3530      5701903 :       auto old_post_ra_split_completed = post_ra_split_completed;
    3531      5701903 :       post_ra_split_completed = true;
    3532      5701903 :       first = NEXT_INSN (first);
    3533      2703303 :       for (;;)
    3534              :         {
    3535      8405206 :           if (INSN_P (first))
    3536      8401307 :             cleanup_subreg_operands (first);
    3537      8405206 :           if (first == last)
    3538              :             break;
    3539      2703303 :           first = NEXT_INSN (first);
    3540              :         }
    3541      5701903 :       post_ra_split_completed = old_post_ra_split_completed;
    3542              :     }
    3543              : 
    3544              :   return last;
    3545              : }
    3546              : 
    3547              : /* Split all insns in the function.  If UPD_LIFE, update life info after.  */
    3548              : 
    3549              : void
    3550      4018596 : split_all_insns (void)
    3551              : {
    3552      4018596 :   bool changed;
    3553      4018596 :   bool need_cfg_cleanup = false;
    3554      4018596 :   basic_block bb;
    3555              : 
    3556      4018596 :   auto_sbitmap blocks (last_basic_block_for_fn (cfun));
    3557      4018596 :   bitmap_clear (blocks);
    3558      4018596 :   changed = false;
    3559              : 
    3560     43166418 :   FOR_EACH_BB_REVERSE_FN (bb, cfun)
    3561              :     {
    3562     39147822 :       rtx_insn *insn, *next;
    3563     39147822 :       bool finish = false;
    3564              : 
    3565     39147822 :       rtl_profile_for_bb (bb);
    3566    491799738 :       for (insn = BB_HEAD (bb); !finish ; insn = next)
    3567              :         {
    3568              :           /* Can't use `next_real_insn' because that might go across
    3569              :              CODE_LABELS and short-out basic blocks.  */
    3570    452651916 :           next = NEXT_INSN (insn);
    3571    452651916 :           finish = (insn == BB_END (bb));
    3572              : 
    3573              :           /* If INSN has a REG_EH_REGION note and we split INSN, the
    3574              :              resulting split may not have/need REG_EH_REGION notes.
    3575              : 
    3576              :              If that happens and INSN was the last reference to the
    3577              :              given EH region, then the EH region will become unreachable.
    3578              :              We cannot leave the unreachable blocks in the CFG as that
    3579              :              will trigger a checking failure.
    3580              : 
    3581              :              So track if INSN has a REG_EH_REGION note.  If so and we
    3582              :              split INSN, then trigger a CFG cleanup.  */
    3583    452651916 :           rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
    3584    452651916 :           if (INSN_P (insn))
    3585              :             {
    3586    372572952 :               rtx set = single_set (insn);
    3587              : 
    3588              :               /* Don't split no-op move insns.  These should silently
    3589              :                  disappear later in final.  Splitting such insns would
    3590              :                  break the code that handles LIBCALL blocks.  */
    3591    372572952 :               if (set && set_noop_p (set))
    3592              :                 {
    3593              :                   /* Nops get in the way while scheduling, so delete them
    3594              :                      now if register allocation has already been done.  It
    3595              :                      is too risky to try to do this before register
    3596              :                      allocation, and there are unlikely to be very many
    3597              :                      nops then anyways.  */
    3598        46788 :                   if (reload_completed)
    3599        46788 :                       delete_insn_and_edges (insn);
    3600        46788 :                   if (note)
    3601    452651916 :                     need_cfg_cleanup = true;
    3602              :                 }
    3603              :               else
    3604              :                 {
    3605    372526164 :                   if (split_insn (insn))
    3606              :                     {
    3607      6136928 :                       bitmap_set_bit (blocks, bb->index);
    3608      6136928 :                       changed = true;
    3609      6136928 :                       if (note)
    3610         2806 :                         need_cfg_cleanup = true;
    3611              :                     }
    3612              :                 }
    3613              :             }
    3614              :         }
    3615              :     }
    3616              : 
    3617      4018596 :   if (reload_completed)
    3618      2530228 :     post_ra_split_completed = true;
    3619              : 
    3620      4018596 :   default_rtl_profile ();
    3621      4018596 :   if (changed)
    3622              :     {
    3623       752387 :       find_many_sub_basic_blocks (blocks);
    3624              : 
    3625              :       /* Splitting could drop an REG_EH_REGION if it potentially
    3626              :          trapped in its original form, but does not in its split
    3627              :          form.  Consider a FLOAT_TRUNCATE which splits into a memory
    3628              :          store/load pair and -fnon-call-exceptions.  */
    3629       752387 :       if (need_cfg_cleanup)
    3630         1340 :         cleanup_cfg (0);
    3631              :     }
    3632              : 
    3633      4018596 :   checking_verify_flow_info ();
    3634      4018596 : }
    3635              : 
    3636              : /* Same as split_all_insns, but do not expect CFG to be available.
    3637              :    Used by machine dependent reorg passes.  */
    3638              : 
    3639              : void
    3640            0 : split_all_insns_noflow (void)
    3641              : {
    3642            0 :   rtx_insn *next, *insn;
    3643              : 
    3644            0 :   for (insn = get_insns (); insn; insn = next)
    3645              :     {
    3646            0 :       next = NEXT_INSN (insn);
    3647            0 :       if (INSN_P (insn))
    3648              :         {
    3649              :           /* Don't split no-op move insns.  These should silently
    3650              :              disappear later in final.  Splitting such insns would
    3651              :              break the code that handles LIBCALL blocks.  */
    3652            0 :           rtx set = single_set (insn);
    3653            0 :           if (set && set_noop_p (set))
    3654              :             {
    3655              :               /* Nops get in the way while scheduling, so delete them
    3656              :                  now if register allocation has already been done.  It
    3657              :                  is too risky to try to do this before register
    3658              :                  allocation, and there are unlikely to be very many
    3659              :                  nops then anyways.
    3660              : 
    3661              :                  ??? Should we use delete_insn when the CFG isn't valid?  */
    3662            0 :               if (reload_completed)
    3663            0 :                 delete_insn_and_edges (insn);
    3664              :             }
    3665              :           else
    3666            0 :             split_insn (insn);
    3667              :         }
    3668              :     }
    3669              : 
    3670            0 :   if (reload_completed)
    3671            0 :     post_ra_split_completed = true;
    3672            0 : }
    3673              : 
    3674              : struct peep2_insn_data
    3675              : {
    3676              :   rtx_insn *insn;
    3677              :   regset live_before;
    3678              : };
    3679              : 
    3680              : static struct peep2_insn_data peep2_insn_data[MAX_INSNS_PER_PEEP2 + 1];
    3681              : static int peep2_current;
    3682              : 
    3683              : static bool peep2_do_rebuild_jump_labels;
    3684              : static bool peep2_do_cleanup_cfg;
    3685              : 
    3686              : /* The number of instructions available to match a peep2.  */
    3687              : int peep2_current_count;
    3688              : 
    3689              : /* A marker indicating the last insn of the block.  The live_before regset
    3690              :    for this element is correct, indicating DF_LIVE_OUT for the block.  */
    3691              : #define PEEP2_EOB invalid_insn_rtx
    3692              : 
    3693              : /* Wrap N to fit into the peep2_insn_data buffer.  */
    3694              : 
    3695              : static int
    3696    418926790 : peep2_buf_position (int n)
    3697              : {
    3698            0 :   if (n >= MAX_INSNS_PER_PEEP2 + 1)
    3699    141330162 :     n -= MAX_INSNS_PER_PEEP2 + 1;
    3700    418908786 :   return n;
    3701              : }
    3702              : 
    3703              : /* Return the Nth non-note insn after `current', or return NULL_RTX if it
    3704              :    does not exist.  Used by the recognizer to find the next insn to match
    3705              :    in a multi-insn pattern.  */
    3706              : 
    3707              : rtx_insn *
    3708    216732896 : peep2_next_insn (int n)
    3709              : {
    3710    216732896 :   gcc_assert (n <= peep2_current_count);
    3711              : 
    3712    216732896 :   n = peep2_buf_position (peep2_current + n);
    3713              : 
    3714    216732896 :   return peep2_insn_data[n].insn;
    3715              : }
    3716              : 
    3717              : /* Return true if REGNO is dead before the Nth non-note insn
    3718              :    after `current'.  */
    3719              : 
    3720              : bool
    3721     12812640 : peep2_regno_dead_p (int ofs, int regno)
    3722              : {
    3723     12812640 :   gcc_assert (ofs < MAX_INSNS_PER_PEEP2 + 1);
    3724              : 
    3725     12812640 :   ofs = peep2_buf_position (peep2_current + ofs);
    3726              : 
    3727     12812640 :   gcc_assert (peep2_insn_data[ofs].insn != NULL_RTX);
    3728              : 
    3729     12812640 :   return ! REGNO_REG_SET_P (peep2_insn_data[ofs].live_before, regno);
    3730              : }
    3731              : 
    3732              : /* Similarly for a REG.  */
    3733              : 
    3734              : bool
    3735       293618 : peep2_reg_dead_p (int ofs, rtx reg)
    3736              : {
    3737       293618 :   gcc_assert (ofs < MAX_INSNS_PER_PEEP2 + 1);
    3738              : 
    3739       293618 :   ofs = peep2_buf_position (peep2_current + ofs);
    3740              : 
    3741       293618 :   gcc_assert (peep2_insn_data[ofs].insn != NULL_RTX);
    3742              : 
    3743       293618 :   unsigned int end_regno = END_REGNO (reg);
    3744       369126 :   for (unsigned int regno = REGNO (reg); regno < end_regno; ++regno)
    3745       293618 :     if (REGNO_REG_SET_P (peep2_insn_data[ofs].live_before, regno))
    3746              :       return false;
    3747              :   return true;
    3748              : }
    3749              : 
    3750              : /* Regno offset to be used in the register search.  */
    3751              : static int search_ofs;
    3752              : 
    3753              : /* Try to find a hard register of mode MODE, matching the register class in
    3754              :    CLASS_STR, which is available at the beginning of insn CURRENT_INSN and
    3755              :    remains available until the end of LAST_INSN.  LAST_INSN may be NULL_RTX,
    3756              :    in which case the only condition is that the register must be available
    3757              :    before CURRENT_INSN.
    3758              :    Registers that already have bits set in REG_SET will not be considered.
    3759              : 
    3760              :    If an appropriate register is available, it will be returned and the
    3761              :    corresponding bit(s) in REG_SET will be set; otherwise, NULL_RTX is
    3762              :    returned.  */
    3763              : 
    3764              : rtx
    3765       595870 : peep2_find_free_register (int from, int to, const char *class_str,
    3766              :                           machine_mode mode, HARD_REG_SET *reg_set)
    3767              : {
    3768       595870 :   enum reg_class cl;
    3769       595870 :   HARD_REG_SET live;
    3770       595870 :   df_ref def;
    3771       595870 :   int i;
    3772              : 
    3773       595870 :   gcc_assert (from < MAX_INSNS_PER_PEEP2 + 1);
    3774       595870 :   gcc_assert (to < MAX_INSNS_PER_PEEP2 + 1);
    3775              : 
    3776       595870 :   from = peep2_buf_position (peep2_current + from);
    3777       595870 :   to = peep2_buf_position (peep2_current + to);
    3778              : 
    3779       595870 :   gcc_assert (peep2_insn_data[from].insn != NULL_RTX);
    3780       595870 :   REG_SET_TO_HARD_REG_SET (live, peep2_insn_data[from].live_before);
    3781              : 
    3782       595870 :   while (from != to)
    3783              :     {
    3784        18004 :       gcc_assert (peep2_insn_data[from].insn != NULL_RTX);
    3785              : 
    3786              :       /* Don't use registers set or clobbered by the insn.  */
    3787        72016 :       FOR_EACH_INSN_DEF (def, peep2_insn_data[from].insn)
    3788        54012 :         SET_HARD_REG_BIT (live, DF_REF_REGNO (def));
    3789              : 
    3790       631878 :       from = peep2_buf_position (from + 1);
    3791              :     }
    3792              : 
    3793       595870 :   cl = reg_class_for_constraint (lookup_constraint (class_str));
    3794              : 
    3795      5817791 :   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
    3796              :     {
    3797      5812967 :       int raw_regno, regno, j;
    3798      5812967 :       bool success;
    3799              : 
    3800              :       /* Distribute the free registers as much as possible.  */
    3801      5812967 :       raw_regno = search_ofs + i;
    3802      5812967 :       if (raw_regno >= FIRST_PSEUDO_REGISTER)
    3803       261146 :         raw_regno -= FIRST_PSEUDO_REGISTER;
    3804              : #ifdef REG_ALLOC_ORDER
    3805      5812967 :       regno = reg_alloc_order[raw_regno];
    3806              : #else
    3807              :       regno = raw_regno;
    3808              : #endif
    3809              : 
    3810              :       /* Can it support the mode we need?  */
    3811      5812967 :       if (!targetm.hard_regno_mode_ok (regno, mode))
    3812      1783656 :         continue;
    3813              : 
    3814      4620357 :       success = true;
    3815      4620357 :       for (j = 0; success && j < hard_regno_nregs (regno, mode); j++)
    3816              :         {
    3817              :           /* Don't allocate fixed registers.  */
    3818      4029311 :           if (fixed_regs[regno + j])
    3819              :             {
    3820              :               success = false;
    3821              :               break;
    3822              :             }
    3823              :           /* Don't allocate global registers.  */
    3824      2099569 :           if (global_regs[regno + j])
    3825              :             {
    3826              :               success = false;
    3827              :               break;
    3828              :             }
    3829              :           /* Make sure the register is of the right class.  */
    3830      2099569 :           if (! TEST_HARD_REG_BIT (reg_class_contents[cl], regno + j))
    3831              :             {
    3832              :               success = false;
    3833              :               break;
    3834              :             }
    3835              :           /* And that we don't create an extra save/restore.  */
    3836      1121804 :           if (! crtl->abi->clobbers_full_reg_p (regno + j)
    3837      1121804 :               && ! df_regs_ever_live_p (regno + j))
    3838              :             {
    3839              :               success = false;
    3840              :               break;
    3841              :             }
    3842              : 
    3843      1085300 :           if (! targetm.hard_regno_scratch_ok (regno + j))
    3844              :             {
    3845              :               success = false;
    3846              :               break;
    3847              :             }
    3848              : 
    3849              :           /* And we don't clobber traceback for noreturn functions.  */
    3850      1085180 :           if ((regno + j == FRAME_POINTER_REGNUM
    3851      1085180 :                || regno + j == HARD_FRAME_POINTER_REGNUM)
    3852        49574 :               && (! reload_completed || frame_pointer_needed))
    3853              :             {
    3854              :               success = false;
    3855              :               break;
    3856              :             }
    3857              : 
    3858      1074448 :           if (TEST_HARD_REG_BIT (*reg_set, regno + j)
    3859      1074448 :               || TEST_HARD_REG_BIT (live, regno + j))
    3860              :             {
    3861              :               success = false;
    3862              :               break;
    3863              :             }
    3864              :         }
    3865              : 
    3866      4029311 :       if (success)
    3867              :         {
    3868       591046 :           add_to_hard_reg_set (reg_set, mode, regno);
    3869              : 
    3870              :           /* Start the next search with the next register.  */
    3871       591046 :           if (++raw_regno >= FIRST_PSEUDO_REGISTER)
    3872         6634 :             raw_regno = 0;
    3873       591046 :           search_ofs = raw_regno;
    3874              : 
    3875       591046 :           return gen_rtx_REG (mode, regno);
    3876              :         }
    3877              :     }
    3878              : 
    3879         4824 :   search_ofs = 0;
    3880         4824 :   return NULL_RTX;
    3881              : }
    3882              : 
    3883              : /* Forget all currently tracked instructions, only remember current
    3884              :    LIVE regset.  */
    3885              : 
    3886              : static void
    3887     10661880 : peep2_reinit_state (regset live)
    3888              : {
    3889     10661880 :   int i;
    3890              : 
    3891              :   /* Indicate that all slots except the last holds invalid data.  */
    3892     74633160 :   for (i = 0; i < MAX_INSNS_PER_PEEP2; ++i)
    3893     63971280 :     peep2_insn_data[i].insn = NULL;
    3894     10661880 :   peep2_current_count = 0;
    3895              : 
    3896              :   /* Indicate that the last slot contains live_after data.  */
    3897     10661880 :   peep2_insn_data[MAX_INSNS_PER_PEEP2].insn = PEEP2_EOB;
    3898     10661880 :   peep2_current = MAX_INSNS_PER_PEEP2;
    3899              : 
    3900     10661880 :   COPY_REG_SET (peep2_insn_data[MAX_INSNS_PER_PEEP2].live_before, live);
    3901     10661880 : }
    3902              : 
    3903              : /* Copies frame related info of an insn (OLD_INSN) to the single
    3904              :    insn (NEW_INSN) that was obtained by splitting OLD_INSN.  */
    3905              : 
    3906              : void
    3907       131747 : copy_frame_info_to_split_insn (rtx_insn *old_insn, rtx_insn *new_insn)
    3908              : {
    3909       131747 :   bool any_note = false;
    3910       131747 :   rtx note;
    3911              : 
    3912       131747 :   if (!RTX_FRAME_RELATED_P (old_insn))
    3913              :     return;
    3914              : 
    3915       131747 :   RTX_FRAME_RELATED_P (new_insn) = 1;
    3916              : 
    3917              :   /* Allow the backend to fill in a note during the split.  */
    3918       131747 :   for (note = REG_NOTES (new_insn); note ; note = XEXP (note, 1))
    3919            0 :     switch (REG_NOTE_KIND (note))
    3920              :       {
    3921            0 :       case REG_FRAME_RELATED_EXPR:
    3922            0 :       case REG_CFA_DEF_CFA:
    3923            0 :       case REG_CFA_ADJUST_CFA:
    3924            0 :       case REG_CFA_OFFSET:
    3925            0 :       case REG_CFA_REGISTER:
    3926            0 :       case REG_CFA_EXPRESSION:
    3927            0 :       case REG_CFA_RESTORE:
    3928            0 :       case REG_CFA_SET_VDRAP:
    3929            0 :         any_note = true;
    3930            0 :         break;
    3931              :       default:
    3932              :         break;
    3933              :       }
    3934              : 
    3935              :   /* If the backend didn't supply a note, copy one over.  */
    3936       131747 :   if (!any_note)
    3937       322792 :     for (note = REG_NOTES (old_insn); note ; note = XEXP (note, 1))
    3938       191045 :       switch (REG_NOTE_KIND (note))
    3939              :         {
    3940       143741 :         case REG_FRAME_RELATED_EXPR:
    3941       143741 :         case REG_CFA_DEF_CFA:
    3942       143741 :         case REG_CFA_ADJUST_CFA:
    3943       143741 :         case REG_CFA_OFFSET:
    3944       143741 :         case REG_CFA_REGISTER:
    3945       143741 :         case REG_CFA_EXPRESSION:
    3946       143741 :         case REG_CFA_RESTORE:
    3947       143741 :         case REG_CFA_SET_VDRAP:
    3948       143741 :           add_reg_note (new_insn, REG_NOTE_KIND (note), XEXP (note, 0));
    3949       143741 :           any_note = true;
    3950       143741 :           break;
    3951              :         default:
    3952              :           break;
    3953              :         }
    3954              : 
    3955              :   /* If there still isn't a note, make sure the unwind info sees the
    3956              :      same expression as before the split.  */
    3957       131747 :   if (!any_note)
    3958              :     {
    3959         2415 :       rtx old_set, new_set;
    3960              : 
    3961              :       /* The old insn had better have been simple, or annotated.  */
    3962         2415 :       old_set = single_set (old_insn);
    3963         2415 :       gcc_assert (old_set != NULL);
    3964              : 
    3965         2415 :       new_set = single_set (new_insn);
    3966         2415 :       if (!new_set || !rtx_equal_p (new_set, old_set))
    3967          274 :         add_reg_note (new_insn, REG_FRAME_RELATED_EXPR, old_set);
    3968              :     }
    3969              : 
    3970              :   /* Copy prologue/epilogue status.  This is required in order to keep
    3971              :      proper placement of EPILOGUE_BEG and the DW_CFA_remember_state.  */
    3972       131747 :   maybe_copy_prologue_epilogue_insn (old_insn, new_insn);
    3973              : }
    3974              : 
    3975              : /* While scanning basic block BB, we found a match of length MATCH_LEN + 1,
    3976              :    starting at INSN.  Perform the replacement, removing the old insns and
    3977              :    replacing them with ATTEMPT.  Returns the last insn emitted, or NULL
    3978              :    if the replacement is rejected.  */
    3979              : 
    3980              : static rtx_insn *
    3981      2231117 : peep2_attempt (basic_block bb, rtx_insn *insn, int match_len, rtx_insn *attempt)
    3982              : {
    3983      2231117 :   int i;
    3984      2231117 :   rtx_insn *last, *before_try, *x;
    3985      2231117 :   rtx eh_note, as_note;
    3986      2231117 :   rtx_insn *old_insn;
    3987      2231117 :   rtx_insn *new_insn;
    3988      2231117 :   bool was_call = false;
    3989              : 
    3990              :   /* If we are splitting an RTX_FRAME_RELATED_P insn, do not allow it to
    3991              :      match more than one insn, or to be split into more than one insn.  */
    3992      2231117 :   old_insn = peep2_insn_data[peep2_current].insn;
    3993      2231117 :   if (RTX_FRAME_RELATED_P (old_insn))
    3994              :     {
    3995       134526 :       if (match_len != 0)
    3996              :         return NULL;
    3997              : 
    3998              :       /* Look for one "active" insn.  I.e. ignore any "clobber" insns that
    3999              :          may be in the stream for the purpose of register allocation.  */
    4000       134526 :       if (active_insn_p (attempt))
    4001              :         new_insn = attempt;
    4002              :       else
    4003        34864 :         new_insn = next_active_insn (attempt);
    4004       134526 :       if (next_active_insn (new_insn))
    4005              :         return NULL;
    4006              : 
    4007              :       /* We have a 1-1 replacement.  Copy over any frame-related info.  */
    4008       131723 :       copy_frame_info_to_split_insn (old_insn, new_insn);
    4009              :     }
    4010              : 
    4011              :   /* If we are splitting a CALL_INSN, look for the CALL_INSN
    4012              :      in SEQ and copy our CALL_INSN_FUNCTION_USAGE and other
    4013              :      cfg-related call notes.  */
    4014      4663601 :   for (i = 0; i <= match_len; ++i)
    4015              :     {
    4016      2436803 :       int j;
    4017      2436803 :       rtx note;
    4018              : 
    4019      2436803 :       j = peep2_buf_position (peep2_current + i);
    4020      2436803 :       old_insn = peep2_insn_data[j].insn;
    4021      2436803 :       if (!CALL_P (old_insn))
    4022      2435287 :         continue;
    4023         1516 :       was_call = true;
    4024              : 
    4025              :       new_insn = attempt;
    4026         1516 :       while (new_insn != NULL_RTX)
    4027              :         {
    4028         1516 :           if (CALL_P (new_insn))
    4029              :             break;
    4030            0 :           new_insn = NEXT_INSN (new_insn);
    4031              :         }
    4032              : 
    4033         1516 :       gcc_assert (new_insn != NULL_RTX);
    4034              : 
    4035         1516 :       CALL_INSN_FUNCTION_USAGE (new_insn)
    4036         1516 :         = CALL_INSN_FUNCTION_USAGE (old_insn);
    4037         1516 :       CALL_INSN_ABI_ID (new_insn) = CALL_INSN_ABI_ID (old_insn);
    4038         1516 :       SIBLING_CALL_P (new_insn) = SIBLING_CALL_P (old_insn);
    4039              : 
    4040         1516 :       for (note = REG_NOTES (old_insn);
    4041         6860 :            note;
    4042         5344 :            note = XEXP (note, 1))
    4043         5344 :         switch (REG_NOTE_KIND (note))
    4044              :           {
    4045            0 :           case REG_NORETURN:
    4046            0 :           case REG_SETJMP:
    4047            0 :           case REG_TM:
    4048            0 :           case REG_CALL_NOCF_CHECK:
    4049            0 :             add_reg_note (new_insn, REG_NOTE_KIND (note),
    4050              :                           XEXP (note, 0));
    4051            0 :             break;
    4052              :           default:
    4053              :             /* Discard all other reg notes.  */
    4054              :             break;
    4055              :           }
    4056              : 
    4057              :       /* Croak if there is another call in the sequence.  */
    4058         1516 :       while (++i <= match_len)
    4059              :         {
    4060            0 :           j = peep2_buf_position (peep2_current + i);
    4061            0 :           old_insn = peep2_insn_data[j].insn;
    4062            0 :           gcc_assert (!CALL_P (old_insn));
    4063              :         }
    4064              :       break;
    4065              :     }
    4066              : 
    4067              :   /* If we matched any instruction that had a REG_ARGS_SIZE, then
    4068              :      move those notes over to the new sequence.  */
    4069      2228314 :   as_note = NULL;
    4070      4547359 :   for (i = match_len; i >= 0; --i)
    4071              :     {
    4072      2436803 :       int j = peep2_buf_position (peep2_current + i);
    4073      2436803 :       old_insn = peep2_insn_data[j].insn;
    4074              : 
    4075      2436803 :       as_note = find_reg_note (old_insn, REG_ARGS_SIZE, NULL);
    4076      2436803 :       if (as_note)
    4077              :         break;
    4078              :     }
    4079              : 
    4080      2228314 :   i = peep2_buf_position (peep2_current + match_len);
    4081      2228314 :   eh_note = find_reg_note (peep2_insn_data[i].insn, REG_EH_REGION, NULL_RTX);
    4082              : 
    4083              :   /* Replace the old sequence with the new.  */
    4084      2228314 :   rtx_insn *peepinsn = peep2_insn_data[i].insn;
    4085      4456628 :   last = emit_insn_after_setloc (attempt,
    4086              :                                  peep2_insn_data[i].insn,
    4087      2228314 :                                  INSN_LOCATION (peepinsn));
    4088      2228314 :   if (JUMP_P (peepinsn) && JUMP_P (last))
    4089          806 :     CROSSING_JUMP_P (last) = CROSSING_JUMP_P (peepinsn);
    4090      2228314 :   before_try = PREV_INSN (insn);
    4091      2228314 :   delete_insn_chain (insn, peep2_insn_data[i].insn, false);
    4092              : 
    4093              :   /* Re-insert the EH_REGION notes.  */
    4094      2228314 :   if (eh_note || (was_call && nonlocal_goto_handler_labels))
    4095              :     {
    4096           40 :       edge eh_edge;
    4097           40 :       edge_iterator ei;
    4098              : 
    4099           48 :       FOR_EACH_EDGE (eh_edge, ei, bb->succs)
    4100           47 :         if (eh_edge->flags & (EDGE_EH | EDGE_ABNORMAL_CALL))
    4101              :           break;
    4102              : 
    4103           40 :       if (eh_note)
    4104           40 :         copy_reg_eh_region_note_backward (eh_note, last, before_try);
    4105              : 
    4106           40 :       if (eh_edge)
    4107          117 :         for (x = last; x != before_try; x = PREV_INSN (x))
    4108           78 :           if (x != BB_END (bb)
    4109           78 :               && (can_throw_internal (x)
    4110           39 :                   || can_nonlocal_goto (x)))
    4111              :             {
    4112            0 :               edge nfte, nehe;
    4113            0 :               int flags;
    4114              : 
    4115            0 :               nfte = split_block (bb, x);
    4116            0 :               flags = (eh_edge->flags
    4117              :                        & (EDGE_EH | EDGE_ABNORMAL));
    4118            0 :               if (CALL_P (x))
    4119            0 :                 flags |= EDGE_ABNORMAL_CALL;
    4120            0 :               nehe = make_edge (nfte->src, eh_edge->dest,
    4121              :                                 flags);
    4122              : 
    4123            0 :               nehe->probability = eh_edge->probability;
    4124            0 :               nfte->probability = nehe->probability.invert ();
    4125              : 
    4126            0 :               peep2_do_cleanup_cfg |= purge_dead_edges (nfte->dest);
    4127            0 :               bb = nfte->src;
    4128            0 :               eh_edge = nehe;
    4129              :             }
    4130              : 
    4131              :       /* Converting possibly trapping insn to non-trapping is
    4132              :          possible.  Zap dummy outgoing edges.  */
    4133           40 :       peep2_do_cleanup_cfg |= purge_dead_edges (bb);
    4134              :     }
    4135              : 
    4136              :   /* Re-insert the ARGS_SIZE notes.  */
    4137      2228314 :   if (as_note)
    4138       117758 :     fixup_args_size_notes (before_try, last, get_args_size (as_note));
    4139              : 
    4140              :   /* Scan the new insns for embedded side effects and add appropriate
    4141              :      REG_INC notes.  */
    4142              :   if (AUTO_INC_DEC)
    4143              :     for (x = last; x != before_try; x = PREV_INSN (x))
    4144              :       if (NONDEBUG_INSN_P (x))
    4145              :         add_auto_inc_notes (x, PATTERN (x));
    4146              : 
    4147              :   /* If we generated a jump instruction, it won't have
    4148              :      JUMP_LABEL set.  Recompute after we're done.  */
    4149      5190113 :   for (x = last; x != before_try; x = PREV_INSN (x))
    4150      2962605 :     if (JUMP_P (x))
    4151              :       {
    4152          806 :         peep2_do_rebuild_jump_labels = true;
    4153          806 :         break;
    4154              :       }
    4155              : 
    4156              :   return last;
    4157              : }
    4158              : 
    4159              : /* After performing a replacement in basic block BB, fix up the life
    4160              :    information in our buffer.  LAST is the last of the insns that we
    4161              :    emitted as a replacement.  PREV is the insn before the start of
    4162              :    the replacement.  MATCH_LEN + 1 is the number of instructions that were
    4163              :    matched, and which now need to be replaced in the buffer.  */
    4164              : 
    4165              : static void
    4166      2228314 : peep2_update_life (basic_block bb, int match_len, rtx_insn *last,
    4167              :                    rtx_insn *prev)
    4168              : {
    4169      2228314 :   int i = peep2_buf_position (peep2_current + match_len + 1);
    4170      2228314 :   rtx_insn *x;
    4171      2228314 :   regset_head live;
    4172              : 
    4173      2228314 :   INIT_REG_SET (&live);
    4174      2228314 :   COPY_REG_SET (&live, peep2_insn_data[i].live_before);
    4175              : 
    4176      2228314 :   gcc_assert (peep2_current_count >= match_len + 1);
    4177      2228314 :   peep2_current_count -= match_len + 1;
    4178              : 
    4179      2228314 :   x = last;
    4180      2963305 :   do
    4181              :     {
    4182      2963305 :       if (INSN_P (x))
    4183              :         {
    4184      2963305 :           df_insn_rescan (x);
    4185      2963305 :           if (peep2_current_count < MAX_INSNS_PER_PEEP2)
    4186              :             {
    4187      2820003 :               peep2_current_count++;
    4188      2820003 :               if (--i < 0)
    4189       820457 :                 i = MAX_INSNS_PER_PEEP2;
    4190      2820003 :               peep2_insn_data[i].insn = x;
    4191      2820003 :               df_simulate_one_insn_backwards (bb, x, &live);
    4192      2820003 :               COPY_REG_SET (peep2_insn_data[i].live_before, &live);
    4193              :             }
    4194              :         }
    4195      2963305 :       x = PREV_INSN (x);
    4196              :     }
    4197      2963305 :   while (x != prev);
    4198      2228314 :   CLEAR_REG_SET (&live);
    4199              : 
    4200      2228314 :   peep2_current = i;
    4201      2228314 : }
    4202              : 
    4203              : /* Add INSN, which is in BB, at the end of the peep2 insn buffer if possible.
    4204              :    Return true if we added it, false otherwise.  The caller will try to match
    4205              :    peepholes against the buffer if we return false; otherwise it will try to
    4206              :    add more instructions to the buffer.  */
    4207              : 
    4208              : static bool
    4209     81528329 : peep2_fill_buffer (basic_block bb, rtx_insn *insn, regset live)
    4210              : {
    4211     81528329 :   int pos;
    4212              : 
    4213              :   /* Once we have filled the maximum number of insns the buffer can hold,
    4214              :      allow the caller to match the insns against peepholes.  We wait until
    4215              :      the buffer is full in case the target has similar peepholes of different
    4216              :      length; we always want to match the longest if possible.  */
    4217     81528329 :   if (peep2_current_count == MAX_INSNS_PER_PEEP2)
    4218              :     return false;
    4219              : 
    4220              :   /* If an insn has RTX_FRAME_RELATED_P set, do not allow it to be matched with
    4221              :      any other pattern, lest it change the semantics of the frame info.  */
    4222     62784547 :   if (RTX_FRAME_RELATED_P (insn))
    4223              :     {
    4224              :       /* Let the buffer drain first.  */
    4225      7648758 :       if (peep2_current_count > 0)
    4226              :         return false;
    4227              :       /* Now the insn will be the only thing in the buffer.  */
    4228              :     }
    4229              : 
    4230     58517648 :   pos = peep2_buf_position (peep2_current + peep2_current_count);
    4231     58517648 :   peep2_insn_data[pos].insn = insn;
    4232     58517648 :   COPY_REG_SET (peep2_insn_data[pos].live_before, live);
    4233     58517648 :   peep2_current_count++;
    4234              : 
    4235     58517648 :   df_simulate_one_insn_forwards (bb, insn, live);
    4236     58517648 :   return true;
    4237              : }
    4238              : 
    4239              : /* Perform the peephole2 optimization pass.  */
    4240              : 
    4241              : static void
    4242       961299 : peephole2_optimize (void)
    4243              : {
    4244       961299 :   rtx_insn *insn;
    4245       961299 :   bitmap live;
    4246       961299 :   int i;
    4247       961299 :   basic_block bb;
    4248              : 
    4249       961299 :   peep2_do_cleanup_cfg = false;
    4250       961299 :   peep2_do_rebuild_jump_labels = false;
    4251              : 
    4252       961299 :   df_set_flags (DF_LR_RUN_DCE);
    4253       961299 :   df_note_add_problem ();
    4254       961299 :   df_analyze ();
    4255              : 
    4256              :   /* Initialize the regsets we're going to use.  */
    4257      8651691 :   for (i = 0; i < MAX_INSNS_PER_PEEP2 + 1; ++i)
    4258      6729093 :     peep2_insn_data[i].live_before = BITMAP_ALLOC (&reg_obstack);
    4259       961299 :   search_ofs = 0;
    4260       961299 :   live = BITMAP_ALLOC (&reg_obstack);
    4261              : 
    4262     11623179 :   FOR_EACH_BB_REVERSE_FN (bb, cfun)
    4263              :     {
    4264     10661880 :       bool past_end = false;
    4265     10661880 :       int pos;
    4266              : 
    4267     10661880 :       rtl_profile_for_bb (bb);
    4268              : 
    4269              :       /* Start up propagation.  */
    4270     21323760 :       bitmap_copy (live, DF_LR_IN (bb));
    4271     10661880 :       df_simulate_initialize_forwards (bb, live);
    4272     10661880 :       peep2_reinit_state (live);
    4273              : 
    4274     10661880 :       insn = BB_HEAD (bb);
    4275    200816357 :       for (;;)
    4276              :         {
    4277    200816357 :           rtx_insn *attempt, *head;
    4278    200816357 :           int match_len;
    4279              : 
    4280    200816357 :           if (!past_end && !NONDEBUG_INSN_P (insn))
    4281              :             {
    4282     70507667 :             next_insn:
    4283    129025315 :               insn = NEXT_INSN (insn);
    4284    129025315 :               if (insn == NEXT_INSN (BB_END (bb)))
    4285     10661880 :                 past_end = true;
    4286    131253629 :               continue;
    4287              :             }
    4288     81528329 :           if (!past_end && peep2_fill_buffer (bb, insn, live))
    4289     58517648 :             goto next_insn;
    4290              : 
    4291              :           /* If we did not fill an empty buffer, it signals the end of the
    4292              :              block.  */
    4293     71791042 :           if (peep2_current_count == 0)
    4294              :             break;
    4295              : 
    4296              :           /* The buffer filled to the current maximum, so try to match.  */
    4297              : 
    4298     61129162 :           pos = peep2_buf_position (peep2_current + peep2_current_count);
    4299     61129162 :           peep2_insn_data[pos].insn = PEEP2_EOB;
    4300     61129162 :           COPY_REG_SET (peep2_insn_data[pos].live_before, live);
    4301              : 
    4302              :           /* Match the peephole.  */
    4303     61129162 :           head = peep2_insn_data[peep2_current].insn;
    4304     61129162 :           attempt = peephole2_insns (PATTERN (head), head, &match_len);
    4305     61129162 :           if (attempt != NULL)
    4306              :             {
    4307      2231117 :               rtx_insn *last = peep2_attempt (bb, head, match_len, attempt);
    4308      2231117 :               if (last)
    4309              :                 {
    4310      2228314 :                   peep2_update_life (bb, match_len, last, PREV_INSN (attempt));
    4311      2228314 :                   continue;
    4312              :                 }
    4313              :             }
    4314              : 
    4315              :           /* No match: advance the buffer by one insn.  */
    4316     58900848 :           peep2_current = peep2_buf_position (peep2_current + 1);
    4317     58900848 :           peep2_current_count--;
    4318              :         }
    4319              :     }
    4320              : 
    4321       961299 :   default_rtl_profile ();
    4322      8651691 :   for (i = 0; i < MAX_INSNS_PER_PEEP2 + 1; ++i)
    4323      6729093 :     BITMAP_FREE (peep2_insn_data[i].live_before);
    4324       961299 :   BITMAP_FREE (live);
    4325       961299 :   if (peep2_do_rebuild_jump_labels)
    4326          747 :     rebuild_jump_labels (get_insns ());
    4327       961299 :   if (peep2_do_cleanup_cfg)
    4328            0 :     cleanup_cfg (CLEANUP_CFG_CHANGED);
    4329       961299 : }
    4330              : 
    4331              : /* Common predicates for use with define_bypass.  */
    4332              : 
    4333              : /* Helper function for store_data_bypass_p, handle just a single SET
    4334              :    IN_SET.  */
    4335              : 
    4336              : static bool
    4337            0 : store_data_bypass_p_1 (rtx_insn *out_insn, rtx in_set)
    4338              : {
    4339            0 :   if (!MEM_P (SET_DEST (in_set)))
    4340              :     return false;
    4341              : 
    4342            0 :   rtx out_set = single_set (out_insn);
    4343            0 :   if (out_set)
    4344            0 :     return !reg_mentioned_p (SET_DEST (out_set), SET_DEST (in_set));
    4345              : 
    4346            0 :   rtx out_pat = PATTERN (out_insn);
    4347            0 :   if (GET_CODE (out_pat) != PARALLEL)
    4348              :     return false;
    4349              : 
    4350            0 :   for (int i = 0; i < XVECLEN (out_pat, 0); i++)
    4351              :     {
    4352            0 :       rtx out_exp = XVECEXP (out_pat, 0, i);
    4353              : 
    4354            0 :       if (GET_CODE (out_exp) == CLOBBER || GET_CODE (out_exp) == USE)
    4355            0 :         continue;
    4356              : 
    4357            0 :       gcc_assert (GET_CODE (out_exp) == SET);
    4358              : 
    4359            0 :       if (reg_mentioned_p (SET_DEST (out_exp), SET_DEST (in_set)))
    4360              :         return false;
    4361              :     }
    4362              : 
    4363              :   return true;
    4364              : }
    4365              : 
    4366              : /* True if the dependency between OUT_INSN and IN_INSN is on the store
    4367              :    data not the address operand(s) of the store.  IN_INSN and OUT_INSN
    4368              :    must be either a single_set or a PARALLEL with SETs inside.  */
    4369              : 
    4370              : bool
    4371            0 : store_data_bypass_p (rtx_insn *out_insn, rtx_insn *in_insn)
    4372              : {
    4373            0 :   rtx in_set = single_set (in_insn);
    4374            0 :   if (in_set)
    4375            0 :     return store_data_bypass_p_1 (out_insn, in_set);
    4376              : 
    4377            0 :   rtx in_pat = PATTERN (in_insn);
    4378            0 :   if (GET_CODE (in_pat) != PARALLEL)
    4379              :     return false;
    4380              : 
    4381            0 :   for (int i = 0; i < XVECLEN (in_pat, 0); i++)
    4382              :     {
    4383            0 :       rtx in_exp = XVECEXP (in_pat, 0, i);
    4384              : 
    4385            0 :       if (GET_CODE (in_exp) == CLOBBER || GET_CODE (in_exp) == USE)
    4386            0 :         continue;
    4387              : 
    4388            0 :       gcc_assert (GET_CODE (in_exp) == SET);
    4389              : 
    4390            0 :       if (!store_data_bypass_p_1 (out_insn, in_exp))
    4391              :         return false;
    4392              :     }
    4393              : 
    4394              :   return true;
    4395              : }
    4396              : 
    4397              : /* True if the dependency between OUT_INSN and IN_INSN is in the IF_THEN_ELSE
    4398              :    condition, and not the THEN or ELSE branch.  OUT_INSN may be either a single
    4399              :    or multiple set; IN_INSN should be single_set for truth, but for convenience
    4400              :    of insn categorization may be any JUMP or CALL insn.  */
    4401              : 
    4402              : bool
    4403            0 : if_test_bypass_p (rtx_insn *out_insn, rtx_insn *in_insn)
    4404              : {
    4405            0 :   rtx out_set, in_set;
    4406              : 
    4407            0 :   in_set = single_set (in_insn);
    4408            0 :   if (! in_set)
    4409              :     {
    4410            0 :       gcc_assert (JUMP_P (in_insn) || CALL_P (in_insn));
    4411              :       return false;
    4412              :     }
    4413              : 
    4414            0 :   if (GET_CODE (SET_SRC (in_set)) != IF_THEN_ELSE)
    4415              :     return false;
    4416            0 :   in_set = SET_SRC (in_set);
    4417              : 
    4418            0 :   out_set = single_set (out_insn);
    4419            0 :   if (out_set)
    4420              :     {
    4421            0 :       if (reg_mentioned_p (SET_DEST (out_set), XEXP (in_set, 1))
    4422            0 :           || reg_mentioned_p (SET_DEST (out_set), XEXP (in_set, 2)))
    4423            0 :         return false;
    4424              :     }
    4425              :   else
    4426              :     {
    4427            0 :       rtx out_pat;
    4428            0 :       int i;
    4429              : 
    4430            0 :       out_pat = PATTERN (out_insn);
    4431            0 :       gcc_assert (GET_CODE (out_pat) == PARALLEL);
    4432              : 
    4433            0 :       for (i = 0; i < XVECLEN (out_pat, 0); i++)
    4434              :         {
    4435            0 :           rtx exp = XVECEXP (out_pat, 0, i);
    4436              : 
    4437            0 :           if (GET_CODE (exp) == CLOBBER)
    4438            0 :             continue;
    4439              : 
    4440            0 :           gcc_assert (GET_CODE (exp) == SET);
    4441              : 
    4442            0 :           if (reg_mentioned_p (SET_DEST (out_set), XEXP (in_set, 1))
    4443            0 :               || reg_mentioned_p (SET_DEST (out_set), XEXP (in_set, 2)))
    4444            0 :             return false;
    4445              :         }
    4446              :     }
    4447              : 
    4448              :   return true;
    4449              : }
    4450              : 
    4451              : static unsigned int
    4452       961299 : rest_of_handle_peephole2 (void)
    4453              : {
    4454       961299 :   if (HAVE_peephole2)
    4455            0 :     peephole2_optimize ();
    4456              : 
    4457       961299 :   return 0;
    4458              : }
    4459              : 
    4460              : namespace {
    4461              : 
    4462              : const pass_data pass_data_peephole2 =
    4463              : {
    4464              :   RTL_PASS, /* type */
    4465              :   "peephole2", /* name */
    4466              :   OPTGROUP_NONE, /* optinfo_flags */
    4467              :   TV_PEEPHOLE2, /* tv_id */
    4468              :   0, /* properties_required */
    4469              :   0, /* properties_provided */
    4470              :   0, /* properties_destroyed */
    4471              :   0, /* todo_flags_start */
    4472              :   TODO_df_finish, /* todo_flags_finish */
    4473              : };
    4474              : 
    4475              : class pass_peephole2 : public rtl_opt_pass
    4476              : {
    4477              : public:
    4478       298828 :   pass_peephole2 (gcc::context *ctxt)
    4479       597656 :     : rtl_opt_pass (pass_data_peephole2, ctxt)
    4480              :   {}
    4481              : 
    4482              :   /* opt_pass methods: */
    4483              :   /* The epiphany backend creates a second instance of this pass, so we need
    4484              :      a clone method.  */
    4485            0 :   opt_pass * clone () final override { return new pass_peephole2 (m_ctxt); }
    4486      1488378 :   bool gate (function *) final override
    4487              :   {
    4488      1488378 :     return (optimize > 0 && flag_peephole2);
    4489              :   }
    4490       961299 :   unsigned int execute (function *) final override
    4491              :     {
    4492       961299 :       return rest_of_handle_peephole2 ();
    4493              :     }
    4494              : 
    4495              : }; // class pass_peephole2
    4496              : 
    4497              : } // anon namespace
    4498              : 
    4499              : rtl_opt_pass *
    4500       298828 : make_pass_peephole2 (gcc::context *ctxt)
    4501              : {
    4502       298828 :   return new pass_peephole2 (ctxt);
    4503              : }
    4504              : 
    4505              : namespace {
    4506              : 
    4507              : const pass_data pass_data_split_all_insns =
    4508              : {
    4509              :   RTL_PASS, /* type */
    4510              :   "split1", /* name */
    4511              :   OPTGROUP_NONE, /* optinfo_flags */
    4512              :   TV_NONE, /* tv_id */
    4513              :   0, /* properties_required */
    4514              :   PROP_rtl_split_insns, /* properties_provided */
    4515              :   0, /* properties_destroyed */
    4516              :   0, /* todo_flags_start */
    4517              :   0, /* todo_flags_finish */
    4518              : };
    4519              : 
    4520              : class pass_split_all_insns : public rtl_opt_pass
    4521              : {
    4522              : public:
    4523       298828 :   pass_split_all_insns (gcc::context *ctxt)
    4524       597656 :     : rtl_opt_pass (pass_data_split_all_insns, ctxt)
    4525              :   {}
    4526              : 
    4527              :   /* opt_pass methods: */
    4528              :   /* The epiphany backend creates a second instance of this pass, so
    4529              :      we need a clone method.  */
    4530            0 :   opt_pass * clone () final override
    4531              :   {
    4532            0 :     return new pass_split_all_insns (m_ctxt);
    4533              :   }
    4534      1488368 :   unsigned int execute (function *) final override
    4535              :     {
    4536      1488368 :       split_all_insns ();
    4537      1488368 :       return 0;
    4538              :     }
    4539              : 
    4540              : }; // class pass_split_all_insns
    4541              : 
    4542              : } // anon namespace
    4543              : 
    4544              : rtl_opt_pass *
    4545       298828 : make_pass_split_all_insns (gcc::context *ctxt)
    4546              : {
    4547       298828 :   return new pass_split_all_insns (ctxt);
    4548              : }
    4549              : 
    4550              : namespace {
    4551              : 
    4552              : const pass_data pass_data_split_after_reload =
    4553              : {
    4554              :   RTL_PASS, /* type */
    4555              :   "split2", /* name */
    4556              :   OPTGROUP_NONE, /* optinfo_flags */
    4557              :   TV_NONE, /* tv_id */
    4558              :   0, /* properties_required */
    4559              :   0, /* properties_provided */
    4560              :   0, /* properties_destroyed */
    4561              :   0, /* todo_flags_start */
    4562              :   0, /* todo_flags_finish */
    4563              : };
    4564              : 
    4565              : class pass_split_after_reload : public rtl_opt_pass
    4566              : {
    4567              : public:
    4568       298828 :   pass_split_after_reload (gcc::context *ctxt)
    4569       597656 :     : rtl_opt_pass (pass_data_split_after_reload, ctxt)
    4570              :   {}
    4571              : 
    4572              :   /* opt_pass methods: */
    4573      1488378 :   bool gate (function *) final override
    4574              :     {
    4575              :       /* If optimizing, then go ahead and split insns now.  */
    4576      1488378 :       return optimize > 0;
    4577              :     }
    4578              : 
    4579      1041770 :   unsigned int execute (function *) final override
    4580              :     {
    4581      1041770 :       split_all_insns ();
    4582      1041770 :       return 0;
    4583              :     }
    4584              : 
    4585              : }; // class pass_split_after_reload
    4586              : 
    4587              : } // anon namespace
    4588              : 
    4589              : rtl_opt_pass *
    4590       298828 : make_pass_split_after_reload (gcc::context *ctxt)
    4591              : {
    4592       298828 :   return new pass_split_after_reload (ctxt);
    4593              : }
    4594              : 
    4595              : static bool
    4596      2976756 : enable_split_before_sched2 (void)
    4597              : {
    4598              : #ifdef INSN_SCHEDULING
    4599      2083542 :   return optimize > 0 && flag_schedule_insns_after_reload;
    4600              : #else
    4601              :   return false;
    4602              : #endif
    4603              : }
    4604              : 
    4605              : namespace {
    4606              : 
    4607              : const pass_data pass_data_split_before_sched2 =
    4608              : {
    4609              :   RTL_PASS, /* type */
    4610              :   "split3", /* name */
    4611              :   OPTGROUP_NONE, /* optinfo_flags */
    4612              :   TV_NONE, /* tv_id */
    4613              :   0, /* properties_required */
    4614              :   0, /* properties_provided */
    4615              :   0, /* properties_destroyed */
    4616              :   0, /* todo_flags_start */
    4617              :   0, /* todo_flags_finish */
    4618              : };
    4619              : 
    4620              : class pass_split_before_sched2 : public rtl_opt_pass
    4621              : {
    4622              : public:
    4623       298828 :   pass_split_before_sched2 (gcc::context *ctxt)
    4624       597656 :     : rtl_opt_pass (pass_data_split_before_sched2, ctxt)
    4625              :   {}
    4626              : 
    4627              :   /* opt_pass methods: */
    4628      1488378 :   bool gate (function *) final override
    4629              :     {
    4630      1488378 :       return enable_split_before_sched2 ();
    4631              :     }
    4632              : 
    4633       961304 :   unsigned int execute (function *) final override
    4634              :     {
    4635       961304 :       split_all_insns ();
    4636       961304 :       return 0;
    4637              :     }
    4638              : 
    4639              : }; // class pass_split_before_sched2
    4640              : 
    4641              : } // anon namespace
    4642              : 
    4643              : rtl_opt_pass *
    4644       298828 : make_pass_split_before_sched2 (gcc::context *ctxt)
    4645              : {
    4646       298828 :   return new pass_split_before_sched2 (ctxt);
    4647              : }
    4648              : 
    4649              : namespace {
    4650              : 
    4651              : const pass_data pass_data_split_before_regstack =
    4652              : {
    4653              :   RTL_PASS, /* type */
    4654              :   "split4", /* name */
    4655              :   OPTGROUP_NONE, /* optinfo_flags */
    4656              :   TV_NONE, /* tv_id */
    4657              :   0, /* properties_required */
    4658              :   0, /* properties_provided */
    4659              :   0, /* properties_destroyed */
    4660              :   0, /* todo_flags_start */
    4661              :   0, /* todo_flags_finish */
    4662              : };
    4663              : 
    4664              : class pass_split_before_regstack : public rtl_opt_pass
    4665              : {
    4666              : public:
    4667       298828 :   pass_split_before_regstack (gcc::context *ctxt)
    4668       597656 :     : rtl_opt_pass (pass_data_split_before_regstack, ctxt)
    4669              :   {}
    4670              : 
    4671              :   /* opt_pass methods: */
    4672              :   bool gate (function *) final override;
    4673       527154 :   unsigned int execute (function *) final override
    4674              :     {
    4675       527154 :       split_all_insns ();
    4676       527154 :       return 0;
    4677              :     }
    4678              : 
    4679              : }; // class pass_split_before_regstack
    4680              : 
    4681              : bool
    4682      1488378 : pass_split_before_regstack::gate (function *)
    4683              : {
    4684              : #if HAVE_ATTR_length && defined (STACK_REGS)
    4685              :   /* If flow2 creates new instructions which need splitting
    4686              :      and scheduling after reload is not done, they might not be
    4687              :      split until final which doesn't allow splitting
    4688              :      if HAVE_ATTR_length.  Selective scheduling can result in
    4689              :      further instructions that need splitting.  */
    4690              : #ifdef INSN_SCHEDULING
    4691      2449683 :   return !enable_split_before_sched2 () || flag_selective_scheduling2;
    4692              : #else
    4693              :   return !enable_split_before_sched2 ();
    4694              : #endif
    4695              : #else
    4696              :   return false;
    4697              : #endif
    4698              : }
    4699              : 
    4700              : } // anon namespace
    4701              : 
    4702              : rtl_opt_pass *
    4703       298828 : make_pass_split_before_regstack (gcc::context *ctxt)
    4704              : {
    4705       298828 :   return new pass_split_before_regstack (ctxt);
    4706              : }
    4707              : 
    4708              : namespace {
    4709              : 
    4710              : const pass_data pass_data_split_for_shorten_branches =
    4711              : {
    4712              :   RTL_PASS, /* type */
    4713              :   "split5", /* name */
    4714              :   OPTGROUP_NONE, /* optinfo_flags */
    4715              :   TV_NONE, /* tv_id */
    4716              :   0, /* properties_required */
    4717              :   0, /* properties_provided */
    4718              :   0, /* properties_destroyed */
    4719              :   0, /* todo_flags_start */
    4720              :   0, /* todo_flags_finish */
    4721              : };
    4722              : 
    4723              : class pass_split_for_shorten_branches : public rtl_opt_pass
    4724              : {
    4725              : public:
    4726       298828 :   pass_split_for_shorten_branches (gcc::context *ctxt)
    4727       597656 :     : rtl_opt_pass (pass_data_split_for_shorten_branches, ctxt)
    4728              :   {}
    4729              : 
    4730              :   /* opt_pass methods: */
    4731      1488378 :   bool gate (function *) final override
    4732              :     {
    4733              :       /* The placement of the splitting that we do for shorten_branches
    4734              :          depends on whether regstack is used by the target or not.  */
    4735              : #if HAVE_ATTR_length && !defined (STACK_REGS)
    4736              :       return true;
    4737              : #else
    4738      1488378 :       return false;
    4739              : #endif
    4740              :     }
    4741              : 
    4742            0 :   unsigned int execute (function *) final override
    4743              :     {
    4744            0 :       split_all_insns_noflow ();
    4745            0 :       return 0;
    4746              :     }
    4747              : 
    4748              : }; // class pass_split_for_shorten_branches
    4749              : 
    4750              : } // anon namespace
    4751              : 
    4752              : rtl_opt_pass *
    4753       298828 : make_pass_split_for_shorten_branches (gcc::context *ctxt)
    4754              : {
    4755       298828 :   return new pass_split_for_shorten_branches (ctxt);
    4756              : }
    4757              : 
    4758              : /* (Re)initialize the target information after a change in target.  */
    4759              : 
    4760              : void
    4761       222045 : recog_init ()
    4762              : {
    4763              :   /* The information is zero-initialized, so we don't need to do anything
    4764              :      first time round.  */
    4765       222045 :   if (!this_target_recog->x_initialized)
    4766              :     {
    4767       219838 :       this_target_recog->x_initialized = true;
    4768       219838 :       return;
    4769              :     }
    4770         2207 :   memset (this_target_recog->x_bool_attr_masks, 0,
    4771              :           sizeof (this_target_recog->x_bool_attr_masks));
    4772     33557435 :   for (unsigned int i = 0; i < NUM_INSN_CODES; ++i)
    4773     33555228 :     if (this_target_recog->x_op_alt[i])
    4774              :       {
    4775        30839 :         free (this_target_recog->x_op_alt[i]);
    4776        30839 :         this_target_recog->x_op_alt[i] = 0;
    4777              :       }
    4778              : }
        

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.