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

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.