LCOV - code coverage report
Current view: top level - gcc - recog.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 86.5 % 1905 1648
Test Date: 2026-07-11 15:47:05 Functions: 86.3 % 124 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      7929758 : init_recog_no_volatile (void)
     110              : {
     111      7929758 :   volatile_ok = 0;
     112      7929758 : }
     113              : 
     114              : void
     115     11792466 : init_recog (void)
     116              : {
     117     11792466 :   volatile_ok = 1;
     118     11792466 : }
     119              : 
     120              : 
     121              : /* Return true if labels in asm operands BODY are LABEL_REFs.  */
     122              : 
     123              : static bool
     124    106408638 : asm_labels_ok (rtx body)
     125              : {
     126    106408638 :   rtx asmop;
     127    106408638 :   int i;
     128              : 
     129    106408638 :   asmop = extract_asm_operands (body);
     130    106408638 :   if (asmop == NULL_RTX)
     131              :     return true;
     132              : 
     133       834469 :   for (i = 0; i < ASM_OPERANDS_LABEL_LENGTH (asmop); i++)
     134         7559 :     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    106408638 : check_asm_operands (rtx x)
     145              : {
     146    106408638 :   int noperands;
     147    106408638 :   rtx *operands;
     148    106408638 :   const char **constraints;
     149    106408638 :   int i;
     150              : 
     151    106408638 :   if (!asm_labels_ok (x))
     152              :     return false;
     153              : 
     154              :   /* Post-reload, be more strict with things.  */
     155    106408638 :   if (reload_completed)
     156              :     {
     157              :       /* ??? Doh!  We've not got the wrapping insn.  Cook one up.  */
     158        28969 :       rtx_insn *insn = make_insn_raw (x);
     159        28969 :       extract_insn (insn);
     160        28969 :       constrain_operands (1, get_enabled_alternatives (insn));
     161        28969 :       return which_alternative >= 0;
     162              :     }
     163              : 
     164    106379669 :   noperands = asm_noperands (x);
     165    106379669 :   if (noperands < 0)
     166              :     return false;
     167       782172 :   if (noperands == 0)
     168              :     return true;
     169              : 
     170       668941 :   operands = XALLOCAVEC (rtx, noperands);
     171       668941 :   constraints = XALLOCAVEC (const char *, noperands);
     172              : 
     173       668941 :   decode_asm_operands (x, operands, NULL, constraints, NULL, NULL);
     174              : 
     175      3234605 :   for (i = 0; i < noperands; i++)
     176              :     {
     177      2851710 :       const char *c = constraints[i];
     178      2851710 :       if (c[0] == '%')
     179        12321 :         c++;
     180      2851710 :       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   1819333892 : validate_change_1 (rtx object, rtx *loc, rtx new_rtx, bool in_group,
     227              :                    bool unshare, int new_len = -1)
     228              : {
     229   1819333892 :   gcc_assert (!undo_recog_changes::is_active ());
     230   1819333892 :   rtx old = *loc;
     231              : 
     232              :   /* Single-element parallels aren't valid and won't match anything.
     233              :      Replace them with the single element.  */
     234   1819333892 :   if (new_len == 1 && GET_CODE (new_rtx) == PARALLEL)
     235              :     {
     236      6470248 :       new_rtx = XVECEXP (new_rtx, 0, 0);
     237      6470248 :       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   1819333892 :   if (!in_group
     245    211659476 :       && (old == new_rtx || rtx_equal_p (old, new_rtx))
     246   2012647363 :       && (new_len < 0 || XVECLEN (new_rtx, 0) == new_len))
     247              :     return true;
     248              : 
     249   1626020421 :   gcc_assert ((in_group != 0 || num_changes == 0)
     250              :               && (new_len < 0 || new_rtx == *loc));
     251              : 
     252   1626020421 :   *loc = new_rtx;
     253              : 
     254              :   /* Save the information describing this change.  */
     255   1626020421 :   if (num_changes >= changes_allocated)
     256              :     {
     257       174323 :       if (changes_allocated == 0)
     258              :         /* This value allows for repeated substitutions inside complex
     259              :            indexed addresses, or changes in up to 5 insns.  */
     260       173067 :         changes_allocated = MAX_RECOG_OPERANDS * 5;
     261              :       else
     262         1256 :         changes_allocated *= 2;
     263              : 
     264       174323 :       changes = XRESIZEVEC (change_t, changes, changes_allocated);
     265              :     }
     266              : 
     267   1626020421 :   changes[num_changes].object = object;
     268   1626020421 :   changes[num_changes].loc = loc;
     269   1626020421 :   changes[num_changes].old = old;
     270   1626020421 :   changes[num_changes].old_len = (new_len >= 0 ? XVECLEN (new_rtx, 0) : -1);
     271   1626020421 :   changes[num_changes].unshare = unshare;
     272              : 
     273   1626020421 :   if (new_len >= 0)
     274     11617659 :     XVECLEN (new_rtx, 0) = new_len;
     275              : 
     276   1626020421 :   if (object && !MEM_P (object))
     277              :     {
     278              :       /* Set INSN_CODE to force rerecognition of insn.  Save old code in
     279              :          case invalid.  */
     280   1601447928 :       changes[num_changes].old_code = INSN_CODE (object);
     281   1601447928 :       INSN_CODE (object) = -1;
     282              :     }
     283              : 
     284   1626020421 :   num_changes++;
     285              : 
     286              :   /* If we are making a group of changes, return 1.  Otherwise, validate the
     287              :      change group we made.  */
     288              : 
     289   1626020421 :   if (in_group)
     290              :     return true;
     291              :   else
     292     18346005 :     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   1511779582 : validate_change (rtx object, rtx *loc, rtx new_rtx, bool in_group)
     300              : {
     301   1511779582 :   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    289466403 : validate_unshare_change (rtx object, rtx *loc, rtx new_rtx, bool in_group)
     309              : {
     310    289466403 :   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     18087907 : validate_change_xveclen (rtx object, rtx *loc, int new_len, bool in_group)
     318              : {
     319     18087907 :   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      1871151 : canonicalize_change_group (rtx_insn *insn, rtx x)
     329              : {
     330      1871151 :   if (COMMUTATIVE_P (x)
     331      1871151 :       && 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       105510 :       rtx tem = XEXP (x, 0);
     336       105510 :       validate_unshare_change (insn, &XEXP (x, 0), XEXP (x, 1), 1);
     337       105510 :       validate_unshare_change (insn, &XEXP (x, 1), tem, 1);
     338       105510 :       return true;
     339              :     }
     340              :   else
     341      1765641 :     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    471822013 : insn_invalid_p (rtx_insn *insn, bool in_group)
     365              : {
     366    471822013 :   rtx pat = PATTERN (insn);
     367    471822013 :   int num_clobbers = 0;
     368              :   /* If we are before reload and the pattern is a SET, see if we can add
     369              :      clobbers.  */
     370    471822013 :   int icode = recog (pat, insn,
     371    471822013 :                      (GET_CODE (pat) == SET
     372    390029017 :                       && ! reload_completed
     373    370226145 :                       && ! reload_in_progress)
     374              :                      ? &num_clobbers : 0);
     375    471822013 :   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       577920 :   if ((is_asm && ! check_asm_operands (PATTERN (insn)))
     381    471620115 :       || (!is_asm && icode < 0))
     382     17859275 :     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    453962738 :   if (num_clobbers > 0)
     388              :     {
     389         1984 :       rtx newpat;
     390              : 
     391         1984 :       if (added_clobbers_hard_reg_p (icode))
     392              :         return true;
     393              : 
     394          678 :       newpat = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (num_clobbers + 1));
     395          678 :       XVECEXP (newpat, 0, 0) = pat;
     396          678 :       add_clobbers (newpat, icode);
     397          678 :       if (in_group)
     398          677 :         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    453961432 :   if (reload_completed)
     405              :     {
     406     19745528 :       extract_insn (insn);
     407              : 
     408     19745528 :       if (! constrain_operands (1, get_preferred_alternatives (insn)))
     409              :         return true;
     410              :     }
     411              : 
     412              :   /* Punt if REG_INC argument overlaps some stored REG.  */
     413    453937169 :   for (rtx link = FIND_REG_INC_NOTE (insn, NULL_RTX);
     414    453937169 :        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    453937169 :   INSN_CODE (insn) = icode;
     424    453937169 :   return false;
     425              : }
     426              : 
     427              : /* Return number of changes made and not validated yet.  */
     428              : int
     429      4813965 : num_changes_pending (void)
     430              : {
     431      4813965 :   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    774373255 : verify_changes (int num)
     439              : {
     440    774373255 :   int i;
     441    774373255 :   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   2262629542 :   for (i = num; i < num_changes; i++)
     453              :     {
     454   1502899295 :       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   1502899295 :       if (object == 0 || object == last_validated)
     459    768944505 :         continue;
     460              : 
     461    733954790 :       if (MEM_P (object))
     462              :         {
     463        35844 :           if (! memory_address_addr_space_p (GET_MODE (object),
     464              :                                              XEXP (object, 0),
     465        17922 :                                              MEM_ADDR_SPACE (object)))
     466              :             break;
     467              :         }
     468    733936868 :       else if (/* changes[i].old might be zero, e.g. when putting a
     469              :                REG_FRAME_RELATED_EXPR into a previously empty list.  */
     470    733936868 :                changes[i].old
     471    733936868 :                && REG_P (changes[i].old)
     472    234852760 :                && asm_noperands (PATTERN (object)) > 0
     473    734135811 :                && 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    733936867 :       else if (DEBUG_INSN_P (object))
     480    263059494 :         continue;
     481    470877373 :       else if (insn_invalid_p (as_a <rtx_insn *> (object), true))
     482              :         {
     483     17316996 :           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     17316996 :           if (GET_CODE (pat) == PARALLEL
     491      4108016 :               && GET_CODE (XVECEXP (pat, 0, XVECLEN (pat, 0) - 1)) == CLOBBER
     492     20178242 :               && asm_noperands (PATTERN (object)) < 0)
     493              :             {
     494      2661005 :               rtx newpat;
     495              : 
     496      2661005 :               if (XVECLEN (pat, 0) == 2)
     497      2254706 :                 newpat = XVECEXP (pat, 0, 0);
     498              :               else
     499              :                 {
     500       406299 :                   int j;
     501              : 
     502       406299 :                   newpat
     503       406299 :                     = gen_rtx_PARALLEL (VOIDmode,
     504              :                                         rtvec_alloc (XVECLEN (pat, 0) - 1));
     505      1253129 :                   for (j = 0; j < XVECLEN (newpat, 0); j++)
     506       846830 :                     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      2661005 :               validate_change (object, &PATTERN (object), newpat, 1);
     519      2661005 :               continue;
     520      2661005 :             }
     521     14655991 :           else if (GET_CODE (pat) == USE || GET_CODE (pat) == CLOBBER
     522     14642937 :                    || GET_CODE (pat) == VAR_LOCATION)
     523              :             /* If this insn is a CLOBBER or USE, it is always valid, but is
     524              :                never recognized.  */
     525        13054 :             continue;
     526              :           else
     527              :             break;
     528              :         }
     529              :       last_validated = object;
     530              :     }
     531              : 
     532    774373255 :   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    770845204 : confirm_change_group (void)
     541              : {
     542    770845204 :   int i;
     543    770845204 :   rtx last_object = NULL;
     544              : 
     545    770845204 :   gcc_assert (!undo_recog_changes::is_active ());
     546   2268681843 :   for (i = 0; i < num_changes; i++)
     547              :     {
     548   1497836639 :       rtx object = changes[i].object;
     549              : 
     550   1497836639 :       if (changes[i].unshare)
     551     19866354 :         *changes[i].loc = copy_rtx (*changes[i].loc);
     552              : 
     553              :       /* Avoid unnecessary rescanning when multiple changes to same instruction
     554              :          are made.  */
     555   1497836639 :       if (object)
     556              :         {
     557   1495474259 :           if (object != last_object && last_object && INSN_P (last_object))
     558      7689985 :             df_insn_rescan (as_a <rtx_insn *> (last_object));
     559              :           last_object = object;
     560              :         }
     561              :     }
     562              : 
     563    770845204 :   if (last_object && INSN_P (last_object))
     564    605059387 :     df_insn_rescan (as_a <rtx_insn *> (last_object));
     565    770845204 :   num_changes = 0;
     566    770845204 : }
     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    767235539 : apply_change_group (void)
     574              : {
     575    767235539 :   if (verify_changes (0))
     576              :     {
     577    755352527 :       confirm_change_group ();
     578    755352527 :       return true;
     579              :     }
     580              :   else
     581              :     {
     582     11883012 :       cancel_changes (0);
     583     11883012 :       return false;
     584              :     }
     585              : }
     586              : 
     587              : 
     588              : /* Return the number of changes so far in the current group.  */
     589              : 
     590              : int
     591    743168368 : num_validated_changes (void)
     592              : {
     593    743168368 :   return num_changes;
     594              : }
     595              : 
     596              : /* Retract the changes numbered NUM and up.  */
     597              : 
     598              : void
     599    169955676 : cancel_changes (int num)
     600              : {
     601    169955676 :   gcc_assert (!undo_recog_changes::is_active ());
     602    169955676 :   int i;
     603              : 
     604              :   /* Back out all the changes.  Do this in the opposite order in which
     605              :      they were made.  */
     606    298139458 :   for (i = num_changes - 1; i >= num; i--)
     607              :     {
     608    128183782 :       if (changes[i].old_len >= 0)
     609     10763658 :         XVECLEN (*changes[i].loc, 0) = changes[i].old_len;
     610              :       else
     611    117420124 :         *changes[i].loc = changes[i].old;
     612    128183782 :       if (changes[i].object && !MEM_P (changes[i].object))
     613              :         {
     614    105991521 :           INSN_CODE (changes[i].object) = changes[i].old_code;
     615    105991521 :           if (recog_data.insn == changes[i].object)
     616          184 :             recog_data.insn = nullptr;
     617              :         }
     618              :     }
     619    169955676 :   num_changes = num;
     620    169955676 : }
     621              : 
     622              : /* Swap the status of change NUM from being applied to not being applied,
     623              :    or vice versa.  */
     624              : 
     625              : static void
     626     47445604 : swap_change (int num)
     627              : {
     628     47445604 :   if (changes[num].old_len >= 0)
     629      2136712 :     std::swap (XVECLEN (*changes[num].loc, 0), changes[num].old_len);
     630              :   else
     631     45308892 :     std::swap (*changes[num].loc, changes[num].old);
     632     47445604 :   if (changes[num].object && !MEM_P (changes[num].object))
     633              :     {
     634     47445604 :       std::swap (INSN_CODE (changes[num].object), changes[num].old_code);
     635     47445604 :       if (recog_data.insn == changes[num].object)
     636            8 :         recog_data.insn = nullptr;
     637              :     }
     638     47445604 : }
     639              : 
     640     27568697 : undo_recog_changes::undo_recog_changes (int num)
     641     27568697 :   : m_old_num_changes (s_num_changes)
     642              : {
     643     27568697 :   gcc_assert (num <= num_changes - s_num_changes);
     644     51291499 :   for (int i = num_changes - s_num_changes - 1; i >= num; i--)
     645     23722802 :     swap_change (i);
     646     27568697 :   s_num_changes = num_changes - num;
     647     27568697 : }
     648              : 
     649     27568697 : undo_recog_changes::~undo_recog_changes ()
     650              : {
     651     51291499 :   for (int i = num_changes - s_num_changes;
     652     51291499 :        i < num_changes - m_old_num_changes; ++i)
     653     23722802 :     swap_change (i);
     654     27568697 :   s_num_changes = m_old_num_changes;
     655     27568697 : }
     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     12346887 : simplify_while_replacing (rtx *loc, rtx to, rtx_insn *object,
     663              :                           machine_mode op0_mode)
     664              : {
     665     12346887 :   rtx x = *loc;
     666     12346887 :   enum rtx_code code = GET_CODE (x);
     667     12346887 :   rtx new_rtx = NULL_RTX;
     668     12346887 :   scalar_int_mode is_mode;
     669              : 
     670     12346887 :   if (SWAPPABLE_OPERANDS_P (x)
     671     12346887 :       && swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1)))
     672              :     {
     673       447341 :       validate_unshare_change (object, loc,
     674       447341 :                                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       447341 :       x = *loc;
     679       447341 :       code = GET_CODE (x);
     680              :     }
     681              : 
     682              :   /* Canonicalize arithmetics with all constant operands.  */
     683     12346887 :   switch (GET_RTX_CLASS (code))
     684              :     {
     685       806623 :     case RTX_UNARY:
     686       806623 :       if (CONSTANT_P (XEXP (x, 0)))
     687       561463 :         new_rtx = simplify_unary_operation (code, GET_MODE (x), XEXP (x, 0),
     688              :                                             op0_mode);
     689              :       break;
     690      6370795 :     case RTX_COMM_ARITH:
     691      6370795 :     case RTX_BIN_ARITH:
     692      6370795 :       if (CONSTANT_P (XEXP (x, 0)) && CONSTANT_P (XEXP (x, 1)))
     693       255279 :         new_rtx = simplify_binary_operation (code, GET_MODE (x), XEXP (x, 0),
     694              :                                              XEXP (x, 1));
     695              :       break;
     696       114328 :     case RTX_COMPARE:
     697       114328 :     case RTX_COMM_COMPARE:
     698       114328 :       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       819949 :   if (new_rtx)
     706              :     {
     707       788805 :       validate_change (object, loc, new_rtx, 1);
     708       788805 :       return;
     709              :     }
     710              : 
     711     11558082 :   switch (code)
     712              :     {
     713      2169124 :     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      2169124 :       if (CONST_INT_P (XEXP (x, 1)) && XEXP (x, 1) == to)
     719       193437 :         validate_change (object, loc,
     720              :                          simplify_gen_binary
     721       193437 :                          (PLUS, GET_MODE (x), XEXP (x, 0), XEXP (x, 1)), 1);
     722              :       break;
     723       486110 :     case MINUS:
     724       486110 :       if (CONST_SCALAR_INT_P (XEXP (x, 1)))
     725        22845 :         validate_change (object, loc,
     726              :                          simplify_gen_binary
     727        22845 :                          (PLUS, GET_MODE (x), XEXP (x, 0),
     728              :                           simplify_gen_unary (NEG,
     729              :                                               GET_MODE (x), XEXP (x, 1),
     730        22845 :                                               GET_MODE (x))), 1);
     731              :       break;
     732       182148 :     case ZERO_EXTEND:
     733       182148 :     case SIGN_EXTEND:
     734       182148 :       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       151660 :     case SUBREG:
     746              :       /* All subregs possible to simplify should be simplified.  */
     747       303320 :       new_rtx = simplify_subreg (GET_MODE (x), SUBREG_REG (x), op0_mode,
     748       151660 :                              SUBREG_BYTE (x));
     749              : 
     750              :       /* Subregs of VOIDmode operands are incorrect.  */
     751       151660 :       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       133537 :         validate_change (object, loc, new_rtx, 1);
     755              :       break;
     756         5315 :     case ZERO_EXTRACT:
     757         5315 :     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         5315 :       if (MEM_P (XEXP (x, 0))
     764          396 :           && is_a <scalar_int_mode> (GET_MODE (XEXP (x, 0)), &is_mode)
     765          396 :           && CONST_INT_P (XEXP (x, 1))
     766          396 :           && CONST_INT_P (XEXP (x, 2))
     767          289 :           && !mode_dependent_address_p (XEXP (XEXP (x, 0), 0),
     768          307 :                                         MEM_ADDR_SPACE (XEXP (x, 0)))
     769         5604 :           && !MEM_VOLATILE_P (XEXP (x, 0)))
     770              :         {
     771          285 :           int pos = INTVAL (XEXP (x, 2));
     772          285 :           machine_mode new_mode = is_mode;
     773          285 :           if (GET_CODE (x) == ZERO_EXTRACT && targetm.have_extzv ())
     774            0 :             new_mode = insn_data[targetm.code_for_extzv].operand[1].mode;
     775          285 :           else if (GET_CODE (x) == SIGN_EXTRACT && targetm.have_extv ())
     776            0 :             new_mode = insn_data[targetm.code_for_extv].operand[1].mode;
     777          285 :           scalar_int_mode wanted_mode = (new_mode == VOIDmode
     778          285 :                                          ? word_mode
     779          285 :                                          : as_a <scalar_int_mode> (new_mode));
     780              : 
     781              :           /* If we have a narrower mode, we can do something.  */
     782          855 :           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     69515126 : validate_replace_rtx_1 (rtx *loc, rtx from, rtx to, rtx_insn *object,
     817              :                         bool simplify)
     818              : {
     819     69515126 :   int i, j;
     820     69515126 :   const char *fmt;
     821     69515126 :   rtx x = *loc;
     822     69515126 :   enum rtx_code code;
     823     69515126 :   machine_mode op0_mode = VOIDmode;
     824     69515126 :   int prev_changes = num_changes;
     825              : 
     826     69515126 :   if (!x)
     827              :     return;
     828              : 
     829     69515126 :   code = GET_CODE (x);
     830     69515126 :   fmt = GET_RTX_FORMAT (code);
     831     69515126 :   if (fmt[0] == 'e')
     832     23854017 :     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     69515126 :   if (x == from
     839     53733952 :       || (REG_P (x) && REG_P (from)
     840     15524193 :           && GET_MODE (x) == GET_MODE (from)
     841      9137741 :           && REGNO (x) == REGNO (from))
     842    123249075 :       || (GET_CODE (x) == GET_CODE (from) && GET_MODE (x) == GET_MODE (from)
     843      9137738 :           && rtx_equal_p (x, from)))
     844              :     {
     845     15781177 :       validate_unshare_change (object, loc, to, 1);
     846     15781177 :       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     53733949 :   if (GET_CODE (x) == PARALLEL)
     855              :     {
     856      1400779 :       for (j = XVECLEN (x, 0) - 1; j >= 0; j--)
     857              :         {
     858      1033804 :           if (j && GET_CODE (XVECEXP (x, 0, j)) == SET
     859        30626 :               && 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      1033529 :             validate_replace_rtx_1 (&XVECEXP (x, 0, j), from, to, object,
     870              :                                     simplify);
     871              :         }
     872              :     }
     873              :   else
     874    136196850 :     for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
     875              :       {
     876     82829876 :         if (fmt[i] == 'e')
     877     40754958 :           validate_replace_rtx_1 (&XEXP (x, i), from, to, object, simplify);
     878     42074918 :         else if (fmt[i] == 'E')
     879      6381545 :           for (j = XVECLEN (x, i) - 1; j >= 0; j--)
     880      3475807 :             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     53733949 :   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     12346958 :   if (fmt[0] == 'e' && GET_MODE (XEXP (x, 0)) != VOIDmode)
     892      9348125 :     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     12346958 :   if (simplify)
     897     12346887 :     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      2051760 : validate_replace_rtx (rtx from, rtx to, rtx_insn *insn)
     916              : {
     917      2051760 :   validate_replace_rtx_1 (&PATTERN (insn), from, to, insn, true);
     918      2051760 :   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     22198687 : validate_replace_src_1 (rtx *x, void *data)
     968              : {
     969     22198687 :   struct validate_replace_src_data *d
     970              :     = (struct validate_replace_src_data *) data;
     971              : 
     972     22198687 :   validate_replace_rtx_1 (x, d->from, d->to, d->insn, true);
     973     22198687 : }
     974              : 
     975              : /* Try replacing every occurrence of FROM in INSN with TO, avoiding
     976              :    SET_DESTs.  */
     977              : 
     978              : void
     979     15843661 : validate_replace_src_group (rtx from, rtx to, rtx_insn *insn)
     980              : {
     981     15843661 :   struct validate_replace_src_data d;
     982              : 
     983     15843661 :   d.from = from;
     984     15843661 :   d.to = to;
     985     15843661 :   d.insn = insn;
     986     15843661 :   note_uses (&PATTERN (insn), validate_replace_src_1, &d);
     987     15843661 : }
     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     24345657 : insn_propagation::apply_to_mem_1 (rtx mem)
    1034              : {
    1035     24345657 :   auto old_num_changes = num_validated_changes ();
    1036     24345657 :   mem_depth += 1;
    1037     24345657 :   bool res = apply_to_rvalue_1 (&XEXP (mem, 0));
    1038     24345657 :   mem_depth -= 1;
    1039     24345657 :   if (!res)
    1040              :     return false;
    1041              : 
    1042     24345024 :   if (old_num_changes != num_validated_changes ()
    1043      7834930 :       && should_check_mems
    1044     27662293 :       && !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    237441302 : insn_propagation::apply_to_rvalue_1 (rtx *loc)
    1055              : {
    1056    237441302 :   rtx x = *loc;
    1057    237441302 :   enum rtx_code code = GET_CODE (x);
    1058    237441302 :   machine_mode mode = GET_MODE (x);
    1059              : 
    1060    237441302 :   auto old_num_changes = num_validated_changes ();
    1061    237441302 :   if (from
    1062    226286240 :       && GET_CODE (x) == GET_CODE (from)
    1063    330664718 :       && (REG_P (x)
    1064     93223416 :           ? REGNO (x) == REGNO (from)
    1065        24093 :           : 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     59945828 :       if (REG_P (x)
    1070     59922633 :           && HARD_REGISTER_P (x)
    1071     18311702 :           && register_asm_p (x)
    1072     59947825 :           && asm_noperands (PATTERN (insn)) > 0)
    1073              :         return false;
    1074              : 
    1075     59944000 :       rtx newval = to;
    1076     59944000 :       if (GET_MODE (x) != GET_MODE (from))
    1077              :         {
    1078       699081 :           gcc_assert (REG_P (x) && HARD_REGISTER_P (x));
    1079       699081 :           if (REG_NREGS (x) != REG_NREGS (from)
    1080       699081 :               || !REG_CAN_CHANGE_MODE_P (REGNO (x), GET_MODE (from),
    1081              :                                          GET_MODE (x)))
    1082       356398 :             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       615243 :           if (paradoxical_subreg_p (GET_MODE (x), GET_MODE (from))
    1090       615243 :               && !CONSTANT_P (to))
    1091              :             return false;
    1092              : 
    1093       595993 :           newval = simplify_subreg (GET_MODE (x), to, GET_MODE (from),
    1094              :                                     subreg_lowpart_offset (GET_MODE (x),
    1095              :                                                            GET_MODE (from)));
    1096       595993 :           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       345538 :           subrtx_iterator::array_type array;
    1113      1322400 :           FOR_EACH_SUBRTX (iter, array, newval, NONCONST)
    1114       979717 :             if (GET_CODE (*iter) == SUBREG)
    1115         2855 :               return false;
    1116       345538 :         }
    1117              : 
    1118     59587602 :       if (should_unshare)
    1119     59587602 :         validate_unshare_change (insn, loc, newval, 1);
    1120              :       else
    1121            0 :         validate_change (insn, loc, newval, 1);
    1122     59587602 :       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      3555461 :           insn_propagation subprop (insn);
    1128      3555461 :           subprop.mem_depth += 1;
    1129      3555461 :           if (!subprop.apply_to_rvalue (loc))
    1130            0 :             gcc_unreachable ();
    1131      3555461 :           if (should_unshare
    1132      3555461 :               && 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       297166 :               newval = copy_rtx (*loc);
    1137       297166 :               cancel_changes (old_num_changes);
    1138       297166 :               validate_change (insn, loc, newval, 1);
    1139              :             }
    1140              :         }
    1141     59587602 :       num_replacements += 1;
    1142     59587602 :       should_unshare = true;
    1143     59587602 :       result_flags |= UNSIMPLIFIED;
    1144     59587602 :       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    177495474 :   auto old_result_flags = result_flags;
    1152    177495474 :   rtx newx = NULL_RTX;
    1153    177495474 :   bool recurse_p = false;
    1154    177495474 :   switch (GET_RTX_CLASS (code))
    1155              :     {
    1156      3024151 :     case RTX_UNARY:
    1157      3024151 :       {
    1158      3024151 :         machine_mode op0_mode = GET_MODE (XEXP (x, 0));
    1159      3024151 :         if (!apply_to_rvalue_1 (&XEXP (x, 0)))
    1160              :           return false;
    1161      2985382 :         if (from && old_num_changes == num_validated_changes ())
    1162              :           return true;
    1163              : 
    1164      2402486 :         newx = simplify_unary_operation (code, mode, XEXP (x, 0), op0_mode);
    1165      2402486 :         break;
    1166              :       }
    1167              : 
    1168     46019446 :     case RTX_BIN_ARITH:
    1169     46019446 :     case RTX_COMM_ARITH:
    1170     46019446 :       {
    1171     46019446 :         if (!apply_to_rvalue_1 (&XEXP (x, 0))
    1172     46019446 :             || !apply_to_rvalue_1 (&XEXP (x, 1)))
    1173       471327 :           return false;
    1174     45548119 :         if (from && old_num_changes == num_validated_changes ())
    1175              :           return true;
    1176              : 
    1177     34901010 :         if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
    1178     34901010 :             && swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1)))
    1179      2700530 :           newx = simplify_gen_binary (code, mode, XEXP (x, 1), XEXP (x, 0));
    1180              :         else
    1181     32200480 :           newx = simplify_binary_operation (code, mode,
    1182              :                                             XEXP (x, 0), XEXP (x, 1));
    1183              :         break;
    1184              :       }
    1185              : 
    1186      6053429 :     case RTX_COMPARE:
    1187      6053429 :     case RTX_COMM_COMPARE:
    1188      6053429 :       {
    1189     12106985 :         machine_mode op_mode = (GET_MODE (XEXP (x, 0)) != VOIDmode
    1190      6053429 :                                 ? GET_MODE (XEXP (x, 0))
    1191          127 :                                 : GET_MODE (XEXP (x, 1)));
    1192      6053429 :         if (!apply_to_rvalue_1 (&XEXP (x, 0))
    1193      6053429 :             || !apply_to_rvalue_1 (&XEXP (x, 1)))
    1194         4373 :           return false;
    1195      6049056 :         if (from && old_num_changes == num_validated_changes ())
    1196              :           return true;
    1197              : 
    1198      5159822 :         newx = simplify_relational_operation (code, mode, op_mode,
    1199              :                                               XEXP (x, 0), XEXP (x, 1));
    1200      5159822 :         break;
    1201              :       }
    1202              : 
    1203      5451975 :     case RTX_TERNARY:
    1204      5451975 :     case RTX_BITFIELD_OPS:
    1205      5451975 :       {
    1206      5451975 :         machine_mode op0_mode = GET_MODE (XEXP (x, 0));
    1207      5451975 :         if (!apply_to_rvalue_1 (&XEXP (x, 0))
    1208      5444752 :             || !apply_to_rvalue_1 (&XEXP (x, 1))
    1209     10874220 :             || !apply_to_rvalue_1 (&XEXP (x, 2)))
    1210        32021 :           return false;
    1211      5419954 :         if (from && old_num_changes == num_validated_changes ())
    1212              :           return true;
    1213              : 
    1214      5352096 :         newx = simplify_ternary_operation (code, mode, op0_mode,
    1215              :                                            XEXP (x, 0), XEXP (x, 1),
    1216              :                                            XEXP (x, 2));
    1217      5352096 :         break;
    1218              :       }
    1219              : 
    1220     11244830 :     case RTX_EXTRA:
    1221     11244830 :       if (code == SUBREG)
    1222              :         {
    1223      2516895 :           machine_mode inner_mode = GET_MODE (SUBREG_REG (x));
    1224      2516895 :           if (!apply_to_rvalue_1 (&SUBREG_REG (x)))
    1225              :             return false;
    1226      2516879 :           if (from && old_num_changes == num_validated_changes ())
    1227              :             return true;
    1228              : 
    1229      1851331 :           rtx inner = SUBREG_REG (x);
    1230      1851331 :           newx = simplify_subreg (mode, inner, inner_mode, SUBREG_BYTE (x));
    1231              :           /* Reject the same cases that simplify_gen_subreg would.  */
    1232      1851331 :           if (!newx
    1233      1851331 :               && (GET_CODE (inner) == SUBREG
    1234      1160145 :                   || GET_CODE (inner) == CONCAT
    1235      1147516 :                   || GET_MODE (inner) == VOIDmode
    1236      1147515 :                   || !validate_subreg (mode, inner_mode,
    1237      1147515 :                                        inner, SUBREG_BYTE (x))))
    1238              :             {
    1239        12674 :               failure_reason = "would create an invalid subreg";
    1240        12674 :               return false;
    1241              :             }
    1242              :           break;
    1243              :         }
    1244              :       else
    1245              :         recurse_p = true;
    1246              :       break;
    1247              : 
    1248     54217089 :     case RTX_OBJ:
    1249     54217089 :       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     54217089 :       else if (code == REG)
    1270              :         {
    1271     37424575 :           if (from && REG_P (from) && reg_overlap_mentioned_p (x, from))
    1272              :             {
    1273        61823 :               failure_reason = "inexact register overlap";
    1274        61823 :               return false;
    1275              :             }
    1276              :         }
    1277     16792514 :       else if (code == MEM)
    1278     12690072 :         return apply_to_mem_1 (x);
    1279              :       else
    1280              :         recurse_p = true;
    1281              :       break;
    1282              : 
    1283              :     case RTX_CONST_OBJ:
    1284              :       break;
    1285              : 
    1286      1431656 :     case RTX_AUTOINC:
    1287      1431656 :       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     49654071 :   if (recurse_p)
    1301              :     {
    1302     14262033 :       const char *fmt = GET_RTX_FORMAT (code);
    1303     32518718 :       for (int i = 0; fmt[i]; i++)
    1304     18370804 :         switch (fmt[i])
    1305              :           {
    1306              :           case 'E':
    1307      6121067 :             for (int j = 0; j < XVECLEN (x, i); j++)
    1308      4354497 :               if (!apply_to_rvalue_1 (&XVECEXP (x, i, j)))
    1309              :                 return false;
    1310              :             break;
    1311              : 
    1312     12507472 :           case 'e':
    1313     12507472 :             if (XEXP (x, i) && !apply_to_rvalue_1 (&XEXP (x, i)))
    1314              :               return false;
    1315              :             break;
    1316              :           }
    1317              :     }
    1318    137069721 :   else if (newx && !rtx_equal_p (x, newx))
    1319              :     {
    1320              :       /* All substitutions made by OLD_NUM_CHANGES onwards have been
    1321              :          simplified.  */
    1322     10782448 :       result_flags = ((result_flags & ~UNSIMPLIFIED)
    1323              :                       | (old_result_flags & UNSIMPLIFIED));
    1324              : 
    1325     10782448 :       if (should_note_simplifications)
    1326      3927126 :         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     21535455 :       for (int i = old_num_changes; i < num_changes; ++i)
    1332              :         {
    1333     10753007 :           unshare |= changes[i].unshare;
    1334     10753007 :           changes[i].unshare = false;
    1335              :         }
    1336     10782448 :       if (unshare)
    1337     10360482 :         validate_unshare_change (insn, loc, newx, 1);
    1338              :       else
    1339       421966 :         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     63664211 : insn_propagation::apply_to_lvalue_1 (rtx dest)
    1350              : {
    1351     63664211 :   rtx old_dest = dest;
    1352     63664211 :   while (GET_CODE (dest) == SUBREG
    1353     63868870 :          || GET_CODE (dest) == ZERO_EXTRACT
    1354     63868870 :          || GET_CODE (dest) == STRICT_LOW_PART)
    1355              :     {
    1356       204659 :       if (GET_CODE (dest) == ZERO_EXTRACT
    1357       204659 :           && (!apply_to_rvalue_1 (&XEXP (dest, 1))
    1358         2745 :               || !apply_to_rvalue_1 (&XEXP (dest, 2))))
    1359            0 :         return false;
    1360       204659 :       dest = XEXP (dest, 0);
    1361              :     }
    1362              : 
    1363     63664211 :   if (MEM_P (dest))
    1364     11655585 :     return apply_to_mem_1 (dest);
    1365              : 
    1366              :   /* Check whether the substitution is safe in the presence of this lvalue.  */
    1367     52008626 :   if (!from
    1368     52008626 :       || dest == old_dest
    1369       200476 :       || !REG_P (dest)
    1370     52209102 :       || !reg_overlap_mentioned_p (dest, from))
    1371     51907937 :     return true;
    1372              : 
    1373       100689 :   if (SUBREG_P (old_dest)
    1374        96070 :       && SUBREG_REG (old_dest) == dest
    1375       196759 :       && !read_modify_subreg_p (old_dest))
    1376              :     return true;
    1377              : 
    1378       100418 :   failure_reason = "is part of a read-write destination";
    1379       100418 :   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     67408875 : insn_propagation::apply_to_pattern_1 (rtx *loc)
    1387              : {
    1388     67408875 :   rtx body = *loc;
    1389     67408875 :   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     14642516 :       for (int i = 0; i < XVECLEN (body, 0); ++i)
    1397              :         {
    1398     10008930 :           rtx *subloc = &XVECEXP (body, 0, i);
    1399     10008930 :           if (GET_CODE (*subloc) == SET)
    1400              :             {
    1401      5437481 :               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       761421 :               if ((i == 0 || GET_CODE (SET_SRC (*subloc)) != ASM_OPERANDS)
    1406      6063162 :                   && !apply_to_rvalue_1 (&SET_SRC (*subloc)))
    1407              :                 return false;
    1408              :             }
    1409              :           else
    1410              :             {
    1411      4571449 :               if (!apply_to_pattern_1 (subloc))
    1412              :                 return false;
    1413              :             }
    1414              :         }
    1415              :       return true;
    1416              : 
    1417         8600 :     case ASM_OPERANDS:
    1418        30454 :       for (int i = 0, len = ASM_OPERANDS_INPUT_LENGTH (body); i < len; ++i)
    1419        22074 :         if (!apply_to_rvalue_1 (&ASM_OPERANDS_INPUT (body, i)))
    1420              :           return false;
    1421              :       return true;
    1422              : 
    1423      4371738 :     case CLOBBER:
    1424      4371738 :       return apply_to_lvalue_1 (XEXP (body, 0));
    1425              : 
    1426     53854992 :     case SET:
    1427     53854992 :       return (apply_to_lvalue_1 (SET_DEST (body))
    1428     53854992 :               && apply_to_rvalue_1 (&SET_SRC (body)));
    1429              : 
    1430      4487135 :     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      4487135 :       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     62837426 : insn_propagation::apply_to_pattern (rtx *loc)
    1448              : {
    1449     62837426 :   unsigned int num_changes = num_validated_changes ();
    1450     62837426 :   bool res = apply_to_pattern_1 (loc);
    1451     62837426 :   if (!res)
    1452      2289876 :     cancel_changes (num_changes);
    1453     62837426 :   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      7416715 : insn_propagation::apply_to_rvalue (rtx *loc)
    1461              : {
    1462      7416715 :   unsigned int num_changes = num_validated_changes ();
    1463      7416715 :   bool res = apply_to_rvalue_1 (loc);
    1464      7416715 :   if (!res)
    1465        20763 :     cancel_changes (num_changes);
    1466      7416715 :   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       184024 : insn_propagation::apply_to_note (rtx *loc)
    1474              : {
    1475       184024 :   auto old_code = INSN_CODE (insn);
    1476       184024 :   bool res = apply_to_rvalue (loc);
    1477       184024 :   if (INSN_CODE (insn) != old_code)
    1478        88693 :     INSN_CODE (insn) = old_code;
    1479       184024 :   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   4913989922 : general_operand (rtx op, machine_mode mode)
    1514              : {
    1515   4913989922 :   enum rtx_code code = GET_CODE (op);
    1516              : 
    1517   4913989922 :   if (mode == VOIDmode)
    1518   1293961884 :     mode = GET_MODE (op);
    1519              : 
    1520              :   /* Don't accept CONST_INT or anything similar
    1521              :      if the caller wants something floating.  */
    1522   4913989922 :   if (GET_MODE (op) == VOIDmode && mode != VOIDmode
    1523    221925289 :       && GET_MODE_CLASS (mode) != MODE_INT
    1524         6389 :       && GET_MODE_CLASS (mode) != MODE_PARTIAL_INT)
    1525              :     return false;
    1526              : 
    1527   4913983533 :   if (CONST_INT_P (op)
    1528    271353465 :       && mode != VOIDmode
    1529   5132678759 :       && trunc_int_for_mode (INTVAL (op), mode) != INTVAL (op))
    1530              :     return false;
    1531              : 
    1532   4913983284 :   if (CONSTANT_P (op))
    1533     64032730 :     return ((GET_MODE (op) == VOIDmode || GET_MODE (op) == mode
    1534         7832 :              || mode == VOIDmode)
    1535    335948696 :             && (! flag_pic || LEGITIMATE_PIC_OPERAND_P (op))
    1536    724059216 :             && targetm.legitimate_constant_p (mode == VOIDmode
    1537     52733940 :                                               ? 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   4578026756 :   if (GET_MODE (op) != mode)
    1544              :     return false;
    1545              : 
    1546   4523943074 :   if (code == SUBREG)
    1547              :     {
    1548     35612560 :       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     35563896 :       if (!reload_completed && MEM_P (sub)
    1556     35681519 :           && 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     35543819 :       if (!reload_completed
    1566     35495155 :           && maybe_ne (SUBREG_BYTE (op), 0)
    1567     40714025 :           && MEM_P (sub))
    1568              :         return false;
    1569              : 
    1570     35543819 :       if (REG_P (sub)
    1571     33836661 :           && REGNO (sub) < FIRST_PSEUDO_REGISTER
    1572         4690 :           && !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     35543819 :           && ! 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     35543819 :       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       322370 :           && ! lra_in_progress
    1590     35849318 :           && paradoxical_subreg_p (op))
    1591              :         return false;
    1592              : 
    1593     35543819 :       op = sub;
    1594     35543819 :       code = GET_CODE (op);
    1595              :     }
    1596              : 
    1597   4523874333 :   if (code == REG)
    1598   3711862445 :     return (REGNO (op) >= FIRST_PSEUDO_REGISTER
    1599   3711862445 :             || in_hard_reg_set_p (operand_reg_set, GET_MODE (op), REGNO (op)));
    1600              : 
    1601    812011888 :   if (code == MEM)
    1602              :     {
    1603    718268007 :       rtx y = XEXP (op, 0);
    1604              : 
    1605              :       /* If -ffuse-ops-with-volatile-access is enabled, allow volatile
    1606              :          memory reference.  */
    1607    718268007 :       if (!flag_fuse_ops_with_volatile_access
    1608       152029 :           && !volatile_ok
    1609    718314846 :           && 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    718261965 :       if (lra_in_progress
    1617    771734193 :           || memory_address_addr_space_p (GET_MODE (op), y, MEM_ADDR_SPACE (op)))
    1618    699965223 :         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    115115192 : address_operand (rtx op, machine_mode mode)
    1632              : {
    1633              :   /* Wrong mode for an address expr.  */
    1634    115115192 :   if (GET_MODE (op) != VOIDmode
    1635    102738345 :       && ! SCALAR_INT_MODE_P (GET_MODE (op)))
    1636              :     return false;
    1637              : 
    1638    114224850 :   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   2671211663 : register_operand (rtx op, machine_mode mode)
    1649              : {
    1650   2671211663 :   if (GET_CODE (op) == SUBREG)
    1651              :     {
    1652     12120772 :       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     12120772 :       if (!REG_P (sub) && (reload_completed || !MEM_P (sub)))
    1661              :         return false;
    1662              :     }
    1663   2659090891 :   else if (!REG_P (op))
    1664              :     return false;
    1665   1963951268 :   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       705403 : scratch_operand (rtx op, machine_mode mode)
    1681              : {
    1682       705403 :   if (GET_MODE (op) != mode && mode != VOIDmode)
    1683              :     return false;
    1684              : 
    1685       666846 :   return (GET_CODE (op) == SCRATCH
    1686       666846 :           || (REG_P (op)
    1687        87944 :               && (lra_in_progress
    1688        70196 :                   || (REGNO (op) < FIRST_PSEUDO_REGISTER
    1689        67916 :                       && 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    509208626 : 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    509208626 :   if (GET_MODE (op) == VOIDmode && mode != VOIDmode
    1703    145197851 :       && GET_MODE_CLASS (mode) != MODE_INT
    1704            0 :       && GET_MODE_CLASS (mode) != MODE_PARTIAL_INT)
    1705              :     return false;
    1706              : 
    1707    509208626 :   if (CONST_INT_P (op)
    1708    327274185 :       && mode != VOIDmode
    1709    651313336 :       && trunc_int_for_mode (INTVAL (op), mode) != INTVAL (op))
    1710              :     return false;
    1711              : 
    1712    508983255 :   return (CONSTANT_P (op)
    1713    393671108 :           && (GET_MODE (op) == mode || mode == VOIDmode
    1714    146488817 :               || GET_MODE (op) == VOIDmode)
    1715    391131060 :           && (! flag_pic || LEGITIMATE_PIC_OPERAND_P (op))
    1716   1119028172 :           && targetm.legitimate_constant_p (mode == VOIDmode
    1717    223639923 :                                             ? 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     39330830 : const_int_operand (rtx op, machine_mode mode)
    1725              : {
    1726     39330830 :   if (!CONST_INT_P (op))
    1727              :     return false;
    1728              : 
    1729     33151453 :   if (mode != VOIDmode
    1730     33151453 :       && 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      2360750 : const_scalar_int_operand (rtx op, machine_mode mode)
    1741              : {
    1742      2360750 :   if (!CONST_SCALAR_INT_P (op))
    1743              :     return false;
    1744              : 
    1745      1983023 :   if (CONST_INT_P (op))
    1746       157648 :     return const_int_operand (op, mode);
    1747              : 
    1748      1825375 :   if (mode != VOIDmode)
    1749              :     {
    1750      1825375 :       scalar_int_mode int_mode = as_a <scalar_int_mode> (mode);
    1751      1825375 :       int prec = GET_MODE_PRECISION (int_mode);
    1752      1825375 :       int bitsize = GET_MODE_BITSIZE (int_mode);
    1753              : 
    1754      1825375 :       if (CONST_WIDE_INT_NUNITS (op) * HOST_BITS_PER_WIDE_INT > bitsize)
    1755              :         return false;
    1756              : 
    1757      1825375 :       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   1893904252 : nonimmediate_operand (rtx op, machine_mode mode)
    1803              : {
    1804   1893904252 :   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    526346966 : nonmemory_operand (rtx op, machine_mode mode)
    1812              : {
    1813    526346966 :   if (CONSTANT_P (op))
    1814     32544545 :     return immediate_operand (op, mode);
    1815    493802421 :   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    843636899 : push_operand (rtx op, machine_mode mode)
    1826              : {
    1827    843636899 :   if (!MEM_P (op))
    1828              :     return false;
    1829              : 
    1830    249088337 :   if (mode != VOIDmode && GET_MODE (op) != mode)
    1831              :     return false;
    1832              : 
    1833    471508702 :   poly_int64 rounded_size = GET_MODE_SIZE (mode);
    1834              : 
    1835              : #ifdef PUSH_ROUNDING
    1836    235754351 :   rounded_size = PUSH_ROUNDING (MACRO_INT (rounded_size));
    1837              : #endif
    1838              : 
    1839    235754351 :   op = XEXP (op, 0);
    1840              : 
    1841    471508702 :   if (known_eq (rounded_size, GET_MODE_SIZE (mode)))
    1842              :     {
    1843    200824714 :       if (GET_CODE (op) != STACK_PUSH_CODE)
    1844              :         return false;
    1845              :     }
    1846              :   else
    1847              :     {
    1848     34929637 :       poly_int64 offset;
    1849     34929637 :       if (GET_CODE (op) != PRE_MODIFY
    1850      1200059 :           || GET_CODE (XEXP (op, 1)) != PLUS
    1851      1200059 :           || XEXP (XEXP (op, 1), 0) != XEXP (op, 0)
    1852      1200059 :           || !poly_int_rtx_p (XEXP (XEXP (op, 1), 1), &offset)
    1853     34929637 :           || (STACK_GROWS_DOWNWARD
    1854      1200059 :               ? maybe_ne (offset, -rounded_size)
    1855              :               : maybe_ne (offset, rounded_size)))
    1856    799883347 :         return false;
    1857              :     }
    1858              : 
    1859     43753552 :   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    292902769 : pop_operand (rtx op, machine_mode mode)
    1870              : {
    1871    292902769 :   if (!MEM_P (op))
    1872              :     return false;
    1873              : 
    1874     67530518 :   if (mode != VOIDmode && GET_MODE (op) != mode)
    1875              :     return false;
    1876              : 
    1877     67530518 :   op = XEXP (op, 0);
    1878              : 
    1879     67530518 :   if (GET_CODE (op) != STACK_POP_CODE)
    1880              :     return false;
    1881              : 
    1882      1394286 :   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   1433651500 : 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   1433651500 :   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   1238306802 : memory_operand (rtx op, machine_mode mode)
    1912              : {
    1913   1238306802 :   rtx inner;
    1914              : 
    1915   1238306802 :   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    124015727 :     return MEM_P (op) && general_operand (op, mode);
    1919              : 
    1920   1114291075 :   if (mode != VOIDmode && GET_MODE (op) != mode)
    1921              :     return false;
    1922              : 
    1923    814378565 :   inner = op;
    1924    814378565 :   if (GET_CODE (inner) == SUBREG)
    1925         8098 :     inner = SUBREG_REG (inner);
    1926              : 
    1927    814378565 :   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     28773943 : ordered_comparison_operator (rtx op, machine_mode mode)
    1963              : {
    1964     28773943 :   if (mode != VOIDmode && GET_MODE (op) != mode)
    1965              :     return false;
    1966     28773943 :   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    116138959 : comparison_operator (rtx op, machine_mode mode)
    1989              : {
    1990      4905894 :   return ((mode == VOIDmode || GET_MODE (op) == mode)
    1991    120629402 :           && COMPARISON_P (op));
    1992              : }
    1993              : 
    1994              : /* If BODY is an insn body that uses ASM_OPERANDS, return it.  */
    1995              : 
    1996              : rtx
    1997   2089053944 : extract_asm_operands (rtx body)
    1998              : {
    1999   2089053944 :   rtx tmp;
    2000   2089053944 :   switch (GET_CODE (body))
    2001              :     {
    2002              :     case ASM_OPERANDS:
    2003              :       return body;
    2004              : 
    2005   1604471417 :     case SET:
    2006              :       /* Single output operand: BODY is (set OUTPUT (asm_operands ...)).  */
    2007   1604471417 :       tmp = SET_SRC (body);
    2008   1604471417 :       if (GET_CODE (tmp) == ASM_OPERANDS)
    2009              :         return tmp;
    2010              :       break;
    2011              : 
    2012    348517671 :     case PARALLEL:
    2013    348517671 :       tmp = XVECEXP (body, 0, 0);
    2014    348517671 :       if (GET_CODE (tmp) == ASM_OPERANDS)
    2015              :         return tmp;
    2016    346249131 :       if (GET_CODE (tmp) == SET)
    2017              :         {
    2018    341907073 :           tmp = SET_SRC (tmp);
    2019    341907073 :           if (GET_CODE (tmp) == ASM_OPERANDS)
    2020              :             return tmp;
    2021              :         }
    2022              :       break;
    2023              : 
    2024              :     default:
    2025              :       break;
    2026              :     }
    2027   2083036045 :   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   1618566041 : asm_noperands (const_rtx body)
    2038              : {
    2039   1618566041 :   rtx asm_op = extract_asm_operands (const_cast<rtx> (body));
    2040   1618566041 :   int i, n_sets = 0;
    2041              : 
    2042   1618566041 :   if (asm_op == NULL)
    2043              :     {
    2044   1613721349 :       if (GET_CODE (body) == PARALLEL && XVECLEN (body, 0) >= 2
    2045    255551261 :           && GET_CODE (XVECEXP (body, 0, 0)) == ASM_INPUT)
    2046              :         {
    2047              :           /* body is [(asm_input ...) (clobber (reg ...))...].  */
    2048        59826 :           for (i = XVECLEN (body, 0) - 1; i > 0; i--)
    2049        39884 :             if (GET_CODE (XVECEXP (body, 0, i)) != CLOBBER)
    2050              :               return -1;
    2051              :           return 0;
    2052              :         }
    2053              :       return -1;
    2054              :     }
    2055              : 
    2056      4844692 :   if (GET_CODE (body) == SET)
    2057              :     n_sets = 1;
    2058      4836953 :   else if (GET_CODE (body) == PARALLEL)
    2059              :     {
    2060      4826786 :       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      5930128 :           for (i = XVECLEN (body, 0); i > 0; i--)
    2070              :             {
    2071      5930128 :               if (GET_CODE (XVECEXP (body, 0, i - 1)) == SET)
    2072              :                 break;
    2073      2986561 :               if (GET_CODE (XVECEXP (body, 0, i - 1)) != USE
    2074      2986561 :                   && GET_CODE (XVECEXP (body, 0, i - 1)) != CLOBBER)
    2075              :                 return -1;
    2076              :             }
    2077              : 
    2078              :           /* N_SETS is now number of output operands.  */
    2079     11316227 :           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     11316227 :           for (i = 0; i < n_sets; i++)
    2085              :             {
    2086      8412649 :               rtx elt = XVECEXP (body, 0, i);
    2087      8412649 :               if (GET_CODE (elt) != SET)
    2088              :                 return -1;
    2089      8407245 :               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      8390789 :               if (ASM_OPERANDS_INPUT_VEC (SET_SRC (elt))
    2094      8390789 :                   != 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      5797854 :           for (i = XVECLEN (body, 0) - 1; i > 0; i--)
    2106      3917007 :             if (GET_CODE (XVECEXP (body, 0, i)) != USE
    2107      3917007 :                 && GET_CODE (XVECEXP (body, 0, i)) != CLOBBER)
    2108              :               return -1;
    2109              :         }
    2110              :     }
    2111              : 
    2112      4802331 :   return (ASM_OPERANDS_INPUT_LENGTH (asm_op)
    2113      4802331 :           + 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      2241859 : decode_asm_operands (rtx body, rtx *operands, rtx **operand_locs,
    2131              :                      const char **constraints, machine_mode *modes,
    2132              :                      location_t *loc)
    2133              : {
    2134      2241859 :   int nbase = 0, n, i;
    2135      2241859 :   rtx asmop;
    2136              : 
    2137      2241859 :   switch (GET_CODE (body))
    2138              :     {
    2139              :     case ASM_OPERANDS:
    2140              :       /* Zero output asm: BODY is (asm_operands ...).  */
    2141              :       asmop = body;
    2142              :       break;
    2143              : 
    2144         3655 :     case SET:
    2145              :       /* Single output asm: BODY is (set OUTPUT (asm_operands ...)).  */
    2146         3655 :       asmop = SET_SRC (body);
    2147              : 
    2148              :       /* The output is in the SET.
    2149              :          Its constraint is in the ASM_OPERANDS itself.  */
    2150         3655 :       if (operands)
    2151         3545 :         operands[0] = SET_DEST (body);
    2152         3655 :       if (operand_locs)
    2153          455 :         operand_locs[0] = &SET_DEST (body);
    2154         3655 :       if (constraints)
    2155         3545 :         constraints[0] = ASM_OPERANDS_OUTPUT_CONSTRAINT (asmop);
    2156         3655 :       if (modes)
    2157          455 :         modes[0] = GET_MODE (SET_DEST (body));
    2158              :       nbase = 1;
    2159              :       break;
    2160              : 
    2161      2233920 :     case PARALLEL:
    2162      2233920 :       {
    2163      2233920 :         int nparallel = XVECLEN (body, 0); /* Includes CLOBBERs.  */
    2164              : 
    2165      2233920 :         asmop = XVECEXP (body, 0, 0);
    2166      2233920 :         if (GET_CODE (asmop) == SET)
    2167              :           {
    2168      1219292 :             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      4493435 :             for (i = 0; i < nparallel; i++)
    2173              :               {
    2174      4472077 :                 if (GET_CODE (XVECEXP (body, 0, i)) == USE
    2175      4472077 :                     || GET_CODE (XVECEXP (body, 0, i)) == CLOBBER)
    2176              :                   break;                /* Past last SET */
    2177      3274143 :                 gcc_assert (GET_CODE (XVECEXP (body, 0, i)) == SET);
    2178      3274143 :                 if (operands)
    2179      3098642 :                   operands[i] = SET_DEST (XVECEXP (body, 0, i));
    2180      3274143 :                 if (operand_locs)
    2181      1196141 :                   operand_locs[i] = &SET_DEST (XVECEXP (body, 0, i));
    2182      3274143 :                 if (constraints)
    2183      3114574 :                   constraints[i] = XSTR (SET_SRC (XVECEXP (body, 0, i)), 1);
    2184      3274143 :                 if (modes)
    2185      1196141 :                   modes[i] = GET_MODE (SET_DEST (XVECEXP (body, 0, i)));
    2186              :               }
    2187              :             nbase = i;
    2188              :           }
    2189      1014628 :         else if (GET_CODE (asmop) == ASM_INPUT)
    2190              :           {
    2191        10158 :             if (loc)
    2192            0 :               *loc = ASM_INPUT_SOURCE_LOCATION (asmop);
    2193        10158 :             return XSTR (asmop, 0);
    2194              :           }
    2195              :         break;
    2196              :       }
    2197              : 
    2198            0 :     default:
    2199            0 :       gcc_unreachable ();
    2200              :     }
    2201              : 
    2202      2231701 :   n = ASM_OPERANDS_INPUT_LENGTH (asmop);
    2203      4309975 :   for (i = 0; i < n; i++)
    2204              :     {
    2205      2078274 :       if (operand_locs)
    2206       889782 :         operand_locs[nbase + i] = &ASM_OPERANDS_INPUT (asmop, i);
    2207      2078274 :       if (operands)
    2208      1937934 :         operands[nbase + i] = ASM_OPERANDS_INPUT (asmop, i);
    2209      2078274 :       if (constraints)
    2210      1957350 :         constraints[nbase + i] = ASM_OPERANDS_INPUT_CONSTRAINT (asmop, i);
    2211      2078274 :       if (modes)
    2212       889782 :         modes[nbase + i] = ASM_OPERANDS_INPUT_MODE (asmop, i);
    2213              :     }
    2214      2231701 :   nbase += n;
    2215              : 
    2216      2231701 :   n = ASM_OPERANDS_LABEL_LENGTH (asmop);
    2217      2252300 :   for (i = 0; i < n; i++)
    2218              :     {
    2219        20599 :       if (operand_locs)
    2220        11478 :         operand_locs[nbase + i] = &ASM_OPERANDS_LABEL (asmop, i);
    2221        20599 :       if (operands)
    2222        18716 :         operands[nbase + i] = ASM_OPERANDS_LABEL (asmop, i);
    2223        20599 :       if (constraints)
    2224        18788 :         constraints[nbase + i] = "";
    2225        20599 :       if (modes)
    2226        11478 :         modes[nbase + i] = Pmode;
    2227              :     }
    2228              : 
    2229      2231701 :   if (loc)
    2230       108164 :     *loc = ASM_OPERANDS_SOURCE_LOCATION (asmop);
    2231              : 
    2232      2231701 :   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      3580035 : asm_operand_ok (rtx op, const char *constraint, const char **constraints)
    2284              : {
    2285      3580035 :   int result = 0;
    2286      3580035 :   bool incdec_ok = false;
    2287              : 
    2288              :   /* Use constrain_operands after reload.  */
    2289      3580035 :   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      3580035 :   if (*constraint == '\0')
    2294         3833 :     result = 1;
    2295              : 
    2296      9864448 :   while (*constraint)
    2297              :     {
    2298      6284415 :       enum constraint_num cn;
    2299      6284415 :       char c = *constraint;
    2300      6284415 :       int len;
    2301      6284415 :       switch (c)
    2302              :         {
    2303        11497 :         case ',':
    2304        11497 :           raw_constraint_p = false;
    2305        11497 :           constraint++;
    2306        11497 :           continue;
    2307              : 
    2308       669972 :         case '0': case '1': case '2': case '3': case '4':
    2309       669972 :         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       669972 :           if (constraints)
    2316              :             {
    2317       669771 :               char *end;
    2318       669771 :               unsigned long match;
    2319              : 
    2320       669771 :               match = strtoul (constraint, &end, 10);
    2321       669771 :               if (!result)
    2322       669510 :                 result = asm_operand_ok (op, constraints[match], NULL);
    2323       669771 :               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       669972 :           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      2395544 :             result = 1;
    2348              :           break;
    2349              : 
    2350       161772 :         case 'g':
    2351       161772 :           if (general_operand (op, VOIDmode))
    2352      2395544 :             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      5441106 :           incdec_ok = true;
    2369              :           /* FALLTHRU */
    2370      5441106 :         default:
    2371      5441106 :           cn = lookup_constraint (constraint);
    2372      5441106 :           rtx mem = NULL;
    2373      5441106 :           switch (get_constraint_type (cn))
    2374              :             {
    2375      5216803 :             case CT_REGISTER:
    2376      5216803 :               if (!result
    2377      2549287 :                   && (reg_class_for_constraint (cn) != NO_REGS
    2378      2665547 :                       || constraint[0] == '{')
    2379      2549945 :                   && GET_MODE (op) != BLKmode
    2380      7766713 :                   && 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       201267 :             case CT_MEMORY:
    2392       201267 :             case CT_RELAXED_MEMORY:
    2393       201267 :               mem = op;
    2394              :               /* Fall through.  */
    2395       201267 :             case CT_SPECIAL_MEMORY:
    2396              :               /* Every memory operand can be reloaded to fit.  */
    2397       201267 :               if (!mem)
    2398            0 :                 mem = extract_mem_from_operand (op);
    2399       201267 :               result = result || memory_operand (mem, VOIDmode);
    2400       201267 :               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        22889 :             case CT_FIXED_FORM:
    2408        22889 :               result = result || constraint_satisfied_p (op, cn);
    2409        22889 :               break;
    2410              :             }
    2411              :           break;
    2412       681501 :         }
    2413      5602914 :       len = CONSTRAINT_LEN (c, constraint);
    2414      5606993 :       do
    2415      5606993 :         constraint++;
    2416     11209907 :       while (--len && *constraint && *constraint != ',');
    2417      5602914 :       if (len)
    2418              :         {
    2419            2 :           raw_constraint_p = false;
    2420            2 :           return 0;
    2421              :         }
    2422              :     }
    2423      3580033 :   raw_constraint_p = false;
    2424              : 
    2425              :   /* For operands without < or > constraints reject side-effects.  */
    2426      3580033 :   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      3580033 :   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     40286703 : find_constant_term_loc (rtx *p)
    2449              : {
    2450     40286703 :   rtx *tem;
    2451     40286703 :   enum rtx_code code = GET_CODE (*p);
    2452              : 
    2453              :   /* If *P IS such a constant term, P is its location.  */
    2454              : 
    2455     40286703 :   if (code == CONST_INT || code == SYMBOL_REF || code == LABEL_REF
    2456     28678593 :       || code == CONST)
    2457              :     return p;
    2458              : 
    2459              :   /* Otherwise, if not a sum, it has no constant term.  */
    2460              : 
    2461     28630794 :   if (GET_CODE (*p) != PLUS)
    2462              :     return 0;
    2463              : 
    2464              :   /* If one of the summands is constant, return its location.  */
    2465              : 
    2466     13453872 :   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     13453872 :   if (XEXP (*p, 0) != 0)
    2473              :     {
    2474     13453872 :       tem = find_constant_term_loc (&XEXP (*p, 0));
    2475     13453872 :       if (tem != 0)
    2476              :         return tem;
    2477              :     }
    2478              : 
    2479     13453872 :   if (XEXP (*p, 1) != 0)
    2480              :     {
    2481     13453872 :       tem = find_constant_term_loc (&XEXP (*p, 1));
    2482     13453872 :       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      5580289 : offsettable_memref_p (rtx op)
    2500              : {
    2501      5580289 :   return ((MEM_P (op))
    2502     11155132 :           && offsettable_address_addr_space_p (1, GET_MODE (op), XEXP (op, 0),
    2503      5574843 :                                                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     11817442 : offsettable_nonstrict_memref_p (rtx op)
    2511              : {
    2512     11817442 :   return ((MEM_P (op))
    2513     23634850 :           && offsettable_address_addr_space_p (0, GET_MODE (op), XEXP (op, 0),
    2514     11817408 :                                                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     17392251 : offsettable_address_addr_space_p (int strictp, machine_mode mode, rtx y,
    2529              :                                   addr_space_t as)
    2530              : {
    2531     17392251 :   enum rtx_code ycode = GET_CODE (y);
    2532     17392251 :   rtx z;
    2533     17392251 :   rtx y1 = y;
    2534     17392251 :   rtx *y2;
    2535     11817408 :   bool (*addressp) (machine_mode, rtx, addr_space_t, code_helper) =
    2536     17392251 :     (strictp ? strict_memory_address_addr_space_p
    2537              :              : memory_address_addr_space_p);
    2538     34784502 :   poly_int64 mode_sz = GET_MODE_SIZE (mode);
    2539              : 
    2540     17392251 :   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     14721270 :   if (mode_dependent_address_p (y, as))
    2547              :     return false;
    2548              : 
    2549     14537161 :   machine_mode address_mode = GET_MODE (y);
    2550     14537161 :   if (address_mode == VOIDmode)
    2551            0 :     address_mode = targetm.addr_space.address_mode (as);
    2552              : #ifdef POINTERS_EXTEND_UNSIGNED
    2553     14537161 :   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     14537161 :   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     14537161 :   if ((ycode == PLUS) && (y2 = find_constant_term_loc (&y1)))
    2567              :     {
    2568     11655909 :       bool good;
    2569              : 
    2570     11655909 :       y1 = *y2;
    2571     11655909 :       *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     11655909 :       good = (*addressp) (QImode, y, as, ERROR_MARK);
    2575              : 
    2576              :       /* In any case, restore old contents of memory.  */
    2577     11655909 :       *y2 = y1;
    2578     11655909 :       return good;
    2579              :     }
    2580              : 
    2581      2881252 :   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      2881252 :   if (GET_CODE (y) == LO_SUM
    2590            0 :       && mode != BLKmode
    2591      2881252 :       && 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      2881252 :   else if (POINTERS_EXTEND_UNSIGNED > 0
    2598      2881252 :            && 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      2881245 :     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      2881252 :   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     40317673 : 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     40317673 :   if (GET_CODE (addr) == PRE_INC
    2627     40317673 :       || GET_CODE (addr) == POST_INC
    2628     40317667 :       || GET_CODE (addr) == PRE_DEC
    2629     36536802 :       || GET_CODE (addr) == POST_DEC)
    2630              :     return true;
    2631              : 
    2632     36536802 :   return targetm.mode_dependent_address_p (addr, addrspace);
    2633              : }
    2634              : 
    2635              : /* Return true if boolean attribute ATTR is supported.  */
    2636              : 
    2637              : static bool
    2638   1643234569 : have_bool_attr (bool_attr attr)
    2639              : {
    2640   1643234569 :   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   1746310780 : get_bool_attr (rtx_insn *insn, bool_attr attr)
    2656              : {
    2657   1746310780 :   switch (attr)
    2658              :     {
    2659    739917040 :     case BA_ENABLED:
    2660    739917040 :       return get_attr_enabled (insn);
    2661    361384746 :     case BA_PREFERRED_FOR_SIZE:
    2662    361384746 :       return get_attr_enabled (insn) && get_attr_preferred_for_size (insn);
    2663    645008994 :     case BA_PREFERRED_FOR_SPEED:
    2664    645008994 :       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    104398130 : 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    104398130 :   rtx_insn *old_insn = recog_data.insn;
    2679    104398130 :   int old_alternative = which_alternative;
    2680              : 
    2681    104398130 :   recog_data.insn = insn;
    2682    104398130 :   alternative_mask mask = ALL_ALTERNATIVES;
    2683    104398130 :   int n_alternatives = insn_data[INSN_CODE (insn)].n_alternatives;
    2684   1850708910 :   for (int i = 0; i < n_alternatives; i++)
    2685              :     {
    2686   1746310780 :       which_alternative = i;
    2687   1746310780 :       if (!get_bool_attr (insn, attr))
    2688    529847803 :         mask &= ~ALTERNATIVE_BIT (i);
    2689              :     }
    2690              : 
    2691    104398130 :   recog_data.insn = old_insn;
    2692    104398130 :   which_alternative = old_alternative;
    2693    104398130 :   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   1645553212 : 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   1645553212 :   int code = INSN_CODE (insn);
    2706   1645553212 :   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   1643234569 :   if (!this_target_recog->x_bool_attr_masks[code][attr])
    2712     13066047 :     this_target_recog->x_bool_attr_masks[code][attr]
    2713     13066047 :       = get_bool_attr_mask_uncached (insn, attr);
    2714   1643234569 :   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   1187376095 : get_enabled_alternatives (rtx_insn *insn)
    2722              : {
    2723   1187376095 :   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    458092080 : get_preferred_alternatives (rtx_insn *insn)
    2732              : {
    2733    458092080 :   if (optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn)))
    2734    401699622 :     return get_bool_attr_mask (insn, BA_PREFERRED_FOR_SPEED);
    2735              :   else
    2736     56392458 :     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        85037 : get_preferred_alternatives (rtx_insn *insn, basic_block bb)
    2747              : {
    2748        85037 :   if (optimize_bb_for_speed_p (bb))
    2749        80046 :     return get_bool_attr_mask (insn, BA_PREFERRED_FOR_SPEED);
    2750              :   else
    2751         4991 :     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     36929752 : check_bool_attrs (rtx_insn *insn)
    2761              : {
    2762     36929752 :   int code = INSN_CODE (insn);
    2763     36929752 :   if (code >= 0)
    2764    147719008 :     for (int i = 0; i <= BA_LAST; ++i)
    2765              :       {
    2766    110789256 :         enum bool_attr attr = (enum bool_attr) i;
    2767    110789256 :         if (this_target_recog->x_bool_attr_masks[code][attr])
    2768     91332083 :           gcc_assert (this_target_recog->x_bool_attr_masks[code][attr]
    2769              :                       == get_bool_attr_mask_uncached (insn, attr));
    2770              :       }
    2771     36929752 :   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  10583396215 : extract_insn_cached (rtx_insn *insn)
    2780              : {
    2781  10583396215 :   if (recog_data.insn == insn && INSN_CODE (insn) >= 0)
    2782              :     return;
    2783    775241741 :   extract_insn (insn);
    2784    775241741 :   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    268017705 : extract_constrain_insn (rtx_insn *insn)
    2792              : {
    2793    268017705 :   extract_insn (insn);
    2794    268017705 :   if (!constrain_operands (reload_completed, get_enabled_alternatives (insn)))
    2795            0 :     fatal_insn_not_found (insn);
    2796    268017705 : }
    2797              : 
    2798              : /* Do cached extract_insn, constrain_operands and complain about failures.
    2799              :    Used by insn_attrtab.  */
    2800              : void
    2801   9362074631 : extract_constrain_insn_cached (rtx_insn *insn)
    2802              : {
    2803   9362074631 :   extract_insn_cached (insn);
    2804   9362074631 :   if (which_alternative == -1
    2805   9362074631 :       && !constrain_operands (reload_completed,
    2806              :                               get_enabled_alternatives (insn)))
    2807            0 :     fatal_insn_not_found (insn);
    2808   9362074631 : }
    2809              : 
    2810              : /* Do cached constrain_operands on INSN and complain about failures.  */
    2811              : bool
    2812    340924675 : constrain_operands_cached (rtx_insn *insn, int strict)
    2813              : {
    2814    340924675 :   if (which_alternative == -1)
    2815     93815196 :     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   2483799888 : extract_insn (rtx_insn *insn)
    2824              : {
    2825   2483799888 :   int i;
    2826   2483799888 :   int icode;
    2827   2483799888 :   int noperands;
    2828   2483799888 :   rtx body = PATTERN (insn);
    2829              : 
    2830   2483799888 :   recog_data.n_operands = 0;
    2831   2483799888 :   recog_data.n_alternatives = 0;
    2832   2483799888 :   recog_data.n_dups = 0;
    2833   2483799888 :   recog_data.is_asm = false;
    2834              : 
    2835   2483799888 :   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   1828335767 :     case SET:
    2847   1828335767 :       if (GET_CODE (SET_SRC (body)) == ASM_OPERANDS)
    2848          400 :         goto asm_insn;
    2849              :       else
    2850   1828335367 :         goto normal_insn;
    2851    248955758 :     case PARALLEL:
    2852    248955758 :       if ((GET_CODE (XVECEXP (body, 0, 0)) == SET
    2853    244356155 :            && GET_CODE (SET_SRC (XVECEXP (body, 0, 0))) == ASM_OPERANDS)
    2854    248468766 :           || GET_CODE (XVECEXP (body, 0, 0)) == ASM_OPERANDS
    2855    247740916 :           || GET_CODE (XVECEXP (body, 0, 0)) == ASM_INPUT)
    2856      1223303 :         goto asm_insn;
    2857              :       else
    2858    247732455 :         goto normal_insn;
    2859      1223843 :     case ASM_OPERANDS:
    2860      1223843 :     asm_insn:
    2861      1223843 :       recog_data.n_operands = noperands = asm_noperands (body);
    2862      1223843 :       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      1223843 :           gcc_assert (noperands <= MAX_RECOG_OPERANDS);
    2868              : 
    2869              :           /* Now get the operand values and constraints out of the insn.  */
    2870      1223843 :           decode_asm_operands (body, recog_data.operand,
    2871              :                                recog_data.operand_loc,
    2872              :                                recog_data.constraints,
    2873              :                                recog_data.operand_mode, NULL);
    2874      1223843 :           memset (recog_data.is_operator, 0, sizeof recog_data.is_operator);
    2875      1223843 :           if (noperands > 0)
    2876              :             {
    2877       593021 :               const char *p =  recog_data.constraints[0];
    2878       593021 :               recog_data.n_alternatives = 1;
    2879      1676825 :               while (*p)
    2880      1083804 :                 recog_data.n_alternatives += (*p++ == ',');
    2881              :             }
    2882      1223843 :           recog_data.is_asm = true;
    2883      1223843 :           break;
    2884              :         }
    2885            0 :       fatal_insn_not_found (insn);
    2886              : 
    2887   2139456804 :     default:
    2888   2139456804 :     normal_insn:
    2889              :       /* Ordinary insn: recognize it, get the operands via insn_extract
    2890              :          and get the constraints.  */
    2891              : 
    2892   2139456804 :       icode = recog_memoized (insn);
    2893   2139456804 :       if (icode < 0)
    2894            0 :         fatal_insn_not_found (insn);
    2895              : 
    2896   2139456804 :       recog_data.n_operands = noperands = insn_data[icode].n_operands;
    2897   2139456804 :       recog_data.n_alternatives = insn_data[icode].n_alternatives;
    2898   2139456804 :       recog_data.n_dups = insn_data[icode].n_dups;
    2899              : 
    2900   2139456804 :       insn_extract (insn);
    2901              : 
    2902   8861021872 :       for (i = 0; i < noperands; i++)
    2903              :         {
    2904   4582108264 :           recog_data.constraints[i] = insn_data[icode].operand[i].constraint;
    2905   4582108264 :           recog_data.is_operator[i] = insn_data[icode].operand[i].is_operator;
    2906   4582108264 :           recog_data.operand_mode[i] = insn_data[icode].operand[i].mode;
    2907              :           /* VOIDmode match_operands gets mode from their real operand.  */
    2908   4582108264 :           if (recog_data.operand_mode[i] == VOIDmode)
    2909    469340908 :             recog_data.operand_mode[i] = GET_MODE (recog_data.operand[i]);
    2910              :         }
    2911              :     }
    2912   6724714099 :   for (i = 0; i < noperands; i++)
    2913   4584033452 :     recog_data.operand_type[i]
    2914   7452362397 :       = (recog_data.constraints[i][0] == '=' ? OP_OUT
    2915   2868328945 :          : recog_data.constraints[i][0] == '+' ? OP_INOUT
    2916              :          : OP_IN);
    2917              : 
    2918   2140680647 :   gcc_assert (recog_data.n_alternatives <= MAX_RECOG_ALTERNATIVES);
    2919              : 
    2920   2140680647 :   recog_data.insn = NULL;
    2921   2140680647 :   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      4801578 : preprocess_constraints (int n_operands, int n_alternatives,
    2935              :                         const char **constraints,
    2936              :                         operand_alternative *op_alt_base,
    2937              :                         rtx **oploc)
    2938              : {
    2939     12388194 :   for (int i = 0; i < n_operands; i++)
    2940              :     {
    2941      7586616 :       int j;
    2942      7586616 :       struct operand_alternative *op_alt;
    2943      7586616 :       const char *p = constraints[i];
    2944              : 
    2945      7586616 :       op_alt = op_alt_base;
    2946              : 
    2947     49368724 :       for (j = 0; j < n_alternatives; j++, op_alt += n_operands)
    2948              :         {
    2949     41782108 :           op_alt[i].cl = NO_REGS;
    2950     41782108 :           op_alt[i].register_filters = 0;
    2951     41782108 :           op_alt[i].dependent_filters = 0;
    2952     41782108 :           op_alt[i].constraint = p;
    2953     41782108 :           op_alt[i].matches = -1;
    2954     41782108 :           op_alt[i].matched = -1;
    2955              : 
    2956     41782108 :           if (*p == '\0' || *p == ',')
    2957              :             {
    2958      1783246 :               op_alt[i].anything_ok = 1;
    2959      1783246 :               continue;
    2960              :             }
    2961              : 
    2962    104764016 :           for (;;)
    2963              :             {
    2964    104764016 :               char c = *p;
    2965    104764016 :               if (c == '#')
    2966            0 :                 do
    2967            0 :                   c = *++p;
    2968            0 :                 while (c != ',' && c != '\0');
    2969    104764016 :               if (c == ',' || c == '\0')
    2970              :                 {
    2971     39998862 :                   p++;
    2972     39998862 :                   break;
    2973              :                 }
    2974              : 
    2975     64765154 :               switch (c)
    2976              :                 {
    2977      5793533 :                 case '?':
    2978      5793533 :                   op_alt[i].reject += 6;
    2979      5793533 :                   break;
    2980       406763 :                 case '!':
    2981       406763 :                   op_alt[i].reject += 600;
    2982       406763 :                   break;
    2983        61135 :                 case '&':
    2984        61135 :                   op_alt[i].earlyclobber = 1;
    2985        61135 :                   break;
    2986              : 
    2987      2062948 :                 case '0': case '1': case '2': case '3': case '4':
    2988      2062948 :                 case '5': case '6': case '7': case '8': case '9':
    2989      2062948 :                   {
    2990      2062948 :                     char *end;
    2991      2062948 :                     op_alt[i].matches = strtoul (p, &end, 10);
    2992      2062948 :                     op_alt[op_alt[i].matches].matched = i;
    2993      2062948 :                     p = end;
    2994              :                   }
    2995      2062948 :                   continue;
    2996              : 
    2997        31385 :                 case 'X':
    2998        31385 :                   op_alt[i].anything_ok = 1;
    2999        31385 :                   break;
    3000              : 
    3001       213660 :                 case 'g':
    3002       213660 :                   op_alt[i].cl =
    3003       213660 :                    reg_class_subunion[(int) op_alt[i].cl][(int) GENERAL_REGS];
    3004       213660 :                   break;
    3005              : 
    3006     56195730 :                 default:
    3007     56195730 :                   enum constraint_num cn = lookup_constraint (p);
    3008     56195730 :                   enum reg_class cl;
    3009     56195730 :                   switch (get_constraint_type (cn))
    3010              :                     {
    3011     40162175 :                     case CT_REGISTER:
    3012     40162175 :                       cl = reg_class_for_constraint (cn);
    3013     29177074 :                       if (cl != NO_REGS)
    3014              :                         {
    3015     25564325 :                           op_alt[i].cl = reg_class_subunion[op_alt[i].cl][cl];
    3016     25564325 :                           auto filter_id = get_register_filter_id (cn);
    3017     25564325 :                           if (filter_id >= 0)
    3018              :                             op_alt[i].register_filters |= 1U << filter_id;
    3019     25564325 :                           auto dep_filter_id = get_dependent_filter_id (cn);
    3020     25564325 :                           if (dep_filter_id >= 0)
    3021              :                             op_alt[i].dependent_filters |= 1U << dep_filter_id;
    3022              :                         }
    3023              :                       break;
    3024              : 
    3025              :                     case CT_CONST_INT:
    3026              :                       break;
    3027              : 
    3028      7952920 :                     case CT_MEMORY:
    3029      7952920 :                     case CT_SPECIAL_MEMORY:
    3030      7952920 :                     case CT_RELAXED_MEMORY:
    3031      7952920 :                       op_alt[i].memory_ok = 1;
    3032      7952920 :                       break;
    3033              : 
    3034        87774 :                     case CT_ADDRESS:
    3035        87774 :                       if (oploc && !address_operand (*oploc[i], VOIDmode))
    3036              :                         break;
    3037              : 
    3038        87755 :                       op_alt[i].is_address = 1;
    3039        87755 :                       op_alt[i].cl
    3040        87755 :                         = (reg_class_subunion
    3041        87755 :                            [(int) op_alt[i].cl]
    3042        87755 :                            [(int) base_reg_class (VOIDmode, ADDR_SPACE_GENERIC,
    3043        87755 :                                                   ADDRESS, SCRATCH)]);
    3044        87755 :                       break;
    3045              : 
    3046              :                     case CT_FIXED_FORM:
    3047              :                       break;
    3048              :                     }
    3049              :                   break;
    3050      2062948 :                 }
    3051     62702206 :               p += CONSTRAINT_LEN (c, p);
    3052              :             }
    3053              :         }
    3054              :     }
    3055      4801578 : }
    3056              : 
    3057              : /* Return an array of operand_alternative instructions for
    3058              :    instruction ICODE.  */
    3059              : 
    3060              : const operand_alternative *
    3061    295633481 : preprocess_insn_constraints (unsigned int icode)
    3062              : {
    3063    295633481 :   gcc_checking_assert (IN_RANGE (icode, 0, NUM_INSN_CODES - 1));
    3064    295633481 :   if (this_target_recog->x_op_alt[icode])
    3065              :     return this_target_recog->x_op_alt[icode];
    3066              : 
    3067      5515313 :   int n_operands = insn_data[icode].n_operands;
    3068      5515313 :   if (n_operands == 0)
    3069              :     return 0;
    3070              :   /* Always provide at least one alternative so that which_op_alt ()
    3071              :      works correctly.  If the instruction has 0 alternatives (i.e. all
    3072              :      constraint strings are empty) then each operand in this alternative
    3073              :      will have anything_ok set.  */
    3074      2978444 :   int n_alternatives = MAX (insn_data[icode].n_alternatives, 1);
    3075      2978444 :   int n_entries = n_operands * n_alternatives;
    3076              : 
    3077      2978444 :   operand_alternative *op_alt = XCNEWVEC (operand_alternative, n_entries);
    3078      2978444 :   const char **constraints = XALLOCAVEC (const char *, n_operands);
    3079              : 
    3080     10108175 :   for (int i = 0; i < n_operands; ++i)
    3081      7129731 :     constraints[i] = insn_data[icode].operand[i].constraint;
    3082      2978444 :   preprocess_constraints (n_operands, n_alternatives, constraints, op_alt,
    3083              :                           NULL);
    3084              : 
    3085      2978444 :   this_target_recog->x_op_alt[icode] = op_alt;
    3086      2978444 :   return op_alt;
    3087              : }
    3088              : 
    3089              : /* After calling extract_insn, you can use this function to extract some
    3090              :    information from the constraint strings into a more usable form.
    3091              :    The collected data is stored in recog_op_alt.  */
    3092              : 
    3093              : void
    3094    201423225 : preprocess_constraints (rtx_insn *insn)
    3095              : {
    3096    201423225 :   int icode = INSN_CODE (insn);
    3097    201423225 :   if (icode >= 0)
    3098    199644207 :     recog_op_alt = preprocess_insn_constraints (icode);
    3099              :   else
    3100              :     {
    3101      1779018 :       int n_operands = recog_data.n_operands;
    3102      1779018 :       int n_alternatives = recog_data.n_alternatives;
    3103      1779018 :       int n_entries = n_operands * n_alternatives;
    3104      1779018 :       memset (asm_op_alt, 0, n_entries * sizeof (operand_alternative));
    3105      1779018 :       preprocess_constraints (n_operands, n_alternatives,
    3106              :                               recog_data.constraints, asm_op_alt,
    3107              :                               NULL);
    3108      1779018 :       recog_op_alt = asm_op_alt;
    3109              :     }
    3110    201423225 : }
    3111              : 
    3112              : /* Check the operands of an insn against the insn's operand constraints
    3113              :    and return 1 if they match any of the alternatives in ALTERNATIVES.
    3114              : 
    3115              :    The information about the insn's operands, constraints, operand modes
    3116              :    etc. is obtained from the global variables set up by extract_insn.
    3117              : 
    3118              :    WHICH_ALTERNATIVE is set to a number which indicates which
    3119              :    alternative of constraints was matched: 0 for the first alternative,
    3120              :    1 for the next, etc.
    3121              : 
    3122              :    In addition, when two operands are required to match
    3123              :    and it happens that the output operand is (reg) while the
    3124              :    input operand is --(reg) or ++(reg) (a pre-inc or pre-dec),
    3125              :    make the output operand look like the input.
    3126              :    This is because the output operand is the one the template will print.
    3127              : 
    3128              :    This is used in final, just before printing the assembler code and by
    3129              :    the routines that determine an insn's attribute.
    3130              : 
    3131              :    If STRICT is a positive nonzero value, it means that we have been
    3132              :    called after reload has been completed.  In that case, we must
    3133              :    do all checks strictly.  If it is zero, it means that we have been called
    3134              :    before reload has completed.  In that case, we first try to see if we can
    3135              :    find an alternative that matches strictly.  If not, we try again, this
    3136              :    time assuming that reload will fix up the insn.  This provides a "best
    3137              :    guess" for the alternative and is used to compute attributes of insns prior
    3138              :    to reload.  A negative value of STRICT is used for this internal call.  */
    3139              : 
    3140              : struct funny_match
    3141              : {
    3142              :   int this_op, other;
    3143              : };
    3144              : 
    3145              : /* For a register constraint CN with a dependent filter, return true if
    3146              :    the respective filter allows REGNO (OP) + OFFSET given the ref-operand
    3147              :    in recog_data.operand or false if it doesn't.
    3148              :    If the filter cannot be evaluated, for example when no hard reg
    3149              :    has been chosen yet, return true.  */
    3150              : 
    3151              : static bool
    3152            0 : test_dependent_filter (constraint_num cn, rtx op, int offset,
    3153              :                        machine_mode mode)
    3154              : {
    3155            0 :   int id = get_dependent_filter_id (cn);
    3156            0 :   if (id < 0 || !REG_P (op))
    3157            0 :     return true;
    3158              :   int ref_opno = get_dependent_filter_ref (id);
    3159              :   if (ref_opno < 0 || ref_opno >= recog_data.n_operands)
    3160              :     return true;
    3161              :   rtx ref_op = recog_data.operand[ref_opno];
    3162              :   if (!REG_P (ref_op))
    3163              :     return true;
    3164              :   return eval_dependent_filter (id, REGNO (op) + offset, mode,
    3165              :                                 REGNO (ref_op), GET_MODE (ref_op));
    3166              : }
    3167              : 
    3168              : bool
    3169   1137374681 : constrain_operands (int strict, alternative_mask alternatives)
    3170              : {
    3171   1138288502 :   const char *constraints[MAX_RECOG_OPERANDS];
    3172   1138288502 :   int matching_operands[MAX_RECOG_OPERANDS];
    3173   1138288502 :   int earlyclobber[MAX_RECOG_OPERANDS];
    3174   1138288502 :   int c;
    3175              : 
    3176   1138288502 :   struct funny_match funny_match[MAX_RECOG_OPERANDS];
    3177   1138288502 :   int funny_match_index;
    3178              : 
    3179   1138288502 :   which_alternative = 0;
    3180   1138288502 :   if (recog_data.n_operands == 0 || recog_data.n_alternatives == 0)
    3181              :     return true;
    3182              : 
    3183   3381282389 :   for (c = 0; c < recog_data.n_operands; c++)
    3184   2303569707 :     constraints[c] = recog_data.constraints[c];
    3185              : 
    3186   4047510653 :   do
    3187              :     {
    3188   4047510653 :       int seen_earlyclobber_at = -1;
    3189   4047510653 :       int opno;
    3190   4047510653 :       bool lose = false;
    3191   4047510653 :       funny_match_index = 0;
    3192              : 
    3193   4047510653 :       if (!TEST_BIT (alternatives, which_alternative))
    3194              :         {
    3195              :           int i;
    3196              : 
    3197   2752035198 :           for (i = 0; i < recog_data.n_operands; i++)
    3198   3694243120 :             constraints[i] = skip_alternative (constraints[i]);
    3199              : 
    3200    904913638 :           which_alternative++;
    3201    904913638 :           continue;
    3202    904913638 :         }
    3203              : 
    3204   9662941992 :       for (opno = 0; opno < recog_data.n_operands; opno++)
    3205   6520344977 :         matching_operands[opno] = -1;
    3206              : 
    3207   9662941992 :       for (opno = 0; opno < recog_data.n_operands; opno++)
    3208              :         {
    3209   6520344977 :           rtx op = recog_data.operand[opno];
    3210   6520344977 :           machine_mode mode = GET_MODE (op);
    3211   6520344977 :           const char *p = constraints[opno];
    3212   6520344977 :           int offset = 0;
    3213   6520344977 :           bool win = false;
    3214   6520344977 :           int val;
    3215   6520344977 :           int len;
    3216              : 
    3217   6520344977 :           earlyclobber[opno] = 0;
    3218              : 
    3219   6520344977 :           if (GET_CODE (op) == SUBREG)
    3220              :             {
    3221      1518660 :               if (REG_P (SUBREG_REG (op))
    3222      1518660 :                   && REGNO (SUBREG_REG (op)) < FIRST_PSEUDO_REGISTER)
    3223          360 :                 offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
    3224          360 :                                               GET_MODE (SUBREG_REG (op)),
    3225          360 :                                               SUBREG_BYTE (op),
    3226              :                                               GET_MODE (op));
    3227      1518660 :               op = SUBREG_REG (op);
    3228              :             }
    3229              : 
    3230              :           /* An empty constraint or empty alternative
    3231              :              allows anything which matched the pattern.  */
    3232   6520344977 :           if (*p == 0 || *p == ',')
    3233     96521640 :             win = true;
    3234              : 
    3235  16474448485 :           do
    3236  16474448485 :             switch (c = *p, len = CONSTRAINT_LEN (c, p), c)
    3237              :               {
    3238              :               case '\0':
    3239              :                 len = 0;
    3240              :                 break;
    3241   6172559749 :               case ',':
    3242   6172559749 :                 c = '\0';
    3243   6172559749 :                 break;
    3244           32 :               case '-':
    3245           32 :                 raw_constraint_p = true;
    3246           32 :                 break;
    3247              : 
    3248            0 :               case '#':
    3249              :                 /* Ignore rest of this alternative as far as
    3250              :                    constraint checking is concerned.  */
    3251            0 :                 do
    3252            0 :                   p++;
    3253            0 :                 while (*p && *p != ',');
    3254              :                 len = 0;
    3255              :                 break;
    3256              : 
    3257       463564 :               case '&':
    3258       463564 :                 earlyclobber[opno] = 1;
    3259       463564 :                 if (seen_earlyclobber_at < 0)
    3260       442251 :                   seen_earlyclobber_at = opno;
    3261              :                 break;
    3262              : 
    3263    190102004 :               case '0':  case '1':  case '2':  case '3':  case '4':
    3264    190102004 :               case '5':  case '6':  case '7':  case '8':  case '9':
    3265    190102004 :                 {
    3266              :                   /* This operand must be the same as a previous one.
    3267              :                      This kind of constraint is used for instructions such
    3268              :                      as add when they take only two operands.
    3269              : 
    3270              :                      Note that the lower-numbered operand is passed first.
    3271              : 
    3272              :                      If we are not testing strictly, assume that this
    3273              :                      constraint will be satisfied.  */
    3274              : 
    3275    190102004 :                   char *end;
    3276    190102004 :                   int match;
    3277              : 
    3278    190102004 :                   match = strtoul (p, &end, 10);
    3279    190102004 :                   p = end;
    3280              : 
    3281    190102004 :                   if (strict < 0)
    3282              :                     val = 1;
    3283              :                   else
    3284              :                     {
    3285    189167623 :                       rtx op1 = recog_data.operand[match];
    3286    189167623 :                       rtx op2 = recog_data.operand[opno];
    3287    189167623 :                       val = operands_match_p (op1, op2);
    3288              :                     }
    3289              : 
    3290    190102004 :                   matching_operands[opno] = match;
    3291    190102004 :                   matching_operands[match] = opno;
    3292              : 
    3293    190102004 :                   if (val != 0)
    3294    156500020 :                     win = true;
    3295              : 
    3296              :                   /* If output is *x and input is *--x, arrange later
    3297              :                      to change the output to *--x as well, since the
    3298              :                      output op is the one that will be printed.  */
    3299    190102004 :                   if (val == 2 && strict > 0)
    3300              :                     {
    3301            0 :                       funny_match[funny_match_index].this_op = opno;
    3302            0 :                       funny_match[funny_match_index++].other = match;
    3303              :                     }
    3304              :                 }
    3305    190102004 :                 len = 0;
    3306    190102004 :                 break;
    3307              : 
    3308       267470 :               case 'p':
    3309              :                 /* p is used for address_operands.  When we are called by
    3310              :                    gen_reload, no one will have checked that the address is
    3311              :                    strictly valid, i.e., that all pseudos requiring hard regs
    3312              :                    have gotten them.  We also want to make sure we have a
    3313              :                    valid mode.  */
    3314       267470 :                 {
    3315       267383 :                   auto mem_mode = (recog_data.is_asm
    3316       267470 :                                    ? VOIDmode
    3317              :                                    : recog_data.operand_mode[opno]);
    3318       267470 :                   if ((GET_MODE (op) == VOIDmode
    3319       267470 :                        || SCALAR_INT_MODE_P (GET_MODE (op)))
    3320       534914 :                       && (strict <= 0
    3321       267470 :                           || strict_memory_address_p (mem_mode, op)))
    3322       267404 :                     win = true;
    3323              :                   break;
    3324              :                 }
    3325              : 
    3326              :                 /* No need to check general_operand again;
    3327              :                    it was done in insn-recog.cc.  Well, except that reload
    3328              :                    doesn't check the validity of its replacements, but
    3329              :                    that should only matter when there's a bug.  */
    3330    122716940 :               case 'g':
    3331              :                 /* Anything goes unless it is a REG and really has a hard reg
    3332              :                    but the hard reg is not in the class GENERAL_REGS.  */
    3333    122716940 :                 if (REG_P (op))
    3334              :                   {
    3335     46528249 :                     if (strict < 0
    3336              :                         || GENERAL_REGS == ALL_REGS
    3337     46528197 :                         || (reload_in_progress
    3338            0 :                             && REGNO (op) >= FIRST_PSEUDO_REGISTER)
    3339     93056446 :                         || reg_fits_class_p (op, GENERAL_REGS, offset, mode))
    3340              :                       win = true;
    3341              :                   }
    3342     76188691 :                 else if (strict < 0 || general_operand (op, mode))
    3343              :                   win = true;
    3344              :                 break;
    3345              : 
    3346          255 :               case '{':
    3347          247 :                 if ((REG_P (op) && HARD_REGISTER_P (op)
    3348          247 :                      && (int) REGNO (op) == decode_hard_reg_constraint (p))
    3349          269 :                     || !reload_completed)
    3350              :                   win = true;
    3351              :                 break;
    3352              : 
    3353   9640553243 :               default:
    3354   9640553243 :                 {
    3355   9640553243 :                   enum constraint_num cn = lookup_constraint (p);
    3356   9640553243 :                   enum reg_class cl = reg_class_for_constraint (cn);
    3357   4463756986 :                   if (cl != NO_REGS)
    3358              :                     {
    3359   4286288639 :                       auto *filter = get_register_filter (cn);
    3360   4286288639 :                       if (strict < 0
    3361   4284590203 :                           || (strict == 0
    3362     22638884 :                               && REG_P (op)
    3363     16601204 :                               && REGNO (op) >= FIRST_PSEUDO_REGISTER)
    3364      6116003 :                           || (strict == 0 && GET_CODE (op) == SCRATCH)
    3365   8554337846 :                           || (REG_P (op)
    3366   3082513737 :                               && reg_fits_class_p (op, cl, offset, mode)
    3367              :                               && (!filter
    3368              :                                   || TEST_HARD_REG_BIT (*filter,
    3369              :                                                         REGNO (op) + offset))
    3370              :                               && (strict <= 0
    3371              :                                   || test_dependent_filter (cn, op, offset,
    3372              :                                                             mode))))
    3373              :                         win = true;
    3374              :                     }
    3375              : 
    3376   5354264604 :                   else if (constraint_satisfied_p (op, cn))
    3377              :                     win = true;
    3378              : 
    3379   4474621140 :                   else if ((insn_extra_memory_constraint (cn)
    3380              :                             || insn_extra_relaxed_memory_constraint (cn))
    3381              :                            /* Every memory operand can be reloaded to fit.  */
    3382   4474621140 :                            && ((strict < 0 && MEM_P (op))
    3383              :                                /* Before reload, accept what reload can turn
    3384              :                                   into a mem.  */
    3385       702210 :                                || (strict < 0 && CONSTANT_P (op))
    3386              :                                /* Before reload, accept a pseudo or hard register,
    3387              :                                   since LRA can turn it into a mem.  */
    3388       701848 :                                || (strict < 0 && targetm.lra_p () && REG_P (op))
    3389              :                                /* During reload, accept a pseudo  */
    3390    942027460 :                                || (reload_in_progress && REG_P (op)
    3391            0 :                                    && REGNO (op) >= FIRST_PSEUDO_REGISTER)))
    3392              :                     win = true;
    3393   4473918930 :                   else if (insn_extra_address_constraint (cn)
    3394              :                            /* Every address operand can be reloaded to fit.  */
    3395   4473918930 :                            && strict < 0)
    3396              :                     win = true;
    3397              :                   /* Cater to architectures like IA-64 that define extra memory
    3398              :                      constraints without using define_memory_constraint.  */
    3399   4473918930 :                   else if (reload_in_progress
    3400            0 :                            && REG_P (op)
    3401            0 :                            && REGNO (op) >= FIRST_PSEUDO_REGISTER
    3402            0 :                            && reg_renumber[REGNO (op)] < 0
    3403            0 :                            && reg_equiv_mem (REGNO (op)) != 0
    3404   4473918930 :                            && constraint_satisfied_p
    3405            0 :                               (reg_equiv_mem (REGNO (op)), cn))
    3406              :                     win = true;
    3407              :                   break;
    3408              :                 }
    3409              :               }
    3410  16474448485 :           while (p += len, c);
    3411              : 
    3412   6520344977 :           raw_constraint_p = false;
    3413   6520344977 :           constraints[opno] = p;
    3414              :           /* If this operand did not win somehow,
    3415              :              this alternative loses.  */
    3416   6520344977 :           if (! win)
    3417   3152904541 :             lose = true;
    3418              :         }
    3419              :       /* This alternative won; the operands are ok.
    3420              :          Change whichever operands this alternative says to change.  */
    3421   3142597015 :       if (! lose)
    3422              :         {
    3423   1073347049 :           int opno, eopno;
    3424              : 
    3425              :           /* See if any earlyclobber operand conflicts with some other
    3426              :              operand.  */
    3427              : 
    3428   1073347049 :           if (strict > 0  && seen_earlyclobber_at >= 0)
    3429      1125708 :             for (eopno = seen_earlyclobber_at;
    3430      1485292 :                  eopno < recog_data.n_operands;
    3431              :                  eopno++)
    3432              :               /* Ignore earlyclobber operands now in memory,
    3433              :                  because we would often report failure when we have
    3434              :                  two memory operands, one of which was formerly a REG.  */
    3435      1125708 :               if (earlyclobber[eopno]
    3436       379019 :                   && REG_P (recog_data.operand[eopno]))
    3437      1924498 :                 for (opno = 0; opno < recog_data.n_operands; opno++)
    3438      1545479 :                   if ((MEM_P (recog_data.operand[opno])
    3439      1406818 :                        || recog_data.operand_type[opno] != OP_OUT)
    3440       902256 :                       && opno != eopno
    3441              :                       /* Ignore things like match_operator operands.  */
    3442       901698 :                       && *recog_data.constraints[opno] != 0
    3443       925970 :                       && ! (matching_operands[opno] == eopno
    3444        99554 :                             && operands_match_p (recog_data.operand[opno],
    3445              :                                                  recog_data.operand[eopno]))
    3446      2274476 :                       && ! safe_from_earlyclobber (recog_data.operand[opno],
    3447              :                                                    recog_data.operand[eopno]))
    3448              :                     lose = true;
    3449              : 
    3450   1073347049 :           if (! lose)
    3451              :             {
    3452   1073343081 :               while (--funny_match_index >= 0)
    3453              :                 {
    3454            0 :                   recog_data.operand[funny_match[funny_match_index].other]
    3455            0 :                     = recog_data.operand[funny_match[funny_match_index].this_op];
    3456              :                 }
    3457              : 
    3458              :               /* For operands without < or > constraints reject side-effects.  */
    3459              :               if (AUTO_INC_DEC && recog_data.is_asm)
    3460              :                 {
    3461              :                   for (opno = 0; opno < recog_data.n_operands; opno++)
    3462              :                     if (MEM_P (recog_data.operand[opno]))
    3463              :                       switch (GET_CODE (XEXP (recog_data.operand[opno], 0)))
    3464              :                         {
    3465              :                         case PRE_INC:
    3466              :                         case POST_INC:
    3467              :                         case PRE_DEC:
    3468              :                         case POST_DEC:
    3469              :                         case PRE_MODIFY:
    3470              :                         case POST_MODIFY:
    3471              :                           if (strchr (recog_data.constraints[opno], '<') == NULL
    3472              :                               && strchr (recog_data.constraints[opno], '>')
    3473              :                                  == NULL)
    3474              :                             return false;
    3475              :                           break;
    3476              :                         default:
    3477              :                           break;
    3478              :                         }
    3479              :                 }
    3480              : 
    3481              :               return true;
    3482              :             }
    3483              :         }
    3484              : 
    3485   2069253934 :       which_alternative++;
    3486              :     }
    3487   2974167572 :   while (which_alternative < recog_data.n_alternatives);
    3488              : 
    3489      4369601 :   which_alternative = -1;
    3490              :   /* If we are about to reject this, but we are not to test strictly,
    3491              :      try a very loose test.  Only return failure if it fails also.  */
    3492      4369601 :   if (strict == 0)
    3493              :     return constrain_operands (-1, alternatives);
    3494              :   else
    3495              :     return false;
    3496              : }
    3497              : 
    3498              : /* Return true iff OPERAND (assumed to be a REG rtx)
    3499              :    is a hard reg in class CLASS when its regno is offset by OFFSET
    3500              :    and changed to mode MODE.
    3501              :    If REG occupies multiple hard regs, all of them must be in CLASS.  */
    3502              : 
    3503              : bool
    3504   3379847505 : reg_fits_class_p (const_rtx operand, reg_class_t cl, int offset,
    3505              :                   machine_mode mode)
    3506              : {
    3507   3379847505 :   unsigned int regno = REGNO (operand);
    3508              : 
    3509   3379847505 :   if (cl == NO_REGS)
    3510              :     return false;
    3511              : 
    3512              :   /* Regno must not be a pseudo register.  Offset may be negative.  */
    3513   3281199294 :   return (HARD_REGISTER_NUM_P (regno)
    3514   3281123292 :           && HARD_REGISTER_NUM_P (regno + offset)
    3515   6562322586 :           && in_hard_reg_set_p (reg_class_contents[(int) cl], mode,
    3516              :                                 regno + offset));
    3517              : }
    3518              : 
    3519              : /* Split single instruction.  Helper function for split_all_insns and
    3520              :    split_all_insns_noflow.  Return last insn in the sequence if successful,
    3521              :    or NULL if unsuccessful.  */
    3522              : 
    3523              : static rtx_insn *
    3524    390199719 : split_insn (rtx_insn *insn)
    3525              : {
    3526              :   /* Split insns here to get max fine-grain parallelism.  */
    3527    390199719 :   rtx_insn *first = PREV_INSN (insn);
    3528    390199719 :   rtx_insn *last = try_split (PATTERN (insn), insn, 1);
    3529    390199719 :   rtx insn_set, last_set, note;
    3530              : 
    3531    390199719 :   if (last == insn)
    3532              :     return NULL;
    3533              : 
    3534              :   /* If the original instruction was a single set that was known to be
    3535              :      equivalent to a constant, see if we can say the same about the last
    3536              :      instruction in the split sequence.  The two instructions must set
    3537              :      the same destination.  */
    3538      6190861 :   insn_set = single_set (insn);
    3539      6190861 :   if (insn_set)
    3540              :     {
    3541      6073548 :       last_set = single_set (last);
    3542      6073548 :       if (last_set && rtx_equal_p (SET_DEST (last_set), SET_DEST (insn_set)))
    3543              :         {
    3544      2870425 :           note = find_reg_equal_equiv_note (insn);
    3545      2870425 :           if (note && CONSTANT_P (XEXP (note, 0)))
    3546        75983 :             set_unique_reg_note (last, REG_EQUAL, XEXP (note, 0));
    3547      2794442 :           else if (CONSTANT_P (SET_SRC (insn_set)))
    3548        34454 :             set_unique_reg_note (last, REG_EQUAL,
    3549              :                                  copy_rtx (SET_SRC (insn_set)));
    3550              :         }
    3551              :     }
    3552              : 
    3553              :   /* try_split returns the NOTE that INSN became.  */
    3554      6190861 :   SET_INSN_DELETED (insn);
    3555              : 
    3556              :   /* ??? Coddle to md files that generate subregs in post-reload
    3557              :      splitters instead of computing the proper hard register.  */
    3558      6190861 :   if (reload_completed && first != last)
    3559              :     {
    3560      5763745 :       auto old_post_ra_split_completed = post_ra_split_completed;
    3561      5763745 :       post_ra_split_completed = true;
    3562      5763745 :       first = NEXT_INSN (first);
    3563      2722849 :       for (;;)
    3564              :         {
    3565      8486594 :           if (INSN_P (first))
    3566      8482557 :             cleanup_subreg_operands (first);
    3567      8486594 :           if (first == last)
    3568              :             break;
    3569      2722849 :           first = NEXT_INSN (first);
    3570              :         }
    3571      5763745 :       post_ra_split_completed = old_post_ra_split_completed;
    3572              :     }
    3573              : 
    3574              :   return last;
    3575              : }
    3576              : 
    3577              : /* Split all insns in the function.  If UPD_LIFE, update life info after.  */
    3578              : 
    3579              : void
    3580      4067045 : split_all_insns (void)
    3581              : {
    3582      4067045 :   bool changed;
    3583      4067045 :   bool need_cfg_cleanup = false;
    3584      4067045 :   basic_block bb;
    3585              : 
    3586      4067045 :   auto_sbitmap blocks (last_basic_block_for_fn (cfun));
    3587      4067045 :   bitmap_clear (blocks);
    3588      4067045 :   changed = false;
    3589              : 
    3590     44161738 :   FOR_EACH_BB_REVERSE_FN (bb, cfun)
    3591              :     {
    3592     40094693 :       rtx_insn *insn, *next;
    3593     40094693 :       bool finish = false;
    3594              : 
    3595     40094693 :       rtl_profile_for_bb (bb);
    3596    512209557 :       for (insn = BB_HEAD (bb); !finish ; insn = next)
    3597              :         {
    3598              :           /* Can't use `next_real_insn' because that might go across
    3599              :              CODE_LABELS and short-out basic blocks.  */
    3600    472114864 :           next = NEXT_INSN (insn);
    3601    472114864 :           finish = (insn == BB_END (bb));
    3602              : 
    3603              :           /* If INSN has a REG_EH_REGION note and we split INSN, the
    3604              :              resulting split may not have/need REG_EH_REGION notes.
    3605              : 
    3606              :              If that happens and INSN was the last reference to the
    3607              :              given EH region, then the EH region will become unreachable.
    3608              :              We cannot leave the unreachable blocks in the CFG as that
    3609              :              will trigger a checking failure.
    3610              : 
    3611              :              So track if INSN has a REG_EH_REGION note.  If so and we
    3612              :              split INSN, then trigger a CFG cleanup.  */
    3613    472114864 :           rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
    3614    472114864 :           if (INSN_P (insn))
    3615              :             {
    3616    390247596 :               rtx set = single_set (insn);
    3617              : 
    3618              :               /* Don't split no-op move insns.  These should silently
    3619              :                  disappear later in final.  Splitting such insns would
    3620              :                  break the code that handles LIBCALL blocks.  */
    3621    390247596 :               if (set && set_noop_p (set))
    3622              :                 {
    3623              :                   /* Nops get in the way while scheduling, so delete them
    3624              :                      now if register allocation has already been done.  It
    3625              :                      is too risky to try to do this before register
    3626              :                      allocation, and there are unlikely to be very many
    3627              :                      nops then anyways.  */
    3628        47877 :                   if (reload_completed)
    3629        47877 :                       delete_insn_and_edges (insn);
    3630        47877 :                   if (note)
    3631    472114864 :                     need_cfg_cleanup = true;
    3632              :                 }
    3633              :               else
    3634              :                 {
    3635    390199719 :                   if (split_insn (insn))
    3636              :                     {
    3637      6190861 :                       bitmap_set_bit (blocks, bb->index);
    3638      6190861 :                       changed = true;
    3639      6190861 :                       if (note)
    3640         2806 :                         need_cfg_cleanup = true;
    3641              :                     }
    3642              :                 }
    3643              :             }
    3644              :         }
    3645              :     }
    3646              : 
    3647      4067045 :   if (reload_completed)
    3648      2562097 :     post_ra_split_completed = true;
    3649              : 
    3650      4067045 :   default_rtl_profile ();
    3651      4067045 :   if (changed)
    3652              :     {
    3653       762362 :       find_many_sub_basic_blocks (blocks);
    3654              : 
    3655              :       /* Splitting could drop an REG_EH_REGION if it potentially
    3656              :          trapped in its original form, but does not in its split
    3657              :          form.  Consider a FLOAT_TRUNCATE which splits into a memory
    3658              :          store/load pair and -fnon-call-exceptions.  */
    3659       762362 :       if (need_cfg_cleanup)
    3660         1340 :         cleanup_cfg (0);
    3661              :     }
    3662              : 
    3663      4067045 :   checking_verify_flow_info ();
    3664      4067045 : }
    3665              : 
    3666              : /* Same as split_all_insns, but do not expect CFG to be available.
    3667              :    Used by machine dependent reorg passes.  */
    3668              : 
    3669              : void
    3670            0 : split_all_insns_noflow (void)
    3671              : {
    3672            0 :   rtx_insn *next, *insn;
    3673              : 
    3674            0 :   for (insn = get_insns (); insn; insn = next)
    3675              :     {
    3676            0 :       next = NEXT_INSN (insn);
    3677            0 :       if (INSN_P (insn))
    3678              :         {
    3679              :           /* Don't split no-op move insns.  These should silently
    3680              :              disappear later in final.  Splitting such insns would
    3681              :              break the code that handles LIBCALL blocks.  */
    3682            0 :           rtx set = single_set (insn);
    3683            0 :           if (set && set_noop_p (set))
    3684              :             {
    3685              :               /* Nops get in the way while scheduling, so delete them
    3686              :                  now if register allocation has already been done.  It
    3687              :                  is too risky to try to do this before register
    3688              :                  allocation, and there are unlikely to be very many
    3689              :                  nops then anyways.
    3690              : 
    3691              :                  ??? Should we use delete_insn when the CFG isn't valid?  */
    3692            0 :               if (reload_completed)
    3693            0 :                 delete_insn_and_edges (insn);
    3694              :             }
    3695              :           else
    3696            0 :             split_insn (insn);
    3697              :         }
    3698              :     }
    3699              : 
    3700            0 :   if (reload_completed)
    3701            0 :     post_ra_split_completed = true;
    3702            0 : }
    3703              : 
    3704              : struct peep2_insn_data
    3705              : {
    3706              :   rtx_insn *insn;
    3707              :   regset live_before;
    3708              : };
    3709              : 
    3710              : static struct peep2_insn_data peep2_insn_data[MAX_INSNS_PER_PEEP2 + 1];
    3711              : static int peep2_current;
    3712              : 
    3713              : static bool peep2_do_rebuild_jump_labels;
    3714              : static bool peep2_do_cleanup_cfg;
    3715              : 
    3716              : /* The number of instructions available to match a peep2.  */
    3717              : int peep2_current_count;
    3718              : 
    3719              : /* A marker indicating the last insn of the block.  The live_before regset
    3720              :    for this element is correct, indicating DF_LIVE_OUT for the block.  */
    3721              : #define PEEP2_EOB invalid_insn_rtx
    3722              : 
    3723              : /* Wrap N to fit into the peep2_insn_data buffer.  */
    3724              : 
    3725              : static int
    3726    429584322 : peep2_buf_position (int n)
    3727              : {
    3728            0 :   if (n >= MAX_INSNS_PER_PEEP2 + 1)
    3729    145074619 :     n -= MAX_INSNS_PER_PEEP2 + 1;
    3730    429566226 :   return n;
    3731              : }
    3732              : 
    3733              : /* Return the Nth non-note insn after `current', or return NULL_RTX if it
    3734              :    does not exist.  Used by the recognizer to find the next insn to match
    3735              :    in a multi-insn pattern.  */
    3736              : 
    3737              : rtx_insn *
    3738    222552977 : peep2_next_insn (int n)
    3739              : {
    3740    222552977 :   gcc_assert (n <= peep2_current_count);
    3741              : 
    3742    222552977 :   n = peep2_buf_position (peep2_current + n);
    3743              : 
    3744    222552977 :   return peep2_insn_data[n].insn;
    3745              : }
    3746              : 
    3747              : /* Return true if REGNO is dead before the Nth non-note insn
    3748              :    after `current'.  */
    3749              : 
    3750              : bool
    3751     13233592 : peep2_regno_dead_p (int ofs, int regno)
    3752              : {
    3753     13233592 :   gcc_assert (ofs < MAX_INSNS_PER_PEEP2 + 1);
    3754              : 
    3755     13233592 :   ofs = peep2_buf_position (peep2_current + ofs);
    3756              : 
    3757     13233592 :   gcc_assert (peep2_insn_data[ofs].insn != NULL_RTX);
    3758              : 
    3759     13233592 :   return ! REGNO_REG_SET_P (peep2_insn_data[ofs].live_before, regno);
    3760              : }
    3761              : 
    3762              : /* Similarly for a REG.  */
    3763              : 
    3764              : bool
    3765       281454 : peep2_reg_dead_p (int ofs, rtx reg)
    3766              : {
    3767       281454 :   gcc_assert (ofs < MAX_INSNS_PER_PEEP2 + 1);
    3768              : 
    3769       281454 :   ofs = peep2_buf_position (peep2_current + ofs);
    3770              : 
    3771       281454 :   gcc_assert (peep2_insn_data[ofs].insn != NULL_RTX);
    3772              : 
    3773       281454 :   unsigned int end_regno = END_REGNO (reg);
    3774       359309 :   for (unsigned int regno = REGNO (reg); regno < end_regno; ++regno)
    3775       281454 :     if (REGNO_REG_SET_P (peep2_insn_data[ofs].live_before, regno))
    3776              :       return false;
    3777              :   return true;
    3778              : }
    3779              : 
    3780              : /* Regno offset to be used in the register search.  */
    3781              : static int search_ofs;
    3782              : 
    3783              : /* Try to find a hard register of mode MODE, matching the register class in
    3784              :    CLASS_STR, which is available at the beginning of insn CURRENT_INSN and
    3785              :    remains available until the end of LAST_INSN.  LAST_INSN may be NULL_RTX,
    3786              :    in which case the only condition is that the register must be available
    3787              :    before CURRENT_INSN.
    3788              :    Registers that already have bits set in REG_SET will not be considered.
    3789              : 
    3790              :    If an appropriate register is available, it will be returned and the
    3791              :    corresponding bit(s) in REG_SET will be set; otherwise, NULL_RTX is
    3792              :    returned.  */
    3793              : 
    3794              : rtx
    3795       601353 : peep2_find_free_register (int from, int to, const char *class_str,
    3796              :                           machine_mode mode, HARD_REG_SET *reg_set)
    3797              : {
    3798       601353 :   enum reg_class cl;
    3799       601353 :   HARD_REG_SET live;
    3800       601353 :   df_ref def;
    3801       601353 :   int i;
    3802              : 
    3803       601353 :   gcc_assert (from < MAX_INSNS_PER_PEEP2 + 1);
    3804       601353 :   gcc_assert (to < MAX_INSNS_PER_PEEP2 + 1);
    3805              : 
    3806       601353 :   from = peep2_buf_position (peep2_current + from);
    3807       601353 :   to = peep2_buf_position (peep2_current + to);
    3808              : 
    3809       601353 :   gcc_assert (peep2_insn_data[from].insn != NULL_RTX);
    3810       601353 :   REG_SET_TO_HARD_REG_SET (live, peep2_insn_data[from].live_before);
    3811              : 
    3812       601353 :   while (from != to)
    3813              :     {
    3814        18096 :       gcc_assert (peep2_insn_data[from].insn != NULL_RTX);
    3815              : 
    3816              :       /* Don't use registers set or clobbered by the insn.  */
    3817        72384 :       FOR_EACH_INSN_DEF (def, peep2_insn_data[from].insn)
    3818        54288 :         SET_HARD_REG_BIT (live, DF_REF_REGNO (def));
    3819              : 
    3820       637545 :       from = peep2_buf_position (from + 1);
    3821              :     }
    3822              : 
    3823       601353 :   cl = reg_class_for_constraint (lookup_constraint (class_str));
    3824              : 
    3825      5830105 :   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
    3826              :     {
    3827      5825316 :       int raw_regno, regno, j;
    3828      5825316 :       bool success;
    3829              : 
    3830              :       /* Distribute the free registers as much as possible.  */
    3831      5825316 :       raw_regno = search_ofs + i;
    3832      5825316 :       if (raw_regno >= FIRST_PSEUDO_REGISTER)
    3833       258365 :         raw_regno -= FIRST_PSEUDO_REGISTER;
    3834              : #ifdef REG_ALLOC_ORDER
    3835      5825316 :       regno = reg_alloc_order[raw_regno];
    3836              : #else
    3837              :       regno = raw_regno;
    3838              : #endif
    3839              : 
    3840              :       /* Can it support the mode we need?  */
    3841      5825316 :       if (!targetm.hard_regno_mode_ok (regno, mode))
    3842      1794136 :         continue;
    3843              : 
    3844      4627744 :       success = true;
    3845      4627744 :       for (j = 0; success && j < hard_regno_nregs (regno, mode); j++)
    3846              :         {
    3847              :           /* Don't allocate fixed registers.  */
    3848      4031180 :           if (fixed_regs[regno + j])
    3849              :             {
    3850              :               success = false;
    3851              :               break;
    3852              :             }
    3853              :           /* Don't allocate global registers.  */
    3854      2114818 :           if (global_regs[regno + j])
    3855              :             {
    3856              :               success = false;
    3857              :               break;
    3858              :             }
    3859              :           /* Make sure the register is of the right class.  */
    3860      2114818 :           if (! TEST_HARD_REG_BIT (reg_class_contents[cl], regno + j))
    3861              :             {
    3862              :               success = false;
    3863              :               break;
    3864              :             }
    3865              :           /* And that we don't create an extra save/restore.  */
    3866      1131261 :           if (! crtl->abi->clobbers_full_reg_p (regno + j)
    3867      1131261 :               && ! df_regs_ever_live_p (regno + j))
    3868              :             {
    3869              :               success = false;
    3870              :               break;
    3871              :             }
    3872              : 
    3873      1094544 :           if (! targetm.hard_regno_scratch_ok (regno + j))
    3874              :             {
    3875              :               success = false;
    3876              :               break;
    3877              :             }
    3878              : 
    3879              :           /* And we don't clobber traceback for noreturn functions.  */
    3880      1094381 :           if ((regno + j == FRAME_POINTER_REGNUM
    3881      1094381 :                || regno + j == HARD_FRAME_POINTER_REGNUM)
    3882        49906 :               && (! reload_completed || frame_pointer_needed))
    3883              :             {
    3884              :               success = false;
    3885              :               break;
    3886              :             }
    3887              : 
    3888      1083551 :           if (TEST_HARD_REG_BIT (*reg_set, regno + j)
    3889      1083551 :               || TEST_HARD_REG_BIT (live, regno + j))
    3890              :             {
    3891              :               success = false;
    3892              :               break;
    3893              :             }
    3894              :         }
    3895              : 
    3896      4031180 :       if (success)
    3897              :         {
    3898       596564 :           add_to_hard_reg_set (reg_set, mode, regno);
    3899              : 
    3900              :           /* Start the next search with the next register.  */
    3901       596564 :           if (++raw_regno >= FIRST_PSEUDO_REGISTER)
    3902         6575 :             raw_regno = 0;
    3903       596564 :           search_ofs = raw_regno;
    3904              : 
    3905       596564 :           return gen_rtx_REG (mode, regno);
    3906              :         }
    3907              :     }
    3908              : 
    3909         4789 :   search_ofs = 0;
    3910         4789 :   return NULL_RTX;
    3911              : }
    3912              : 
    3913              : /* Forget all currently tracked instructions, only remember current
    3914              :    LIVE regset.  */
    3915              : 
    3916              : static void
    3917     10961190 : peep2_reinit_state (regset live)
    3918              : {
    3919     10961190 :   int i;
    3920              : 
    3921              :   /* Indicate that all slots except the last holds invalid data.  */
    3922     76728330 :   for (i = 0; i < MAX_INSNS_PER_PEEP2; ++i)
    3923     65767140 :     peep2_insn_data[i].insn = NULL;
    3924     10961190 :   peep2_current_count = 0;
    3925              : 
    3926              :   /* Indicate that the last slot contains live_after data.  */
    3927     10961190 :   peep2_insn_data[MAX_INSNS_PER_PEEP2].insn = PEEP2_EOB;
    3928     10961190 :   peep2_current = MAX_INSNS_PER_PEEP2;
    3929              : 
    3930     10961190 :   COPY_REG_SET (peep2_insn_data[MAX_INSNS_PER_PEEP2].live_before, live);
    3931     10961190 : }
    3932              : 
    3933              : /* Copies frame related info of an insn (OLD_INSN) to the single
    3934              :    insn (NEW_INSN) that was obtained by splitting OLD_INSN.  */
    3935              : 
    3936              : void
    3937       133431 : copy_frame_info_to_split_insn (rtx_insn *old_insn, rtx_insn *new_insn)
    3938              : {
    3939       133431 :   bool any_note = false;
    3940       133431 :   rtx note;
    3941              : 
    3942       133431 :   if (!RTX_FRAME_RELATED_P (old_insn))
    3943              :     return;
    3944              : 
    3945       133431 :   RTX_FRAME_RELATED_P (new_insn) = 1;
    3946              : 
    3947              :   /* Allow the backend to fill in a note during the split.  */
    3948       133431 :   for (note = REG_NOTES (new_insn); note ; note = XEXP (note, 1))
    3949            0 :     switch (REG_NOTE_KIND (note))
    3950              :       {
    3951            0 :       case REG_FRAME_RELATED_EXPR:
    3952            0 :       case REG_CFA_DEF_CFA:
    3953            0 :       case REG_CFA_ADJUST_CFA:
    3954            0 :       case REG_CFA_OFFSET:
    3955            0 :       case REG_CFA_REGISTER:
    3956            0 :       case REG_CFA_EXPRESSION:
    3957            0 :       case REG_CFA_RESTORE:
    3958            0 :       case REG_CFA_SET_VDRAP:
    3959            0 :         any_note = true;
    3960            0 :         break;
    3961              :       default:
    3962              :         break;
    3963              :       }
    3964              : 
    3965              :   /* If the backend didn't supply a note, copy one over.  */
    3966       133431 :   if (!any_note)
    3967       325994 :     for (note = REG_NOTES (old_insn); note ; note = XEXP (note, 1))
    3968       192563 :       switch (REG_NOTE_KIND (note))
    3969              :         {
    3970       145193 :         case REG_FRAME_RELATED_EXPR:
    3971       145193 :         case REG_CFA_DEF_CFA:
    3972       145193 :         case REG_CFA_ADJUST_CFA:
    3973       145193 :         case REG_CFA_OFFSET:
    3974       145193 :         case REG_CFA_REGISTER:
    3975       145193 :         case REG_CFA_EXPRESSION:
    3976       145193 :         case REG_CFA_RESTORE:
    3977       145193 :         case REG_CFA_SET_VDRAP:
    3978       145193 :           add_reg_note (new_insn, REG_NOTE_KIND (note), XEXP (note, 0));
    3979       145193 :           any_note = true;
    3980       145193 :           break;
    3981              :         default:
    3982              :           break;
    3983              :         }
    3984              : 
    3985              :   /* If there still isn't a note, make sure the unwind info sees the
    3986              :      same expression as before the split.  */
    3987       133431 :   if (!any_note)
    3988              :     {
    3989         2432 :       rtx old_set, new_set;
    3990              : 
    3991              :       /* The old insn had better have been simple, or annotated.  */
    3992         2432 :       old_set = single_set (old_insn);
    3993         2432 :       gcc_assert (old_set != NULL);
    3994              : 
    3995         2432 :       new_set = single_set (new_insn);
    3996         2432 :       if (!new_set || !rtx_equal_p (new_set, old_set))
    3997          285 :         add_reg_note (new_insn, REG_FRAME_RELATED_EXPR, old_set);
    3998              :     }
    3999              : 
    4000              :   /* Copy prologue/epilogue status.  This is required in order to keep
    4001              :      proper placement of EPILOGUE_BEG and the DW_CFA_remember_state.  */
    4002       133431 :   maybe_copy_prologue_epilogue_insn (old_insn, new_insn);
    4003              : }
    4004              : 
    4005              : /* While scanning basic block BB, we found a match of length MATCH_LEN + 1,
    4006              :    starting at INSN.  Perform the replacement, removing the old insns and
    4007              :    replacing them with ATTEMPT.  Returns the last insn emitted, or NULL
    4008              :    if the replacement is rejected.  */
    4009              : 
    4010              : static rtx_insn *
    4011      2258263 : peep2_attempt (basic_block bb, rtx_insn *insn, int match_len, rtx_insn *attempt)
    4012              : {
    4013      2258263 :   int i;
    4014      2258263 :   rtx_insn *last, *before_try, *x;
    4015      2258263 :   rtx eh_note, as_note;
    4016      2258263 :   rtx_insn *old_insn;
    4017      2258263 :   rtx_insn *new_insn;
    4018      2258263 :   bool was_call = false;
    4019              : 
    4020              :   /* If we are splitting an RTX_FRAME_RELATED_P insn, do not allow it to
    4021              :      match more than one insn, or to be split into more than one insn.  */
    4022      2258263 :   old_insn = peep2_insn_data[peep2_current].insn;
    4023      2258263 :   if (RTX_FRAME_RELATED_P (old_insn))
    4024              :     {
    4025       136190 :       if (match_len != 0)
    4026              :         return NULL;
    4027              : 
    4028              :       /* Look for one "active" insn.  I.e. ignore any "clobber" insns that
    4029              :          may be in the stream for the purpose of register allocation.  */
    4030       136190 :       if (active_insn_p (attempt))
    4031              :         new_insn = attempt;
    4032              :       else
    4033        34981 :         new_insn = next_active_insn (attempt);
    4034       136190 :       if (next_active_insn (new_insn))
    4035              :         return NULL;
    4036              : 
    4037              :       /* We have a 1-1 replacement.  Copy over any frame-related info.  */
    4038       133394 :       copy_frame_info_to_split_insn (old_insn, new_insn);
    4039              :     }
    4040              : 
    4041              :   /* If we are splitting a CALL_INSN, look for the CALL_INSN
    4042              :      in SEQ and copy our CALL_INSN_FUNCTION_USAGE and other
    4043              :      cfg-related call notes.  */
    4044      4726975 :   for (i = 0; i <= match_len; ++i)
    4045              :     {
    4046      2473041 :       int j;
    4047      2473041 :       rtx note;
    4048              : 
    4049      2473041 :       j = peep2_buf_position (peep2_current + i);
    4050      2473041 :       old_insn = peep2_insn_data[j].insn;
    4051      2473041 :       if (!CALL_P (old_insn))
    4052      2471508 :         continue;
    4053         1533 :       was_call = true;
    4054              : 
    4055              :       new_insn = attempt;
    4056         1533 :       while (new_insn != NULL_RTX)
    4057              :         {
    4058         1533 :           if (CALL_P (new_insn))
    4059              :             break;
    4060            0 :           new_insn = NEXT_INSN (new_insn);
    4061              :         }
    4062              : 
    4063         1533 :       gcc_assert (new_insn != NULL_RTX);
    4064              : 
    4065         1533 :       CALL_INSN_FUNCTION_USAGE (new_insn)
    4066         1533 :         = CALL_INSN_FUNCTION_USAGE (old_insn);
    4067         1533 :       CALL_INSN_ABI_ID (new_insn) = CALL_INSN_ABI_ID (old_insn);
    4068         1533 :       SIBLING_CALL_P (new_insn) = SIBLING_CALL_P (old_insn);
    4069              : 
    4070         1533 :       for (note = REG_NOTES (old_insn);
    4071         6949 :            note;
    4072         5416 :            note = XEXP (note, 1))
    4073         5416 :         switch (REG_NOTE_KIND (note))
    4074              :           {
    4075            0 :           case REG_NORETURN:
    4076            0 :           case REG_SETJMP:
    4077            0 :           case REG_TM:
    4078            0 :           case REG_CALL_NOCF_CHECK:
    4079            0 :             add_reg_note (new_insn, REG_NOTE_KIND (note),
    4080              :                           XEXP (note, 0));
    4081            0 :             break;
    4082              :           default:
    4083              :             /* Discard all other reg notes.  */
    4084              :             break;
    4085              :           }
    4086              : 
    4087              :       /* Croak if there is another call in the sequence.  */
    4088         1533 :       while (++i <= match_len)
    4089              :         {
    4090            0 :           j = peep2_buf_position (peep2_current + i);
    4091            0 :           old_insn = peep2_insn_data[j].insn;
    4092            0 :           gcc_assert (!CALL_P (old_insn));
    4093              :         }
    4094              :       break;
    4095              :     }
    4096              : 
    4097              :   /* If we matched any instruction that had a REG_ARGS_SIZE, then
    4098              :      move those notes over to the new sequence.  */
    4099      2255467 :   as_note = NULL;
    4100      4610570 :   for (i = match_len; i >= 0; --i)
    4101              :     {
    4102      2473041 :       int j = peep2_buf_position (peep2_current + i);
    4103      2473041 :       old_insn = peep2_insn_data[j].insn;
    4104              : 
    4105      2473041 :       as_note = find_reg_note (old_insn, REG_ARGS_SIZE, NULL);
    4106      2473041 :       if (as_note)
    4107              :         break;
    4108              :     }
    4109              : 
    4110      2255467 :   i = peep2_buf_position (peep2_current + match_len);
    4111      2255467 :   eh_note = find_reg_note (peep2_insn_data[i].insn, REG_EH_REGION, NULL_RTX);
    4112              : 
    4113              :   /* Replace the old sequence with the new.  */
    4114      2255467 :   rtx_insn *peepinsn = peep2_insn_data[i].insn;
    4115      4510934 :   last = emit_insn_after_setloc (attempt,
    4116              :                                  peep2_insn_data[i].insn,
    4117      2255467 :                                  INSN_LOCATION (peepinsn));
    4118      2255467 :   if (JUMP_P (peepinsn) && JUMP_P (last))
    4119          799 :     CROSSING_JUMP_P (last) = CROSSING_JUMP_P (peepinsn);
    4120      2255467 :   before_try = PREV_INSN (insn);
    4121      2255467 :   delete_insn_chain (insn, peep2_insn_data[i].insn, false);
    4122              : 
    4123              :   /* Re-insert the EH_REGION notes.  */
    4124      2255467 :   if (eh_note || (was_call && nonlocal_goto_handler_labels))
    4125              :     {
    4126           40 :       edge eh_edge;
    4127           40 :       edge_iterator ei;
    4128              : 
    4129           48 :       FOR_EACH_EDGE (eh_edge, ei, bb->succs)
    4130           47 :         if (eh_edge->flags & (EDGE_EH | EDGE_ABNORMAL_CALL))
    4131              :           break;
    4132              : 
    4133           40 :       if (eh_note)
    4134           40 :         copy_reg_eh_region_note_backward (eh_note, last, before_try);
    4135              : 
    4136           40 :       if (eh_edge)
    4137          117 :         for (x = last; x != before_try; x = PREV_INSN (x))
    4138           78 :           if (x != BB_END (bb)
    4139           78 :               && (can_throw_internal (x)
    4140           39 :                   || can_nonlocal_goto (x)))
    4141              :             {
    4142            0 :               edge nfte, nehe;
    4143            0 :               int flags;
    4144              : 
    4145            0 :               nfte = split_block (bb, x);
    4146            0 :               flags = (eh_edge->flags
    4147              :                        & (EDGE_EH | EDGE_ABNORMAL));
    4148            0 :               if (CALL_P (x))
    4149            0 :                 flags |= EDGE_ABNORMAL_CALL;
    4150            0 :               nehe = make_edge (nfte->src, eh_edge->dest,
    4151              :                                 flags);
    4152              : 
    4153            0 :               nehe->probability = eh_edge->probability;
    4154            0 :               nfte->probability = nehe->probability.invert ();
    4155              : 
    4156            0 :               peep2_do_cleanup_cfg |= purge_dead_edges (nfte->dest);
    4157            0 :               bb = nfte->src;
    4158            0 :               eh_edge = nehe;
    4159              :             }
    4160              : 
    4161              :       /* Converting possibly trapping insn to non-trapping is
    4162              :          possible.  Zap dummy outgoing edges.  */
    4163           40 :       peep2_do_cleanup_cfg |= purge_dead_edges (bb);
    4164              :     }
    4165              : 
    4166              :   /* Re-insert the ARGS_SIZE notes.  */
    4167      2255467 :   if (as_note)
    4168       117938 :     fixup_args_size_notes (before_try, last, get_args_size (as_note));
    4169              : 
    4170              :   /* Scan the new insns for embedded side effects and add appropriate
    4171              :      REG_INC notes.  */
    4172              :   if (AUTO_INC_DEC)
    4173              :     for (x = last; x != before_try; x = PREV_INSN (x))
    4174              :       if (NONDEBUG_INSN_P (x))
    4175              :         add_auto_inc_notes (x, PATTERN (x));
    4176              : 
    4177              :   /* If we generated a jump instruction, it won't have
    4178              :      JUMP_LABEL set.  Recompute after we're done.  */
    4179      5253014 :   for (x = last; x != before_try; x = PREV_INSN (x))
    4180      2998346 :     if (JUMP_P (x))
    4181              :       {
    4182          799 :         peep2_do_rebuild_jump_labels = true;
    4183          799 :         break;
    4184              :       }
    4185              : 
    4186              :   return last;
    4187              : }
    4188              : 
    4189              : /* After performing a replacement in basic block BB, fix up the life
    4190              :    information in our buffer.  LAST is the last of the insns that we
    4191              :    emitted as a replacement.  PREV is the insn before the start of
    4192              :    the replacement.  MATCH_LEN + 1 is the number of instructions that were
    4193              :    matched, and which now need to be replaced in the buffer.  */
    4194              : 
    4195              : static void
    4196      2255467 : peep2_update_life (basic_block bb, int match_len, rtx_insn *last,
    4197              :                    rtx_insn *prev)
    4198              : {
    4199      2255467 :   int i = peep2_buf_position (peep2_current + match_len + 1);
    4200      2255467 :   rtx_insn *x;
    4201      2255467 :   regset_head live;
    4202              : 
    4203      2255467 :   INIT_REG_SET (&live);
    4204      2255467 :   COPY_REG_SET (&live, peep2_insn_data[i].live_before);
    4205              : 
    4206      2255467 :   gcc_assert (peep2_current_count >= match_len + 1);
    4207      2255467 :   peep2_current_count -= match_len + 1;
    4208              : 
    4209      2255467 :   x = last;
    4210      2999039 :   do
    4211              :     {
    4212      2999039 :       if (INSN_P (x))
    4213              :         {
    4214      2999039 :           df_insn_rescan (x);
    4215      2999039 :           if (peep2_current_count < MAX_INSNS_PER_PEEP2)
    4216              :             {
    4217      2855724 :               peep2_current_count++;
    4218      2855724 :               if (--i < 0)
    4219       832005 :                 i = MAX_INSNS_PER_PEEP2;
    4220      2855724 :               peep2_insn_data[i].insn = x;
    4221      2855724 :               df_simulate_one_insn_backwards (bb, x, &live);
    4222      2855724 :               COPY_REG_SET (peep2_insn_data[i].live_before, &live);
    4223              :             }
    4224              :         }
    4225      2999039 :       x = PREV_INSN (x);
    4226              :     }
    4227      2999039 :   while (x != prev);
    4228      2255467 :   CLEAR_REG_SET (&live);
    4229              : 
    4230      2255467 :   peep2_current = i;
    4231      2255467 : }
    4232              : 
    4233              : /* Add INSN, which is in BB, at the end of the peep2 insn buffer if possible.
    4234              :    Return true if we added it, false otherwise.  The caller will try to match
    4235              :    peepholes against the buffer if we return false; otherwise it will try to
    4236              :    add more instructions to the buffer.  */
    4237              : 
    4238              : static bool
    4239     83336195 : peep2_fill_buffer (basic_block bb, rtx_insn *insn, regset live)
    4240              : {
    4241     83336195 :   int pos;
    4242              : 
    4243              :   /* Once we have filled the maximum number of insns the buffer can hold,
    4244              :      allow the caller to match the insns against peepholes.  We wait until
    4245              :      the buffer is full in case the target has similar peepholes of different
    4246              :      length; we always want to match the longest if possible.  */
    4247     83336195 :   if (peep2_current_count == MAX_INSNS_PER_PEEP2)
    4248              :     return false;
    4249              : 
    4250              :   /* If an insn has RTX_FRAME_RELATED_P set, do not allow it to be matched with
    4251              :      any other pattern, lest it change the semantics of the frame info.  */
    4252     64282129 :   if (RTX_FRAME_RELATED_P (insn))
    4253              :     {
    4254              :       /* Let the buffer drain first.  */
    4255      7787553 :       if (peep2_current_count > 0)
    4256              :         return false;
    4257              :       /* Now the insn will be the only thing in the buffer.  */
    4258              :     }
    4259              : 
    4260     59939216 :   pos = peep2_buf_position (peep2_current + peep2_current_count);
    4261     59939216 :   peep2_insn_data[pos].insn = insn;
    4262     59939216 :   COPY_REG_SET (peep2_insn_data[pos].live_before, live);
    4263     59939216 :   peep2_current_count++;
    4264              : 
    4265     59939216 :   df_simulate_one_insn_forwards (bb, insn, live);
    4266     59939216 :   return true;
    4267              : }
    4268              : 
    4269              : /* Perform the peephole2 optimization pass.  */
    4270              : 
    4271              : static void
    4272       976479 : peephole2_optimize (void)
    4273              : {
    4274       976479 :   rtx_insn *insn;
    4275       976479 :   bitmap live;
    4276       976479 :   int i;
    4277       976479 :   basic_block bb;
    4278              : 
    4279       976479 :   peep2_do_cleanup_cfg = false;
    4280       976479 :   peep2_do_rebuild_jump_labels = false;
    4281              : 
    4282       976479 :   df_set_flags (DF_LR_RUN_DCE);
    4283       976479 :   df_note_add_problem ();
    4284       976479 :   df_analyze ();
    4285              : 
    4286              :   /* Initialize the regsets we're going to use.  */
    4287      8788311 :   for (i = 0; i < MAX_INSNS_PER_PEEP2 + 1; ++i)
    4288      6835353 :     peep2_insn_data[i].live_before = BITMAP_ALLOC (&reg_obstack);
    4289       976479 :   search_ofs = 0;
    4290       976479 :   live = BITMAP_ALLOC (&reg_obstack);
    4291              : 
    4292     11937669 :   FOR_EACH_BB_REVERSE_FN (bb, cfun)
    4293              :     {
    4294     10961190 :       bool past_end = false;
    4295     10961190 :       int pos;
    4296              : 
    4297     10961190 :       rtl_profile_for_bb (bb);
    4298              : 
    4299              :       /* Start up propagation.  */
    4300     21922380 :       bitmap_copy (live, DF_LR_IN (bb));
    4301     10961190 :       df_simulate_initialize_forwards (bb, live);
    4302     10961190 :       peep2_reinit_state (live);
    4303              : 
    4304     10961190 :       insn = BB_HEAD (bb);
    4305    208912676 :       for (;;)
    4306              :         {
    4307    208912676 :           rtx_insn *attempt, *head;
    4308    208912676 :           int match_len;
    4309              : 
    4310    208912676 :           if (!past_end && !NONDEBUG_INSN_P (insn))
    4311              :             {
    4312     75434904 :             next_insn:
    4313    135374120 :               insn = NEXT_INSN (insn);
    4314    135374120 :               if (insn == NEXT_INSN (BB_END (bb)))
    4315     10961190 :                 past_end = true;
    4316    137629587 :               continue;
    4317              :             }
    4318     83336195 :           if (!past_end && peep2_fill_buffer (bb, insn, live))
    4319     59939216 :             goto next_insn;
    4320              : 
    4321              :           /* If we did not fill an empty buffer, it signals the end of the
    4322              :              block.  */
    4323     73538556 :           if (peep2_current_count == 0)
    4324              :             break;
    4325              : 
    4326              :           /* The buffer filled to the current maximum, so try to match.  */
    4327              : 
    4328     62577366 :           pos = peep2_buf_position (peep2_current + peep2_current_count);
    4329     62577366 :           peep2_insn_data[pos].insn = PEEP2_EOB;
    4330     62577366 :           COPY_REG_SET (peep2_insn_data[pos].live_before, live);
    4331              : 
    4332              :           /* Match the peephole.  */
    4333     62577366 :           head = peep2_insn_data[peep2_current].insn;
    4334     62577366 :           attempt = peephole2_insns (PATTERN (head), head, &match_len);
    4335     62577366 :           if (attempt != NULL)
    4336              :             {
    4337      2258263 :               rtx_insn *last = peep2_attempt (bb, head, match_len, attempt);
    4338      2258263 :               if (last)
    4339              :                 {
    4340      2255467 :                   peep2_update_life (bb, match_len, last, PREV_INSN (attempt));
    4341      2255467 :                   continue;
    4342              :                 }
    4343              :             }
    4344              : 
    4345              :           /* No match: advance the buffer by one insn.  */
    4346     60321899 :           peep2_current = peep2_buf_position (peep2_current + 1);
    4347     60321899 :           peep2_current_count--;
    4348              :         }
    4349              :     }
    4350              : 
    4351       976479 :   default_rtl_profile ();
    4352      8788311 :   for (i = 0; i < MAX_INSNS_PER_PEEP2 + 1; ++i)
    4353      6835353 :     BITMAP_FREE (peep2_insn_data[i].live_before);
    4354       976479 :   BITMAP_FREE (live);
    4355       976479 :   if (peep2_do_rebuild_jump_labels)
    4356          740 :     rebuild_jump_labels (get_insns ());
    4357       976479 :   if (peep2_do_cleanup_cfg)
    4358            0 :     cleanup_cfg (CLEANUP_CFG_CHANGED);
    4359       976479 : }
    4360              : 
    4361              : /* Common predicates for use with define_bypass.  */
    4362              : 
    4363              : /* Helper function for store_data_bypass_p, handle just a single SET
    4364              :    IN_SET.  */
    4365              : 
    4366              : static bool
    4367            0 : store_data_bypass_p_1 (rtx_insn *out_insn, rtx in_set)
    4368              : {
    4369            0 :   if (!MEM_P (SET_DEST (in_set)))
    4370              :     return false;
    4371              : 
    4372            0 :   rtx out_set = single_set (out_insn);
    4373            0 :   if (out_set)
    4374            0 :     return !reg_mentioned_p (SET_DEST (out_set), SET_DEST (in_set));
    4375              : 
    4376            0 :   rtx out_pat = PATTERN (out_insn);
    4377            0 :   if (GET_CODE (out_pat) != PARALLEL)
    4378              :     return false;
    4379              : 
    4380            0 :   for (int i = 0; i < XVECLEN (out_pat, 0); i++)
    4381              :     {
    4382            0 :       rtx out_exp = XVECEXP (out_pat, 0, i);
    4383              : 
    4384            0 :       if (GET_CODE (out_exp) == CLOBBER || GET_CODE (out_exp) == USE)
    4385            0 :         continue;
    4386              : 
    4387            0 :       gcc_assert (GET_CODE (out_exp) == SET);
    4388              : 
    4389            0 :       if (reg_mentioned_p (SET_DEST (out_exp), SET_DEST (in_set)))
    4390              :         return false;
    4391              :     }
    4392              : 
    4393              :   return true;
    4394              : }
    4395              : 
    4396              : /* True if the dependency between OUT_INSN and IN_INSN is on the store
    4397              :    data not the address operand(s) of the store.  IN_INSN and OUT_INSN
    4398              :    must be either a single_set or a PARALLEL with SETs inside.  */
    4399              : 
    4400              : bool
    4401            0 : store_data_bypass_p (rtx_insn *out_insn, rtx_insn *in_insn)
    4402              : {
    4403            0 :   rtx in_set = single_set (in_insn);
    4404            0 :   if (in_set)
    4405            0 :     return store_data_bypass_p_1 (out_insn, in_set);
    4406              : 
    4407            0 :   rtx in_pat = PATTERN (in_insn);
    4408            0 :   if (GET_CODE (in_pat) != PARALLEL)
    4409              :     return false;
    4410              : 
    4411            0 :   for (int i = 0; i < XVECLEN (in_pat, 0); i++)
    4412              :     {
    4413            0 :       rtx in_exp = XVECEXP (in_pat, 0, i);
    4414              : 
    4415            0 :       if (GET_CODE (in_exp) == CLOBBER || GET_CODE (in_exp) == USE)
    4416            0 :         continue;
    4417              : 
    4418            0 :       gcc_assert (GET_CODE (in_exp) == SET);
    4419              : 
    4420            0 :       if (!store_data_bypass_p_1 (out_insn, in_exp))
    4421              :         return false;
    4422              :     }
    4423              : 
    4424              :   return true;
    4425              : }
    4426              : 
    4427              : /* True if the dependency between OUT_INSN and IN_INSN is in the IF_THEN_ELSE
    4428              :    condition, and not the THEN or ELSE branch.  OUT_INSN may be either a single
    4429              :    or multiple set; IN_INSN should be single_set for truth, but for convenience
    4430              :    of insn categorization may be any JUMP or CALL insn.  */
    4431              : 
    4432              : bool
    4433            0 : if_test_bypass_p (rtx_insn *out_insn, rtx_insn *in_insn)
    4434              : {
    4435            0 :   rtx out_set, in_set;
    4436              : 
    4437            0 :   in_set = single_set (in_insn);
    4438            0 :   if (! in_set)
    4439              :     {
    4440            0 :       gcc_assert (JUMP_P (in_insn) || CALL_P (in_insn));
    4441              :       return false;
    4442              :     }
    4443              : 
    4444            0 :   if (GET_CODE (SET_SRC (in_set)) != IF_THEN_ELSE)
    4445              :     return false;
    4446            0 :   in_set = SET_SRC (in_set);
    4447              : 
    4448            0 :   out_set = single_set (out_insn);
    4449            0 :   if (out_set)
    4450              :     {
    4451            0 :       if (reg_mentioned_p (SET_DEST (out_set), XEXP (in_set, 1))
    4452            0 :           || reg_mentioned_p (SET_DEST (out_set), XEXP (in_set, 2)))
    4453            0 :         return false;
    4454              :     }
    4455              :   else
    4456              :     {
    4457            0 :       rtx out_pat;
    4458            0 :       int i;
    4459              : 
    4460            0 :       out_pat = PATTERN (out_insn);
    4461            0 :       gcc_assert (GET_CODE (out_pat) == PARALLEL);
    4462              : 
    4463            0 :       for (i = 0; i < XVECLEN (out_pat, 0); i++)
    4464              :         {
    4465            0 :           rtx exp = XVECEXP (out_pat, 0, i);
    4466              : 
    4467            0 :           if (GET_CODE (exp) == CLOBBER)
    4468            0 :             continue;
    4469              : 
    4470            0 :           gcc_assert (GET_CODE (exp) == SET);
    4471              : 
    4472            0 :           if (reg_mentioned_p (SET_DEST (out_set), XEXP (in_set, 1))
    4473            0 :               || reg_mentioned_p (SET_DEST (out_set), XEXP (in_set, 2)))
    4474            0 :             return false;
    4475              :         }
    4476              :     }
    4477              : 
    4478              :   return true;
    4479              : }
    4480              : 
    4481              : static unsigned int
    4482       976479 : rest_of_handle_peephole2 (void)
    4483              : {
    4484       976479 :   if (HAVE_peephole2)
    4485            0 :     peephole2_optimize ();
    4486              : 
    4487       976479 :   return 0;
    4488              : }
    4489              : 
    4490              : namespace {
    4491              : 
    4492              : const pass_data pass_data_peephole2 =
    4493              : {
    4494              :   RTL_PASS, /* type */
    4495              :   "peephole2", /* name */
    4496              :   OPTGROUP_NONE, /* optinfo_flags */
    4497              :   TV_PEEPHOLE2, /* tv_id */
    4498              :   0, /* properties_required */
    4499              :   0, /* properties_provided */
    4500              :   0, /* properties_destroyed */
    4501              :   0, /* todo_flags_start */
    4502              :   TODO_df_finish, /* todo_flags_finish */
    4503              : };
    4504              : 
    4505              : class pass_peephole2 : public rtl_opt_pass
    4506              : {
    4507              : public:
    4508       292371 :   pass_peephole2 (gcc::context *ctxt)
    4509       584742 :     : rtl_opt_pass (pass_data_peephole2, ctxt)
    4510              :   {}
    4511              : 
    4512              :   /* opt_pass methods: */
    4513              :   /* The epiphany backend creates a second instance of this pass, so we need
    4514              :      a clone method.  */
    4515            0 :   opt_pass * clone () final override { return new pass_peephole2 (m_ctxt); }
    4516      1504958 :   bool gate (function *) final override
    4517              :   {
    4518      1504958 :     return (optimize > 0 && flag_peephole2);
    4519              :   }
    4520       976479 :   unsigned int execute (function *) final override
    4521              :     {
    4522       976479 :       return rest_of_handle_peephole2 ();
    4523              :     }
    4524              : 
    4525              : }; // class pass_peephole2
    4526              : 
    4527              : } // anon namespace
    4528              : 
    4529              : rtl_opt_pass *
    4530       292371 : make_pass_peephole2 (gcc::context *ctxt)
    4531              : {
    4532       292371 :   return new pass_peephole2 (ctxt);
    4533              : }
    4534              : 
    4535              : namespace {
    4536              : 
    4537              : const pass_data pass_data_split_all_insns =
    4538              : {
    4539              :   RTL_PASS, /* type */
    4540              :   "split1", /* name */
    4541              :   OPTGROUP_NONE, /* optinfo_flags */
    4542              :   TV_NONE, /* tv_id */
    4543              :   0, /* properties_required */
    4544              :   PROP_rtl_split_insns, /* properties_provided */
    4545              :   0, /* properties_destroyed */
    4546              :   0, /* todo_flags_start */
    4547              :   0, /* todo_flags_finish */
    4548              : };
    4549              : 
    4550              : class pass_split_all_insns : public rtl_opt_pass
    4551              : {
    4552              : public:
    4553       292371 :   pass_split_all_insns (gcc::context *ctxt)
    4554       584742 :     : rtl_opt_pass (pass_data_split_all_insns, ctxt)
    4555              :   {}
    4556              : 
    4557              :   /* opt_pass methods: */
    4558              :   /* The epiphany backend creates a second instance of this pass, so
    4559              :      we need a clone method.  */
    4560            0 :   opt_pass * clone () final override
    4561              :   {
    4562            0 :     return new pass_split_all_insns (m_ctxt);
    4563              :   }
    4564      1504948 :   unsigned int execute (function *) final override
    4565              :     {
    4566      1504948 :       split_all_insns ();
    4567      1504948 :       return 0;
    4568              :     }
    4569              : 
    4570              : }; // class pass_split_all_insns
    4571              : 
    4572              : } // anon namespace
    4573              : 
    4574              : rtl_opt_pass *
    4575       292371 : make_pass_split_all_insns (gcc::context *ctxt)
    4576              : {
    4577       292371 :   return new pass_split_all_insns (ctxt);
    4578              : }
    4579              : 
    4580              : namespace {
    4581              : 
    4582              : const pass_data pass_data_split_after_reload =
    4583              : {
    4584              :   RTL_PASS, /* type */
    4585              :   "split2", /* name */
    4586              :   OPTGROUP_NONE, /* optinfo_flags */
    4587              :   TV_NONE, /* tv_id */
    4588              :   0, /* properties_required */
    4589              :   0, /* properties_provided */
    4590              :   0, /* properties_destroyed */
    4591              :   0, /* todo_flags_start */
    4592              :   0, /* todo_flags_finish */
    4593              : };
    4594              : 
    4595              : class pass_split_after_reload : public rtl_opt_pass
    4596              : {
    4597              : public:
    4598       292371 :   pass_split_after_reload (gcc::context *ctxt)
    4599       584742 :     : rtl_opt_pass (pass_data_split_after_reload, ctxt)
    4600              :   {}
    4601              : 
    4602              :   /* opt_pass methods: */
    4603      1504958 :   bool gate (function *) final override
    4604              :     {
    4605              :       /* If optimizing, then go ahead and split insns now.  */
    4606      1504958 :       return optimize > 0;
    4607              :     }
    4608              : 
    4609      1057059 :   unsigned int execute (function *) final override
    4610              :     {
    4611      1057059 :       split_all_insns ();
    4612      1057059 :       return 0;
    4613              :     }
    4614              : 
    4615              : }; // class pass_split_after_reload
    4616              : 
    4617              : } // anon namespace
    4618              : 
    4619              : rtl_opt_pass *
    4620       292371 : make_pass_split_after_reload (gcc::context *ctxt)
    4621              : {
    4622       292371 :   return new pass_split_after_reload (ctxt);
    4623              : }
    4624              : 
    4625              : static bool
    4626      3009916 : enable_split_before_sched2 (void)
    4627              : {
    4628              : #ifdef INSN_SCHEDULING
    4629      2114120 :   return optimize > 0 && flag_schedule_insns_after_reload;
    4630              : #else
    4631              :   return false;
    4632              : #endif
    4633              : }
    4634              : 
    4635              : namespace {
    4636              : 
    4637              : const pass_data pass_data_split_before_sched2 =
    4638              : {
    4639              :   RTL_PASS, /* type */
    4640              :   "split3", /* name */
    4641              :   OPTGROUP_NONE, /* optinfo_flags */
    4642              :   TV_NONE, /* tv_id */
    4643              :   0, /* properties_required */
    4644              :   0, /* properties_provided */
    4645              :   0, /* properties_destroyed */
    4646              :   0, /* todo_flags_start */
    4647              :   0, /* todo_flags_finish */
    4648              : };
    4649              : 
    4650              : class pass_split_before_sched2 : public rtl_opt_pass
    4651              : {
    4652              : public:
    4653       292371 :   pass_split_before_sched2 (gcc::context *ctxt)
    4654       584742 :     : rtl_opt_pass (pass_data_split_before_sched2, ctxt)
    4655              :   {}
    4656              : 
    4657              :   /* opt_pass methods: */
    4658      1504958 :   bool gate (function *) final override
    4659              :     {
    4660      1504958 :       return enable_split_before_sched2 ();
    4661              :     }
    4662              : 
    4663       976472 :   unsigned int execute (function *) final override
    4664              :     {
    4665       976472 :       split_all_insns ();
    4666       976472 :       return 0;
    4667              :     }
    4668              : 
    4669              : }; // class pass_split_before_sched2
    4670              : 
    4671              : } // anon namespace
    4672              : 
    4673              : rtl_opt_pass *
    4674       292371 : make_pass_split_before_sched2 (gcc::context *ctxt)
    4675              : {
    4676       292371 :   return new pass_split_before_sched2 (ctxt);
    4677              : }
    4678              : 
    4679              : namespace {
    4680              : 
    4681              : const pass_data pass_data_split_before_regstack =
    4682              : {
    4683              :   RTL_PASS, /* type */
    4684              :   "split4", /* name */
    4685              :   OPTGROUP_NONE, /* optinfo_flags */
    4686              :   TV_NONE, /* tv_id */
    4687              :   0, /* properties_required */
    4688              :   0, /* properties_provided */
    4689              :   0, /* properties_destroyed */
    4690              :   0, /* todo_flags_start */
    4691              :   0, /* todo_flags_finish */
    4692              : };
    4693              : 
    4694              : class pass_split_before_regstack : public rtl_opt_pass
    4695              : {
    4696              : public:
    4697       292371 :   pass_split_before_regstack (gcc::context *ctxt)
    4698       584742 :     : rtl_opt_pass (pass_data_split_before_regstack, ctxt)
    4699              :   {}
    4700              : 
    4701              :   /* opt_pass methods: */
    4702              :   bool gate (function *) final override;
    4703       528566 :   unsigned int execute (function *) final override
    4704              :     {
    4705       528566 :       split_all_insns ();
    4706       528566 :       return 0;
    4707              :     }
    4708              : 
    4709              : }; // class pass_split_before_regstack
    4710              : 
    4711              : bool
    4712      1504958 : pass_split_before_regstack::gate (function *)
    4713              : {
    4714              : #if HAVE_ATTR_length && defined (STACK_REGS)
    4715              :   /* If flow2 creates new instructions which need splitting
    4716              :      and scheduling after reload is not done, they might not be
    4717              :      split until final which doesn't allow splitting
    4718              :      if HAVE_ATTR_length.  Selective scheduling can result in
    4719              :      further instructions that need splitting.  */
    4720              : #ifdef INSN_SCHEDULING
    4721      2481431 :   return !enable_split_before_sched2 () || flag_selective_scheduling2;
    4722              : #else
    4723              :   return !enable_split_before_sched2 ();
    4724              : #endif
    4725              : #else
    4726              :   return false;
    4727              : #endif
    4728              : }
    4729              : 
    4730              : } // anon namespace
    4731              : 
    4732              : rtl_opt_pass *
    4733       292371 : make_pass_split_before_regstack (gcc::context *ctxt)
    4734              : {
    4735       292371 :   return new pass_split_before_regstack (ctxt);
    4736              : }
    4737              : 
    4738              : namespace {
    4739              : 
    4740              : const pass_data pass_data_split_for_shorten_branches =
    4741              : {
    4742              :   RTL_PASS, /* type */
    4743              :   "split5", /* name */
    4744              :   OPTGROUP_NONE, /* optinfo_flags */
    4745              :   TV_NONE, /* tv_id */
    4746              :   0, /* properties_required */
    4747              :   0, /* properties_provided */
    4748              :   0, /* properties_destroyed */
    4749              :   0, /* todo_flags_start */
    4750              :   0, /* todo_flags_finish */
    4751              : };
    4752              : 
    4753              : class pass_split_for_shorten_branches : public rtl_opt_pass
    4754              : {
    4755              : public:
    4756       292371 :   pass_split_for_shorten_branches (gcc::context *ctxt)
    4757       584742 :     : rtl_opt_pass (pass_data_split_for_shorten_branches, ctxt)
    4758              :   {}
    4759              : 
    4760              :   /* opt_pass methods: */
    4761      1504958 :   bool gate (function *) final override
    4762              :     {
    4763              :       /* The placement of the splitting that we do for shorten_branches
    4764              :          depends on whether regstack is used by the target or not.  */
    4765              : #if HAVE_ATTR_length && !defined (STACK_REGS)
    4766              :       return true;
    4767              : #else
    4768      1504958 :       return false;
    4769              : #endif
    4770              :     }
    4771              : 
    4772            0 :   unsigned int execute (function *) final override
    4773              :     {
    4774            0 :       split_all_insns_noflow ();
    4775            0 :       return 0;
    4776              :     }
    4777              : 
    4778              : }; // class pass_split_for_shorten_branches
    4779              : 
    4780              : } // anon namespace
    4781              : 
    4782              : rtl_opt_pass *
    4783       292371 : make_pass_split_for_shorten_branches (gcc::context *ctxt)
    4784              : {
    4785       292371 :   return new pass_split_for_shorten_branches (ctxt);
    4786              : }
    4787              : 
    4788              : /* (Re)initialize the target information after a change in target.  */
    4789              : 
    4790              : void
    4791       218792 : recog_init ()
    4792              : {
    4793              :   /* The information is zero-initialized, so we don't need to do anything
    4794              :      first time round.  */
    4795       218792 :   if (!this_target_recog->x_initialized)
    4796              :     {
    4797       217732 :       this_target_recog->x_initialized = true;
    4798       217732 :       return;
    4799              :     }
    4800         1060 :   memset (this_target_recog->x_bool_attr_masks, 0,
    4801              :           sizeof (this_target_recog->x_bool_attr_masks));
    4802     16140620 :   for (unsigned int i = 0; i < NUM_INSN_CODES; ++i)
    4803     16139560 :     if (this_target_recog->x_op_alt[i])
    4804              :       {
    4805        10172 :         free (this_target_recog->x_op_alt[i]);
    4806        10172 :         this_target_recog->x_op_alt[i] = 0;
    4807              :       }
    4808              : }
        

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.