LCOV - code coverage report
Current view: top level - gcc - recog.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 86.7 % 1881 1630
Test Date: 2024-12-21 13:15:12 Functions: 83.7 % 123 103
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

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

Generated by: LCOV version 2.1-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.