LCOV - code coverage report
Current view: top level - gcc - recog.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 86.7 % 1838 1593
Test Date: 2024-04-20 14:03:02 Functions: 83.6 % 122 102
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                 :             : 
      45                 :             : #ifndef STACK_POP_CODE
      46                 :             : #if STACK_GROWS_DOWNWARD
      47                 :             : #define STACK_POP_CODE POST_INC
      48                 :             : #else
      49                 :             : #define STACK_POP_CODE POST_DEC
      50                 :             : #endif
      51                 :             : #endif
      52                 :             : 
      53                 :             : static void validate_replace_rtx_1 (rtx *, rtx, rtx, rtx_insn *, bool);
      54                 :             : static void validate_replace_src_1 (rtx *, void *);
      55                 :             : static rtx_insn *split_insn (rtx_insn *);
      56                 :             : 
      57                 :             : struct target_recog default_target_recog;
      58                 :             : #if SWITCHABLE_TARGET
      59                 :             : struct target_recog *this_target_recog = &default_target_recog;
      60                 :             : #endif
      61                 :             : 
      62                 :             : /* Nonzero means allow operands to be volatile.
      63                 :             :    This should be 0 if you are generating rtl, such as if you are calling
      64                 :             :    the functions in optabs.cc and expmed.cc (most of the time).
      65                 :             :    This should be 1 if all valid insns need to be recognized,
      66                 :             :    such as in reginfo.cc and final.cc and reload.cc.
      67                 :             : 
      68                 :             :    init_recog and init_recog_no_volatile are responsible for setting this.  */
      69                 :             : 
      70                 :             : int volatile_ok;
      71                 :             : 
      72                 :             : struct recog_data_d recog_data;
      73                 :             : 
      74                 :             : /* Contains a vector of operand_alternative structures, such that
      75                 :             :    operand OP of alternative A is at index A * n_operands + OP.
      76                 :             :    Set up by preprocess_constraints.  */
      77                 :             : const operand_alternative *recog_op_alt;
      78                 :             : 
      79                 :             : /* Used to provide recog_op_alt for asms.  */
      80                 :             : static operand_alternative asm_op_alt[MAX_RECOG_OPERANDS
      81                 :             :                                       * MAX_RECOG_ALTERNATIVES];
      82                 :             : 
      83                 :             : /* On return from `constrain_operands', indicate which alternative
      84                 :             :    was satisfied.  */
      85                 :             : 
      86                 :             : int which_alternative;
      87                 :             : 
      88                 :             : /* Nonzero after end of reload pass.
      89                 :             :    Set to 1 or 0 by toplev.cc.
      90                 :             :    Controls the significance of (SUBREG (MEM)).  */
      91                 :             : 
      92                 :             : int reload_completed;
      93                 :             : 
      94                 :             : /* Nonzero after thread_prologue_and_epilogue_insns has run.  */
      95                 :             : int epilogue_completed;
      96                 :             : 
      97                 :             : /* Initialize data used by the function `recog'.
      98                 :             :    This must be called once in the compilation of a function
      99                 :             :    before any insn recognition may be done in the function.  */
     100                 :             : 
     101                 :             : void
     102                 :     3800215 : init_recog_no_volatile (void)
     103                 :             : {
     104                 :     3800215 :   volatile_ok = 0;
     105                 :     3800215 : }
     106                 :             : 
     107                 :             : void
     108                 :     7428860 : init_recog (void)
     109                 :             : {
     110                 :     7428860 :   volatile_ok = 1;
     111                 :     7428860 : }
     112                 :             : 
     113                 :             : 
     114                 :             : /* Return true if labels in asm operands BODY are LABEL_REFs.  */
     115                 :             : 
     116                 :             : static bool
     117                 :    92547312 : asm_labels_ok (rtx body)
     118                 :             : {
     119                 :    92547312 :   rtx asmop;
     120                 :    92547312 :   int i;
     121                 :             : 
     122                 :    92547312 :   asmop = extract_asm_operands (body);
     123                 :    92547312 :   if (asmop == NULL_RTX)
     124                 :             :     return true;
     125                 :             : 
     126                 :      505555 :   for (i = 0; i < ASM_OPERANDS_LABEL_LENGTH (asmop); i++)
     127                 :        4889 :     if (GET_CODE (ASM_OPERANDS_LABEL (asmop, i)) != LABEL_REF)
     128                 :             :       return false;
     129                 :             : 
     130                 :             :   return true;
     131                 :             : }
     132                 :             : 
     133                 :             : /* Check that X is an insn-body for an `asm' with operands
     134                 :             :    and that the operands mentioned in it are legitimate.  */
     135                 :             : 
     136                 :             : bool
     137                 :    92547312 : check_asm_operands (rtx x)
     138                 :             : {
     139                 :    92547312 :   int noperands;
     140                 :    92547312 :   rtx *operands;
     141                 :    92547312 :   const char **constraints;
     142                 :    92547312 :   int i;
     143                 :             : 
     144                 :    92547312 :   if (!asm_labels_ok (x))
     145                 :             :     return false;
     146                 :             : 
     147                 :             :   /* Post-reload, be more strict with things.  */
     148                 :    92547312 :   if (reload_completed)
     149                 :             :     {
     150                 :             :       /* ??? Doh!  We've not got the wrapping insn.  Cook one up.  */
     151                 :        3600 :       rtx_insn *insn = make_insn_raw (x);
     152                 :        3600 :       extract_insn (insn);
     153                 :        3600 :       constrain_operands (1, get_enabled_alternatives (insn));
     154                 :        3600 :       return which_alternative >= 0;
     155                 :             :     }
     156                 :             : 
     157                 :    92543712 :   noperands = asm_noperands (x);
     158                 :    92543712 :   if (noperands < 0)
     159                 :             :     return false;
     160                 :      478304 :   if (noperands == 0)
     161                 :             :     return true;
     162                 :             : 
     163                 :      411774 :   operands = XALLOCAVEC (rtx, noperands);
     164                 :      411774 :   constraints = XALLOCAVEC (const char *, noperands);
     165                 :             : 
     166                 :      411774 :   decode_asm_operands (x, operands, NULL, constraints, NULL, NULL);
     167                 :             : 
     168                 :     1920911 :   for (i = 0; i < noperands; i++)
     169                 :             :     {
     170                 :     1846990 :       const char *c = constraints[i];
     171                 :     1846990 :       if (c[0] == '%')
     172                 :        3575 :         c++;
     173                 :     1846990 :       if (! asm_operand_ok (operands[i], c, constraints))
     174                 :             :         return false;
     175                 :             :     }
     176                 :             : 
     177                 :             :   return true;
     178                 :             : }
     179                 :             : 
     180                 :             : /* Static data for the next two routines.  */
     181                 :             : 
     182                 :             : struct change_t
     183                 :             : {
     184                 :             :   rtx object;
     185                 :             :   int old_code;
     186                 :             :   int old_len;
     187                 :             :   bool unshare;
     188                 :             :   rtx *loc;
     189                 :             :   rtx old;
     190                 :             : };
     191                 :             : 
     192                 :             : static change_t *changes;
     193                 :             : static int changes_allocated;
     194                 :             : 
     195                 :             : static int num_changes = 0;
     196                 :             : static int temporarily_undone_changes = 0;
     197                 :             : 
     198                 :             : /* Validate a proposed change to OBJECT.  LOC is the location in the rtl
     199                 :             :    at which NEW_RTX will be placed.  If NEW_LEN is >= 0, XVECLEN (NEW_RTX, 0)
     200                 :             :    will also be changed to NEW_LEN, which is no greater than the current
     201                 :             :    XVECLEN.  If OBJECT is zero, no validation is done, the change is
     202                 :             :    simply made.
     203                 :             : 
     204                 :             :    Two types of objects are supported:  If OBJECT is a MEM, memory_address_p
     205                 :             :    will be called with the address and mode as parameters.  If OBJECT is
     206                 :             :    an INSN, CALL_INSN, or JUMP_INSN, the insn will be re-recognized with
     207                 :             :    the change in place.
     208                 :             : 
     209                 :             :    IN_GROUP is nonzero if this is part of a group of changes that must be
     210                 :             :    performed as a group.  In that case, the changes will be stored.  The
     211                 :             :    function `apply_change_group' will validate and apply the changes.
     212                 :             : 
     213                 :             :    If IN_GROUP is zero, this is a single change.  Try to recognize the insn
     214                 :             :    or validate the memory reference with the change applied.  If the result
     215                 :             :    is not valid for the machine, suppress the change and return false.
     216                 :             :    Otherwise, perform the change and return true.  */
     217                 :             : 
     218                 :             : static bool
     219                 :  1543389647 : validate_change_1 (rtx object, rtx *loc, rtx new_rtx, bool in_group,
     220                 :             :                    bool unshare, int new_len = -1)
     221                 :             : {
     222                 :  1543389647 :   gcc_assert (temporarily_undone_changes == 0);
     223                 :  1543389647 :   rtx old = *loc;
     224                 :             : 
     225                 :             :   /* Single-element parallels aren't valid and won't match anything.
     226                 :             :      Replace them with the single element.  */
     227                 :  1543389647 :   if (new_len == 1 && GET_CODE (new_rtx) == PARALLEL)
     228                 :             :     {
     229                 :     2963516 :       new_rtx = XVECEXP (new_rtx, 0, 0);
     230                 :     2963516 :       new_len = -1;
     231                 :             :     }
     232                 :             : 
     233                 :   126707966 :   if ((old == new_rtx || rtx_equal_p (old, new_rtx))
     234                 :  1546243275 :       && (new_len < 0 || XVECLEN (new_rtx, 0) == new_len))
     235                 :             :     return true;
     236                 :             : 
     237                 :   123946634 :   gcc_assert ((in_group != 0 || num_changes == 0)
     238                 :             :               && (new_len < 0 || new_rtx == *loc));
     239                 :             : 
     240                 :   123946634 :   *loc = new_rtx;
     241                 :             : 
     242                 :             :   /* Save the information describing this change.  */
     243                 :   123946634 :   if (num_changes >= changes_allocated)
     244                 :             :     {
     245                 :      156368 :       if (changes_allocated == 0)
     246                 :             :         /* This value allows for repeated substitutions inside complex
     247                 :             :            indexed addresses, or changes in up to 5 insns.  */
     248                 :      156351 :         changes_allocated = MAX_RECOG_OPERANDS * 5;
     249                 :             :       else
     250                 :          17 :         changes_allocated *= 2;
     251                 :             : 
     252                 :      156368 :       changes = XRESIZEVEC (change_t, changes, changes_allocated);
     253                 :             :     }
     254                 :             : 
     255                 :   123946634 :   changes[num_changes].object = object;
     256                 :   123946634 :   changes[num_changes].loc = loc;
     257                 :   123946634 :   changes[num_changes].old = old;
     258                 :   123946634 :   changes[num_changes].old_len = (new_len >= 0 ? XVECLEN (new_rtx, 0) : -1);
     259                 :   123946634 :   changes[num_changes].unshare = unshare;
     260                 :             : 
     261                 :   123946634 :   if (new_len >= 0)
     262                 :       92296 :     XVECLEN (new_rtx, 0) = new_len;
     263                 :             : 
     264                 :   123946634 :   if (object && !MEM_P (object))
     265                 :             :     {
     266                 :             :       /* Set INSN_CODE to force rerecognition of insn.  Save old code in
     267                 :             :          case invalid.  */
     268                 :   100897225 :       changes[num_changes].old_code = INSN_CODE (object);
     269                 :   100897225 :       INSN_CODE (object) = -1;
     270                 :             :     }
     271                 :             : 
     272                 :   123946634 :   num_changes++;
     273                 :             : 
     274                 :             :   /* If we are making a group of changes, return 1.  Otherwise, validate the
     275                 :             :      change group we made.  */
     276                 :             : 
     277                 :   123946634 :   if (in_group)
     278                 :             :     return true;
     279                 :             :   else
     280                 :    16269993 :     return apply_change_group ();
     281                 :             : }
     282                 :             : 
     283                 :             : /* Wrapper for validate_change_1 without the UNSHARE argument defaulting
     284                 :             :    UNSHARE to false.  */
     285                 :             : 
     286                 :             : bool
     287                 :  1309293313 : validate_change (rtx object, rtx *loc, rtx new_rtx, bool in_group)
     288                 :             : {
     289                 :  1309293313 :   return validate_change_1 (object, loc, new_rtx, in_group, false);
     290                 :             : }
     291                 :             : 
     292                 :             : /* Wrapper for validate_change_1 without the UNSHARE argument defaulting
     293                 :             :    UNSHARE to true.  */
     294                 :             : 
     295                 :             : bool
     296                 :   227619530 : validate_unshare_change (rtx object, rtx *loc, rtx new_rtx, bool in_group)
     297                 :             : {
     298                 :   227619530 :   return validate_change_1 (object, loc, new_rtx, in_group, true);
     299                 :             : }
     300                 :             : 
     301                 :             : /* Change XVECLEN (*LOC, 0) to NEW_LEN.  OBJECT, IN_GROUP and the return
     302                 :             :    value are as for validate_change_1.  */
     303                 :             : 
     304                 :             : bool
     305                 :     6476804 : validate_change_xveclen (rtx object, rtx *loc, int new_len, bool in_group)
     306                 :             : {
     307                 :     6476804 :   return validate_change_1 (object, loc, *loc, in_group, false, new_len);
     308                 :             : }
     309                 :             : 
     310                 :             : /* Keep X canonicalized if some changes have made it non-canonical; only
     311                 :             :    modifies the operands of X, not (for example) its code.  Simplifications
     312                 :             :    are not the job of this routine.
     313                 :             : 
     314                 :             :    Return true if anything was changed.  */
     315                 :             : bool
     316                 :     1952882 : canonicalize_change_group (rtx_insn *insn, rtx x)
     317                 :             : {
     318                 :     1952882 :   if (COMMUTATIVE_P (x)
     319                 :     1952882 :       && swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1)))
     320                 :             :     {
     321                 :             :       /* Oops, the caller has made X no longer canonical.
     322                 :             :          Let's redo the changes in the correct order.  */
     323                 :      179587 :       rtx tem = XEXP (x, 0);
     324                 :      179587 :       validate_unshare_change (insn, &XEXP (x, 0), XEXP (x, 1), 1);
     325                 :      179587 :       validate_unshare_change (insn, &XEXP (x, 1), tem, 1);
     326                 :      179587 :       return true;
     327                 :             :     }
     328                 :             :   else
     329                 :     1773295 :     return false;
     330                 :             : }
     331                 :             : 
     332                 :             : /* Check if REG_INC argument in *data overlaps a stored REG.  */
     333                 :             : 
     334                 :             : static void
     335                 :           0 : check_invalid_inc_dec (rtx reg, const_rtx, void *data)
     336                 :             : {
     337                 :           0 :   rtx *pinc = (rtx *) data;
     338                 :           0 :   if (*pinc == NULL_RTX || MEM_P (reg))
     339                 :             :     return;
     340                 :           0 :   if (reg_overlap_mentioned_p (reg, *pinc))
     341                 :           0 :     *pinc = NULL_RTX;
     342                 :             : }
     343                 :             : 
     344                 :             : /* This subroutine of apply_change_group verifies whether the changes to INSN
     345                 :             :    were valid; i.e. whether INSN can still be recognized.
     346                 :             : 
     347                 :             :    If IN_GROUP is true clobbers which have to be added in order to
     348                 :             :    match the instructions will be added to the current change group.
     349                 :             :    Otherwise the changes will take effect immediately.  */
     350                 :             : 
     351                 :             : bool
     352                 :    70522564 : insn_invalid_p (rtx_insn *insn, bool in_group)
     353                 :             : {
     354                 :    70522564 :   rtx pat = PATTERN (insn);
     355                 :    70522564 :   int num_clobbers = 0;
     356                 :             :   /* If we are before reload and the pattern is a SET, see if we can add
     357                 :             :      clobbers.  */
     358                 :    70522564 :   int icode = recog (pat, insn,
     359                 :    70522564 :                      (GET_CODE (pat) == SET
     360                 :    60994983 :                       && ! reload_completed 
     361                 :    31883684 :                       && ! reload_in_progress)
     362                 :             :                      ? &num_clobbers : 0);
     363                 :    70522564 :   bool is_asm = icode < 0 && asm_noperands (PATTERN (insn)) >= 0;
     364                 :             : 
     365                 :             : 
     366                 :             :   /* If this is an asm and the operand aren't legal, then fail.  Likewise if
     367                 :             :      this is not an asm and the insn wasn't recognized.  */
     368                 :      276651 :   if ((is_asm && ! check_asm_operands (PATTERN (insn)))
     369                 :    70265160 :       || (!is_asm && icode < 0))
     370                 :    16634530 :     return true;
     371                 :             : 
     372                 :             :   /* If we have to add CLOBBERs, fail if we have to add ones that reference
     373                 :             :      hard registers since our callers can't know if they are live or not.
     374                 :             :      Otherwise, add them.  */
     375                 :    53888034 :   if (num_clobbers > 0)
     376                 :             :     {
     377                 :      733464 :       rtx newpat;
     378                 :             : 
     379                 :      733464 :       if (added_clobbers_hard_reg_p (icode))
     380                 :             :         return true;
     381                 :             : 
     382                 :         501 :       newpat = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (num_clobbers + 1));
     383                 :         501 :       XVECEXP (newpat, 0, 0) = pat;
     384                 :         501 :       add_clobbers (newpat, icode);
     385                 :         501 :       if (in_group)
     386                 :         500 :         validate_change (insn, &PATTERN (insn), newpat, 1);
     387                 :             :       else
     388                 :           1 :         PATTERN (insn) = pat = newpat;
     389                 :             :     }
     390                 :             : 
     391                 :             :   /* After reload, verify that all constraints are satisfied.  */
     392                 :    53155071 :   if (reload_completed)
     393                 :             :     {
     394                 :    29197757 :       extract_insn (insn);
     395                 :             : 
     396                 :    29197757 :       if (! constrain_operands (1, get_preferred_alternatives (insn)))
     397                 :             :         return true;
     398                 :             :     }
     399                 :             : 
     400                 :             :   /* Punt if REG_INC argument overlaps some stored REG.  */
     401                 :    53137063 :   for (rtx link = FIND_REG_INC_NOTE (insn, NULL_RTX);
     402                 :    53137063 :        link; link = XEXP (link, 1))
     403                 :             :     if (REG_NOTE_KIND (link) == REG_INC)
     404                 :             :       {
     405                 :             :         rtx reg = XEXP (link, 0);
     406                 :             :         note_stores (insn, check_invalid_inc_dec, &reg);
     407                 :             :         if (reg == NULL_RTX)
     408                 :             :           return true;
     409                 :             :       }
     410                 :             : 
     411                 :    53137063 :   INSN_CODE (insn) = icode;
     412                 :    53137063 :   return false;
     413                 :             : }
     414                 :             : 
     415                 :             : /* Return number of changes made and not validated yet.  */
     416                 :             : int
     417                 :     4635695 : num_changes_pending (void)
     418                 :             : {
     419                 :     4635695 :   return num_changes;
     420                 :             : }
     421                 :             : 
     422                 :             : /* Tentatively apply the changes numbered NUM and up.
     423                 :             :    Return true if all changes are valid, false otherwise.  */
     424                 :             : 
     425                 :             : bool
     426                 :   669151138 : verify_changes (int num)
     427                 :             : {
     428                 :   669151138 :   int i;
     429                 :   669151138 :   rtx last_validated = NULL_RTX;
     430                 :             : 
     431                 :             :   /* The changes have been applied and all INSN_CODEs have been reset to force
     432                 :             :      rerecognition.
     433                 :             : 
     434                 :             :      The changes are valid if we aren't given an object, or if we are
     435                 :             :      given a MEM and it still is a valid address, or if this is in insn
     436                 :             :      and it is recognized.  In the latter case, if reload has completed,
     437                 :             :      we also require that the operands meet the constraints for
     438                 :             :      the insn.  */
     439                 :             : 
     440                 :   719607862 :   for (i = num; i < num_changes; i++)
     441                 :             :     {
     442                 :    65347342 :       rtx object = changes[i].object;
     443                 :             : 
     444                 :             :       /* If there is no object to test or if it is the same as the one we
     445                 :             :          already tested, ignore it.  */
     446                 :    65347342 :       if (object == 0 || object == last_validated)
     447                 :     5912841 :         continue;
     448                 :             : 
     449                 :    59434501 :       if (MEM_P (object))
     450                 :             :         {
     451                 :       23824 :           if (! memory_address_addr_space_p (GET_MODE (object),
     452                 :             :                                              XEXP (object, 0),
     453                 :       11912 :                                              MEM_ADDR_SPACE (object)))
     454                 :             :             break;
     455                 :             :         }
     456                 :    59422589 :       else if (/* changes[i].old might be zero, e.g. when putting a
     457                 :             :                REG_FRAME_RELATED_EXPR into a previously empty list.  */
     458                 :    59422589 :                changes[i].old
     459                 :    59422589 :                && REG_P (changes[i].old)
     460                 :    22390013 :                && asm_noperands (PATTERN (object)) > 0
     461                 :    59687320 :                && register_asm_p (changes[i].old))
     462                 :             :         {
     463                 :             :           /* Don't allow changes of hard register operands to inline
     464                 :             :              assemblies if they have been defined as register asm ("x").  */
     465                 :             :           break;
     466                 :             :         }
     467                 :    59422588 :       else if (DEBUG_INSN_P (object))
     468                 :      705051 :         continue;
     469                 :    58717537 :       else if (insn_invalid_p (as_a <rtx_insn *> (object), true))
     470                 :             :         {
     471                 :    17385490 :           rtx pat = PATTERN (object);
     472                 :             : 
     473                 :             :           /* Perhaps we couldn't recognize the insn because there were
     474                 :             :              extra CLOBBERs at the end.  If so, try to re-recognize
     475                 :             :              without the last CLOBBER (later iterations will cause each of
     476                 :             :              them to be eliminated, in turn).  But don't do this if we
     477                 :             :              have an ASM_OPERAND.  */
     478                 :    17385490 :           if (GET_CODE (pat) == PARALLEL
     479                 :     4135569 :               && GET_CODE (XVECEXP (pat, 0, XVECLEN (pat, 0) - 1)) == CLOBBER
     480                 :    20137575 :               && asm_noperands (PATTERN (object)) < 0)
     481                 :             :             {
     482                 :     2494683 :               rtx newpat;
     483                 :             : 
     484                 :     2494683 :               if (XVECLEN (pat, 0) == 2)
     485                 :     2100696 :                 newpat = XVECEXP (pat, 0, 0);
     486                 :             :               else
     487                 :             :                 {
     488                 :      393987 :                   int j;
     489                 :             : 
     490                 :      393987 :                   newpat
     491                 :      393987 :                     = gen_rtx_PARALLEL (VOIDmode,
     492                 :             :                                         rtvec_alloc (XVECLEN (pat, 0) - 1));
     493                 :     1213558 :                   for (j = 0; j < XVECLEN (newpat, 0); j++)
     494                 :      819571 :                     XVECEXP (newpat, 0, j) = XVECEXP (pat, 0, j);
     495                 :             :                 }
     496                 :             : 
     497                 :             :               /* Add a new change to this group to replace the pattern
     498                 :             :                  with this new pattern.  Then consider this change
     499                 :             :                  as having succeeded.  The change we added will
     500                 :             :                  cause the entire call to fail if things remain invalid.
     501                 :             : 
     502                 :             :                  Note that this can lose if a later change than the one
     503                 :             :                  we are processing specified &XVECEXP (PATTERN (object), 0, X)
     504                 :             :                  but this shouldn't occur.  */
     505                 :             : 
     506                 :     2494683 :               validate_change (object, &PATTERN (object), newpat, 1);
     507                 :     2494683 :               continue;
     508                 :     2494683 :             }
     509                 :    14890807 :           else if (GET_CODE (pat) == USE || GET_CODE (pat) == CLOBBER
     510                 :    14890543 :                    || GET_CODE (pat) == VAR_LOCATION)
     511                 :             :             /* If this insn is a CLOBBER or USE, it is always valid, but is
     512                 :             :                never recognized.  */
     513                 :         264 :             continue;
     514                 :             :           else
     515                 :             :             break;
     516                 :             :         }
     517                 :             :       last_validated = object;
     518                 :             :     }
     519                 :             : 
     520                 :   669151138 :   return (i == num_changes);
     521                 :             : }
     522                 :             : 
     523                 :             : /* A group of changes has previously been issued with validate_change
     524                 :             :    and verified with verify_changes.  Call df_insn_rescan for each of
     525                 :             :    the insn changed and clear num_changes.  */
     526                 :             : 
     527                 :             : void
     528                 :   653372611 : confirm_change_group (void)
     529                 :             : {
     530                 :   653372611 :   int i;
     531                 :   653372611 :   rtx last_object = NULL;
     532                 :             : 
     533                 :   653372611 :   gcc_assert (temporarily_undone_changes == 0);
     534                 :   705273932 :   for (i = 0; i < num_changes; i++)
     535                 :             :     {
     536                 :    51901321 :       rtx object = changes[i].object;
     537                 :             : 
     538                 :    51901321 :       if (changes[i].unshare)
     539                 :    11477154 :         *changes[i].loc = copy_rtx (*changes[i].loc);
     540                 :             : 
     541                 :             :       /* Avoid unnecessary rescanning when multiple changes to same instruction
     542                 :             :          are made.  */
     543                 :    51901321 :       if (object)
     544                 :             :         {
     545                 :    49319125 :           if (object != last_object && last_object && INSN_P (last_object))
     546                 :     1865177 :             df_insn_rescan (as_a <rtx_insn *> (last_object));
     547                 :             :           last_object = object;
     548                 :             :         }
     549                 :             :     }
     550                 :             : 
     551                 :   653372611 :   if (last_object && INSN_P (last_object))
     552                 :    42487051 :     df_insn_rescan (as_a <rtx_insn *> (last_object));
     553                 :   653372611 :   num_changes = 0;
     554                 :   653372611 : }
     555                 :             : 
     556                 :             : /* Apply a group of changes previously issued with `validate_change'.
     557                 :             :    If all changes are valid, call confirm_change_group and return true,
     558                 :             :    otherwise, call cancel_changes and return false.  */
     559                 :             : 
     560                 :             : bool
     561                 :   661659969 : apply_change_group (void)
     562                 :             : {
     563                 :   661659969 :   if (verify_changes (0))
     564                 :             :     {
     565                 :   650150123 :       confirm_change_group ();
     566                 :   650150123 :       return true;
     567                 :             :     }
     568                 :             :   else
     569                 :             :     {
     570                 :    11509846 :       cancel_changes (0);
     571                 :    11509846 :       return false;
     572                 :             :     }
     573                 :             : }
     574                 :             : 
     575                 :             : 
     576                 :             : /* Return the number of changes so far in the current group.  */
     577                 :             : 
     578                 :             : int
     579                 :   352405258 : num_validated_changes (void)
     580                 :             : {
     581                 :   352405258 :   return num_changes;
     582                 :             : }
     583                 :             : 
     584                 :             : /* Retract the changes numbered NUM and up.  */
     585                 :             : 
     586                 :             : void
     587                 :   116505969 : cancel_changes (int num)
     588                 :             : {
     589                 :   116505969 :   gcc_assert (temporarily_undone_changes == 0);
     590                 :   116505969 :   int i;
     591                 :             : 
     592                 :             :   /* Back out all the changes.  Do this in the opposite order in which
     593                 :             :      they were made.  */
     594                 :   188551282 :   for (i = num_changes - 1; i >= num; i--)
     595                 :             :     {
     596                 :    72045313 :       if (changes[i].old_len >= 0)
     597                 :       92296 :         XVECLEN (*changes[i].loc, 0) = changes[i].old_len;
     598                 :             :       else
     599                 :    71953017 :         *changes[i].loc = changes[i].old;
     600                 :    72045313 :       if (changes[i].object && !MEM_P (changes[i].object))
     601                 :    51589938 :         INSN_CODE (changes[i].object) = changes[i].old_code;
     602                 :             :     }
     603                 :   116505969 :   num_changes = num;
     604                 :   116505969 : }
     605                 :             : 
     606                 :             : /* Swap the status of change NUM from being applied to not being applied,
     607                 :             :    or vice versa.  */
     608                 :             : 
     609                 :             : static void
     610                 :    26995906 : swap_change (int num)
     611                 :             : {
     612                 :    26995906 :   if (changes[num].old_len >= 0)
     613                 :          20 :     std::swap (XVECLEN (*changes[num].loc, 0), changes[num].old_len);
     614                 :             :   else
     615                 :    26995886 :     std::swap (*changes[num].loc, changes[num].old);
     616                 :    26995906 :   if (changes[num].object && !MEM_P (changes[num].object))
     617                 :    26995906 :     std::swap (INSN_CODE (changes[num].object), changes[num].old_code);
     618                 :    26995906 : }
     619                 :             : 
     620                 :             : /* Temporarily undo all the changes numbered NUM and up, with a view
     621                 :             :    to reapplying them later.  The next call to the changes machinery
     622                 :             :    must be:
     623                 :             : 
     624                 :             :       redo_changes (NUM)
     625                 :             : 
     626                 :             :    otherwise things will end up in an invalid state.  */
     627                 :             : 
     628                 :             : void
     629                 :     9166427 : temporarily_undo_changes (int num)
     630                 :             : {
     631                 :     9166427 :   gcc_assert (temporarily_undone_changes == 0 && num <= num_changes);
     632                 :    22664380 :   for (int i = num_changes - 1; i >= num; i--)
     633                 :    13497953 :     swap_change (i);
     634                 :     9166427 :   temporarily_undone_changes = num_changes - num;
     635                 :     9166427 : }
     636                 :             : 
     637                 :             : /* Redo the changes that were temporarily undone by:
     638                 :             : 
     639                 :             :       temporarily_undo_changes (NUM).  */
     640                 :             : 
     641                 :             : void
     642                 :     9166427 : redo_changes (int num)
     643                 :             : {
     644                 :     9166427 :   gcc_assert (temporarily_undone_changes == num_changes - num);
     645                 :    22664380 :   for (int i = num; i < num_changes; ++i)
     646                 :    13497953 :     swap_change (i);
     647                 :     9166427 :   temporarily_undone_changes = 0;
     648                 :     9166427 : }
     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                 :    11726742 : simplify_while_replacing (rtx *loc, rtx to, rtx_insn *object,
     656                 :             :                           machine_mode op0_mode)
     657                 :             : {
     658                 :    11726742 :   rtx x = *loc;
     659                 :    11726742 :   enum rtx_code code = GET_CODE (x);
     660                 :    11726742 :   rtx new_rtx = NULL_RTX;
     661                 :    11726742 :   scalar_int_mode is_mode;
     662                 :             : 
     663                 :    11726742 :   if (SWAPPABLE_OPERANDS_P (x)
     664                 :    11726742 :       && swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1)))
     665                 :             :     {
     666                 :      606819 :       validate_unshare_change (object, loc,
     667                 :      606819 :                                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                 :      606819 :       x = *loc;
     672                 :      606819 :       code = GET_CODE (x);
     673                 :             :     }
     674                 :             : 
     675                 :             :   /* Canonicalize arithmetics with all constant operands.  */
     676                 :    11726742 :   switch (GET_RTX_CLASS (code))
     677                 :             :     {
     678                 :      826587 :     case RTX_UNARY:
     679                 :      826587 :       if (CONSTANT_P (XEXP (x, 0)))
     680                 :      622110 :         new_rtx = simplify_unary_operation (code, GET_MODE (x), XEXP (x, 0),
     681                 :             :                                             op0_mode);
     682                 :             :       break;
     683                 :     6134963 :     case RTX_COMM_ARITH:
     684                 :     6134963 :     case RTX_BIN_ARITH:
     685                 :     6134963 :       if (CONSTANT_P (XEXP (x, 0)) && CONSTANT_P (XEXP (x, 1)))
     686                 :      432487 :         new_rtx = simplify_binary_operation (code, GET_MODE (x), XEXP (x, 0),
     687                 :             :                                              XEXP (x, 1));
     688                 :             :       break;
     689                 :       99926 :     case RTX_COMPARE:
     690                 :       99926 :     case RTX_COMM_COMPARE:
     691                 :       99926 :       if (CONSTANT_P (XEXP (x, 0)) && CONSTANT_P (XEXP (x, 1)))
     692                 :        2878 :         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                 :     1057475 :   if (new_rtx)
     699                 :             :     {
     700                 :      918820 :       validate_change (object, loc, new_rtx, 1);
     701                 :      918820 :       return;
     702                 :             :     }
     703                 :             : 
     704                 :    10807922 :   switch (code)
     705                 :             :     {
     706                 :     2098447 :     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                 :     2098447 :       if (CONST_INT_P (XEXP (x, 1)) && XEXP (x, 1) == to)
     712                 :      189311 :         validate_change (object, loc,
     713                 :             :                          simplify_gen_binary
     714                 :      189311 :                          (PLUS, GET_MODE (x), XEXP (x, 0), XEXP (x, 1)), 1);
     715                 :             :       break;
     716                 :      425626 :     case MINUS:
     717                 :      425626 :       if (CONST_SCALAR_INT_P (XEXP (x, 1)))
     718                 :       22648 :         validate_change (object, loc,
     719                 :             :                          simplify_gen_binary
     720                 :       22648 :                          (PLUS, GET_MODE (x), XEXP (x, 0),
     721                 :             :                           simplify_gen_unary (NEG,
     722                 :             :                                               GET_MODE (x), XEXP (x, 1),
     723                 :       22648 :                                               GET_MODE (x))), 1);
     724                 :             :       break;
     725                 :      150771 :     case ZERO_EXTEND:
     726                 :      150771 :     case SIGN_EXTEND:
     727                 :      150771 :       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                 :      121527 :     case SUBREG:
     739                 :             :       /* All subregs possible to simplify should be simplified.  */
     740                 :      121527 :       new_rtx = simplify_subreg (GET_MODE (x), SUBREG_REG (x), op0_mode,
     741                 :      121527 :                              SUBREG_BYTE (x));
     742                 :             : 
     743                 :             :       /* Subregs of VOIDmode operands are incorrect.  */
     744                 :      121527 :       if (!new_rtx && GET_MODE (SUBREG_REG (x)) == VOIDmode)
     745                 :           2 :         new_rtx = gen_rtx_CLOBBER (GET_MODE (x), const0_rtx);
     746                 :       19050 :       if (new_rtx)
     747                 :      102479 :         validate_change (object, loc, new_rtx, 1);
     748                 :             :       break;
     749                 :        5825 :     case ZERO_EXTRACT:
     750                 :        5825 :     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                 :        5825 :       if (MEM_P (XEXP (x, 0))
     757                 :         421 :           && is_a <scalar_int_mode> (GET_MODE (XEXP (x, 0)), &is_mode)
     758                 :         421 :           && CONST_INT_P (XEXP (x, 1))
     759                 :         421 :           && CONST_INT_P (XEXP (x, 2))
     760                 :         245 :           && !mode_dependent_address_p (XEXP (XEXP (x, 0), 0),
     761                 :         245 :                                         MEM_ADDR_SPACE (XEXP (x, 0)))
     762                 :        6070 :           && !MEM_VOLATILE_P (XEXP (x, 0)))
     763                 :             :         {
     764                 :         245 :           int pos = INTVAL (XEXP (x, 2));
     765                 :         245 :           machine_mode new_mode = is_mode;
     766                 :         245 :           if (GET_CODE (x) == ZERO_EXTRACT && targetm.have_extzv ())
     767                 :           0 :             new_mode = insn_data[targetm.code_for_extzv].operand[1].mode;
     768                 :         245 :           else if (GET_CODE (x) == SIGN_EXTRACT && targetm.have_extv ())
     769                 :           0 :             new_mode = insn_data[targetm.code_for_extv].operand[1].mode;
     770                 :         245 :           scalar_int_mode wanted_mode = (new_mode == VOIDmode
     771                 :         245 :                                          ? word_mode
     772                 :         245 :                                          : as_a <scalar_int_mode> (new_mode));
     773                 :             : 
     774                 :             :           /* If we have a narrower mode, we can do something.  */
     775                 :         735 :           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                 :    67828211 : validate_replace_rtx_1 (rtx *loc, rtx from, rtx to, rtx_insn *object,
     810                 :             :                         bool simplify)
     811                 :             : {
     812                 :    67828211 :   int i, j;
     813                 :    67828211 :   const char *fmt;
     814                 :    67828211 :   rtx x = *loc;
     815                 :    67828211 :   enum rtx_code code;
     816                 :    67828211 :   machine_mode op0_mode = VOIDmode;
     817                 :    67828211 :   int prev_changes = num_changes;
     818                 :             : 
     819                 :    67828211 :   if (!x)
     820                 :             :     return;
     821                 :             : 
     822                 :    67828211 :   code = GET_CODE (x);
     823                 :    67828211 :   fmt = GET_RTX_FORMAT (code);
     824                 :    67828211 :   if (fmt[0] == 'e')
     825                 :    23047583 :     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                 :    67828211 :   if (x == from
     832                 :    53124491 :       || (REG_P (x) && REG_P (from)
     833                 :    15083264 :           && GET_MODE (x) == GET_MODE (from)
     834                 :     9721433 :           && REGNO (x) == REGNO (from))
     835                 :   120952699 :       || (GET_CODE (x) == GET_CODE (from) && GET_MODE (x) == GET_MODE (from)
     836                 :     9721430 :           && rtx_equal_p (x, from)))
     837                 :             :     {
     838                 :    14703723 :       validate_unshare_change (object, loc, to, 1);
     839                 :    14703723 :       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                 :    53124488 :   if (GET_CODE (x) == PARALLEL)
     848                 :             :     {
     849                 :     1202928 :       for (j = XVECLEN (x, 0) - 1; j >= 0; j--)
     850                 :             :         {
     851                 :      890393 :           if (j && GET_CODE (XVECEXP (x, 0, j)) == SET
     852                 :       35410 :               && GET_CODE (SET_SRC (XVECEXP (x, 0, j))) == ASM_OPERANDS)
     853                 :             :             {
     854                 :             :               /* Verify that operands are really shared.  */
     855                 :         193 :               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                 :         193 :               validate_replace_rtx_1 (&SET_DEST (XVECEXP (x, 0, j)),
     859                 :             :                                       from, to, object, simplify);
     860                 :             :             }
     861                 :             :           else
     862                 :      890200 :             validate_replace_rtx_1 (&XVECEXP (x, 0, j), from, to, object,
     863                 :             :                                     simplify);
     864                 :             :         }
     865                 :             :     }
     866                 :             :   else
     867                 :   135663750 :     for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
     868                 :             :       {
     869                 :    82851797 :         if (fmt[i] == 'e')
     870                 :    39236591 :           validate_replace_rtx_1 (&XEXP (x, i), from, to, object, simplify);
     871                 :    43615206 :         else if (fmt[i] == 'E')
     872                 :     7478736 :           for (j = XVECLEN (x, i) - 1; j >= 0; j--)
     873                 :     3973556 :             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                 :    53124488 :   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                 :    11726833 :   if (fmt[0] == 'e' && GET_MODE (XEXP (x, 0)) != VOIDmode)
     885                 :     8630305 :     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                 :    11726833 :   if (simplify)
     890                 :    11726742 :     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                 :     1974709 : validate_replace_rtx (rtx from, rtx to, rtx_insn *insn)
     909                 :             : {
     910                 :     1974709 :   validate_replace_rtx_1 (&PATTERN (insn), from, to, insn, true);
     911                 :     1974709 :   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                 :         116 : validate_replace_rtx_part_nosimplify (rtx from, rtx to, rtx *where,
     930                 :             :                                       rtx_insn *insn)
     931                 :             : {
     932                 :         116 :   validate_replace_rtx_1 (where, from, to, insn, false);
     933                 :         116 :   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                 :    21752825 : validate_replace_src_1 (rtx *x, void *data)
     961                 :             : {
     962                 :    21752825 :   struct validate_replace_src_data *d
     963                 :             :     = (struct validate_replace_src_data *) data;
     964                 :             : 
     965                 :    21752825 :   validate_replace_rtx_1 (x, d->from, d->to, d->insn, true);
     966                 :    21752825 : }
     967                 :             : 
     968                 :             : /* Try replacing every occurrence of FROM in INSN with TO, avoiding
     969                 :             :    SET_DESTs.  */
     970                 :             : 
     971                 :             : void
     972                 :    15324906 : validate_replace_src_group (rtx from, rtx to, rtx_insn *insn)
     973                 :             : {
     974                 :    15324906 :   struct validate_replace_src_data d;
     975                 :             : 
     976                 :    15324906 :   d.from = from;
     977                 :    15324906 :   d.to = to;
     978                 :    15324906 :   d.insn = insn;
     979                 :    15324906 :   note_uses (&PATTERN (insn), validate_replace_src_1, &d);
     980                 :    15324906 : }
     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                 :    11336682 : insn_propagation::apply_to_mem_1 (rtx mem)
    1027                 :             : {
    1028                 :    11336682 :   auto old_num_changes = num_validated_changes ();
    1029                 :    11336682 :   mem_depth += 1;
    1030                 :    11336682 :   bool res = apply_to_rvalue_1 (&XEXP (mem, 0));
    1031                 :    11336682 :   mem_depth -= 1;
    1032                 :    11336682 :   if (!res)
    1033                 :             :     return false;
    1034                 :             : 
    1035                 :    11336310 :   if (old_num_changes != num_validated_changes ()
    1036                 :     2819174 :       && should_check_mems
    1037                 :    14155479 :       && !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                 :   100080484 : insn_propagation::apply_to_rvalue_1 (rtx *loc)
    1048                 :             : {
    1049                 :   100080484 :   rtx x = *loc;
    1050                 :   100080484 :   enum rtx_code code = GET_CODE (x);
    1051                 :   100080484 :   machine_mode mode = GET_MODE (x);
    1052                 :             : 
    1053                 :   100080484 :   auto old_num_changes = num_validated_changes ();
    1054                 :   100080484 :   if (from && GET_CODE (x) == GET_CODE (from) && rtx_equal_p (x, from))
    1055                 :             :     {
    1056                 :             :       /* Don't replace register asms in asm statements; we mustn't
    1057                 :             :          change the user's register allocation.  */
    1058                 :    24212271 :       if (REG_P (x)
    1059                 :    24188123 :           && HARD_REGISTER_P (x)
    1060                 :      514862 :           && register_asm_p (x)
    1061                 :    24213064 :           && asm_noperands (PATTERN (insn)) > 0)
    1062                 :             :         return false;
    1063                 :             : 
    1064                 :    24211632 :       if (should_unshare)
    1065                 :    24211632 :         validate_unshare_change (insn, loc, to, 1);
    1066                 :             :       else
    1067                 :           0 :         validate_change (insn, loc, to, 1);
    1068                 :    24211632 :       if (mem_depth && !REG_P (to) && !CONSTANT_P (to))
    1069                 :             :         {
    1070                 :             :           /* We're substituting into an address, but TO will have the
    1071                 :             :              form expected outside an address.  Canonicalize it if
    1072                 :             :              necessary.  */
    1073                 :     1819904 :           insn_propagation subprop (insn);
    1074                 :     1819904 :           subprop.mem_depth += 1;
    1075                 :     1819904 :           if (!subprop.apply_to_rvalue (loc))
    1076                 :           0 :             gcc_unreachable ();
    1077                 :     1819904 :           if (should_unshare
    1078                 :     1819904 :               && num_validated_changes () != old_num_changes + 1)
    1079                 :             :             {
    1080                 :             :               /* TO is owned by someone else, so create a copy and
    1081                 :             :                  return TO to its original form.  */
    1082                 :      124581 :               rtx to = copy_rtx (*loc);
    1083                 :      124581 :               cancel_changes (old_num_changes);
    1084                 :      124581 :               validate_change (insn, loc, to, 1);
    1085                 :             :             }
    1086                 :             :         }
    1087                 :    24211632 :       num_replacements += 1;
    1088                 :    24211632 :       should_unshare = true;
    1089                 :    24211632 :       result_flags |= UNSIMPLIFIED;
    1090                 :    24211632 :       return true;
    1091                 :             :     }
    1092                 :             : 
    1093                 :             :   /* Recursively apply the substitution and see if we can simplify
    1094                 :             :      the result.  This specifically shouldn't use simplify_gen_* for
    1095                 :             :      speculative simplifications, since we want to avoid generating new
    1096                 :             :      expressions where possible.  */
    1097                 :    75868213 :   auto old_result_flags = result_flags;
    1098                 :    75868213 :   rtx newx = NULL_RTX;
    1099                 :    75868213 :   bool recurse_p = false;
    1100                 :    75868213 :   switch (GET_RTX_CLASS (code))
    1101                 :             :     {
    1102                 :     1432336 :     case RTX_UNARY:
    1103                 :     1432336 :       {
    1104                 :     1432336 :         machine_mode op0_mode = GET_MODE (XEXP (x, 0));
    1105                 :     1432336 :         if (!apply_to_rvalue_1 (&XEXP (x, 0)))
    1106                 :             :           return false;
    1107                 :     1409095 :         if (from && old_num_changes == num_validated_changes ())
    1108                 :             :           return true;
    1109                 :             : 
    1110                 :     1117088 :         newx = simplify_unary_operation (code, mode, XEXP (x, 0), op0_mode);
    1111                 :     1117088 :         break;
    1112                 :             :       }
    1113                 :             : 
    1114                 :    18788519 :     case RTX_BIN_ARITH:
    1115                 :    18788519 :     case RTX_COMM_ARITH:
    1116                 :    18788519 :       {
    1117                 :    18788519 :         if (!apply_to_rvalue_1 (&XEXP (x, 0))
    1118                 :    18788519 :             || !apply_to_rvalue_1 (&XEXP (x, 1)))
    1119                 :      157774 :           return false;
    1120                 :    18630745 :         if (from && old_num_changes == num_validated_changes ())
    1121                 :             :           return true;
    1122                 :             : 
    1123                 :    13374179 :         if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
    1124                 :    13374179 :             && swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1)))
    1125                 :     1256207 :           newx = simplify_gen_binary (code, mode, XEXP (x, 1), XEXP (x, 0));
    1126                 :             :         else
    1127                 :    12117972 :           newx = simplify_binary_operation (code, mode,
    1128                 :             :                                             XEXP (x, 0), XEXP (x, 1));
    1129                 :             :         break;
    1130                 :             :       }
    1131                 :             : 
    1132                 :      950381 :     case RTX_COMPARE:
    1133                 :      950381 :     case RTX_COMM_COMPARE:
    1134                 :      950381 :       {
    1135                 :     1900762 :         machine_mode op_mode = (GET_MODE (XEXP (x, 0)) != VOIDmode
    1136                 :      950381 :                                 ? GET_MODE (XEXP (x, 0))
    1137                 :         225 :                                 : GET_MODE (XEXP (x, 1)));
    1138                 :      950381 :         if (!apply_to_rvalue_1 (&XEXP (x, 0))
    1139                 :      950381 :             || !apply_to_rvalue_1 (&XEXP (x, 1)))
    1140                 :        1151 :           return false;
    1141                 :      949230 :         if (from && old_num_changes == num_validated_changes ())
    1142                 :             :           return true;
    1143                 :             : 
    1144                 :      597909 :         newx = simplify_relational_operation (code, mode, op_mode,
    1145                 :             :                                               XEXP (x, 0), XEXP (x, 1));
    1146                 :      597909 :         break;
    1147                 :             :       }
    1148                 :             : 
    1149                 :      603041 :     case RTX_TERNARY:
    1150                 :      603041 :     case RTX_BITFIELD_OPS:
    1151                 :      603041 :       {
    1152                 :      603041 :         machine_mode op0_mode = GET_MODE (XEXP (x, 0));
    1153                 :      603041 :         if (!apply_to_rvalue_1 (&XEXP (x, 0))
    1154                 :      601364 :             || !apply_to_rvalue_1 (&XEXP (x, 1))
    1155                 :     1188373 :             || !apply_to_rvalue_1 (&XEXP (x, 2)))
    1156                 :       19518 :           return false;
    1157                 :      583523 :         if (from && old_num_changes == num_validated_changes ())
    1158                 :             :           return true;
    1159                 :             : 
    1160                 :      531562 :         newx = simplify_ternary_operation (code, mode, op0_mode,
    1161                 :             :                                            XEXP (x, 0), XEXP (x, 1),
    1162                 :             :                                            XEXP (x, 2));
    1163                 :      531562 :         break;
    1164                 :             :       }
    1165                 :             : 
    1166                 :     8427203 :     case RTX_EXTRA:
    1167                 :     8427203 :       if (code == SUBREG)
    1168                 :             :         {
    1169                 :     1652700 :           machine_mode inner_mode = GET_MODE (SUBREG_REG (x));
    1170                 :     1652700 :           if (!apply_to_rvalue_1 (&SUBREG_REG (x)))
    1171                 :             :             return false;
    1172                 :     1652694 :           if (from && old_num_changes == num_validated_changes ())
    1173                 :             :             return true;
    1174                 :             : 
    1175                 :     1176819 :           rtx inner = SUBREG_REG (x);
    1176                 :     1176819 :           newx = simplify_subreg (mode, inner, inner_mode, SUBREG_BYTE (x));
    1177                 :             :           /* Reject the same cases that simplify_gen_subreg would.  */
    1178                 :     1176819 :           if (!newx
    1179                 :     1176819 :               && (GET_CODE (inner) == SUBREG
    1180                 :      654577 :                   || GET_CODE (inner) == CONCAT
    1181                 :      643996 :                   || GET_MODE (inner) == VOIDmode
    1182                 :      643995 :                   || !validate_subreg (mode, inner_mode,
    1183                 :      643995 :                                        inner, SUBREG_BYTE (x))))
    1184                 :             :             {
    1185                 :       10582 :               failure_reason = "would create an invalid subreg";
    1186                 :       10582 :               return false;
    1187                 :             :             }
    1188                 :             :           break;
    1189                 :             :         }
    1190                 :             :       else
    1191                 :             :         recurse_p = true;
    1192                 :             :       break;
    1193                 :             : 
    1194                 :    23359631 :     case RTX_OBJ:
    1195                 :    23359631 :       if (code == LO_SUM)
    1196                 :             :         {
    1197                 :           0 :           if (!apply_to_rvalue_1 (&XEXP (x, 0))
    1198                 :           0 :               || !apply_to_rvalue_1 (&XEXP (x, 1)))
    1199                 :           0 :             return false;
    1200                 :           0 :           if (from && old_num_changes == num_validated_changes ())
    1201                 :             :             return true;
    1202                 :             : 
    1203                 :             :           /* (lo_sum (high x) y) -> y where x and y have the same base.  */
    1204                 :           0 :           rtx op0 = XEXP (x, 0);
    1205                 :           0 :           rtx op1 = XEXP (x, 1);
    1206                 :           0 :           if (GET_CODE (op0) == HIGH)
    1207                 :             :             {
    1208                 :           0 :               rtx base0, base1, offset0, offset1;
    1209                 :           0 :               split_const (XEXP (op0, 0), &base0, &offset0);
    1210                 :           0 :               split_const (op1, &base1, &offset1);
    1211                 :           0 :               if (rtx_equal_p (base0, base1))
    1212                 :           0 :                 newx = op1;
    1213                 :             :             }
    1214                 :             :         }
    1215                 :    23359631 :       else if (code == REG)
    1216                 :             :         {
    1217                 :    16074136 :           if (from && REG_P (from) && reg_overlap_mentioned_p (x, from))
    1218                 :             :             {
    1219                 :         487 :               failure_reason = "inexact register overlap";
    1220                 :         487 :               return false;
    1221                 :             :             }
    1222                 :             :         }
    1223                 :     7285495 :       else if (code == MEM)
    1224                 :     7222688 :         return apply_to_mem_1 (x);
    1225                 :             :       else
    1226                 :             :         recurse_p = true;
    1227                 :             :       break;
    1228                 :             : 
    1229                 :             :     case RTX_CONST_OBJ:
    1230                 :             :       break;
    1231                 :             : 
    1232                 :      558002 :     case RTX_AUTOINC:
    1233                 :      558002 :       if (from && reg_overlap_mentioned_p (XEXP (x, 0), from))
    1234                 :             :         {
    1235                 :           0 :           failure_reason = "is subject to autoinc";
    1236                 :           0 :           return false;
    1237                 :             :         }
    1238                 :             :       recurse_p = true;
    1239                 :             :       break;
    1240                 :             : 
    1241                 :           0 :     case RTX_MATCH:
    1242                 :           0 :     case RTX_INSN:
    1243                 :           0 :       gcc_unreachable ();
    1244                 :             :     }
    1245                 :             : 
    1246                 :    16786975 :   if (recurse_p)
    1247                 :             :     {
    1248                 :     7395312 :       const char *fmt = GET_RTX_FORMAT (code);
    1249                 :    21237603 :       for (int i = 0; fmt[i]; i++)
    1250                 :    13931255 :         switch (fmt[i])
    1251                 :             :           {
    1252                 :             :           case 'E':
    1253                 :     3011488 :             for (int j = 0; j < XVECLEN (x, i); j++)
    1254                 :     2179171 :               if (!apply_to_rvalue_1 (&XVECEXP (x, i, j)))
    1255                 :             :                 return false;
    1256                 :             :             break;
    1257                 :             : 
    1258                 :    10177559 :           case 'e':
    1259                 :    10177559 :             if (XEXP (x, i) && !apply_to_rvalue_1 (&XEXP (x, i)))
    1260                 :             :               return false;
    1261                 :             :             break;
    1262                 :             :           }
    1263                 :             :     }
    1264                 :    54609724 :   else if (newx && !rtx_equal_p (x, newx))
    1265                 :             :     {
    1266                 :             :       /* All substitutions made by OLD_NUM_CHANGES onwards have been
    1267                 :             :          simplified.  */
    1268                 :     3427454 :       result_flags = ((result_flags & ~UNSIMPLIFIED)
    1269                 :             :                       | (old_result_flags & UNSIMPLIFIED));
    1270                 :             : 
    1271                 :     3427454 :       if (should_note_simplifications)
    1272                 :     3302873 :         note_simplification (old_num_changes, old_result_flags, x, newx);
    1273                 :             : 
    1274                 :             :       /* There's no longer any point unsharing the substitutions made
    1275                 :             :          for subexpressions, since we'll just copy this one instead.  */
    1276                 :             :       bool unshare = false;
    1277                 :     6824119 :       for (int i = old_num_changes; i < num_changes; ++i)
    1278                 :             :         {
    1279                 :     3396665 :           unshare |= changes[i].unshare;
    1280                 :     3396665 :           changes[i].unshare = false;
    1281                 :             :         }
    1282                 :     3427454 :       if (unshare)
    1283                 :     3246726 :         validate_unshare_change (insn, loc, newx, 1);
    1284                 :             :       else
    1285                 :      180728 :         validate_change (insn, loc, newx, 1);
    1286                 :             :     }
    1287                 :             : 
    1288                 :             :   return true;
    1289                 :             : }
    1290                 :             : 
    1291                 :             : /* Try to process the lvalue expression at *LOC.  Return true on success;
    1292                 :             :    leave the caller to clean up on failure.  */
    1293                 :             : 
    1294                 :             : bool
    1295                 :    25185101 : insn_propagation::apply_to_lvalue_1 (rtx dest)
    1296                 :             : {
    1297                 :    25185101 :   rtx old_dest = dest;
    1298                 :    25185101 :   while (GET_CODE (dest) == SUBREG
    1299                 :    25241988 :          || GET_CODE (dest) == ZERO_EXTRACT
    1300                 :    25241988 :          || GET_CODE (dest) == STRICT_LOW_PART)
    1301                 :             :     {
    1302                 :       56887 :       if (GET_CODE (dest) == ZERO_EXTRACT
    1303                 :       56887 :           && (!apply_to_rvalue_1 (&XEXP (dest, 1))
    1304                 :         859 :               || !apply_to_rvalue_1 (&XEXP (dest, 2))))
    1305                 :           0 :         return false;
    1306                 :       56887 :       dest = XEXP (dest, 0);
    1307                 :             :     }
    1308                 :             : 
    1309                 :    25185101 :   if (MEM_P (dest))
    1310                 :     4113994 :     return apply_to_mem_1 (dest);
    1311                 :             : 
    1312                 :             :   /* Check whether the substitution is safe in the presence of this lvalue.  */
    1313                 :    21071107 :   if (!from
    1314                 :    21071107 :       || dest == old_dest
    1315                 :       56155 :       || !REG_P (dest)
    1316                 :    21127262 :       || !reg_overlap_mentioned_p (dest, from))
    1317                 :    21071105 :     return true;
    1318                 :             : 
    1319                 :           2 :   if (SUBREG_P (old_dest)
    1320                 :           2 :       && SUBREG_REG (old_dest) == dest
    1321                 :           4 :       && !read_modify_subreg_p (old_dest))
    1322                 :             :     return true;
    1323                 :             : 
    1324                 :           0 :   failure_reason = "is part of a read-write destination";
    1325                 :           0 :   return false;
    1326                 :             : }
    1327                 :             : 
    1328                 :             : /* Try to process the instruction pattern at *LOC.  Return true on success;
    1329                 :             :    leave the caller to clean up on failure.  */
    1330                 :             : 
    1331                 :             : bool
    1332                 :    27393077 : insn_propagation::apply_to_pattern_1 (rtx *loc)
    1333                 :             : {
    1334                 :    27393077 :   rtx body = *loc;
    1335                 :    27393077 :   switch (GET_CODE (body))
    1336                 :             :     {
    1337                 :           0 :     case COND_EXEC:
    1338                 :           0 :       return (apply_to_rvalue_1 (&COND_EXEC_TEST (body))
    1339                 :           0 :               && apply_to_pattern_1 (&COND_EXEC_CODE (body)));
    1340                 :             : 
    1341                 :             :     case PARALLEL:
    1342                 :      152283 :       for (int i = 0; i < XVECLEN (body, 0); ++i)
    1343                 :             :         {
    1344                 :      124423 :           rtx *subloc = &XVECEXP (body, 0, i);
    1345                 :      124423 :           if (GET_CODE (*subloc) == SET)
    1346                 :             :             {
    1347                 :       90461 :               if (!apply_to_lvalue_1 (SET_DEST (*subloc)))
    1348                 :             :                 return false;
    1349                 :             :               /* ASM_OPERANDS are shared between SETs in the same PARALLEL.
    1350                 :             :                  Only process them on the first iteration.  */
    1351                 :       61900 :               if ((i == 0 || GET_CODE (SET_SRC (*subloc)) != ASM_OPERANDS)
    1352                 :       90415 :                   && !apply_to_rvalue_1 (&SET_SRC (*subloc)))
    1353                 :             :                 return false;
    1354                 :             :             }
    1355                 :             :           else
    1356                 :             :             {
    1357                 :       33962 :               if (!apply_to_pattern_1 (subloc))
    1358                 :             :                 return false;
    1359                 :             :             }
    1360                 :             :         }
    1361                 :             :       return true;
    1362                 :             : 
    1363                 :           0 :     case ASM_OPERANDS:
    1364                 :           0 :       for (int i = 0, len = ASM_OPERANDS_INPUT_LENGTH (body); i < len; ++i)
    1365                 :           0 :         if (!apply_to_rvalue_1 (&ASM_OPERANDS_INPUT (body, i)))
    1366                 :             :           return false;
    1367                 :             :       return true;
    1368                 :             : 
    1369                 :       33962 :     case CLOBBER:
    1370                 :       33962 :       return apply_to_lvalue_1 (XEXP (body, 0));
    1371                 :             : 
    1372                 :    25060678 :     case SET:
    1373                 :    25060678 :       return (apply_to_lvalue_1 (SET_DEST (body))
    1374                 :    25060678 :               && apply_to_rvalue_1 (&SET_SRC (body)));
    1375                 :             : 
    1376                 :     2269876 :     default:
    1377                 :             :       /* All the other possibilities never store and can use a normal
    1378                 :             :          rtx walk.  This includes:
    1379                 :             : 
    1380                 :             :          - USE
    1381                 :             :          - TRAP_IF
    1382                 :             :          - PREFETCH
    1383                 :             :          - UNSPEC
    1384                 :             :          - UNSPEC_VOLATILE.  */
    1385                 :     2269876 :       return apply_to_rvalue_1 (loc);
    1386                 :             :     }
    1387                 :             : }
    1388                 :             : 
    1389                 :             : /* Apply this insn_propagation object's simplification or substitution
    1390                 :             :    to the instruction pattern at LOC.  */
    1391                 :             : 
    1392                 :             : bool
    1393                 :    27359115 : insn_propagation::apply_to_pattern (rtx *loc)
    1394                 :             : {
    1395                 :    27359115 :   unsigned int num_changes = num_validated_changes ();
    1396                 :    27359115 :   bool res = apply_to_pattern_1 (loc);
    1397                 :    27359115 :   if (!res)
    1398                 :     1534480 :     cancel_changes (num_changes);
    1399                 :    27359115 :   return res;
    1400                 :             : }
    1401                 :             : 
    1402                 :             : /* Apply this insn_propagation object's simplification or substitution
    1403                 :             :    to the rvalue expression at LOC.  */
    1404                 :             : 
    1405                 :             : bool
    1406                 :     5124523 : insn_propagation::apply_to_rvalue (rtx *loc)
    1407                 :             : {
    1408                 :     5124523 :   unsigned int num_changes = num_validated_changes ();
    1409                 :     5124523 :   bool res = apply_to_rvalue_1 (loc);
    1410                 :     5124523 :   if (!res)
    1411                 :       17449 :     cancel_changes (num_changes);
    1412                 :     5124523 :   return res;
    1413                 :             : }
    1414                 :             : 
    1415                 :             : /* Check whether INSN matches a specific alternative of an .md pattern.  */
    1416                 :             : 
    1417                 :             : bool
    1418                 :           0 : valid_insn_p (rtx_insn *insn)
    1419                 :             : {
    1420                 :           0 :   recog_memoized (insn);
    1421                 :           0 :   if (INSN_CODE (insn) < 0)
    1422                 :             :     return false;
    1423                 :           0 :   extract_insn (insn);
    1424                 :             :   /* We don't know whether the insn will be in code that is optimized
    1425                 :             :      for size or speed, so consider all enabled alternatives.  */
    1426                 :           0 :   if (!constrain_operands (1, get_enabled_alternatives (insn)))
    1427                 :             :     return false;
    1428                 :             :   return true;
    1429                 :             : }
    1430                 :             : 
    1431                 :             : /* Return true if OP is a valid general operand for machine mode MODE.
    1432                 :             :    This is either a register reference, a memory reference,
    1433                 :             :    or a constant.  In the case of a memory reference, the address
    1434                 :             :    is checked for general validity for the target machine.
    1435                 :             : 
    1436                 :             :    Register and memory references must have mode MODE in order to be valid,
    1437                 :             :    but some constants have no machine mode and are valid for any mode.
    1438                 :             : 
    1439                 :             :    If MODE is VOIDmode, OP is checked for validity for whatever mode
    1440                 :             :    it has.
    1441                 :             : 
    1442                 :             :    The main use of this function is as a predicate in match_operand
    1443                 :             :    expressions in the machine description.  */
    1444                 :             : 
    1445                 :             : bool
    1446                 :  3507088354 : general_operand (rtx op, machine_mode mode)
    1447                 :             : {
    1448                 :  3507088354 :   enum rtx_code code = GET_CODE (op);
    1449                 :             : 
    1450                 :  3507088354 :   if (mode == VOIDmode)
    1451                 :  1143606297 :     mode = GET_MODE (op);
    1452                 :             : 
    1453                 :             :   /* Don't accept CONST_INT or anything similar
    1454                 :             :      if the caller wants something floating.  */
    1455                 :  3507088354 :   if (GET_MODE (op) == VOIDmode && mode != VOIDmode
    1456                 :   107816921 :       && GET_MODE_CLASS (mode) != MODE_INT
    1457                 :        2064 :       && GET_MODE_CLASS (mode) != MODE_PARTIAL_INT)
    1458                 :             :     return false;
    1459                 :             : 
    1460                 :  3507086290 :   if (CONST_INT_P (op)
    1461                 :   152546769 :       && mode != VOIDmode
    1462                 :  3612100110 :       && trunc_int_for_mode (INTVAL (op), mode) != INTVAL (op))
    1463                 :             :     return false;
    1464                 :             : 
    1465                 :  3507086183 :   if (CONSTANT_P (op))
    1466                 :    36348502 :     return ((GET_MODE (op) == VOIDmode || GET_MODE (op) == mode
    1467                 :        7084 :              || mode == VOIDmode)
    1468                 :   189197193 :             && (! flag_pic || LEGITIMATE_PIC_OPERAND_P (op))
    1469                 :   425462942 :             && targetm.legitimate_constant_p (mode == VOIDmode
    1470                 :    47595349 :                                               ? GET_MODE (op)
    1471                 :             :                                               : mode, op));
    1472                 :             : 
    1473                 :             :   /* Except for certain constants with VOIDmode, already checked for,
    1474                 :             :      OP's mode must match MODE if MODE specifies a mode.  */
    1475                 :             : 
    1476                 :  3317881906 :   if (GET_MODE (op) != mode)
    1477                 :             :     return false;
    1478                 :             : 
    1479                 :  3266417682 :   if (code == SUBREG)
    1480                 :             :     {
    1481                 :    17420524 :       rtx sub = SUBREG_REG (op);
    1482                 :             : 
    1483                 :             : #ifdef INSN_SCHEDULING
    1484                 :             :       /* On machines that have insn scheduling, we want all memory
    1485                 :             :          reference to be explicit, so outlaw paradoxical SUBREGs.
    1486                 :             :          However, we must allow them after reload so that they can
    1487                 :             :          get cleaned up by cleanup_subreg_operands.  */
    1488                 :    17375432 :       if (!reload_completed && MEM_P (sub)
    1489                 :    17447679 :           && paradoxical_subreg_p (op))
    1490                 :             :         return false;
    1491                 :             : #endif
    1492                 :             :       /* Avoid memories with nonzero SUBREG_BYTE, as offsetting the memory
    1493                 :             :          may result in incorrect reference.  We should simplify all valid
    1494                 :             :          subregs of MEM anyway.  But allow this after reload because we
    1495                 :             :          might be called from cleanup_subreg_operands.
    1496                 :             : 
    1497                 :             :          ??? This is a kludge.  */
    1498                 :    17393473 :       if (!reload_completed
    1499                 :    17348381 :           && maybe_ne (SUBREG_BYTE (op), 0)
    1500                 :    19615899 :           && MEM_P (sub))
    1501                 :             :         return false;
    1502                 :             : 
    1503                 :    17393473 :       if (REG_P (sub)
    1504                 :    16137031 :           && REGNO (sub) < FIRST_PSEUDO_REGISTER
    1505                 :        4082 :           && !REG_CAN_CHANGE_MODE_P (REGNO (sub), GET_MODE (sub), mode)
    1506                 :           0 :           && GET_MODE_CLASS (GET_MODE (sub)) != MODE_COMPLEX_INT
    1507                 :           0 :           && GET_MODE_CLASS (GET_MODE (sub)) != MODE_COMPLEX_FLOAT
    1508                 :             :           /* LRA can generate some invalid SUBREGS just for matched
    1509                 :             :              operand reload presentation.  LRA needs to treat them as
    1510                 :             :              valid.  */
    1511                 :    17393473 :           && ! LRA_SUBREG_P (op))
    1512                 :             :         return false;
    1513                 :             : 
    1514                 :             :       /* FLOAT_MODE subregs can't be paradoxical.  Combine will occasionally
    1515                 :             :          create such rtl, and we must reject it.  */
    1516                 :    17393473 :       if (SCALAR_FLOAT_MODE_P (GET_MODE (op))
    1517                 :             :           /* LRA can use subreg to store a floating point value in an
    1518                 :             :              integer mode.  Although the floating point and the
    1519                 :             :              integer modes need the same number of hard registers, the
    1520                 :             :              size of floating point mode can be less than the integer
    1521                 :             :              mode.  */
    1522                 :      148620 :           && ! lra_in_progress 
    1523                 :    17528806 :           && paradoxical_subreg_p (op))
    1524                 :             :         return false;
    1525                 :             : 
    1526                 :    17393473 :       op = sub;
    1527                 :    17393473 :       code = GET_CODE (op);
    1528                 :             :     }
    1529                 :             : 
    1530                 :  3266390631 :   if (code == REG)
    1531                 :  2658833680 :     return (REGNO (op) >= FIRST_PSEUDO_REGISTER
    1532                 :  2658833680 :             || in_hard_reg_set_p (operand_reg_set, GET_MODE (op), REGNO (op)));
    1533                 :             : 
    1534                 :   607556951 :   if (code == MEM)
    1535                 :             :     {
    1536                 :   535235194 :       rtx y = XEXP (op, 0);
    1537                 :             : 
    1538                 :   535235194 :       if (! volatile_ok && MEM_VOLATILE_P (op))
    1539                 :             :         return false;
    1540                 :             : 
    1541                 :             :       /* Use the mem's mode, since it will be reloaded thus.  LRA can
    1542                 :             :          generate move insn with invalid addresses which is made valid
    1543                 :             :          and efficiently calculated by LRA through further numerous
    1544                 :             :          transformations.  */
    1545                 :   534594769 :       if (lra_in_progress
    1546                 :   581484411 :           || memory_address_addr_space_p (GET_MODE (op), y, MEM_ADDR_SPACE (op)))
    1547                 :   517611348 :         return true;
    1548                 :             :     }
    1549                 :             : 
    1550                 :             :   return false;
    1551                 :             : }
    1552                 :             : 
    1553                 :             : /* Return true if OP is a valid memory address for a memory reference
    1554                 :             :    of mode MODE.
    1555                 :             : 
    1556                 :             :    The main use of this function is as a predicate in match_operand
    1557                 :             :    expressions in the machine description.  */
    1558                 :             : 
    1559                 :             : bool
    1560                 :    83829587 : address_operand (rtx op, machine_mode mode)
    1561                 :             : {
    1562                 :             :   /* Wrong mode for an address expr.  */
    1563                 :    83829587 :   if (GET_MODE (op) != VOIDmode
    1564                 :    77656181 :       && ! SCALAR_INT_MODE_P (GET_MODE (op)))
    1565                 :             :     return false;
    1566                 :             : 
    1567                 :    83236927 :   return memory_address_p (mode, op);
    1568                 :             : }
    1569                 :             : 
    1570                 :             : /* Return true if OP is a register reference of mode MODE.
    1571                 :             :    If MODE is VOIDmode, accept a register in any mode.
    1572                 :             : 
    1573                 :             :    The main use of this function is as a predicate in match_operand
    1574                 :             :    expressions in the machine description.  */
    1575                 :             : 
    1576                 :             : bool
    1577                 :  2149863936 : register_operand (rtx op, machine_mode mode)
    1578                 :             : {
    1579                 :  2149863936 :   if (GET_CODE (op) == SUBREG)
    1580                 :             :     {
    1581                 :     6791524 :       rtx sub = SUBREG_REG (op);
    1582                 :             : 
    1583                 :             :       /* Before reload, we can allow (SUBREG (MEM...)) as a register operand
    1584                 :             :          because it is guaranteed to be reloaded into one.
    1585                 :             :          Just make sure the MEM is valid in itself.
    1586                 :             :          (Ideally, (SUBREG (MEM)...) should not exist after reload,
    1587                 :             :          but currently it does result from (SUBREG (REG)...) where the
    1588                 :             :          reg went on the stack.)  */
    1589                 :     6791524 :       if (!REG_P (sub) && (reload_completed || !MEM_P (sub)))
    1590                 :             :         return false;
    1591                 :             :     }
    1592                 :  2143072412 :   else if (!REG_P (op))
    1593                 :             :     return false;
    1594                 :  1617801816 :   return general_operand (op, mode);
    1595                 :             : }
    1596                 :             : 
    1597                 :             : /* Return true for a register in Pmode; ignore the tested mode.  */
    1598                 :             : 
    1599                 :             : bool
    1600                 :           0 : pmode_register_operand (rtx op, machine_mode mode ATTRIBUTE_UNUSED)
    1601                 :             : {
    1602                 :           0 :   return register_operand (op, Pmode);
    1603                 :             : }
    1604                 :             : 
    1605                 :             : /* Return true if OP should match a MATCH_SCRATCH, i.e., if it is a SCRATCH
    1606                 :             :    or a hard register.  */
    1607                 :             : 
    1608                 :             : bool
    1609                 :      208895 : scratch_operand (rtx op, machine_mode mode)
    1610                 :             : {
    1611                 :      208895 :   if (GET_MODE (op) != mode && mode != VOIDmode)
    1612                 :             :     return false;
    1613                 :             : 
    1614                 :      201222 :   return (GET_CODE (op) == SCRATCH
    1615                 :      201222 :           || (REG_P (op)
    1616                 :       44456 :               && (lra_in_progress
    1617                 :       33026 :                   || (REGNO (op) < FIRST_PSEUDO_REGISTER
    1618                 :       31842 :                       && REGNO_REG_CLASS (REGNO (op)) != NO_REGS))));
    1619                 :             : }
    1620                 :             : 
    1621                 :             : /* Return true if OP is a valid immediate operand for mode MODE.
    1622                 :             : 
    1623                 :             :    The main use of this function is as a predicate in match_operand
    1624                 :             :    expressions in the machine description.  */
    1625                 :             : 
    1626                 :             : bool
    1627                 :   387623850 : immediate_operand (rtx op, machine_mode mode)
    1628                 :             : {
    1629                 :             :   /* Don't accept CONST_INT or anything similar
    1630                 :             :      if the caller wants something floating.  */
    1631                 :   387623850 :   if (GET_MODE (op) == VOIDmode && mode != VOIDmode
    1632                 :    71744034 :       && GET_MODE_CLASS (mode) != MODE_INT
    1633                 :           0 :       && GET_MODE_CLASS (mode) != MODE_PARTIAL_INT)
    1634                 :             :     return false;
    1635                 :             : 
    1636                 :   387623850 :   if (CONST_INT_P (op)
    1637                 :   256900284 :       && mode != VOIDmode
    1638                 :   456508345 :       && trunc_int_for_mode (INTVAL (op), mode) != INTVAL (op))
    1639                 :             :     return false;
    1640                 :             : 
    1641                 :   387449893 :   return (CONSTANT_P (op)
    1642                 :   310412238 :           && (GET_MODE (op) == mode || mode == VOIDmode
    1643                 :    72681533 :               || GET_MODE (op) == VOIDmode)
    1644                 :   308278890 :           && (! flag_pic || LEGITIMATE_PIC_OPERAND_P (op))
    1645                 :   911717372 :           && targetm.legitimate_constant_p (mode == VOIDmode
    1646                 :   219672107 :                                             ? GET_MODE (op)
    1647                 :             :                                             : mode, op));
    1648                 :             : }
    1649                 :             : 
    1650                 :             : /* Return true if OP is an operand that is a CONST_INT of mode MODE.  */
    1651                 :             : 
    1652                 :             : bool
    1653                 :    27142551 : const_int_operand (rtx op, machine_mode mode)
    1654                 :             : {
    1655                 :    27142551 :   if (!CONST_INT_P (op))
    1656                 :             :     return false;
    1657                 :             : 
    1658                 :    21923171 :   if (mode != VOIDmode
    1659                 :    21923171 :       && trunc_int_for_mode (INTVAL (op), mode) != INTVAL (op))
    1660                 :             :     return false;
    1661                 :             : 
    1662                 :             :   return true;
    1663                 :             : }
    1664                 :             : 
    1665                 :             : #if TARGET_SUPPORTS_WIDE_INT
    1666                 :             : /* Return true if OP is an operand that is a CONST_INT or CONST_WIDE_INT
    1667                 :             :    of mode MODE.  */
    1668                 :             : bool
    1669                 :     1040952 : const_scalar_int_operand (rtx op, machine_mode mode)
    1670                 :             : {
    1671                 :     1040952 :   if (!CONST_SCALAR_INT_P (op))
    1672                 :             :     return false;
    1673                 :             : 
    1674                 :      716660 :   if (CONST_INT_P (op))
    1675                 :      117243 :     return const_int_operand (op, mode);
    1676                 :             : 
    1677                 :      599417 :   if (mode != VOIDmode)
    1678                 :             :     {
    1679                 :      599417 :       scalar_int_mode int_mode = as_a <scalar_int_mode> (mode);
    1680                 :      599417 :       int prec = GET_MODE_PRECISION (int_mode);
    1681                 :      599417 :       int bitsize = GET_MODE_BITSIZE (int_mode);
    1682                 :             : 
    1683                 :      599417 :       if (CONST_WIDE_INT_NUNITS (op) * HOST_BITS_PER_WIDE_INT > bitsize)
    1684                 :             :         return false;
    1685                 :             : 
    1686                 :      599417 :       if (prec == bitsize)
    1687                 :             :         return true;
    1688                 :             :       else
    1689                 :             :         {
    1690                 :             :           /* Multiword partial int.  */
    1691                 :        4924 :           HOST_WIDE_INT x
    1692                 :        4924 :             = CONST_WIDE_INT_ELT (op, CONST_WIDE_INT_NUNITS (op) - 1);
    1693                 :        4924 :           return (sext_hwi (x, prec & (HOST_BITS_PER_WIDE_INT - 1)) == x);
    1694                 :             :         }
    1695                 :             :     }
    1696                 :             :   return true;
    1697                 :             : }
    1698                 :             : 
    1699                 :             : /* Return true if OP is an operand that is a constant integer or constant
    1700                 :             :    floating-point number of MODE.  */
    1701                 :             : 
    1702                 :             : bool
    1703                 :           0 : const_double_operand (rtx op, machine_mode mode)
    1704                 :             : {
    1705                 :           0 :   return (GET_CODE (op) == CONST_DOUBLE)
    1706                 :           0 :           && (GET_MODE (op) == mode || mode == VOIDmode);
    1707                 :             : }
    1708                 :             : #else
    1709                 :             : /* Return true if OP is an operand that is a constant integer or constant
    1710                 :             :    floating-point number of MODE.  */
    1711                 :             : 
    1712                 :             : bool
    1713                 :             : const_double_operand (rtx op, machine_mode mode)
    1714                 :             : {
    1715                 :             :   /* Don't accept CONST_INT or anything similar
    1716                 :             :      if the caller wants something floating.  */
    1717                 :             :   if (GET_MODE (op) == VOIDmode && mode != VOIDmode
    1718                 :             :       && GET_MODE_CLASS (mode) != MODE_INT
    1719                 :             :       && GET_MODE_CLASS (mode) != MODE_PARTIAL_INT)
    1720                 :             :     return false;
    1721                 :             : 
    1722                 :             :   return ((CONST_DOUBLE_P (op) || CONST_INT_P (op))
    1723                 :             :           && (mode == VOIDmode || GET_MODE (op) == mode
    1724                 :             :               || GET_MODE (op) == VOIDmode));
    1725                 :             : }
    1726                 :             : #endif
    1727                 :             : /* Return true if OP is a general operand that is not an immediate
    1728                 :             :    operand of mode MODE.  */
    1729                 :             : 
    1730                 :             : bool
    1731                 :  1086071021 : nonimmediate_operand (rtx op, machine_mode mode)
    1732                 :             : {
    1733                 :  1086071021 :   return (general_operand (op, mode) && ! CONSTANT_P (op));
    1734                 :             : }
    1735                 :             : 
    1736                 :             : /* Return true if OP is a register reference or
    1737                 :             :    immediate value of mode MODE.  */
    1738                 :             : 
    1739                 :             : bool
    1740                 :   478671631 : nonmemory_operand (rtx op, machine_mode mode)
    1741                 :             : {
    1742                 :   478671631 :   if (CONSTANT_P (op))
    1743                 :    16913918 :     return immediate_operand (op, mode);
    1744                 :   461757713 :   return register_operand (op, mode);
    1745                 :             : }
    1746                 :             : 
    1747                 :             : /* Return true if OP is a valid operand that stands for pushing a
    1748                 :             :    value of mode MODE onto the stack.
    1749                 :             : 
    1750                 :             :    The main use of this function is as a predicate in match_operand
    1751                 :             :    expressions in the machine description.  */
    1752                 :             : 
    1753                 :             : bool
    1754                 :   609071606 : push_operand (rtx op, machine_mode mode)
    1755                 :             : {
    1756                 :   609071606 :   if (!MEM_P (op))
    1757                 :             :     return false;
    1758                 :             : 
    1759                 :   190340039 :   if (mode != VOIDmode && GET_MODE (op) != mode)
    1760                 :             :     return false;
    1761                 :             : 
    1762                 :   357043174 :   poly_int64 rounded_size = GET_MODE_SIZE (mode);
    1763                 :             : 
    1764                 :             : #ifdef PUSH_ROUNDING
    1765                 :   178521587 :   rounded_size = PUSH_ROUNDING (MACRO_INT (rounded_size));
    1766                 :             : #endif
    1767                 :             : 
    1768                 :   178521587 :   op = XEXP (op, 0);
    1769                 :             : 
    1770                 :   357043174 :   if (known_eq (rounded_size, GET_MODE_SIZE (mode)))
    1771                 :             :     {
    1772                 :   153679544 :       if (GET_CODE (op) != STACK_PUSH_CODE)
    1773                 :             :         return false;
    1774                 :             :     }
    1775                 :             :   else
    1776                 :             :     {
    1777                 :    24842043 :       poly_int64 offset;
    1778                 :    24842043 :       if (GET_CODE (op) != PRE_MODIFY
    1779                 :      864368 :           || GET_CODE (XEXP (op, 1)) != PLUS
    1780                 :      864368 :           || XEXP (XEXP (op, 1), 0) != XEXP (op, 0)
    1781                 :      864368 :           || !poly_int_rtx_p (XEXP (XEXP (op, 1), 1), &offset)
    1782                 :    24842043 :           || (STACK_GROWS_DOWNWARD
    1783                 :      864368 :               ? maybe_ne (offset, -rounded_size)
    1784                 :             :               : maybe_ne (offset, rounded_size)))
    1785                 :   575676615 :         return false;
    1786                 :             :     }
    1787                 :             : 
    1788                 :    33394991 :   return XEXP (op, 0) == stack_pointer_rtx;
    1789                 :             : }
    1790                 :             : 
    1791                 :             : /* Return true if OP is a valid operand that stands for popping a
    1792                 :             :    value of mode MODE off the stack.
    1793                 :             : 
    1794                 :             :    The main use of this function is as a predicate in match_operand
    1795                 :             :    expressions in the machine description.  */
    1796                 :             : 
    1797                 :             : bool
    1798                 :   126806885 : pop_operand (rtx op, machine_mode mode)
    1799                 :             : {
    1800                 :   126806885 :   if (!MEM_P (op))
    1801                 :             :     return false;
    1802                 :             : 
    1803                 :    36002152 :   if (mode != VOIDmode && GET_MODE (op) != mode)
    1804                 :             :     return false;
    1805                 :             : 
    1806                 :    36002152 :   op = XEXP (op, 0);
    1807                 :             : 
    1808                 :    36002152 :   if (GET_CODE (op) != STACK_POP_CODE)
    1809                 :             :     return false;
    1810                 :             : 
    1811                 :     1681284 :   return XEXP (op, 0) == stack_pointer_rtx;
    1812                 :             : }
    1813                 :             : 
    1814                 :             : /* Return true if ADDR is a valid memory address
    1815                 :             :    for mode MODE in address space AS.  */
    1816                 :             : 
    1817                 :             : bool
    1818                 :  1167177453 : memory_address_addr_space_p (machine_mode mode ATTRIBUTE_UNUSED, rtx addr,
    1819                 :             :                              addr_space_t as, code_helper ch ATTRIBUTE_UNUSED)
    1820                 :             : {
    1821                 :             : #ifdef GO_IF_LEGITIMATE_ADDRESS
    1822                 :             :   gcc_assert (ADDR_SPACE_GENERIC_P (as));
    1823                 :             :   GO_IF_LEGITIMATE_ADDRESS (mode, addr, win);
    1824                 :             :   return false;
    1825                 :             : 
    1826                 :             :  win:
    1827                 :             :   return true;
    1828                 :             : #else
    1829                 :  1167177453 :   return targetm.addr_space.legitimate_address_p (mode, addr, 0, as, ch);
    1830                 :             : #endif
    1831                 :             : }
    1832                 :             : 
    1833                 :             : /* Return true if OP is a valid memory reference with mode MODE,
    1834                 :             :    including a valid address.
    1835                 :             : 
    1836                 :             :    The main use of this function is as a predicate in match_operand
    1837                 :             :    expressions in the machine description.  */
    1838                 :             : 
    1839                 :             : bool
    1840                 :  1121184542 : memory_operand (rtx op, machine_mode mode)
    1841                 :             : {
    1842                 :  1121184542 :   rtx inner;
    1843                 :             : 
    1844                 :  1121184542 :   if (! reload_completed)
    1845                 :             :     /* Note that no SUBREG is a memory operand before end of reload pass,
    1846                 :             :        because (SUBREG (MEM...)) forces reloading into a register.  */
    1847                 :    89944924 :     return MEM_P (op) && general_operand (op, mode);
    1848                 :             : 
    1849                 :  1031239618 :   if (mode != VOIDmode && GET_MODE (op) != mode)
    1850                 :             :     return false;
    1851                 :             : 
    1852                 :   757575679 :   inner = op;
    1853                 :   757575679 :   if (GET_CODE (inner) == SUBREG)
    1854                 :        8675 :     inner = SUBREG_REG (inner);
    1855                 :             : 
    1856                 :   757575679 :   return (MEM_P (inner) && general_operand (op, mode));
    1857                 :             : }
    1858                 :             : 
    1859                 :             : /* Return true if OP is a valid indirect memory reference with mode MODE;
    1860                 :             :    that is, a memory reference whose address is a general_operand.  */
    1861                 :             : 
    1862                 :             : bool
    1863                 :           0 : indirect_operand (rtx op, machine_mode mode)
    1864                 :             : {
    1865                 :             :   /* Before reload, a SUBREG isn't in memory (see memory_operand, above).  */
    1866                 :           0 :   if (! reload_completed
    1867                 :           0 :       && GET_CODE (op) == SUBREG && MEM_P (SUBREG_REG (op)))
    1868                 :             :     {
    1869                 :           0 :       if (mode != VOIDmode && GET_MODE (op) != mode)
    1870                 :             :         return false;
    1871                 :             : 
    1872                 :             :       /* The only way that we can have a general_operand as the resulting
    1873                 :             :          address is if OFFSET is zero and the address already is an operand
    1874                 :             :          or if the address is (plus Y (const_int -OFFSET)) and Y is an
    1875                 :             :          operand.  */
    1876                 :           0 :       poly_int64 offset;
    1877                 :           0 :       rtx addr = strip_offset (XEXP (SUBREG_REG (op), 0), &offset);
    1878                 :           0 :       return (known_eq (offset + SUBREG_BYTE (op), 0)
    1879                 :           0 :               && general_operand (addr, Pmode));
    1880                 :             :     }
    1881                 :             : 
    1882                 :           0 :   return (MEM_P (op)
    1883                 :           0 :           && memory_operand (op, mode)
    1884                 :           0 :           && general_operand (XEXP (op, 0), Pmode));
    1885                 :             : }
    1886                 :             : 
    1887                 :             : /* Return true if this is an ordered comparison operator (not including
    1888                 :             :    ORDERED and UNORDERED).  */
    1889                 :             : 
    1890                 :             : bool
    1891                 :    24652895 : ordered_comparison_operator (rtx op, machine_mode mode)
    1892                 :             : {
    1893                 :    24652895 :   if (mode != VOIDmode && GET_MODE (op) != mode)
    1894                 :             :     return false;
    1895                 :    24652895 :   switch (GET_CODE (op))
    1896                 :             :     {
    1897                 :             :     case EQ:
    1898                 :             :     case NE:
    1899                 :             :     case LT:
    1900                 :             :     case LTU:
    1901                 :             :     case LE:
    1902                 :             :     case LEU:
    1903                 :             :     case GT:
    1904                 :             :     case GTU:
    1905                 :             :     case GE:
    1906                 :             :     case GEU:
    1907                 :             :       return true;
    1908                 :             :     default:
    1909                 :             :       return false;
    1910                 :             :     }
    1911                 :             : }
    1912                 :             : 
    1913                 :             : /* Return true if this is a comparison operator.  This allows the use of
    1914                 :             :    MATCH_OPERATOR to recognize all the branch insns.  */
    1915                 :             : 
    1916                 :             : bool
    1917                 :    58465018 : comparison_operator (rtx op, machine_mode mode)
    1918                 :             : {
    1919                 :     1776460 :   return ((mode == VOIDmode || GET_MODE (op) == mode)
    1920                 :    59995416 :           && COMPARISON_P (op));
    1921                 :             : }
    1922                 :             : 
    1923                 :             : /* If BODY is an insn body that uses ASM_OPERANDS, return it.  */
    1924                 :             : 
    1925                 :             : rtx
    1926                 :  1544200096 : extract_asm_operands (rtx body)
    1927                 :             : {
    1928                 :  1544200096 :   rtx tmp;
    1929                 :  1544200096 :   switch (GET_CODE (body))
    1930                 :             :     {
    1931                 :             :     case ASM_OPERANDS:
    1932                 :             :       return body;
    1933                 :             : 
    1934                 :  1200124762 :     case SET:
    1935                 :             :       /* Single output operand: BODY is (set OUTPUT (asm_operands ...)).  */
    1936                 :  1200124762 :       tmp = SET_SRC (body);
    1937                 :  1200124762 :       if (GET_CODE (tmp) == ASM_OPERANDS)
    1938                 :             :         return tmp;
    1939                 :             :       break;
    1940                 :             : 
    1941                 :   271001018 :     case PARALLEL:
    1942                 :   271001018 :       tmp = XVECEXP (body, 0, 0);
    1943                 :   271001018 :       if (GET_CODE (tmp) == ASM_OPERANDS)
    1944                 :             :         return tmp;
    1945                 :   269058025 :       if (GET_CODE (tmp) == SET)
    1946                 :             :         {
    1947                 :   265586323 :           tmp = SET_SRC (tmp);
    1948                 :   265586323 :           if (GET_CODE (tmp) == ASM_OPERANDS)
    1949                 :             :             return tmp;
    1950                 :             :         }
    1951                 :             :       break;
    1952                 :             : 
    1953                 :             :     default:
    1954                 :             :       break;
    1955                 :             :     }
    1956                 :  1539237586 :   return NULL;
    1957                 :             : }
    1958                 :             : 
    1959                 :             : /* If BODY is an insn body that uses ASM_OPERANDS,
    1960                 :             :    return the number of operands (both input and output) in the insn.
    1961                 :             :    If BODY is an insn body that uses ASM_INPUT with CLOBBERS in PARALLEL,
    1962                 :             :    return 0.
    1963                 :             :    Otherwise return -1.  */
    1964                 :             : 
    1965                 :             : int
    1966                 :  1117908824 : asm_noperands (const_rtx body)
    1967                 :             : {
    1968                 :  1117908824 :   rtx asm_op = extract_asm_operands (CONST_CAST_RTX (body));
    1969                 :  1117908824 :   int i, n_sets = 0;
    1970                 :             : 
    1971                 :  1117908824 :   if (asm_op == NULL)
    1972                 :             :     {
    1973                 :  1113806972 :       if (GET_CODE (body) == PARALLEL && XVECLEN (body, 0) >= 2
    1974                 :   188838512 :           && GET_CODE (XVECEXP (body, 0, 0)) == ASM_INPUT)
    1975                 :             :         {
    1976                 :             :           /* body is [(asm_input ...) (clobber (reg ...))...].  */
    1977                 :       45765 :           for (i = XVECLEN (body, 0) - 1; i > 0; i--)
    1978                 :       30510 :             if (GET_CODE (XVECEXP (body, 0, i)) != CLOBBER)
    1979                 :             :               return -1;
    1980                 :             :           return 0;
    1981                 :             :         }
    1982                 :             :       return -1;
    1983                 :             :     }
    1984                 :             : 
    1985                 :     4101852 :   if (GET_CODE (body) == SET)
    1986                 :             :     n_sets = 1;
    1987                 :     4081218 :   else if (GET_CODE (body) == PARALLEL)
    1988                 :             :     {
    1989                 :     4071296 :       if (GET_CODE (XVECEXP (body, 0, 0)) == SET)
    1990                 :             :         {
    1991                 :             :           /* Multiple output operands, or 1 output plus some clobbers:
    1992                 :             :              body is
    1993                 :             :              [(set OUTPUT (asm_operands ...))...
    1994                 :             :               (use (reg ...))...
    1995                 :             :               (clobber (reg ...))...].  */
    1996                 :             :           /* Count backwards through USEs and CLOBBERs to determine
    1997                 :             :              number of SETs.  */
    1998                 :     5212718 :           for (i = XVECLEN (body, 0); i > 0; i--)
    1999                 :             :             {
    2000                 :     5212718 :               if (GET_CODE (XVECEXP (body, 0, i - 1)) == SET)
    2001                 :             :                 break;
    2002                 :     2768205 :               if (GET_CODE (XVECEXP (body, 0, i - 1)) != USE
    2003                 :     2768205 :                   && GET_CODE (XVECEXP (body, 0, i - 1)) != CLOBBER)
    2004                 :             :                 return -1;
    2005                 :             :             }
    2006                 :             : 
    2007                 :             :           /* N_SETS is now number of output operands.  */
    2008                 :     9754314 :           n_sets = i;
    2009                 :             : 
    2010                 :             :           /* Verify that all the SETs we have
    2011                 :             :              came from a single original asm_operands insn
    2012                 :             :              (so that invalid combinations are blocked).  */
    2013                 :     9754314 :           for (i = 0; i < n_sets; i++)
    2014                 :             :             {
    2015                 :     7375540 :               rtx elt = XVECEXP (body, 0, i);
    2016                 :     7375540 :               if (GET_CODE (elt) != SET)
    2017                 :             :                 return -1;
    2018                 :     7369548 :               if (GET_CODE (SET_SRC (elt)) != ASM_OPERANDS)
    2019                 :             :                 return -1;
    2020                 :             :               /* If these ASM_OPERANDS rtx's came from different original insns
    2021                 :             :                  then they aren't allowed together.  */
    2022                 :     7351327 :               if (ASM_OPERANDS_INPUT_VEC (SET_SRC (elt))
    2023                 :     7351327 :                   != ASM_OPERANDS_INPUT_VEC (asm_op))
    2024                 :             :                 return -1;
    2025                 :             :             }
    2026                 :             :         }
    2027                 :             :       else
    2028                 :             :         {
    2029                 :             :           /* 0 outputs, but some clobbers:
    2030                 :             :              body is [(asm_operands ...)
    2031                 :             :                       (use (reg ...))...
    2032                 :             :                       (clobber (reg ...))...].  */
    2033                 :             :           /* Make sure all the other parallel things really are clobbers.  */
    2034                 :     5066151 :           for (i = XVECLEN (body, 0) - 1; i > 0; i--)
    2035                 :     3441640 :             if (GET_CODE (XVECEXP (body, 0, i)) != USE
    2036                 :     3441640 :                 && GET_CODE (XVECEXP (body, 0, i)) != CLOBBER)
    2037                 :             :               return -1;
    2038                 :             :         }
    2039                 :             :     }
    2040                 :             : 
    2041                 :     4033841 :   return (ASM_OPERANDS_INPUT_LENGTH (asm_op)
    2042                 :     4033841 :           + ASM_OPERANDS_LABEL_LENGTH (asm_op) + n_sets);
    2043                 :             : }
    2044                 :             : 
    2045                 :             : /* Assuming BODY is an insn body that uses ASM_OPERANDS,
    2046                 :             :    copy its operands (both input and output) into the vector OPERANDS,
    2047                 :             :    the locations of the operands within the insn into the vector OPERAND_LOCS,
    2048                 :             :    and the constraints for the operands into CONSTRAINTS.
    2049                 :             :    Write the modes of the operands into MODES.
    2050                 :             :    Write the location info into LOC.
    2051                 :             :    Return the assembler-template.
    2052                 :             :    If BODY is an insn body that uses ASM_INPUT with CLOBBERS in PARALLEL,
    2053                 :             :    return the basic assembly string.
    2054                 :             : 
    2055                 :             :    If LOC, MODES, OPERAND_LOCS, CONSTRAINTS or OPERANDS is 0,
    2056                 :             :    we don't store that info.  */
    2057                 :             : 
    2058                 :             : const char *
    2059                 :     1804827 : decode_asm_operands (rtx body, rtx *operands, rtx **operand_locs,
    2060                 :             :                      const char **constraints, machine_mode *modes,
    2061                 :             :                      location_t *loc)
    2062                 :             : {
    2063                 :     1804827 :   int nbase = 0, n, i;
    2064                 :     1804827 :   rtx asmop;
    2065                 :             : 
    2066                 :     1804827 :   switch (GET_CODE (body))
    2067                 :             :     {
    2068                 :             :     case ASM_OPERANDS:
    2069                 :             :       /* Zero output asm: BODY is (asm_operands ...).  */
    2070                 :             :       asmop = body;
    2071                 :             :       break;
    2072                 :             : 
    2073                 :       10140 :     case SET:
    2074                 :             :       /* Single output asm: BODY is (set OUTPUT (asm_operands ...)).  */
    2075                 :       10140 :       asmop = SET_SRC (body);
    2076                 :             : 
    2077                 :             :       /* The output is in the SET.
    2078                 :             :          Its constraint is in the ASM_OPERANDS itself.  */
    2079                 :       10140 :       if (operands)
    2080                 :       10030 :         operands[0] = SET_DEST (body);
    2081                 :       10140 :       if (operand_locs)
    2082                 :         430 :         operand_locs[0] = &SET_DEST (body);
    2083                 :       10140 :       if (constraints)
    2084                 :       10030 :         constraints[0] = ASM_OPERANDS_OUTPUT_CONSTRAINT (asmop);
    2085                 :       10140 :       if (modes)
    2086                 :         430 :         modes[0] = GET_MODE (SET_DEST (body));
    2087                 :             :       nbase = 1;
    2088                 :             :       break;
    2089                 :             : 
    2090                 :     1790519 :     case PARALLEL:
    2091                 :     1790519 :       {
    2092                 :     1790519 :         int nparallel = XVECLEN (body, 0); /* Includes CLOBBERs.  */
    2093                 :             : 
    2094                 :     1790519 :         asmop = XVECEXP (body, 0, 0);
    2095                 :     1790519 :         if (GET_CODE (asmop) == SET)
    2096                 :             :           {
    2097                 :      898035 :             asmop = SET_SRC (asmop);
    2098                 :             : 
    2099                 :             :             /* At least one output, plus some CLOBBERs.  The outputs are in
    2100                 :             :                the SETs.  Their constraints are in the ASM_OPERANDS itself.  */
    2101                 :     3405270 :             for (i = 0; i < nparallel; i++)
    2102                 :             :               {
    2103                 :     3379833 :                 if (GET_CODE (XVECEXP (body, 0, i)) == USE
    2104                 :     3379833 :                     || GET_CODE (XVECEXP (body, 0, i)) == CLOBBER)
    2105                 :             :                   break;                /* Past last SET */
    2106                 :     2507235 :                 gcc_assert (GET_CODE (XVECEXP (body, 0, i)) == SET);
    2107                 :     2507235 :                 if (operands)
    2108                 :     2309747 :                   operands[i] = SET_DEST (XVECEXP (body, 0, i));
    2109                 :     2507235 :                 if (operand_locs)
    2110                 :     1032004 :                   operand_locs[i] = &SET_DEST (XVECEXP (body, 0, i));
    2111                 :     2507235 :                 if (constraints)
    2112                 :     2323953 :                   constraints[i] = XSTR (SET_SRC (XVECEXP (body, 0, i)), 1);
    2113                 :     2507235 :                 if (modes)
    2114                 :     1032004 :                   modes[i] = GET_MODE (SET_DEST (XVECEXP (body, 0, i)));
    2115                 :             :               }
    2116                 :             :             nbase = i;
    2117                 :             :           }
    2118                 :      892484 :         else if (GET_CODE (asmop) == ASM_INPUT)
    2119                 :             :           {
    2120                 :        8206 :             if (loc)
    2121                 :           0 :               *loc = ASM_INPUT_SOURCE_LOCATION (asmop);
    2122                 :        8206 :             return XSTR (asmop, 0);
    2123                 :             :           }
    2124                 :             :         break;
    2125                 :             :       }
    2126                 :             : 
    2127                 :           0 :     default:
    2128                 :           0 :       gcc_unreachable ();
    2129                 :             :     }
    2130                 :             : 
    2131                 :     1796621 :   n = ASM_OPERANDS_INPUT_LENGTH (asmop);
    2132                 :     3292417 :   for (i = 0; i < n; i++)
    2133                 :             :     {
    2134                 :     1495796 :       if (operand_locs)
    2135                 :      683950 :         operand_locs[nbase + i] = &ASM_OPERANDS_INPUT (asmop, i);
    2136                 :     1495796 :       if (operands)
    2137                 :     1356793 :         operands[nbase + i] = ASM_OPERANDS_INPUT (asmop, i);
    2138                 :     1495796 :       if (constraints)
    2139                 :     1374197 :         constraints[nbase + i] = ASM_OPERANDS_INPUT_CONSTRAINT (asmop, i);
    2140                 :     1495796 :       if (modes)
    2141                 :      683950 :         modes[nbase + i] = ASM_OPERANDS_INPUT_MODE (asmop, i);
    2142                 :             :     }
    2143                 :     1796621 :   nbase += n;
    2144                 :             : 
    2145                 :     1796621 :   n = ASM_OPERANDS_LABEL_LENGTH (asmop);
    2146                 :     1811196 :   for (i = 0; i < n; i++)
    2147                 :             :     {
    2148                 :       14575 :       if (operand_locs)
    2149                 :        8322 :         operand_locs[nbase + i] = &ASM_OPERANDS_LABEL (asmop, i);
    2150                 :       14575 :       if (operands)
    2151                 :       13096 :         operands[nbase + i] = ASM_OPERANDS_LABEL (asmop, i);
    2152                 :       14575 :       if (constraints)
    2153                 :       13165 :         constraints[nbase + i] = "";
    2154                 :       14575 :       if (modes)
    2155                 :        8322 :         modes[nbase + i] = Pmode;
    2156                 :             :     }
    2157                 :             : 
    2158                 :     1796621 :   if (loc)
    2159                 :      112114 :     *loc = ASM_OPERANDS_SOURCE_LOCATION (asmop);
    2160                 :             : 
    2161                 :     1796621 :   return ASM_OPERANDS_TEMPLATE (asmop);
    2162                 :             : }
    2163                 :             : 
    2164                 :             : /* Parse inline assembly string STRING and determine which operands are
    2165                 :             :    referenced by % markers.  For the first NOPERANDS operands, set USED[I]
    2166                 :             :    to true if operand I is referenced.
    2167                 :             : 
    2168                 :             :    This is intended to distinguish barrier-like asms such as:
    2169                 :             : 
    2170                 :             :       asm ("" : "=m" (...));
    2171                 :             : 
    2172                 :             :    from real references such as:
    2173                 :             : 
    2174                 :             :       asm ("sw\t$0, %0" : "=m" (...));  */
    2175                 :             : 
    2176                 :             : void
    2177                 :           0 : get_referenced_operands (const char *string, bool *used,
    2178                 :             :                          unsigned int noperands)
    2179                 :             : {
    2180                 :           0 :   memset (used, 0, sizeof (bool) * noperands);
    2181                 :           0 :   const char *p = string;
    2182                 :           0 :   while (*p)
    2183                 :           0 :     switch (*p)
    2184                 :             :       {
    2185                 :           0 :       case '%':
    2186                 :           0 :         p += 1;
    2187                 :             :         /* A letter followed by a digit indicates an operand number.  */
    2188                 :           0 :         if (ISALPHA (p[0]) && ISDIGIT (p[1]))
    2189                 :           0 :           p += 1;
    2190                 :           0 :         if (ISDIGIT (*p))
    2191                 :             :           {
    2192                 :           0 :             char *endptr;
    2193                 :           0 :             unsigned long opnum = strtoul (p, &endptr, 10);
    2194                 :           0 :             if (endptr != p && opnum < noperands)
    2195                 :           0 :               used[opnum] = true;
    2196                 :           0 :             p = endptr;
    2197                 :             :           }
    2198                 :             :         else
    2199                 :           0 :           p += 1;
    2200                 :             :         break;
    2201                 :             : 
    2202                 :           0 :       default:
    2203                 :           0 :         p++;
    2204                 :           0 :         break;
    2205                 :             :       }
    2206                 :           0 : }
    2207                 :             : 
    2208                 :             : /* Check if an asm_operand matches its constraints.
    2209                 :             :    Return > 0 if ok, = 0 if bad, < 0 if inconclusive.  */
    2210                 :             : 
    2211                 :             : int
    2212                 :     2322303 : asm_operand_ok (rtx op, const char *constraint, const char **constraints)
    2213                 :             : {
    2214                 :     2322303 :   int result = 0;
    2215                 :     2322303 :   bool incdec_ok = false;
    2216                 :             : 
    2217                 :             :   /* Use constrain_operands after reload.  */
    2218                 :     2322303 :   gcc_assert (!reload_completed);
    2219                 :             : 
    2220                 :             :   /* Empty constraint string is the same as "X,...,X", i.e. X for as
    2221                 :             :      many alternatives as required to match the other operands.  */
    2222                 :     2322303 :   if (*constraint == '\0')
    2223                 :        1324 :     result = 1;
    2224                 :             : 
    2225                 :     6418957 :   while (*constraint)
    2226                 :             :     {
    2227                 :     4096656 :       enum constraint_num cn;
    2228                 :     4096656 :       char c = *constraint;
    2229                 :     4096656 :       int len;
    2230                 :     4096656 :       switch (c)
    2231                 :             :         {
    2232                 :        2890 :         case ',':
    2233                 :        2890 :           constraint++;
    2234                 :        2890 :           continue;
    2235                 :             : 
    2236                 :      415836 :         case '0': case '1': case '2': case '3': case '4':
    2237                 :      415836 :         case '5': case '6': case '7': case '8': case '9':
    2238                 :             :           /* If caller provided constraints pointer, look up
    2239                 :             :              the matching constraint.  Otherwise, our caller should have
    2240                 :             :              given us the proper matching constraint, but we can't
    2241                 :             :              actually fail the check if they didn't.  Indicate that
    2242                 :             :              results are inconclusive.  */
    2243                 :      415836 :           if (constraints)
    2244                 :             :             {
    2245                 :      415633 :               char *end;
    2246                 :      415633 :               unsigned long match;
    2247                 :             : 
    2248                 :      415633 :               match = strtoul (constraint, &end, 10);
    2249                 :      415633 :               if (!result)
    2250                 :      415497 :                 result = asm_operand_ok (op, constraints[match], NULL);
    2251                 :      415633 :               constraint = (const char *) end;
    2252                 :             :             }
    2253                 :             :           else
    2254                 :             :             {
    2255                 :         227 :               do
    2256                 :         227 :                 constraint++;
    2257                 :         227 :               while (ISDIGIT (*constraint));
    2258                 :         203 :               if (! result)
    2259                 :         176 :                 result = -1;
    2260                 :             :             }
    2261                 :      415836 :           continue;
    2262                 :             : 
    2263                 :             :           /* The rest of the compiler assumes that reloading the address
    2264                 :             :              of a MEM into a register will make it fit an 'o' constraint.
    2265                 :             :              That is, if it sees a MEM operand for an 'o' constraint,
    2266                 :             :              it assumes that (mem (base-reg)) will fit.
    2267                 :             : 
    2268                 :             :              That assumption fails on targets that don't have offsettable
    2269                 :             :              addresses at all.  We therefore need to treat 'o' asm
    2270                 :             :              constraints as a special case and only accept operands that
    2271                 :             :              are already offsettable, thus proving that at least one
    2272                 :             :              offsettable address exists.  */
    2273                 :          27 :         case 'o': /* offsettable */
    2274                 :          27 :           if (offsettable_nonstrict_memref_p (op))
    2275                 :     1497853 :             result = 1;
    2276                 :             :           break;
    2277                 :             : 
    2278                 :       36378 :         case 'g':
    2279                 :       36378 :           if (general_operand (op, VOIDmode))
    2280                 :     1497853 :             result = 1;
    2281                 :             :           break;
    2282                 :             : 
    2283                 :             :         case '<':
    2284                 :             :         case '>':
    2285                 :             :           /* ??? Before auto-inc-dec, auto inc/dec insns are not supposed
    2286                 :             :              to exist, excepting those that expand_call created.  Further,
    2287                 :             :              on some machines which do not have generalized auto inc/dec,
    2288                 :             :              an inc/dec is not a memory_operand.
    2289                 :             : 
    2290                 :             :              Match any memory and hope things are resolved after reload.  */
    2291                 :     3641525 :           incdec_ok = true;
    2292                 :             :           /* FALLTHRU */
    2293                 :     3641525 :         default:
    2294                 :     3641525 :           cn = lookup_constraint (constraint);
    2295                 :     3641525 :           rtx mem = NULL;
    2296                 :     3641525 :           switch (get_constraint_type (cn))
    2297                 :             :             {
    2298                 :     3592360 :             case CT_REGISTER:
    2299                 :     3592360 :               if (!result
    2300                 :     1827249 :                   && reg_class_for_constraint (cn) != NO_REGS
    2301                 :     1827249 :                   && GET_MODE (op) != BLKmode
    2302                 :     5419572 :                   && register_operand (op, VOIDmode))
    2303                 :             :                 result = 1;
    2304                 :             :               break;
    2305                 :             : 
    2306                 :           4 :             case CT_CONST_INT:
    2307                 :           4 :               if (!result
    2308                 :           4 :                   && CONST_INT_P (op)
    2309                 :           6 :                   && insn_const_int_ok_for_constraint (INTVAL (op), cn))
    2310                 :             :                 result = 1;
    2311                 :             :               break;
    2312                 :             : 
    2313                 :       41187 :             case CT_MEMORY:
    2314                 :       41187 :             case CT_RELAXED_MEMORY:
    2315                 :       41187 :               mem = op;
    2316                 :             :               /* Fall through.  */
    2317                 :       41187 :             case CT_SPECIAL_MEMORY:
    2318                 :             :               /* Every memory operand can be reloaded to fit.  */
    2319                 :       41187 :               if (!mem)
    2320                 :           0 :                 mem = extract_mem_from_operand (op);
    2321                 :       41187 :               result = result || memory_operand (mem, VOIDmode);
    2322                 :       41187 :               break;
    2323                 :             : 
    2324                 :          79 :             case CT_ADDRESS:
    2325                 :             :               /* Every address operand can be reloaded to fit.  */
    2326                 :          79 :               result = result || address_operand (op, VOIDmode);
    2327                 :          79 :               break;
    2328                 :             : 
    2329                 :        7895 :             case CT_FIXED_FORM:
    2330                 :        7895 :               result = result || constraint_satisfied_p (op, cn);
    2331                 :        7895 :               break;
    2332                 :             :             }
    2333                 :             :           break;
    2334                 :      418726 :         }
    2335                 :     3677930 :       len = CONSTRAINT_LEN (c, constraint);
    2336                 :     3678506 :       do
    2337                 :     3678506 :         constraint++;
    2338                 :     7356436 :       while (--len && *constraint && *constraint != ',');
    2339                 :     3677930 :       if (len)
    2340                 :             :         return 0;
    2341                 :             :     }
    2342                 :             : 
    2343                 :             :   /* For operands without < or > constraints reject side-effects.  */
    2344                 :             :   if (AUTO_INC_DEC && !incdec_ok && result && MEM_P (op))
    2345                 :             :     switch (GET_CODE (XEXP (op, 0)))
    2346                 :             :       {
    2347                 :             :       case PRE_INC:
    2348                 :             :       case POST_INC:
    2349                 :             :       case PRE_DEC:
    2350                 :             :       case POST_DEC:
    2351                 :             :       case PRE_MODIFY:
    2352                 :             :       case POST_MODIFY:
    2353                 :             :         return 0;
    2354                 :             :       default:
    2355                 :             :         break;
    2356                 :             :       }
    2357                 :             : 
    2358                 :             :   return result;
    2359                 :             : }
    2360                 :             : 
    2361                 :             : /* Given an rtx *P, if it is a sum containing an integer constant term,
    2362                 :             :    return the location (type rtx *) of the pointer to that constant term.
    2363                 :             :    Otherwise, return a null pointer.  */
    2364                 :             : 
    2365                 :             : rtx *
    2366                 :    39916491 : find_constant_term_loc (rtx *p)
    2367                 :             : {
    2368                 :    39916491 :   rtx *tem;
    2369                 :    39916491 :   enum rtx_code code = GET_CODE (*p);
    2370                 :             : 
    2371                 :             :   /* If *P IS such a constant term, P is its location.  */
    2372                 :             : 
    2373                 :    39916491 :   if (code == CONST_INT || code == SYMBOL_REF || code == LABEL_REF
    2374                 :    27969988 :       || code == CONST)
    2375                 :             :     return p;
    2376                 :             : 
    2377                 :             :   /* Otherwise, if not a sum, it has no constant term.  */
    2378                 :             : 
    2379                 :    27930525 :   if (GET_CODE (*p) != PLUS)
    2380                 :             :     return 0;
    2381                 :             : 
    2382                 :             :   /* If one of the summands is constant, return its location.  */
    2383                 :             : 
    2384                 :    13319957 :   if (XEXP (*p, 0) && CONSTANT_P (XEXP (*p, 0))
    2385                 :           0 :       && XEXP (*p, 1) && CONSTANT_P (XEXP (*p, 1)))
    2386                 :             :     return p;
    2387                 :             : 
    2388                 :             :   /* Otherwise, check each summand for containing a constant term.  */
    2389                 :             : 
    2390                 :    13319957 :   if (XEXP (*p, 0) != 0)
    2391                 :             :     {
    2392                 :    13319957 :       tem = find_constant_term_loc (&XEXP (*p, 0));
    2393                 :    13319957 :       if (tem != 0)
    2394                 :             :         return tem;
    2395                 :             :     }
    2396                 :             : 
    2397                 :    13319957 :   if (XEXP (*p, 1) != 0)
    2398                 :             :     {
    2399                 :    13319957 :       tem = find_constant_term_loc (&XEXP (*p, 1));
    2400                 :    13319957 :       if (tem != 0)
    2401                 :             :         return tem;
    2402                 :             :     }
    2403                 :             : 
    2404                 :             :   return 0;
    2405                 :             : }
    2406                 :             : 
    2407                 :             : /* Return true if OP is a memory reference whose address contains
    2408                 :             :    no side effects and remains valid after the addition of a positive
    2409                 :             :    integer less than the size of the object being referenced.
    2410                 :             : 
    2411                 :             :    We assume that the original address is valid and do not check it.
    2412                 :             : 
    2413                 :             :    This uses strict_memory_address_p as a subroutine, so
    2414                 :             :    don't use it before reload.  */
    2415                 :             : 
    2416                 :             : bool
    2417                 :     5432059 : offsettable_memref_p (rtx op)
    2418                 :             : {
    2419                 :     5432059 :   return ((MEM_P (op))
    2420                 :    10861468 :           && offsettable_address_addr_space_p (1, GET_MODE (op), XEXP (op, 0),
    2421                 :     5429409 :                                                MEM_ADDR_SPACE (op)));
    2422                 :             : }
    2423                 :             : 
    2424                 :             : /* Similar, but don't require a strictly valid mem ref:
    2425                 :             :    consider pseudo-regs valid as index or base regs.  */
    2426                 :             : 
    2427                 :             : bool
    2428                 :    12422280 : offsettable_nonstrict_memref_p (rtx op)
    2429                 :             : {
    2430                 :    12422280 :   return ((MEM_P (op))
    2431                 :    24844535 :           && offsettable_address_addr_space_p (0, GET_MODE (op), XEXP (op, 0),
    2432                 :    12422255 :                                                MEM_ADDR_SPACE (op)));
    2433                 :             : }
    2434                 :             : 
    2435                 :             : /* Return true if Y is a memory address which contains no side effects
    2436                 :             :    and would remain valid for address space AS after the addition of
    2437                 :             :    a positive integer less than the size of that mode.
    2438                 :             : 
    2439                 :             :    We assume that the original address is valid and do not check it.
    2440                 :             :    We do check that it is valid for narrower modes.
    2441                 :             : 
    2442                 :             :    If STRICTP is nonzero, we require a strictly valid address,
    2443                 :             :    for the sake of use in reload.cc.  */
    2444                 :             : 
    2445                 :             : bool
    2446                 :    17851664 : offsettable_address_addr_space_p (int strictp, machine_mode mode, rtx y,
    2447                 :             :                                   addr_space_t as)
    2448                 :             : {
    2449                 :    17851664 :   enum rtx_code ycode = GET_CODE (y);
    2450                 :    17851664 :   rtx z;
    2451                 :    17851664 :   rtx y1 = y;
    2452                 :    17851664 :   rtx *y2;
    2453                 :    35703328 :   bool (*addressp) (machine_mode, rtx, addr_space_t, code_helper) =
    2454                 :    17851664 :     (strictp ? strict_memory_address_addr_space_p
    2455                 :             :              : memory_address_addr_space_p);
    2456                 :    35703328 :   poly_int64 mode_sz = GET_MODE_SIZE (mode);
    2457                 :             : 
    2458                 :    17851664 :   if (CONSTANT_ADDRESS_P (y))
    2459                 :             :     return true;
    2460                 :             : 
    2461                 :             :   /* Adjusting an offsettable address involves changing to a narrower mode.
    2462                 :             :      Make sure that's OK.  */
    2463                 :             : 
    2464                 :    15207446 :   if (mode_dependent_address_p (y, as))
    2465                 :             :     return false;
    2466                 :             : 
    2467                 :    15023962 :   machine_mode address_mode = GET_MODE (y);
    2468                 :    15023962 :   if (address_mode == VOIDmode)
    2469                 :           0 :     address_mode = targetm.addr_space.address_mode (as);
    2470                 :             : #ifdef POINTERS_EXTEND_UNSIGNED
    2471                 :    15023962 :   machine_mode pointer_mode = targetm.addr_space.pointer_mode (as);
    2472                 :             : #endif
    2473                 :             : 
    2474                 :             :   /* ??? How much offset does an offsettable BLKmode reference need?
    2475                 :             :      Clearly that depends on the situation in which it's being used.
    2476                 :             :      However, the current situation in which we test 0xffffffff is
    2477                 :             :      less than ideal.  Caveat user.  */
    2478                 :    15023962 :   if (known_eq (mode_sz, 0))
    2479                 :           0 :     mode_sz = BIGGEST_ALIGNMENT / BITS_PER_UNIT;
    2480                 :             : 
    2481                 :             :   /* If the expression contains a constant term,
    2482                 :             :      see if it remains valid when max possible offset is added.  */
    2483                 :             : 
    2484                 :    15023962 :   if ((ycode == PLUS) && (y2 = find_constant_term_loc (&y1)))
    2485                 :             :     {
    2486                 :    11985966 :       bool good;
    2487                 :             : 
    2488                 :    11985966 :       y1 = *y2;
    2489                 :    11985966 :       *y2 = plus_constant (address_mode, *y2, mode_sz - 1);
    2490                 :             :       /* Use QImode because an odd displacement may be automatically invalid
    2491                 :             :          for any wider mode.  But it should be valid for a single byte.  */
    2492                 :    11985966 :       good = (*addressp) (QImode, y, as, ERROR_MARK);
    2493                 :             : 
    2494                 :             :       /* In any case, restore old contents of memory.  */
    2495                 :    11985966 :       *y2 = y1;
    2496                 :    11985966 :       return good;
    2497                 :             :     }
    2498                 :             : 
    2499                 :     3037996 :   if (GET_RTX_CLASS (ycode) == RTX_AUTOINC)
    2500                 :             :     return false;
    2501                 :             : 
    2502                 :             :   /* The offset added here is chosen as the maximum offset that
    2503                 :             :      any instruction could need to add when operating on something
    2504                 :             :      of the specified mode.  We assume that if Y and Y+c are
    2505                 :             :      valid addresses then so is Y+d for all 0<d<c.  adjust_address will
    2506                 :             :      go inside a LO_SUM here, so we do so as well.  */
    2507                 :     3037996 :   if (GET_CODE (y) == LO_SUM
    2508                 :           0 :       && mode != BLKmode
    2509                 :     3037996 :       && known_le (mode_sz, GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT))
    2510                 :           0 :     z = gen_rtx_LO_SUM (address_mode, XEXP (y, 0),
    2511                 :             :                         plus_constant (address_mode, XEXP (y, 1),
    2512                 :             :                                        mode_sz - 1));
    2513                 :             : #ifdef POINTERS_EXTEND_UNSIGNED
    2514                 :             :   /* Likewise for a ZERO_EXTEND from pointer_mode.  */
    2515                 :     3037996 :   else if (POINTERS_EXTEND_UNSIGNED > 0
    2516                 :     3037996 :            && GET_CODE (y) == ZERO_EXTEND
    2517                 :          12 :            && GET_MODE (XEXP (y, 0)) == pointer_mode)
    2518                 :           7 :     z = gen_rtx_ZERO_EXTEND (address_mode,
    2519                 :             :                              plus_constant (pointer_mode, XEXP (y, 0),
    2520                 :             :                                             mode_sz - 1));
    2521                 :             : #endif
    2522                 :             :   else
    2523                 :     3037989 :     z = plus_constant (address_mode, y, mode_sz - 1);
    2524                 :             : 
    2525                 :             :   /* Use QImode because an odd displacement may be automatically invalid
    2526                 :             :      for any wider mode.  But it should be valid for a single byte.  */
    2527                 :     3037996 :   return (*addressp) (QImode, z, as, ERROR_MARK);
    2528                 :             : }
    2529                 :             : 
    2530                 :             : /* Return true if ADDR is an address-expression whose effect depends
    2531                 :             :    on the mode of the memory reference it is used in.
    2532                 :             : 
    2533                 :             :    ADDRSPACE is the address space associated with the address.
    2534                 :             : 
    2535                 :             :    Autoincrement addressing is a typical example of mode-dependence
    2536                 :             :    because the amount of the increment depends on the mode.  */
    2537                 :             : 
    2538                 :             : bool
    2539                 :    39117090 : mode_dependent_address_p (rtx addr, addr_space_t addrspace)
    2540                 :             : {
    2541                 :             :   /* Auto-increment addressing with anything other than post_modify
    2542                 :             :      or pre_modify always introduces a mode dependency.  Catch such
    2543                 :             :      cases now instead of deferring to the target.  */
    2544                 :    39117090 :   if (GET_CODE (addr) == PRE_INC
    2545                 :    39117090 :       || GET_CODE (addr) == POST_INC
    2546                 :    39117084 :       || GET_CODE (addr) == PRE_DEC
    2547                 :    35364501 :       || GET_CODE (addr) == POST_DEC)
    2548                 :             :     return true;
    2549                 :             : 
    2550                 :    35364501 :   return targetm.mode_dependent_address_p (addr, addrspace);
    2551                 :             : }
    2552                 :             : 
    2553                 :             : /* Return true if boolean attribute ATTR is supported.  */
    2554                 :             : 
    2555                 :             : static bool
    2556                 :  1488979680 : have_bool_attr (bool_attr attr)
    2557                 :             : {
    2558                 :  1488979680 :   switch (attr)
    2559                 :             :     {
    2560                 :             :     case BA_ENABLED:
    2561                 :             :       return HAVE_ATTR_enabled;
    2562                 :             :     case BA_PREFERRED_FOR_SIZE:
    2563                 :             :       return HAVE_ATTR_enabled || HAVE_ATTR_preferred_for_size;
    2564                 :             :     case BA_PREFERRED_FOR_SPEED:
    2565                 :             :       return HAVE_ATTR_enabled || HAVE_ATTR_preferred_for_speed;
    2566                 :             :     }
    2567                 :           0 :   gcc_unreachable ();
    2568                 :             : }
    2569                 :             : 
    2570                 :             : /* Return the value of ATTR for instruction INSN.  */
    2571                 :             : 
    2572                 :             : static bool
    2573                 :  1515176221 : get_bool_attr (rtx_insn *insn, bool_attr attr)
    2574                 :             : {
    2575                 :  1515176221 :   switch (attr)
    2576                 :             :     {
    2577                 :   650009345 :     case BA_ENABLED:
    2578                 :   650009345 :       return get_attr_enabled (insn);
    2579                 :   303380245 :     case BA_PREFERRED_FOR_SIZE:
    2580                 :   303380245 :       return get_attr_enabled (insn) && get_attr_preferred_for_size (insn);
    2581                 :   561786631 :     case BA_PREFERRED_FOR_SPEED:
    2582                 :   561786631 :       return get_attr_enabled (insn) && get_attr_preferred_for_speed (insn);
    2583                 :             :     }
    2584                 :           0 :   gcc_unreachable ();
    2585                 :             : }
    2586                 :             : 
    2587                 :             : /* Like get_bool_attr_mask, but don't use the cache.  */
    2588                 :             : 
    2589                 :             : static alternative_mask
    2590                 :    91416464 : get_bool_attr_mask_uncached (rtx_insn *insn, bool_attr attr)
    2591                 :             : {
    2592                 :             :   /* Temporarily install enough information for get_attr_<foo> to assume
    2593                 :             :      that the insn operands are already cached.  As above, the attribute
    2594                 :             :      mustn't depend on the values of operands, so we don't provide their
    2595                 :             :      real values here.  */
    2596                 :    91416464 :   rtx_insn *old_insn = recog_data.insn;
    2597                 :    91416464 :   int old_alternative = which_alternative;
    2598                 :             : 
    2599                 :    91416464 :   recog_data.insn = insn;
    2600                 :    91416464 :   alternative_mask mask = ALL_ALTERNATIVES;
    2601                 :    91416464 :   int n_alternatives = insn_data[INSN_CODE (insn)].n_alternatives;
    2602                 :  1606592685 :   for (int i = 0; i < n_alternatives; i++)
    2603                 :             :     {
    2604                 :  1515176221 :       which_alternative = i;
    2605                 :  1515176221 :       if (!get_bool_attr (insn, attr))
    2606                 :   231679806 :         mask &= ~ALTERNATIVE_BIT (i);
    2607                 :             :     }
    2608                 :             : 
    2609                 :    91416464 :   recog_data.insn = old_insn;
    2610                 :    91416464 :   which_alternative = old_alternative;
    2611                 :    91416464 :   return mask;
    2612                 :             : }
    2613                 :             : 
    2614                 :             : /* Return the mask of operand alternatives that are allowed for INSN
    2615                 :             :    by boolean attribute ATTR.  This mask depends only on INSN and on
    2616                 :             :    the current target; it does not depend on things like the values of
    2617                 :             :    operands.  */
    2618                 :             : 
    2619                 :             : static alternative_mask
    2620                 :  1491254018 : get_bool_attr_mask (rtx_insn *insn, bool_attr attr)
    2621                 :             : {
    2622                 :             :   /* Quick exit for asms and for targets that don't use these attributes.  */
    2623                 :  1491254018 :   int code = INSN_CODE (insn);
    2624                 :  1491254018 :   if (code < 0 || !have_bool_attr (attr))
    2625                 :             :     return ALL_ALTERNATIVES;
    2626                 :             : 
    2627                 :             :   /* Calling get_attr_<foo> can be expensive, so cache the mask
    2628                 :             :      for speed.  */
    2629                 :  1488979680 :   if (!this_target_recog->x_bool_attr_masks[code][attr])
    2630                 :    12385652 :     this_target_recog->x_bool_attr_masks[code][attr]
    2631                 :    12385652 :       = get_bool_attr_mask_uncached (insn, attr);
    2632                 :  1488979680 :   return this_target_recog->x_bool_attr_masks[code][attr];
    2633                 :             : }
    2634                 :             : 
    2635                 :             : /* Return the set of alternatives of INSN that are allowed by the current
    2636                 :             :    target.  */
    2637                 :             : 
    2638                 :             : alternative_mask
    2639                 :  1061194580 : get_enabled_alternatives (rtx_insn *insn)
    2640                 :             : {
    2641                 :  1061194580 :   return get_bool_attr_mask (insn, BA_ENABLED);
    2642                 :             : }
    2643                 :             : 
    2644                 :             : /* Return the set of alternatives of INSN that are allowed by the current
    2645                 :             :    target and are preferred for the current size/speed optimization
    2646                 :             :    choice.  */
    2647                 :             : 
    2648                 :             : alternative_mask
    2649                 :   429982463 : get_preferred_alternatives (rtx_insn *insn)
    2650                 :             : {
    2651                 :   429982463 :   if (optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn)))
    2652                 :   379966385 :     return get_bool_attr_mask (insn, BA_PREFERRED_FOR_SPEED);
    2653                 :             :   else
    2654                 :    50016078 :     return get_bool_attr_mask (insn, BA_PREFERRED_FOR_SIZE);
    2655                 :             : }
    2656                 :             : 
    2657                 :             : /* Return the set of alternatives of INSN that are allowed by the current
    2658                 :             :    target and are preferred for the size/speed optimization choice
    2659                 :             :    associated with BB.  Passing a separate BB is useful if INSN has not
    2660                 :             :    been emitted yet or if we are considering moving it to a different
    2661                 :             :    block.  */
    2662                 :             : 
    2663                 :             : alternative_mask
    2664                 :       76975 : get_preferred_alternatives (rtx_insn *insn, basic_block bb)
    2665                 :             : {
    2666                 :       76975 :   if (optimize_bb_for_speed_p (bb))
    2667                 :       73550 :     return get_bool_attr_mask (insn, BA_PREFERRED_FOR_SPEED);
    2668                 :             :   else
    2669                 :        3425 :     return get_bool_attr_mask (insn, BA_PREFERRED_FOR_SIZE);
    2670                 :             : }
    2671                 :             : 
    2672                 :             : /* Assert that the cached boolean attributes for INSN are still accurate.
    2673                 :             :    The backend is required to define these attributes in a way that only
    2674                 :             :    depends on the current target (rather than operands, compiler phase,
    2675                 :             :    etc.).  */
    2676                 :             : 
    2677                 :             : bool
    2678                 :    32144391 : check_bool_attrs (rtx_insn *insn)
    2679                 :             : {
    2680                 :    32144391 :   int code = INSN_CODE (insn);
    2681                 :    32144391 :   if (code >= 0)
    2682                 :   128577564 :     for (int i = 0; i <= BA_LAST; ++i)
    2683                 :             :       {
    2684                 :    96433173 :         enum bool_attr attr = (enum bool_attr) i;
    2685                 :    96433173 :         if (this_target_recog->x_bool_attr_masks[code][attr])
    2686                 :    79030812 :           gcc_assert (this_target_recog->x_bool_attr_masks[code][attr]
    2687                 :             :                       == get_bool_attr_mask_uncached (insn, attr));
    2688                 :             :       }
    2689                 :    32144391 :   return true;
    2690                 :             : }
    2691                 :             : 
    2692                 :             : /* Like extract_insn, but save insn extracted and don't extract again, when
    2693                 :             :    called again for the same insn expecting that recog_data still contain the
    2694                 :             :    valid information.  This is used primary by gen_attr infrastructure that
    2695                 :             :    often does extract insn again and again.  */
    2696                 :             : void
    2697                 :  9103734959 : extract_insn_cached (rtx_insn *insn)
    2698                 :             : {
    2699                 :  9103734959 :   if (recog_data.insn == insn && INSN_CODE (insn) >= 0)
    2700                 :             :     return;
    2701                 :   677371965 :   extract_insn (insn);
    2702                 :   677371965 :   recog_data.insn = insn;
    2703                 :             : }
    2704                 :             : 
    2705                 :             : /* Do uncached extract_insn, constrain_operands and complain about failures.
    2706                 :             :    This should be used when extracting a pre-existing constrained instruction
    2707                 :             :    if the caller wants to know which alternative was chosen.  */
    2708                 :             : void
    2709                 :   245802100 : extract_constrain_insn (rtx_insn *insn)
    2710                 :             : {
    2711                 :   245802100 :   extract_insn (insn);
    2712                 :   245802100 :   if (!constrain_operands (reload_completed, get_enabled_alternatives (insn)))
    2713                 :           0 :     fatal_insn_not_found (insn);
    2714                 :   245802100 : }
    2715                 :             : 
    2716                 :             : /* Do cached extract_insn, constrain_operands and complain about failures.
    2717                 :             :    Used by insn_attrtab.  */
    2718                 :             : void
    2719                 :  8043095110 : extract_constrain_insn_cached (rtx_insn *insn)
    2720                 :             : {
    2721                 :  8043095110 :   extract_insn_cached (insn);
    2722                 :  8043095110 :   if (which_alternative == -1
    2723                 :  8043095110 :       && !constrain_operands (reload_completed,
    2724                 :             :                               get_enabled_alternatives (insn)))
    2725                 :           0 :     fatal_insn_not_found (insn);
    2726                 :  8043095110 : }
    2727                 :             : 
    2728                 :             : /* Do cached constrain_operands on INSN and complain about failures.  */
    2729                 :             : bool
    2730                 :   290886966 : constrain_operands_cached (rtx_insn *insn, int strict)
    2731                 :             : {
    2732                 :   290886966 :   if (which_alternative == -1)
    2733                 :    86605330 :     return constrain_operands (strict, get_enabled_alternatives (insn));
    2734                 :             :   else
    2735                 :             :     return true;
    2736                 :             : }
    2737                 :             : 
    2738                 :             : /* Analyze INSN and fill in recog_data.  */
    2739                 :             : 
    2740                 :             : void
    2741                 :  1849692032 : extract_insn (rtx_insn *insn)
    2742                 :             : {
    2743                 :  1849692032 :   int i;
    2744                 :  1849692032 :   int icode;
    2745                 :  1849692032 :   int noperands;
    2746                 :  1849692032 :   rtx body = PATTERN (insn);
    2747                 :             : 
    2748                 :  1849692032 :   recog_data.n_operands = 0;
    2749                 :  1849692032 :   recog_data.n_alternatives = 0;
    2750                 :  1849692032 :   recog_data.n_dups = 0;
    2751                 :  1849692032 :   recog_data.is_asm = false;
    2752                 :             : 
    2753                 :  1849692032 :   switch (GET_CODE (body))
    2754                 :             :     {
    2755                 :             :     case USE:
    2756                 :             :     case CLOBBER:
    2757                 :             :     case ASM_INPUT:
    2758                 :             :     case ADDR_VEC:
    2759                 :             :     case ADDR_DIFF_VEC:
    2760                 :             :     case VAR_LOCATION:
    2761                 :             :     case DEBUG_MARKER:
    2762                 :             :       return;
    2763                 :             : 
    2764                 :  1500565215 :     case SET:
    2765                 :  1500565215 :       if (GET_CODE (SET_SRC (body)) == ASM_OPERANDS)
    2766                 :         375 :         goto asm_insn;
    2767                 :             :       else
    2768                 :  1500564840 :         goto normal_insn;
    2769                 :   190037053 :     case PARALLEL:
    2770                 :   190037053 :       if ((GET_CODE (XVECEXP (body, 0, 0)) == SET
    2771                 :   186282497 :            && GET_CODE (SET_SRC (XVECEXP (body, 0, 0))) == ASM_OPERANDS)
    2772                 :   189638971 :           || GET_CODE (XVECEXP (body, 0, 0)) == ASM_OPERANDS
    2773                 :   189008675 :           || GET_CODE (XVECEXP (body, 0, 0)) == ASM_INPUT)
    2774                 :     1035133 :         goto asm_insn;
    2775                 :             :       else
    2776                 :   189001920 :         goto normal_insn;
    2777                 :     1035631 :     case ASM_OPERANDS:
    2778                 :     1035631 :     asm_insn:
    2779                 :     1035631 :       recog_data.n_operands = noperands = asm_noperands (body);
    2780                 :     1035631 :       if (noperands >= 0)
    2781                 :             :         {
    2782                 :             :           /* This insn is an `asm' with operands.  */
    2783                 :             : 
    2784                 :             :           /* expand_asm_operands makes sure there aren't too many operands.  */
    2785                 :     1035631 :           gcc_assert (noperands <= MAX_RECOG_OPERANDS);
    2786                 :             : 
    2787                 :             :           /* Now get the operand values and constraints out of the insn.  */
    2788                 :     1035631 :           decode_asm_operands (body, recog_data.operand,
    2789                 :             :                                recog_data.operand_loc,
    2790                 :             :                                recog_data.constraints,
    2791                 :             :                                recog_data.operand_mode, NULL);
    2792                 :     1035631 :           memset (recog_data.is_operator, 0, sizeof recog_data.is_operator);
    2793                 :     1035631 :           if (noperands > 0)
    2794                 :             :             {
    2795                 :      473905 :               const char *p =  recog_data.constraints[0];
    2796                 :      473905 :               recog_data.n_alternatives = 1;
    2797                 :     1347672 :               while (*p)
    2798                 :      873767 :                 recog_data.n_alternatives += (*p++ == ',');
    2799                 :             :             }
    2800                 :     1035631 :           recog_data.is_asm = true;
    2801                 :     1035631 :           break;
    2802                 :             :         }
    2803                 :           0 :       fatal_insn_not_found (insn);
    2804                 :             : 
    2805                 :  1740753209 :     default:
    2806                 :  1740753209 :     normal_insn:
    2807                 :             :       /* Ordinary insn: recognize it, get the operands via insn_extract
    2808                 :             :          and get the constraints.  */
    2809                 :             : 
    2810                 :  1740753209 :       icode = recog_memoized (insn);
    2811                 :  1740753209 :       if (icode < 0)
    2812                 :           0 :         fatal_insn_not_found (insn);
    2813                 :             : 
    2814                 :  1740753209 :       recog_data.n_operands = noperands = insn_data[icode].n_operands;
    2815                 :  1740753209 :       recog_data.n_alternatives = insn_data[icode].n_alternatives;
    2816                 :  1740753209 :       recog_data.n_dups = insn_data[icode].n_dups;
    2817                 :             : 
    2818                 :  1740753209 :       insn_extract (insn);
    2819                 :             : 
    2820                 :  7182157074 :       for (i = 0; i < noperands; i++)
    2821                 :             :         {
    2822                 :  3700650656 :           recog_data.constraints[i] = insn_data[icode].operand[i].constraint;
    2823                 :  3700650656 :           recog_data.is_operator[i] = insn_data[icode].operand[i].is_operator;
    2824                 :  3700650656 :           recog_data.operand_mode[i] = insn_data[icode].operand[i].mode;
    2825                 :             :           /* VOIDmode match_operands gets mode from their real operand.  */
    2826                 :  3700650656 :           if (recog_data.operand_mode[i] == VOIDmode)
    2827                 :   357965352 :             recog_data.operand_mode[i] = GET_MODE (recog_data.operand[i]);
    2828                 :             :         }
    2829                 :             :     }
    2830                 :  5443982120 :   for (i = 0; i < noperands; i++)
    2831                 :  3702193280 :     recog_data.operand_type[i]
    2832                 :  5979465066 :       = (recog_data.constraints[i][0] == '=' ? OP_OUT
    2833                 :  2277271786 :          : recog_data.constraints[i][0] == '+' ? OP_INOUT
    2834                 :             :          : OP_IN);
    2835                 :             : 
    2836                 :  1741788840 :   gcc_assert (recog_data.n_alternatives <= MAX_RECOG_ALTERNATIVES);
    2837                 :             : 
    2838                 :  1741788840 :   recog_data.insn = NULL;
    2839                 :  1741788840 :   which_alternative = -1;
    2840                 :             : }
    2841                 :             : 
    2842                 :             : /* Fill in OP_ALT_BASE for an instruction that has N_OPERANDS
    2843                 :             :    operands, N_ALTERNATIVES alternatives and constraint strings
    2844                 :             :    CONSTRAINTS.  OP_ALT_BASE has N_ALTERNATIVES * N_OPERANDS entries
    2845                 :             :    and CONSTRAINTS has N_OPERANDS entries.  OPLOC should be passed in
    2846                 :             :    if the insn is an asm statement and preprocessing should take the
    2847                 :             :    asm operands into account, e.g. to determine whether they could be
    2848                 :             :    addresses in constraints that require addresses; it should then
    2849                 :             :    point to an array of pointers to each operand.  */
    2850                 :             : 
    2851                 :             : void
    2852                 :     4574268 : preprocess_constraints (int n_operands, int n_alternatives,
    2853                 :             :                         const char **constraints,
    2854                 :             :                         operand_alternative *op_alt_base,
    2855                 :             :                         rtx **oploc)
    2856                 :             : {
    2857                 :    11727896 :   for (int i = 0; i < n_operands; i++)
    2858                 :             :     {
    2859                 :     7153628 :       int j;
    2860                 :     7153628 :       struct operand_alternative *op_alt;
    2861                 :     7153628 :       const char *p = constraints[i];
    2862                 :             : 
    2863                 :     7153628 :       op_alt = op_alt_base;
    2864                 :             : 
    2865                 :    44553336 :       for (j = 0; j < n_alternatives; j++, op_alt += n_operands)
    2866                 :             :         {
    2867                 :    37399708 :           op_alt[i].cl = NO_REGS;
    2868                 :    37399708 :           op_alt[i].register_filters = 0;
    2869                 :    37399708 :           op_alt[i].constraint = p;
    2870                 :    37399708 :           op_alt[i].matches = -1;
    2871                 :    37399708 :           op_alt[i].matched = -1;
    2872                 :             : 
    2873                 :    37399708 :           if (*p == '\0' || *p == ',')
    2874                 :             :             {
    2875                 :     1575060 :               op_alt[i].anything_ok = 1;
    2876                 :     1575060 :               continue;
    2877                 :             :             }
    2878                 :             : 
    2879                 :    95784818 :           for (;;)
    2880                 :             :             {
    2881                 :    95784818 :               char c = *p;
    2882                 :    95784818 :               if (c == '#')
    2883                 :           0 :                 do
    2884                 :           0 :                   c = *++p;
    2885                 :           0 :                 while (c != ',' && c != '\0');
    2886                 :    95784818 :               if (c == ',' || c == '\0')
    2887                 :             :                 {
    2888                 :    35824648 :                   p++;
    2889                 :    35824648 :                   break;
    2890                 :             :                 }
    2891                 :             : 
    2892                 :    59960170 :               switch (c)
    2893                 :             :                 {
    2894                 :     5360859 :                 case '?':
    2895                 :     5360859 :                   op_alt[i].reject += 6;
    2896                 :     5360859 :                   break;
    2897                 :      386116 :                 case '!':
    2898                 :      386116 :                   op_alt[i].reject += 600;
    2899                 :      386116 :                   break;
    2900                 :       51388 :                 case '&':
    2901                 :       51388 :                   op_alt[i].earlyclobber = 1;
    2902                 :       51388 :                   break;
    2903                 :             : 
    2904                 :     1689905 :                 case '0': case '1': case '2': case '3': case '4':
    2905                 :     1689905 :                 case '5': case '6': case '7': case '8': case '9':
    2906                 :     1689905 :                   {
    2907                 :     1689905 :                     char *end;
    2908                 :     1689905 :                     op_alt[i].matches = strtoul (p, &end, 10);
    2909                 :     1689905 :                     op_alt[op_alt[i].matches].matched = i;
    2910                 :     1689905 :                     p = end;
    2911                 :             :                   }
    2912                 :     1689905 :                   continue;
    2913                 :             : 
    2914                 :       29726 :                 case 'X':
    2915                 :       29726 :                   op_alt[i].anything_ok = 1;
    2916                 :       29726 :                   break;
    2917                 :             : 
    2918                 :      199744 :                 case 'g':
    2919                 :      199744 :                   op_alt[i].cl =
    2920                 :      199744 :                    reg_class_subunion[(int) op_alt[i].cl][(int) GENERAL_REGS];
    2921                 :      199744 :                   break;
    2922                 :             : 
    2923                 :    52242432 :                 default:
    2924                 :    52242432 :                   enum constraint_num cn = lookup_constraint (p);
    2925                 :    52242432 :                   enum reg_class cl;
    2926                 :    52242432 :                   switch (get_constraint_type (cn))
    2927                 :             :                     {
    2928                 :    37490351 :                     case CT_REGISTER:
    2929                 :    37490351 :                       cl = reg_class_for_constraint (cn);
    2930                 :    26651362 :                       if (cl != NO_REGS)
    2931                 :             :                         {
    2932                 :    23143351 :                           op_alt[i].cl = reg_class_subunion[op_alt[i].cl][cl];
    2933                 :    23143351 :                           auto filter_id = get_register_filter_id (cn);
    2934                 :    23143351 :                           if (filter_id >= 0)
    2935                 :             :                             op_alt[i].register_filters |= 1U << filter_id;
    2936                 :             :                         }
    2937                 :             :                       break;
    2938                 :             : 
    2939                 :             :                     case CT_CONST_INT:
    2940                 :             :                       break;
    2941                 :             : 
    2942                 :     7294803 :                     case CT_MEMORY:
    2943                 :     7294803 :                     case CT_SPECIAL_MEMORY:
    2944                 :     7294803 :                     case CT_RELAXED_MEMORY:
    2945                 :     7294803 :                       op_alt[i].memory_ok = 1;
    2946                 :     7294803 :                       break;
    2947                 :             : 
    2948                 :       82540 :                     case CT_ADDRESS:
    2949                 :       82540 :                       if (oploc && !address_operand (*oploc[i], VOIDmode))
    2950                 :             :                         break;
    2951                 :             : 
    2952                 :       82521 :                       op_alt[i].is_address = 1;
    2953                 :       82521 :                       op_alt[i].cl
    2954                 :       82521 :                         = (reg_class_subunion
    2955                 :       82521 :                            [(int) op_alt[i].cl]
    2956                 :       82521 :                            [(int) base_reg_class (VOIDmode, ADDR_SPACE_GENERIC,
    2957                 :       82521 :                                                   ADDRESS, SCRATCH)]);
    2958                 :       82521 :                       break;
    2959                 :             : 
    2960                 :             :                     case CT_FIXED_FORM:
    2961                 :             :                       break;
    2962                 :             :                     }
    2963                 :             :                   break;
    2964                 :     1689905 :                 }
    2965                 :    58270265 :               p += CONSTRAINT_LEN (c, p);
    2966                 :             :             }
    2967                 :             :         }
    2968                 :             :     }
    2969                 :     4574268 : }
    2970                 :             : 
    2971                 :             : /* Return an array of operand_alternative instructions for
    2972                 :             :    instruction ICODE.  */
    2973                 :             : 
    2974                 :             : const operand_alternative *
    2975                 :   270935152 : preprocess_insn_constraints (unsigned int icode)
    2976                 :             : {
    2977                 :   270935152 :   gcc_checking_assert (IN_RANGE (icode, 0, NUM_INSN_CODES - 1));
    2978                 :   270935152 :   if (this_target_recog->x_op_alt[icode])
    2979                 :             :     return this_target_recog->x_op_alt[icode];
    2980                 :             : 
    2981                 :     5238149 :   int n_operands = insn_data[icode].n_operands;
    2982                 :     5238149 :   if (n_operands == 0)
    2983                 :             :     return 0;
    2984                 :             :   /* Always provide at least one alternative so that which_op_alt ()
    2985                 :             :      works correctly.  If the instruction has 0 alternatives (i.e. all
    2986                 :             :      constraint strings are empty) then each operand in this alternative
    2987                 :             :      will have anything_ok set.  */
    2988                 :     2794202 :   int n_alternatives = MAX (insn_data[icode].n_alternatives, 1);
    2989                 :     2794202 :   int n_entries = n_operands * n_alternatives;
    2990                 :             : 
    2991                 :     2794202 :   operand_alternative *op_alt = XCNEWVEC (operand_alternative, n_entries);
    2992                 :     2794202 :   const char **constraints = XALLOCAVEC (const char *, n_operands);
    2993                 :             : 
    2994                 :     9450757 :   for (int i = 0; i < n_operands; ++i)
    2995                 :     6656555 :     constraints[i] = insn_data[icode].operand[i].constraint;
    2996                 :     2794202 :   preprocess_constraints (n_operands, n_alternatives, constraints, op_alt,
    2997                 :             :                           NULL);
    2998                 :             : 
    2999                 :     2794202 :   this_target_recog->x_op_alt[icode] = op_alt;
    3000                 :     2794202 :   return op_alt;
    3001                 :             : }
    3002                 :             : 
    3003                 :             : /* After calling extract_insn, you can use this function to extract some
    3004                 :             :    information from the constraint strings into a more usable form.
    3005                 :             :    The collected data is stored in recog_op_alt.  */
    3006                 :             : 
    3007                 :             : void
    3008                 :   184236682 : preprocess_constraints (rtx_insn *insn)
    3009                 :             : {
    3010                 :   184236682 :   int icode = INSN_CODE (insn);
    3011                 :   184236682 :   if (icode >= 0)
    3012                 :   182503143 :     recog_op_alt = preprocess_insn_constraints (icode);
    3013                 :             :   else
    3014                 :             :     {
    3015                 :     1733539 :       int n_operands = recog_data.n_operands;
    3016                 :     1733539 :       int n_alternatives = recog_data.n_alternatives;
    3017                 :     1733539 :       int n_entries = n_operands * n_alternatives;
    3018                 :     1733539 :       memset (asm_op_alt, 0, n_entries * sizeof (operand_alternative));
    3019                 :     1733539 :       preprocess_constraints (n_operands, n_alternatives,
    3020                 :             :                               recog_data.constraints, asm_op_alt,
    3021                 :             :                               NULL);
    3022                 :     1733539 :       recog_op_alt = asm_op_alt;
    3023                 :             :     }
    3024                 :   184236682 : }
    3025                 :             : 
    3026                 :             : /* Check the operands of an insn against the insn's operand constraints
    3027                 :             :    and return 1 if they match any of the alternatives in ALTERNATIVES.
    3028                 :             : 
    3029                 :             :    The information about the insn's operands, constraints, operand modes
    3030                 :             :    etc. is obtained from the global variables set up by extract_insn.
    3031                 :             : 
    3032                 :             :    WHICH_ALTERNATIVE is set to a number which indicates which
    3033                 :             :    alternative of constraints was matched: 0 for the first alternative,
    3034                 :             :    1 for the next, etc.
    3035                 :             : 
    3036                 :             :    In addition, when two operands are required to match
    3037                 :             :    and it happens that the output operand is (reg) while the
    3038                 :             :    input operand is --(reg) or ++(reg) (a pre-inc or pre-dec),
    3039                 :             :    make the output operand look like the input.
    3040                 :             :    This is because the output operand is the one the template will print.
    3041                 :             : 
    3042                 :             :    This is used in final, just before printing the assembler code and by
    3043                 :             :    the routines that determine an insn's attribute.
    3044                 :             : 
    3045                 :             :    If STRICT is a positive nonzero value, it means that we have been
    3046                 :             :    called after reload has been completed.  In that case, we must
    3047                 :             :    do all checks strictly.  If it is zero, it means that we have been called
    3048                 :             :    before reload has completed.  In that case, we first try to see if we can
    3049                 :             :    find an alternative that matches strictly.  If not, we try again, this
    3050                 :             :    time assuming that reload will fix up the insn.  This provides a "best
    3051                 :             :    guess" for the alternative and is used to compute attributes of insns prior
    3052                 :             :    to reload.  A negative value of STRICT is used for this internal call.  */
    3053                 :             : 
    3054                 :             : struct funny_match
    3055                 :             : {
    3056                 :             :   int this_op, other;
    3057                 :             : };
    3058                 :             : 
    3059                 :             : bool
    3060                 :  1025721784 : constrain_operands (int strict, alternative_mask alternatives)
    3061                 :             : {
    3062                 :  1025723212 :   const char *constraints[MAX_RECOG_OPERANDS];
    3063                 :  1025723212 :   int matching_operands[MAX_RECOG_OPERANDS];
    3064                 :  1025723212 :   int earlyclobber[MAX_RECOG_OPERANDS];
    3065                 :  1025723212 :   int c;
    3066                 :             : 
    3067                 :  1025723212 :   struct funny_match funny_match[MAX_RECOG_OPERANDS];
    3068                 :  1025723212 :   int funny_match_index;
    3069                 :             : 
    3070                 :  1025723212 :   which_alternative = 0;
    3071                 :  1025723212 :   if (recog_data.n_operands == 0 || recog_data.n_alternatives == 0)
    3072                 :             :     return true;
    3073                 :             : 
    3074                 :  3043767717 :   for (c = 0; c < recog_data.n_operands; c++)
    3075                 :  2071954825 :     constraints[c] = recog_data.constraints[c];
    3076                 :             : 
    3077                 :  3635275292 :   do
    3078                 :             :     {
    3079                 :  3635275292 :       int seen_earlyclobber_at = -1;
    3080                 :  3635275292 :       int opno;
    3081                 :  3635275292 :       bool lose = false;
    3082                 :  3635275292 :       funny_match_index = 0;
    3083                 :             : 
    3084                 :  3635275292 :       if (!TEST_BIT (alternatives, which_alternative))
    3085                 :             :         {
    3086                 :             :           int i;
    3087                 :             : 
    3088                 :  2448241419 :           for (i = 0; i < recog_data.n_operands; i++)
    3089                 :  3282470438 :             constraints[i] = skip_alternative (constraints[i]);
    3090                 :             : 
    3091                 :   807006200 :           which_alternative++;
    3092                 :   807006200 :           continue;
    3093                 :   807006200 :         }
    3094                 :             : 
    3095                 :  8640278539 :       for (opno = 0; opno < recog_data.n_operands; opno++)
    3096                 :  5812009447 :         matching_operands[opno] = -1;
    3097                 :             : 
    3098                 :  8640278539 :       for (opno = 0; opno < recog_data.n_operands; opno++)
    3099                 :             :         {
    3100                 :  5812009447 :           rtx op = recog_data.operand[opno];
    3101                 :  5812009447 :           machine_mode mode = GET_MODE (op);
    3102                 :  5812009447 :           const char *p = constraints[opno];
    3103                 :  5812009447 :           int offset = 0;
    3104                 :  5812009447 :           bool win = false;
    3105                 :  5812009447 :           int val;
    3106                 :  5812009447 :           int len;
    3107                 :             : 
    3108                 :  5812009447 :           earlyclobber[opno] = 0;
    3109                 :             : 
    3110                 :  5812009447 :           if (GET_CODE (op) == SUBREG)
    3111                 :             :             {
    3112                 :        4528 :               if (REG_P (SUBREG_REG (op))
    3113                 :        4528 :                   && REGNO (SUBREG_REG (op)) < FIRST_PSEUDO_REGISTER)
    3114                 :           9 :                 offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
    3115                 :           9 :                                               GET_MODE (SUBREG_REG (op)),
    3116                 :           9 :                                               SUBREG_BYTE (op),
    3117                 :             :                                               GET_MODE (op));
    3118                 :        4528 :               op = SUBREG_REG (op);
    3119                 :             :             }
    3120                 :             : 
    3121                 :             :           /* An empty constraint or empty alternative
    3122                 :             :              allows anything which matched the pattern.  */
    3123                 :  5812009447 :           if (*p == 0 || *p == ',')
    3124                 :    83419738 :             win = true;
    3125                 :             : 
    3126                 : 14856091264 :           do
    3127                 : 14856091264 :             switch (c = *p, len = CONSTRAINT_LEN (c, p), c)
    3128                 :             :               {
    3129                 :             :               case '\0':
    3130                 :             :                 len = 0;
    3131                 :             :                 break;
    3132                 :  5512406649 :               case ',':
    3133                 :  5512406649 :                 c = '\0';
    3134                 :  5512406649 :                 break;
    3135                 :             : 
    3136                 :           0 :               case '#':
    3137                 :             :                 /* Ignore rest of this alternative as far as
    3138                 :             :                    constraint checking is concerned.  */
    3139                 :           0 :                 do
    3140                 :           0 :                   p++;
    3141                 :           0 :                 while (*p && *p != ',');
    3142                 :             :                 len = 0;
    3143                 :             :                 break;
    3144                 :             : 
    3145                 :      314727 :               case '&':
    3146                 :      314727 :                 earlyclobber[opno] = 1;
    3147                 :      314727 :                 if (seen_earlyclobber_at < 0)
    3148                 :      299404 :                   seen_earlyclobber_at = opno;
    3149                 :             :                 break;
    3150                 :             : 
    3151                 :   118364790 :               case '0':  case '1':  case '2':  case '3':  case '4':
    3152                 :   118364790 :               case '5':  case '6':  case '7':  case '8':  case '9':
    3153                 :   118364790 :                 {
    3154                 :             :                   /* This operand must be the same as a previous one.
    3155                 :             :                      This kind of constraint is used for instructions such
    3156                 :             :                      as add when they take only two operands.
    3157                 :             : 
    3158                 :             :                      Note that the lower-numbered operand is passed first.
    3159                 :             : 
    3160                 :             :                      If we are not testing strictly, assume that this
    3161                 :             :                      constraint will be satisfied.  */
    3162                 :             : 
    3163                 :   118364790 :                   char *end;
    3164                 :   118364790 :                   int match;
    3165                 :             : 
    3166                 :   118364790 :                   match = strtoul (p, &end, 10);
    3167                 :   118364790 :                   p = end;
    3168                 :             : 
    3169                 :   118364790 :                   if (strict < 0)
    3170                 :             :                     val = 1;
    3171                 :             :                   else
    3172                 :             :                     {
    3173                 :   118363378 :                       rtx op1 = recog_data.operand[match];
    3174                 :   118363378 :                       rtx op2 = recog_data.operand[opno];
    3175                 :   118363378 :                       val = operands_match_p (op1, op2);
    3176                 :             :                     }
    3177                 :             : 
    3178                 :   118364790 :                   matching_operands[opno] = match;
    3179                 :   118364790 :                   matching_operands[match] = opno;
    3180                 :             : 
    3181                 :   118364790 :                   if (val != 0)
    3182                 :   100229623 :                     win = true;
    3183                 :             : 
    3184                 :             :                   /* If output is *x and input is *--x, arrange later
    3185                 :             :                      to change the output to *--x as well, since the
    3186                 :             :                      output op is the one that will be printed.  */
    3187                 :   118364790 :                   if (val == 2 && strict > 0)
    3188                 :             :                     {
    3189                 :           0 :                       funny_match[funny_match_index].this_op = opno;
    3190                 :           0 :                       funny_match[funny_match_index++].other = match;
    3191                 :             :                     }
    3192                 :             :                 }
    3193                 :   118364790 :                 len = 0;
    3194                 :   118364790 :                 break;
    3195                 :             : 
    3196                 :      241080 :               case 'p':
    3197                 :             :                 /* p is used for address_operands.  When we are called by
    3198                 :             :                    gen_reload, no one will have checked that the address is
    3199                 :             :                    strictly valid, i.e., that all pseudos requiring hard regs
    3200                 :             :                    have gotten them.  We also want to make sure we have a
    3201                 :             :                    valid mode.  */
    3202                 :      241080 :                 {
    3203                 :      482160 :                   auto mem_mode = (recog_data.is_asm
    3204                 :      241080 :                                    ? VOIDmode
    3205                 :             :                                    : recog_data.operand_mode[opno]);
    3206                 :      241080 :                   if ((GET_MODE (op) == VOIDmode
    3207                 :      241080 :                        || SCALAR_INT_MODE_P (GET_MODE (op)))
    3208                 :      482135 :                       && (strict <= 0
    3209                 :      241080 :                           || strict_memory_address_p (mem_mode, op)))
    3210                 :      241015 :                     win = true;
    3211                 :             :                   break;
    3212                 :             :                 }
    3213                 :             : 
    3214                 :             :                 /* No need to check general_operand again;
    3215                 :             :                    it was done in insn-recog.cc.  Well, except that reload
    3216                 :             :                    doesn't check the validity of its replacements, but
    3217                 :             :                    that should only matter when there's a bug.  */
    3218                 :   118469515 :               case 'g':
    3219                 :             :                 /* Anything goes unless it is a REG and really has a hard reg
    3220                 :             :                    but the hard reg is not in the class GENERAL_REGS.  */
    3221                 :   118469515 :                 if (REG_P (op))
    3222                 :             :                   {
    3223                 :    45390455 :                     if (strict < 0
    3224                 :             :                         || GENERAL_REGS == ALL_REGS
    3225                 :    45390397 :                         || (reload_in_progress
    3226                 :           0 :                             && REGNO (op) >= FIRST_PSEUDO_REGISTER)
    3227                 :    90780852 :                         || reg_fits_class_p (op, GENERAL_REGS, offset, mode))
    3228                 :             :                       win = true;
    3229                 :             :                   }
    3230                 :    73079060 :                 else if (strict < 0 || general_operand (op, mode))
    3231                 :             :                   win = true;
    3232                 :             :                 break;
    3233                 :             : 
    3234                 :  8806691705 :               default:
    3235                 :  8806691705 :                 {
    3236                 :  8806691705 :                   enum constraint_num cn = lookup_constraint (p);
    3237                 :  8806691705 :                   enum reg_class cl = reg_class_for_constraint (cn);
    3238                 :  4048606719 :                   if (cl != NO_REGS)
    3239                 :             :                     {
    3240                 :  3877305516 :                       auto *filter = get_register_filter (cn);
    3241                 :  3877305516 :                       if (strict < 0
    3242                 :  3877302675 :                           || (strict == 0
    3243                 :       94587 :                               && REG_P (op)
    3244                 :       74787 :                               && REGNO (op) >= FIRST_PSEUDO_REGISTER)
    3245                 :       38717 :                           || (strict == 0 && GET_CODE (op) == SCRATCH)
    3246                 :  7754552321 :                           || (REG_P (op)
    3247                 :  2848392492 :                               && reg_fits_class_p (op, cl, offset, mode)
    3248                 :             :                               && (!filter
    3249                 :             :                                   || TEST_HARD_REG_BIT (*filter,
    3250                 :             :                                                         REGNO (op) + offset))))
    3251                 :             :                         win = true;
    3252                 :             :                     }
    3253                 :             : 
    3254                 :  4929386189 :                   else if (constraint_satisfied_p (op, cn))
    3255                 :             :                     win = true;
    3256                 :             : 
    3257                 :  4158485536 :                   else if ((insn_extra_memory_constraint (cn)
    3258                 :             :                             || insn_extra_relaxed_memory_constraint (cn))
    3259                 :             :                            /* Every memory operand can be reloaded to fit.  */
    3260                 :  4158485536 :                            && ((strict < 0 && MEM_P (op))
    3261                 :             :                                /* Before reload, accept what reload can turn
    3262                 :             :                                   into a mem.  */
    3263                 :        1068 :                                || (strict < 0 && CONSTANT_P (op))
    3264                 :             :                                /* Before reload, accept a pseudo or hard register,
    3265                 :             :                                   since LRA can turn it into a mem.  */
    3266                 :        1032 :                                || (strict < 0 && targetm.lra_p () && REG_P (op))
    3267                 :             :                                /* During reload, accept a pseudo  */
    3268                 :   855918485 :                                || (reload_in_progress && REG_P (op)
    3269                 :           0 :                                    && REGNO (op) >= FIRST_PSEUDO_REGISTER)))
    3270                 :             :                     win = true;
    3271                 :  4158484468 :                   else if (insn_extra_address_constraint (cn)
    3272                 :             :                            /* Every address operand can be reloaded to fit.  */
    3273                 :  4158484468 :                            && strict < 0)
    3274                 :             :                     win = true;
    3275                 :             :                   /* Cater to architectures like IA-64 that define extra memory
    3276                 :             :                      constraints without using define_memory_constraint.  */
    3277                 :  4158484468 :                   else if (reload_in_progress
    3278                 :           0 :                            && REG_P (op)
    3279                 :           0 :                            && REGNO (op) >= FIRST_PSEUDO_REGISTER
    3280                 :           0 :                            && reg_renumber[REGNO (op)] < 0
    3281                 :           0 :                            && reg_equiv_mem (REGNO (op)) != 0
    3282                 :  4158484468 :                            && constraint_satisfied_p
    3283                 :           0 :                               (reg_equiv_mem (REGNO (op)), cn))
    3284                 :             :                     win = true;
    3285                 :             :                   break;
    3286                 :             :                 }
    3287                 :             :               }
    3288                 : 14856091264 :           while (p += len, c);
    3289                 :             : 
    3290                 :  5812009447 :           constraints[opno] = p;
    3291                 :             :           /* If this operand did not win somehow,
    3292                 :             :              this alternative loses.  */
    3293                 :  5812009447 :           if (! win)
    3294                 :  2857480698 :             lose = true;
    3295                 :             :         }
    3296                 :             :       /* This alternative won; the operands are ok.
    3297                 :             :          Change whichever operands this alternative says to change.  */
    3298                 :  2828269092 :       if (! lose)
    3299                 :             :         {
    3300                 :   970513527 :           int opno, eopno;
    3301                 :             : 
    3302                 :             :           /* See if any earlyclobber operand conflicts with some other
    3303                 :             :              operand.  */
    3304                 :             : 
    3305                 :   970513527 :           if (strict > 0  && seen_earlyclobber_at >= 0)
    3306                 :      939995 :             for (eopno = seen_earlyclobber_at;
    3307                 :     1238491 :                  eopno < recog_data.n_operands;
    3308                 :             :                  eopno++)
    3309                 :             :               /* Ignore earlyclobber operands now in memory,
    3310                 :             :                  because we would often report failure when we have
    3311                 :             :                  two memory operands, one of which was formerly a REG.  */
    3312                 :      939995 :               if (earlyclobber[eopno]
    3313                 :      313819 :                   && REG_P (recog_data.operand[eopno]))
    3314                 :     1604601 :                 for (opno = 0; opno < recog_data.n_operands; opno++)
    3315                 :     1290782 :                   if ((MEM_P (recog_data.operand[opno])
    3316                 :     1154997 :                        || recog_data.operand_type[opno] != OP_OUT)
    3317                 :      776649 :                       && opno != eopno
    3318                 :             :                       /* Ignore things like match_operator operands.  */
    3319                 :      776086 :                       && *recog_data.constraints[opno] != 0
    3320                 :      803267 :                       && ! (matching_operands[opno] == eopno
    3321                 :       95955 :                             && operands_match_p (recog_data.operand[opno],
    3322                 :             :                                                  recog_data.operand[eopno]))
    3323                 :     1904175 :                       && ! safe_from_earlyclobber (recog_data.operand[opno],
    3324                 :             :                                                    recog_data.operand[eopno]))
    3325                 :             :                     lose = true;
    3326                 :             : 
    3327                 :   970513527 :           if (! lose)
    3328                 :             :             {
    3329                 :   970513466 :               while (--funny_match_index >= 0)
    3330                 :             :                 {
    3331                 :           0 :                   recog_data.operand[funny_match[funny_match_index].other]
    3332                 :           0 :                     = recog_data.operand[funny_match[funny_match_index].this_op];
    3333                 :             :                 }
    3334                 :             : 
    3335                 :             :               /* For operands without < or > constraints reject side-effects.  */
    3336                 :             :               if (AUTO_INC_DEC && recog_data.is_asm)
    3337                 :             :                 {
    3338                 :             :                   for (opno = 0; opno < recog_data.n_operands; opno++)
    3339                 :             :                     if (MEM_P (recog_data.operand[opno]))
    3340                 :             :                       switch (GET_CODE (XEXP (recog_data.operand[opno], 0)))
    3341                 :             :                         {
    3342                 :             :                         case PRE_INC:
    3343                 :             :                         case POST_INC:
    3344                 :             :                         case PRE_DEC:
    3345                 :             :                         case POST_DEC:
    3346                 :             :                         case PRE_MODIFY:
    3347                 :             :                         case POST_MODIFY:
    3348                 :             :                           if (strchr (recog_data.constraints[opno], '<') == NULL
    3349                 :             :                               && strchr (recog_data.constraints[opno], '>')
    3350                 :             :                                  == NULL)
    3351                 :             :                             return false;
    3352                 :             :                           break;
    3353                 :             :                         default:
    3354                 :             :                           break;
    3355                 :             :                         }
    3356                 :             :                 }
    3357                 :             : 
    3358                 :             :               return true;
    3359                 :             :             }
    3360                 :             :         }
    3361                 :             : 
    3362                 :  1857755626 :       which_alternative++;
    3363                 :             :     }
    3364                 :  2664761826 :   while (which_alternative < recog_data.n_alternatives);
    3365                 :             : 
    3366                 :     1299426 :   which_alternative = -1;
    3367                 :             :   /* If we are about to reject this, but we are not to test strictly,
    3368                 :             :      try a very loose test.  Only return failure if it fails also.  */
    3369                 :     1299426 :   if (strict == 0)
    3370                 :             :     return constrain_operands (-1, alternatives);
    3371                 :             :   else
    3372                 :             :     return false;
    3373                 :             : }
    3374                 :             : 
    3375                 :             : /* Return true iff OPERAND (assumed to be a REG rtx)
    3376                 :             :    is a hard reg in class CLASS when its regno is offset by OFFSET
    3377                 :             :    and changed to mode MODE.
    3378                 :             :    If REG occupies multiple hard regs, all of them must be in CLASS.  */
    3379                 :             : 
    3380                 :             : bool
    3381                 :  3149929029 : reg_fits_class_p (const_rtx operand, reg_class_t cl, int offset,
    3382                 :             :                   machine_mode mode)
    3383                 :             : {
    3384                 :  3149929029 :   unsigned int regno = REGNO (operand);
    3385                 :             : 
    3386                 :  3149929029 :   if (cl == NO_REGS)
    3387                 :             :     return false;
    3388                 :             : 
    3389                 :             :   /* Regno must not be a pseudo register.  Offset may be negative.  */
    3390                 :  3029033365 :   return (HARD_REGISTER_NUM_P (regno)
    3391                 :  3029030796 :           && HARD_REGISTER_NUM_P (regno + offset)
    3392                 :  6058064161 :           && in_hard_reg_set_p (reg_class_contents[(int) cl], mode, 
    3393                 :             :                                 regno + offset));
    3394                 :             : }
    3395                 :             : 
    3396                 :             : /* Split single instruction.  Helper function for split_all_insns and
    3397                 :             :    split_all_insns_noflow.  Return last insn in the sequence if successful,
    3398                 :             :    or NULL if unsuccessful.  */
    3399                 :             : 
    3400                 :             : static rtx_insn *
    3401                 :   332520179 : split_insn (rtx_insn *insn)
    3402                 :             : {
    3403                 :             :   /* Split insns here to get max fine-grain parallelism.  */
    3404                 :   332520179 :   rtx_insn *first = PREV_INSN (insn);
    3405                 :   332520179 :   rtx_insn *last = try_split (PATTERN (insn), insn, 1);
    3406                 :   332520179 :   rtx insn_set, last_set, note;
    3407                 :             : 
    3408                 :   332520179 :   if (last == insn)
    3409                 :             :     return NULL;
    3410                 :             : 
    3411                 :             :   /* If the original instruction was a single set that was known to be
    3412                 :             :      equivalent to a constant, see if we can say the same about the last
    3413                 :             :      instruction in the split sequence.  The two instructions must set
    3414                 :             :      the same destination.  */
    3415                 :     5870232 :   insn_set = single_set (insn);
    3416                 :     5870232 :   if (insn_set)
    3417                 :             :     {
    3418                 :     5789065 :       last_set = single_set (last);
    3419                 :     5789065 :       if (last_set && rtx_equal_p (SET_DEST (last_set), SET_DEST (insn_set)))
    3420                 :             :         {
    3421                 :     2711031 :           note = find_reg_equal_equiv_note (insn);
    3422                 :     2711031 :           if (note && CONSTANT_P (XEXP (note, 0)))
    3423                 :       85632 :             set_unique_reg_note (last, REG_EQUAL, XEXP (note, 0));
    3424                 :     2625399 :           else if (CONSTANT_P (SET_SRC (insn_set)))
    3425                 :          84 :             set_unique_reg_note (last, REG_EQUAL,
    3426                 :             :                                  copy_rtx (SET_SRC (insn_set)));
    3427                 :             :         }
    3428                 :             :     }
    3429                 :             : 
    3430                 :             :   /* try_split returns the NOTE that INSN became.  */
    3431                 :     5870232 :   SET_INSN_DELETED (insn);
    3432                 :             : 
    3433                 :             :   /* ??? Coddle to md files that generate subregs in post-reload
    3434                 :             :      splitters instead of computing the proper hard register.  */
    3435                 :     5870232 :   if (reload_completed && first != last)
    3436                 :             :     {
    3437                 :     5495158 :       first = NEXT_INSN (first);
    3438                 :     2617506 :       for (;;)
    3439                 :             :         {
    3440                 :     8112664 :           if (INSN_P (first))
    3441                 :     8109543 :             cleanup_subreg_operands (first);
    3442                 :     8112664 :           if (first == last)
    3443                 :             :             break;
    3444                 :     2617506 :           first = NEXT_INSN (first);
    3445                 :             :         }
    3446                 :             :     }
    3447                 :             : 
    3448                 :             :   return last;
    3449                 :             : }
    3450                 :             : 
    3451                 :             : /* Split all insns in the function.  If UPD_LIFE, update life info after.  */
    3452                 :             : 
    3453                 :             : void
    3454                 :     3841303 : split_all_insns (void)
    3455                 :             : {
    3456                 :     3841303 :   bool changed;
    3457                 :     3841303 :   bool need_cfg_cleanup = false;
    3458                 :     3841303 :   basic_block bb;
    3459                 :             : 
    3460                 :     3841303 :   auto_sbitmap blocks (last_basic_block_for_fn (cfun));
    3461                 :     3841303 :   bitmap_clear (blocks);
    3462                 :     3841303 :   changed = false;
    3463                 :             : 
    3464                 :    39879836 :   FOR_EACH_BB_REVERSE_FN (bb, cfun)
    3465                 :             :     {
    3466                 :    36038533 :       rtx_insn *insn, *next;
    3467                 :    36038533 :       bool finish = false;
    3468                 :             : 
    3469                 :    36038533 :       rtl_profile_for_bb (bb);
    3470                 :   442077419 :       for (insn = BB_HEAD (bb); !finish ; insn = next)
    3471                 :             :         {
    3472                 :             :           /* Can't use `next_real_insn' because that might go across
    3473                 :             :              CODE_LABELS and short-out basic blocks.  */
    3474                 :   406038886 :           next = NEXT_INSN (insn);
    3475                 :   406038886 :           finish = (insn == BB_END (bb));
    3476                 :             : 
    3477                 :             :           /* If INSN has a REG_EH_REGION note and we split INSN, the
    3478                 :             :              resulting split may not have/need REG_EH_REGION notes.
    3479                 :             : 
    3480                 :             :              If that happens and INSN was the last reference to the
    3481                 :             :              given EH region, then the EH region will become unreachable.
    3482                 :             :              We cannot leave the unreachable blocks in the CFG as that
    3483                 :             :              will trigger a checking failure.
    3484                 :             : 
    3485                 :             :              So track if INSN has a REG_EH_REGION note.  If so and we
    3486                 :             :              split INSN, then trigger a CFG cleanup.  */
    3487                 :   406038886 :           rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
    3488                 :   406038886 :           if (INSN_P (insn))
    3489                 :             :             {
    3490                 :   332560193 :               rtx set = single_set (insn);
    3491                 :             : 
    3492                 :             :               /* Don't split no-op move insns.  These should silently
    3493                 :             :                  disappear later in final.  Splitting such insns would
    3494                 :             :                  break the code that handles LIBCALL blocks.  */
    3495                 :   332560193 :               if (set && set_noop_p (set))
    3496                 :             :                 {
    3497                 :             :                   /* Nops get in the way while scheduling, so delete them
    3498                 :             :                      now if register allocation has already been done.  It
    3499                 :             :                      is too risky to try to do this before register
    3500                 :             :                      allocation, and there are unlikely to be very many
    3501                 :             :                      nops then anyways.  */
    3502                 :       40014 :                   if (reload_completed)
    3503                 :       39989 :                       delete_insn_and_edges (insn);
    3504                 :       40014 :                   if (note)
    3505                 :   406038886 :                     need_cfg_cleanup = true;
    3506                 :             :                 }
    3507                 :             :               else
    3508                 :             :                 {
    3509                 :   332520179 :                   if (split_insn (insn))
    3510                 :             :                     {
    3511                 :     5870232 :                       bitmap_set_bit (blocks, bb->index);
    3512                 :     5870232 :                       changed = true;
    3513                 :     5870232 :                       if (note)
    3514                 :        2588 :                         need_cfg_cleanup = true;
    3515                 :             :                     }
    3516                 :             :                 }
    3517                 :             :             }
    3518                 :             :         }
    3519                 :             :     }
    3520                 :             : 
    3521                 :     3841303 :   default_rtl_profile ();
    3522                 :     3841303 :   if (changed)
    3523                 :             :     {
    3524                 :      719587 :       find_many_sub_basic_blocks (blocks);
    3525                 :             : 
    3526                 :             :       /* Splitting could drop an REG_EH_REGION if it potentially
    3527                 :             :          trapped in its original form, but does not in its split
    3528                 :             :          form.  Consider a FLOAT_TRUNCATE which splits into a memory
    3529                 :             :          store/load pair and -fnon-call-exceptions.  */
    3530                 :      719587 :       if (need_cfg_cleanup)
    3531                 :        1255 :         cleanup_cfg (0);
    3532                 :             :     }
    3533                 :             : 
    3534                 :     3841303 :   checking_verify_flow_info ();
    3535                 :     3841303 : }
    3536                 :             : 
    3537                 :             : /* Same as split_all_insns, but do not expect CFG to be available.
    3538                 :             :    Used by machine dependent reorg passes.  */
    3539                 :             : 
    3540                 :             : void
    3541                 :           0 : split_all_insns_noflow (void)
    3542                 :             : {
    3543                 :           0 :   rtx_insn *next, *insn;
    3544                 :             : 
    3545                 :           0 :   for (insn = get_insns (); insn; insn = next)
    3546                 :             :     {
    3547                 :           0 :       next = NEXT_INSN (insn);
    3548                 :           0 :       if (INSN_P (insn))
    3549                 :             :         {
    3550                 :             :           /* Don't split no-op move insns.  These should silently
    3551                 :             :              disappear later in final.  Splitting such insns would
    3552                 :             :              break the code that handles LIBCALL blocks.  */
    3553                 :           0 :           rtx set = single_set (insn);
    3554                 :           0 :           if (set && set_noop_p (set))
    3555                 :             :             {
    3556                 :             :               /* Nops get in the way while scheduling, so delete them
    3557                 :             :                  now if register allocation has already been done.  It
    3558                 :             :                  is too risky to try to do this before register
    3559                 :             :                  allocation, and there are unlikely to be very many
    3560                 :             :                  nops then anyways.
    3561                 :             : 
    3562                 :             :                  ??? Should we use delete_insn when the CFG isn't valid?  */
    3563                 :           0 :               if (reload_completed)
    3564                 :           0 :                 delete_insn_and_edges (insn);
    3565                 :             :             }
    3566                 :             :           else
    3567                 :           0 :             split_insn (insn);
    3568                 :             :         }
    3569                 :             :     }
    3570                 :           0 : }
    3571                 :             : 
    3572                 :             : struct peep2_insn_data
    3573                 :             : {
    3574                 :             :   rtx_insn *insn;
    3575                 :             :   regset live_before;
    3576                 :             : };
    3577                 :             : 
    3578                 :             : static struct peep2_insn_data peep2_insn_data[MAX_INSNS_PER_PEEP2 + 1];
    3579                 :             : static int peep2_current;
    3580                 :             : 
    3581                 :             : static bool peep2_do_rebuild_jump_labels;
    3582                 :             : static bool peep2_do_cleanup_cfg;
    3583                 :             : 
    3584                 :             : /* The number of instructions available to match a peep2.  */
    3585                 :             : int peep2_current_count;
    3586                 :             : 
    3587                 :             : /* A marker indicating the last insn of the block.  The live_before regset
    3588                 :             :    for this element is correct, indicating DF_LIVE_OUT for the block.  */
    3589                 :             : #define PEEP2_EOB invalid_insn_rtx
    3590                 :             : 
    3591                 :             : /* Wrap N to fit into the peep2_insn_data buffer.  */
    3592                 :             : 
    3593                 :             : static int
    3594                 :   393965868 : peep2_buf_position (int n)
    3595                 :             : {
    3596                 :           0 :   if (n >= MAX_INSNS_PER_PEEP2 + 1)
    3597                 :   131639542 :     n -= MAX_INSNS_PER_PEEP2 + 1;
    3598                 :   393948653 :   return n;
    3599                 :             : }
    3600                 :             : 
    3601                 :             : /* Return the Nth non-note insn after `current', or return NULL_RTX if it
    3602                 :             :    does not exist.  Used by the recognizer to find the next insn to match
    3603                 :             :    in a multi-insn pattern.  */
    3604                 :             : 
    3605                 :             : rtx_insn *
    3606                 :   204047442 : peep2_next_insn (int n)
    3607                 :             : {
    3608                 :   204047442 :   gcc_assert (n <= peep2_current_count);
    3609                 :             : 
    3610                 :   204047442 :   n = peep2_buf_position (peep2_current + n);
    3611                 :             : 
    3612                 :   204047442 :   return peep2_insn_data[n].insn;
    3613                 :             : }
    3614                 :             : 
    3615                 :             : /* Return true if REGNO is dead before the Nth non-note insn
    3616                 :             :    after `current'.  */
    3617                 :             : 
    3618                 :             : bool
    3619                 :    12297395 : peep2_regno_dead_p (int ofs, int regno)
    3620                 :             : {
    3621                 :    12297395 :   gcc_assert (ofs < MAX_INSNS_PER_PEEP2 + 1);
    3622                 :             : 
    3623                 :    12297395 :   ofs = peep2_buf_position (peep2_current + ofs);
    3624                 :             : 
    3625                 :    12297395 :   gcc_assert (peep2_insn_data[ofs].insn != NULL_RTX);
    3626                 :             : 
    3627                 :    12297395 :   return ! REGNO_REG_SET_P (peep2_insn_data[ofs].live_before, regno);
    3628                 :             : }
    3629                 :             : 
    3630                 :             : /* Similarly for a REG.  */
    3631                 :             : 
    3632                 :             : bool
    3633                 :      318225 : peep2_reg_dead_p (int ofs, rtx reg)
    3634                 :             : {
    3635                 :      318225 :   gcc_assert (ofs < MAX_INSNS_PER_PEEP2 + 1);
    3636                 :             : 
    3637                 :      318225 :   ofs = peep2_buf_position (peep2_current + ofs);
    3638                 :             : 
    3639                 :      318225 :   gcc_assert (peep2_insn_data[ofs].insn != NULL_RTX);
    3640                 :             : 
    3641                 :      318225 :   unsigned int end_regno = END_REGNO (reg);
    3642                 :      402695 :   for (unsigned int regno = REGNO (reg); regno < end_regno; ++regno)
    3643                 :      318225 :     if (REGNO_REG_SET_P (peep2_insn_data[ofs].live_before, regno))
    3644                 :             :       return false;
    3645                 :             :   return true;
    3646                 :             : }
    3647                 :             : 
    3648                 :             : /* Regno offset to be used in the register search.  */
    3649                 :             : static int search_ofs;
    3650                 :             : 
    3651                 :             : /* Try to find a hard register of mode MODE, matching the register class in
    3652                 :             :    CLASS_STR, which is available at the beginning of insn CURRENT_INSN and
    3653                 :             :    remains available until the end of LAST_INSN.  LAST_INSN may be NULL_RTX,
    3654                 :             :    in which case the only condition is that the register must be available
    3655                 :             :    before CURRENT_INSN.
    3656                 :             :    Registers that already have bits set in REG_SET will not be considered.
    3657                 :             : 
    3658                 :             :    If an appropriate register is available, it will be returned and the
    3659                 :             :    corresponding bit(s) in REG_SET will be set; otherwise, NULL_RTX is
    3660                 :             :    returned.  */
    3661                 :             : 
    3662                 :             : rtx
    3663                 :      568685 : peep2_find_free_register (int from, int to, const char *class_str,
    3664                 :             :                           machine_mode mode, HARD_REG_SET *reg_set)
    3665                 :             : {
    3666                 :      568685 :   enum reg_class cl;
    3667                 :      568685 :   HARD_REG_SET live;
    3668                 :      568685 :   df_ref def;
    3669                 :      568685 :   int i;
    3670                 :             : 
    3671                 :      568685 :   gcc_assert (from < MAX_INSNS_PER_PEEP2 + 1);
    3672                 :      568685 :   gcc_assert (to < MAX_INSNS_PER_PEEP2 + 1);
    3673                 :             : 
    3674                 :      568685 :   from = peep2_buf_position (peep2_current + from);
    3675                 :      568685 :   to = peep2_buf_position (peep2_current + to);
    3676                 :             : 
    3677                 :      568685 :   gcc_assert (peep2_insn_data[from].insn != NULL_RTX);
    3678                 :      568685 :   REG_SET_TO_HARD_REG_SET (live, peep2_insn_data[from].live_before);
    3679                 :             : 
    3680                 :      568685 :   while (from != to)
    3681                 :             :     {
    3682                 :       17215 :       gcc_assert (peep2_insn_data[from].insn != NULL_RTX);
    3683                 :             : 
    3684                 :             :       /* Don't use registers set or clobbered by the insn.  */
    3685                 :       68860 :       FOR_EACH_INSN_DEF (def, peep2_insn_data[from].insn)
    3686                 :       51645 :         SET_HARD_REG_BIT (live, DF_REF_REGNO (def));
    3687                 :             : 
    3688                 :      603115 :       from = peep2_buf_position (from + 1);
    3689                 :             :     }
    3690                 :             : 
    3691                 :      568685 :   cl = reg_class_for_constraint (lookup_constraint (class_str));
    3692                 :             : 
    3693                 :     5106514 :   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
    3694                 :             :     {
    3695                 :     5103245 :       int raw_regno, regno, j;
    3696                 :     5103245 :       bool success;
    3697                 :             : 
    3698                 :             :       /* Distribute the free registers as much as possible.  */
    3699                 :     5103245 :       raw_regno = search_ofs + i;
    3700                 :     5103245 :       if (raw_regno >= FIRST_PSEUDO_REGISTER)
    3701                 :      203614 :         raw_regno -= FIRST_PSEUDO_REGISTER;
    3702                 :             : #ifdef REG_ALLOC_ORDER
    3703                 :     5103245 :       regno = reg_alloc_order[raw_regno];
    3704                 :             : #else
    3705                 :             :       regno = raw_regno;
    3706                 :             : #endif
    3707                 :             : 
    3708                 :             :       /* Can it support the mode we need?  */
    3709                 :     5103245 :       if (!targetm.hard_regno_mode_ok (regno, mode))
    3710                 :     1552072 :         continue;
    3711                 :             : 
    3712                 :     4116589 :       success = true;
    3713                 :     4116589 :       for (j = 0; success && j < hard_regno_nregs (regno, mode); j++)
    3714                 :             :         {
    3715                 :             :           /* Don't allocate fixed registers.  */
    3716                 :     3551173 :           if (fixed_regs[regno + j])
    3717                 :             :             {
    3718                 :             :               success = false;
    3719                 :             :               break;
    3720                 :             :             }
    3721                 :             :           /* Don't allocate global registers.  */
    3722                 :     1831561 :           if (global_regs[regno + j])
    3723                 :             :             {
    3724                 :             :               success = false;
    3725                 :             :               break;
    3726                 :             :             }
    3727                 :             :           /* Make sure the register is of the right class.  */
    3728                 :     1831561 :           if (! TEST_HARD_REG_BIT (reg_class_contents[cl], regno + j))
    3729                 :             :             {
    3730                 :             :               success = false;
    3731                 :             :               break;
    3732                 :             :             }
    3733                 :             :           /* And that we don't create an extra save/restore.  */
    3734                 :      989852 :           if (! crtl->abi->clobbers_full_reg_p (regno + j)
    3735                 :      989852 :               && ! df_regs_ever_live_p (regno + j))
    3736                 :             :             {
    3737                 :             :               success = false;
    3738                 :             :               break;
    3739                 :             :             }
    3740                 :             : 
    3741                 :      968264 :           if (! targetm.hard_regno_scratch_ok (regno + j))
    3742                 :             :             {
    3743                 :             :               success = false;
    3744                 :             :               break;
    3745                 :             :             }
    3746                 :             : 
    3747                 :             :           /* And we don't clobber traceback for noreturn functions.  */
    3748                 :      968136 :           if ((regno + j == FRAME_POINTER_REGNUM
    3749                 :      968136 :                || regno + j == HARD_FRAME_POINTER_REGNUM)
    3750                 :       45591 :               && (! reload_completed || frame_pointer_needed))
    3751                 :             :             {
    3752                 :             :               success = false;
    3753                 :             :               break;
    3754                 :             :             }
    3755                 :             : 
    3756                 :      958188 :           if (TEST_HARD_REG_BIT (*reg_set, regno + j)
    3757                 :      958188 :               || TEST_HARD_REG_BIT (live, regno + j))
    3758                 :             :             {
    3759                 :             :               success = false;
    3760                 :             :               break;
    3761                 :             :             }
    3762                 :             :         }
    3763                 :             : 
    3764                 :     3551173 :       if (success)
    3765                 :             :         {
    3766                 :      565416 :           add_to_hard_reg_set (reg_set, mode, regno);
    3767                 :             : 
    3768                 :             :           /* Start the next search with the next register.  */
    3769                 :      565416 :           if (++raw_regno >= FIRST_PSEUDO_REGISTER)
    3770                 :        6909 :             raw_regno = 0;
    3771                 :      565416 :           search_ofs = raw_regno;
    3772                 :             : 
    3773                 :      565416 :           return gen_rtx_REG (mode, regno);
    3774                 :             :         }
    3775                 :             :     }
    3776                 :             : 
    3777                 :        3269 :   search_ofs = 0;
    3778                 :        3269 :   return NULL_RTX;
    3779                 :             : }
    3780                 :             : 
    3781                 :             : /* Forget all currently tracked instructions, only remember current
    3782                 :             :    LIVE regset.  */
    3783                 :             : 
    3784                 :             : static void
    3785                 :     9787679 : peep2_reinit_state (regset live)
    3786                 :             : {
    3787                 :     9787679 :   int i;
    3788                 :             : 
    3789                 :             :   /* Indicate that all slots except the last holds invalid data.  */
    3790                 :    68513753 :   for (i = 0; i < MAX_INSNS_PER_PEEP2; ++i)
    3791                 :    58726074 :     peep2_insn_data[i].insn = NULL;
    3792                 :     9787679 :   peep2_current_count = 0;
    3793                 :             : 
    3794                 :             :   /* Indicate that the last slot contains live_after data.  */
    3795                 :     9787679 :   peep2_insn_data[MAX_INSNS_PER_PEEP2].insn = PEEP2_EOB;
    3796                 :     9787679 :   peep2_current = MAX_INSNS_PER_PEEP2;
    3797                 :             : 
    3798                 :     9787679 :   COPY_REG_SET (peep2_insn_data[MAX_INSNS_PER_PEEP2].live_before, live);
    3799                 :     9787679 : }
    3800                 :             : 
    3801                 :             : /* Copies frame related info of an insn (OLD_INSN) to the single
    3802                 :             :    insn (NEW_INSN) that was obtained by splitting OLD_INSN.  */
    3803                 :             : 
    3804                 :             : void
    3805                 :       42086 : copy_frame_info_to_split_insn (rtx_insn *old_insn, rtx_insn *new_insn)
    3806                 :             : {
    3807                 :       42086 :   bool any_note = false;
    3808                 :       42086 :   rtx note;
    3809                 :             : 
    3810                 :       42086 :   if (!RTX_FRAME_RELATED_P (old_insn))
    3811                 :             :     return;
    3812                 :             : 
    3813                 :       42086 :   RTX_FRAME_RELATED_P (new_insn) = 1;
    3814                 :             : 
    3815                 :             :   /* Allow the backend to fill in a note during the split.  */
    3816                 :       42086 :   for (note = REG_NOTES (new_insn); note ; note = XEXP (note, 1))
    3817                 :           0 :     switch (REG_NOTE_KIND (note))
    3818                 :             :       {
    3819                 :           0 :       case REG_FRAME_RELATED_EXPR:
    3820                 :           0 :       case REG_CFA_DEF_CFA:
    3821                 :           0 :       case REG_CFA_ADJUST_CFA:
    3822                 :           0 :       case REG_CFA_OFFSET:
    3823                 :           0 :       case REG_CFA_REGISTER:
    3824                 :           0 :       case REG_CFA_EXPRESSION:
    3825                 :           0 :       case REG_CFA_RESTORE:
    3826                 :           0 :       case REG_CFA_SET_VDRAP:
    3827                 :           0 :         any_note = true;
    3828                 :           0 :         break;
    3829                 :             :       default:
    3830                 :             :         break;
    3831                 :             :       }
    3832                 :             : 
    3833                 :             :   /* If the backend didn't supply a note, copy one over.  */
    3834                 :       42086 :   if (!any_note)
    3835                 :      126072 :     for (note = REG_NOTES (old_insn); note ; note = XEXP (note, 1))
    3836                 :       83986 :       switch (REG_NOTE_KIND (note))
    3837                 :             :         {
    3838                 :       41913 :         case REG_FRAME_RELATED_EXPR:
    3839                 :       41913 :         case REG_CFA_DEF_CFA:
    3840                 :       41913 :         case REG_CFA_ADJUST_CFA:
    3841                 :       41913 :         case REG_CFA_OFFSET:
    3842                 :       41913 :         case REG_CFA_REGISTER:
    3843                 :       41913 :         case REG_CFA_EXPRESSION:
    3844                 :       41913 :         case REG_CFA_RESTORE:
    3845                 :       41913 :         case REG_CFA_SET_VDRAP:
    3846                 :       41913 :           add_reg_note (new_insn, REG_NOTE_KIND (note), XEXP (note, 0));
    3847                 :       41913 :           any_note = true;
    3848                 :       41913 :           break;
    3849                 :             :         default:
    3850                 :             :           break;
    3851                 :             :         }
    3852                 :             : 
    3853                 :             :   /* If there still isn't a note, make sure the unwind info sees the
    3854                 :             :      same expression as before the split.  */
    3855                 :       42086 :   if (!any_note)
    3856                 :             :     {
    3857                 :         173 :       rtx old_set, new_set;
    3858                 :             : 
    3859                 :             :       /* The old insn had better have been simple, or annotated.  */
    3860                 :         173 :       old_set = single_set (old_insn);
    3861                 :         173 :       gcc_assert (old_set != NULL);
    3862                 :             : 
    3863                 :         173 :       new_set = single_set (new_insn);
    3864                 :         173 :       if (!new_set || !rtx_equal_p (new_set, old_set))
    3865                 :         173 :         add_reg_note (new_insn, REG_FRAME_RELATED_EXPR, old_set);
    3866                 :             :     }
    3867                 :             : 
    3868                 :             :   /* Copy prologue/epilogue status.  This is required in order to keep
    3869                 :             :      proper placement of EPILOGUE_BEG and the DW_CFA_remember_state.  */
    3870                 :       42086 :   maybe_copy_prologue_epilogue_insn (old_insn, new_insn);
    3871                 :             : }
    3872                 :             : 
    3873                 :             : /* While scanning basic block BB, we found a match of length MATCH_LEN + 1,
    3874                 :             :    starting at INSN.  Perform the replacement, removing the old insns and
    3875                 :             :    replacing them with ATTEMPT.  Returns the last insn emitted, or NULL
    3876                 :             :    if the replacement is rejected.  */
    3877                 :             : 
    3878                 :             : static rtx_insn *
    3879                 :     2113002 : peep2_attempt (basic_block bb, rtx_insn *insn, int match_len, rtx_insn *attempt)
    3880                 :             : {
    3881                 :     2113002 :   int i;
    3882                 :     2113002 :   rtx_insn *last, *before_try, *x;
    3883                 :     2113002 :   rtx eh_note, as_note;
    3884                 :     2113002 :   rtx_insn *old_insn;
    3885                 :     2113002 :   rtx_insn *new_insn;
    3886                 :     2113002 :   bool was_call = false;
    3887                 :             : 
    3888                 :             :   /* If we are splitting an RTX_FRAME_RELATED_P insn, do not allow it to
    3889                 :             :      match more than one insn, or to be split into more than one insn.  */
    3890                 :     2113002 :   old_insn = peep2_insn_data[peep2_current].insn;
    3891                 :     2113002 :   if (RTX_FRAME_RELATED_P (old_insn))
    3892                 :             :     {
    3893                 :       44620 :       if (match_len != 0)
    3894                 :             :         return NULL;
    3895                 :             : 
    3896                 :             :       /* Look for one "active" insn.  I.e. ignore any "clobber" insns that
    3897                 :             :          may be in the stream for the purpose of register allocation.  */
    3898                 :       44620 :       if (active_insn_p (attempt))
    3899                 :             :         new_insn = attempt;
    3900                 :             :       else
    3901                 :       32066 :         new_insn = next_active_insn (attempt);
    3902                 :       44620 :       if (next_active_insn (new_insn))
    3903                 :             :         return NULL;
    3904                 :             : 
    3905                 :             :       /* We have a 1-1 replacement.  Copy over any frame-related info.  */
    3906                 :       42069 :       copy_frame_info_to_split_insn (old_insn, new_insn);
    3907                 :             :     }
    3908                 :             : 
    3909                 :             :   /* If we are splitting a CALL_INSN, look for the CALL_INSN
    3910                 :             :      in SEQ and copy our CALL_INSN_FUNCTION_USAGE and other
    3911                 :             :      cfg-related call notes.  */
    3912                 :     4441926 :   for (i = 0; i <= match_len; ++i)
    3913                 :             :     {
    3914                 :     2332840 :       int j;
    3915                 :     2332840 :       rtx note;
    3916                 :             : 
    3917                 :     2332840 :       j = peep2_buf_position (peep2_current + i);
    3918                 :     2332840 :       old_insn = peep2_insn_data[j].insn;
    3919                 :     2332840 :       if (!CALL_P (old_insn))
    3920                 :     2331475 :         continue;
    3921                 :        1365 :       was_call = true;
    3922                 :             : 
    3923                 :             :       new_insn = attempt;
    3924                 :        1365 :       while (new_insn != NULL_RTX)
    3925                 :             :         {
    3926                 :        1365 :           if (CALL_P (new_insn))
    3927                 :             :             break;
    3928                 :           0 :           new_insn = NEXT_INSN (new_insn);
    3929                 :             :         }
    3930                 :             : 
    3931                 :        1365 :       gcc_assert (new_insn != NULL_RTX);
    3932                 :             : 
    3933                 :        1365 :       CALL_INSN_FUNCTION_USAGE (new_insn)
    3934                 :        1365 :         = CALL_INSN_FUNCTION_USAGE (old_insn);
    3935                 :        1365 :       SIBLING_CALL_P (new_insn) = SIBLING_CALL_P (old_insn);
    3936                 :             : 
    3937                 :        1365 :       for (note = REG_NOTES (old_insn);
    3938                 :        6827 :            note;
    3939                 :        5462 :            note = XEXP (note, 1))
    3940                 :        5462 :         switch (REG_NOTE_KIND (note))
    3941                 :             :           {
    3942                 :           0 :           case REG_NORETURN:
    3943                 :           0 :           case REG_SETJMP:
    3944                 :           0 :           case REG_TM:
    3945                 :           0 :           case REG_CALL_NOCF_CHECK:
    3946                 :           0 :             add_reg_note (new_insn, REG_NOTE_KIND (note),
    3947                 :             :                           XEXP (note, 0));
    3948                 :           0 :             break;
    3949                 :             :           default:
    3950                 :             :             /* Discard all other reg notes.  */
    3951                 :             :             break;
    3952                 :             :           }
    3953                 :             : 
    3954                 :             :       /* Croak if there is another call in the sequence.  */
    3955                 :        1365 :       while (++i <= match_len)
    3956                 :             :         {
    3957                 :           0 :           j = peep2_buf_position (peep2_current + i);
    3958                 :           0 :           old_insn = peep2_insn_data[j].insn;
    3959                 :           0 :           gcc_assert (!CALL_P (old_insn));
    3960                 :             :         }
    3961                 :             :       break;
    3962                 :             :     }
    3963                 :             : 
    3964                 :             :   /* If we matched any instruction that had a REG_ARGS_SIZE, then
    3965                 :             :      move those notes over to the new sequence.  */
    3966                 :     2110451 :   as_note = NULL;
    3967                 :     4327206 :   for (i = match_len; i >= 0; --i)
    3968                 :             :     {
    3969                 :     2332840 :       int j = peep2_buf_position (peep2_current + i);
    3970                 :     2332840 :       old_insn = peep2_insn_data[j].insn;
    3971                 :             : 
    3972                 :     2332840 :       as_note = find_reg_note (old_insn, REG_ARGS_SIZE, NULL);
    3973                 :     2332840 :       if (as_note)
    3974                 :             :         break;
    3975                 :             :     }
    3976                 :             : 
    3977                 :     2110451 :   i = peep2_buf_position (peep2_current + match_len);
    3978                 :     2110451 :   eh_note = find_reg_note (peep2_insn_data[i].insn, REG_EH_REGION, NULL_RTX);
    3979                 :             : 
    3980                 :             :   /* Replace the old sequence with the new.  */
    3981                 :     2110451 :   rtx_insn *peepinsn = peep2_insn_data[i].insn;
    3982                 :     4220902 :   last = emit_insn_after_setloc (attempt,
    3983                 :             :                                  peep2_insn_data[i].insn,
    3984                 :     2110451 :                                  INSN_LOCATION (peepinsn));
    3985                 :     2110451 :   if (JUMP_P (peepinsn) && JUMP_P (last))
    3986                 :        2977 :     CROSSING_JUMP_P (last) = CROSSING_JUMP_P (peepinsn);
    3987                 :     2110451 :   before_try = PREV_INSN (insn);
    3988                 :     2110451 :   delete_insn_chain (insn, peep2_insn_data[i].insn, false);
    3989                 :             : 
    3990                 :             :   /* Re-insert the EH_REGION notes.  */
    3991                 :     2110451 :   if (eh_note || (was_call && nonlocal_goto_handler_labels))
    3992                 :             :     {
    3993                 :         559 :       edge eh_edge;
    3994                 :         559 :       edge_iterator ei;
    3995                 :             : 
    3996                 :        1079 :       FOR_EACH_EDGE (eh_edge, ei, bb->succs)
    3997                 :         565 :         if (eh_edge->flags & (EDGE_EH | EDGE_ABNORMAL_CALL))
    3998                 :             :           break;
    3999                 :             : 
    4000                 :         559 :       if (eh_note)
    4001                 :         559 :         copy_reg_eh_region_note_backward (eh_note, last, before_try);
    4002                 :             : 
    4003                 :         559 :       if (eh_edge)
    4004                 :         136 :         for (x = last; x != before_try; x = PREV_INSN (x))
    4005                 :          91 :           if (x != BB_END (bb)
    4006                 :          91 :               && (can_throw_internal (x)
    4007                 :          46 :                   || can_nonlocal_goto (x)))
    4008                 :             :             {
    4009                 :           1 :               edge nfte, nehe;
    4010                 :           1 :               int flags;
    4011                 :             : 
    4012                 :           1 :               nfte = split_block (bb, x);
    4013                 :           1 :               flags = (eh_edge->flags
    4014                 :             :                        & (EDGE_EH | EDGE_ABNORMAL));
    4015                 :           1 :               if (CALL_P (x))
    4016                 :           0 :                 flags |= EDGE_ABNORMAL_CALL;
    4017                 :           1 :               nehe = make_edge (nfte->src, eh_edge->dest,
    4018                 :             :                                 flags);
    4019                 :             : 
    4020                 :           1 :               nehe->probability = eh_edge->probability;
    4021                 :           1 :               nfte->probability = nehe->probability.invert ();
    4022                 :             : 
    4023                 :           1 :               peep2_do_cleanup_cfg |= purge_dead_edges (nfte->dest);
    4024                 :           1 :               bb = nfte->src;
    4025                 :           1 :               eh_edge = nehe;
    4026                 :             :             }
    4027                 :             : 
    4028                 :             :       /* Converting possibly trapping insn to non-trapping is
    4029                 :             :          possible.  Zap dummy outgoing edges.  */
    4030                 :         559 :       peep2_do_cleanup_cfg |= purge_dead_edges (bb);
    4031                 :             :     }
    4032                 :             : 
    4033                 :             :   /* Re-insert the ARGS_SIZE notes.  */
    4034                 :     2110451 :   if (as_note)
    4035                 :      116085 :     fixup_args_size_notes (before_try, last, get_args_size (as_note));
    4036                 :             : 
    4037                 :             :   /* Scan the new insns for embedded side effects and add appropriate
    4038                 :             :      REG_INC notes.  */
    4039                 :             :   if (AUTO_INC_DEC)
    4040                 :             :     for (x = last; x != before_try; x = PREV_INSN (x))
    4041                 :             :       if (NONDEBUG_INSN_P (x))
    4042                 :             :         add_auto_inc_notes (x, PATTERN (x));
    4043                 :             : 
    4044                 :             :   /* If we generated a jump instruction, it won't have
    4045                 :             :      JUMP_LABEL set.  Recompute after we're done.  */
    4046                 :     4922978 :   for (x = last; x != before_try; x = PREV_INSN (x))
    4047                 :     2815504 :     if (JUMP_P (x))
    4048                 :             :       {
    4049                 :        2977 :         peep2_do_rebuild_jump_labels = true;
    4050                 :        2977 :         break;
    4051                 :             :       }
    4052                 :             : 
    4053                 :             :   return last;
    4054                 :             : }
    4055                 :             : 
    4056                 :             : /* After performing a replacement in basic block BB, fix up the life
    4057                 :             :    information in our buffer.  LAST is the last of the insns that we
    4058                 :             :    emitted as a replacement.  PREV is the insn before the start of
    4059                 :             :    the replacement.  MATCH_LEN + 1 is the number of instructions that were
    4060                 :             :    matched, and which now need to be replaced in the buffer.  */
    4061                 :             : 
    4062                 :             : static void
    4063                 :     2110451 : peep2_update_life (basic_block bb, int match_len, rtx_insn *last,
    4064                 :             :                    rtx_insn *prev)
    4065                 :             : {
    4066                 :     2110451 :   int i = peep2_buf_position (peep2_current + match_len + 1);
    4067                 :     2110451 :   rtx_insn *x;
    4068                 :     2110451 :   regset_head live;
    4069                 :             : 
    4070                 :     2110451 :   INIT_REG_SET (&live);
    4071                 :     2110451 :   COPY_REG_SET (&live, peep2_insn_data[i].live_before);
    4072                 :             : 
    4073                 :     2110451 :   gcc_assert (peep2_current_count >= match_len + 1);
    4074                 :     2110451 :   peep2_current_count -= match_len + 1;
    4075                 :             : 
    4076                 :     2110451 :   x = last;
    4077                 :     2818367 :   do
    4078                 :             :     {
    4079                 :     2818367 :       if (INSN_P (x))
    4080                 :             :         {
    4081                 :     2818366 :           df_insn_rescan (x);
    4082                 :     2818366 :           if (peep2_current_count < MAX_INSNS_PER_PEEP2)
    4083                 :             :             {
    4084                 :     2677045 :               peep2_current_count++;
    4085                 :     2677045 :               if (--i < 0)
    4086                 :      735432 :                 i = MAX_INSNS_PER_PEEP2;
    4087                 :     2677045 :               peep2_insn_data[i].insn = x;
    4088                 :     2677045 :               df_simulate_one_insn_backwards (bb, x, &live);
    4089                 :     2677045 :               COPY_REG_SET (peep2_insn_data[i].live_before, &live);
    4090                 :             :             }
    4091                 :             :         }
    4092                 :     2818367 :       x = PREV_INSN (x);
    4093                 :             :     }
    4094                 :     2818367 :   while (x != prev);
    4095                 :     2110451 :   CLEAR_REG_SET (&live);
    4096                 :             : 
    4097                 :     2110451 :   peep2_current = i;
    4098                 :     2110451 : }
    4099                 :             : 
    4100                 :             : /* Add INSN, which is in BB, at the end of the peep2 insn buffer if possible.
    4101                 :             :    Return true if we added it, false otherwise.  The caller will try to match
    4102                 :             :    peepholes against the buffer if we return false; otherwise it will try to
    4103                 :             :    add more instructions to the buffer.  */
    4104                 :             : 
    4105                 :             : static bool
    4106                 :    76962293 : peep2_fill_buffer (basic_block bb, rtx_insn *insn, regset live)
    4107                 :             : {
    4108                 :    76962293 :   int pos;
    4109                 :             : 
    4110                 :             :   /* Once we have filled the maximum number of insns the buffer can hold,
    4111                 :             :      allow the caller to match the insns against peepholes.  We wait until
    4112                 :             :      the buffer is full in case the target has similar peepholes of different
    4113                 :             :      length; we always want to match the longest if possible.  */
    4114                 :    76962293 :   if (peep2_current_count == MAX_INSNS_PER_PEEP2)
    4115                 :             :     return false;
    4116                 :             : 
    4117                 :             :   /* If an insn has RTX_FRAME_RELATED_P set, do not allow it to be matched with
    4118                 :             :      any other pattern, lest it change the semantics of the frame info.  */
    4119                 :    59100399 :   if (RTX_FRAME_RELATED_P (insn))
    4120                 :             :     {
    4121                 :             :       /* Let the buffer drain first.  */
    4122                 :     7744105 :       if (peep2_current_count > 0)
    4123                 :             :         return false;
    4124                 :             :       /* Now the insn will be the only thing in the buffer.  */
    4125                 :             :     }
    4126                 :             : 
    4127                 :    54820926 :   pos = peep2_buf_position (peep2_current + peep2_current_count);
    4128                 :    54820926 :   peep2_insn_data[pos].insn = insn;
    4129                 :    54820926 :   COPY_REG_SET (peep2_insn_data[pos].live_before, live);
    4130                 :    54820926 :   peep2_current_count++;
    4131                 :             : 
    4132                 :    54820926 :   df_simulate_one_insn_forwards (bb, insn, live);
    4133                 :    54820926 :   return true;
    4134                 :             : }
    4135                 :             : 
    4136                 :             : /* Perform the peephole2 optimization pass.  */
    4137                 :             : 
    4138                 :             : static void
    4139                 :      914371 : peephole2_optimize (void)
    4140                 :             : {
    4141                 :      914371 :   rtx_insn *insn;
    4142                 :      914371 :   bitmap live;
    4143                 :      914371 :   int i;
    4144                 :      914371 :   basic_block bb;
    4145                 :             : 
    4146                 :      914371 :   peep2_do_cleanup_cfg = false;
    4147                 :      914371 :   peep2_do_rebuild_jump_labels = false;
    4148                 :             : 
    4149                 :      914371 :   df_set_flags (DF_LR_RUN_DCE);
    4150                 :      914371 :   df_note_add_problem ();
    4151                 :      914371 :   df_analyze ();
    4152                 :             : 
    4153                 :             :   /* Initialize the regsets we're going to use.  */
    4154                 :     8229339 :   for (i = 0; i < MAX_INSNS_PER_PEEP2 + 1; ++i)
    4155                 :     6400597 :     peep2_insn_data[i].live_before = BITMAP_ALLOC (&reg_obstack);
    4156                 :      914371 :   search_ofs = 0;
    4157                 :      914371 :   live = BITMAP_ALLOC (&reg_obstack);
    4158                 :             : 
    4159                 :    10702050 :   FOR_EACH_BB_REVERSE_FN (bb, cfun)
    4160                 :             :     {
    4161                 :     9787679 :       bool past_end = false;
    4162                 :     9787679 :       int pos;
    4163                 :             : 
    4164                 :     9787679 :       rtl_profile_for_bb (bb);
    4165                 :             : 
    4166                 :             :       /* Start up propagation.  */
    4167                 :    19575358 :       bitmap_copy (live, DF_LR_IN (bb));
    4168                 :     9787679 :       df_simulate_initialize_forwards (bb, live);
    4169                 :     9787679 :       peep2_reinit_state (live);
    4170                 :             : 
    4171                 :     9787679 :       insn = BB_HEAD (bb);
    4172                 :   181394255 :       for (;;)
    4173                 :             :         {
    4174                 :   181394255 :           rtx_insn *attempt, *head;
    4175                 :   181394255 :           int match_len;
    4176                 :             : 
    4177                 :   181394255 :           if (!past_end && !NONDEBUG_INSN_P (insn))
    4178                 :             :             {
    4179                 :    59510068 :             next_insn:
    4180                 :   114330994 :               insn = NEXT_INSN (insn);
    4181                 :   114330994 :               if (insn == NEXT_INSN (BB_END (bb)))
    4182                 :     9787679 :                 past_end = true;
    4183                 :   116441445 :               continue;
    4184                 :             :             }
    4185                 :    76962293 :           if (!past_end && peep2_fill_buffer (bb, insn, live))
    4186                 :    54820926 :             goto next_insn;
    4187                 :             : 
    4188                 :             :           /* If we did not fill an empty buffer, it signals the end of the
    4189                 :             :              block.  */
    4190                 :    67063261 :           if (peep2_current_count == 0)
    4191                 :             :             break;
    4192                 :             : 
    4193                 :             :           /* The buffer filled to the current maximum, so try to match.  */
    4194                 :             : 
    4195                 :    57275582 :           pos = peep2_buf_position (peep2_current + peep2_current_count);
    4196                 :    57275582 :           peep2_insn_data[pos].insn = PEEP2_EOB;
    4197                 :    57275582 :           COPY_REG_SET (peep2_insn_data[pos].live_before, live);
    4198                 :             : 
    4199                 :             :           /* Match the peephole.  */
    4200                 :    57275582 :           head = peep2_insn_data[peep2_current].insn;
    4201                 :    57275582 :           attempt = peephole2_insns (PATTERN (head), head, &match_len);
    4202                 :    57275582 :           if (attempt != NULL)
    4203                 :             :             {
    4204                 :     2113002 :               rtx_insn *last = peep2_attempt (bb, head, match_len, attempt);
    4205                 :     2113002 :               if (last)
    4206                 :             :                 {
    4207                 :     2110451 :                   peep2_update_life (bb, match_len, last, PREV_INSN (attempt));
    4208                 :     2110451 :                   continue;
    4209                 :             :                 }
    4210                 :             :             }
    4211                 :             : 
    4212                 :             :           /* No match: advance the buffer by one insn.  */
    4213                 :    55165131 :           peep2_current = peep2_buf_position (peep2_current + 1);
    4214                 :    55165131 :           peep2_current_count--;
    4215                 :             :         }
    4216                 :             :     }
    4217                 :             : 
    4218                 :      914371 :   default_rtl_profile ();
    4219                 :     8229339 :   for (i = 0; i < MAX_INSNS_PER_PEEP2 + 1; ++i)
    4220                 :     6400597 :     BITMAP_FREE (peep2_insn_data[i].live_before);
    4221                 :      914371 :   BITMAP_FREE (live);
    4222                 :      914371 :   if (peep2_do_rebuild_jump_labels)
    4223                 :        2148 :     rebuild_jump_labels (get_insns ());
    4224                 :      914371 :   if (peep2_do_cleanup_cfg)
    4225                 :           0 :     cleanup_cfg (CLEANUP_CFG_CHANGED);
    4226                 :      914371 : }
    4227                 :             : 
    4228                 :             : /* Common predicates for use with define_bypass.  */
    4229                 :             : 
    4230                 :             : /* Helper function for store_data_bypass_p, handle just a single SET
    4231                 :             :    IN_SET.  */
    4232                 :             : 
    4233                 :             : static bool
    4234                 :           0 : store_data_bypass_p_1 (rtx_insn *out_insn, rtx in_set)
    4235                 :             : {
    4236                 :           0 :   if (!MEM_P (SET_DEST (in_set)))
    4237                 :             :     return false;
    4238                 :             : 
    4239                 :           0 :   rtx out_set = single_set (out_insn);
    4240                 :           0 :   if (out_set)
    4241                 :           0 :     return !reg_mentioned_p (SET_DEST (out_set), SET_DEST (in_set));
    4242                 :             : 
    4243                 :           0 :   rtx out_pat = PATTERN (out_insn);
    4244                 :           0 :   if (GET_CODE (out_pat) != PARALLEL)
    4245                 :             :     return false;
    4246                 :             : 
    4247                 :           0 :   for (int i = 0; i < XVECLEN (out_pat, 0); i++)
    4248                 :             :     {
    4249                 :           0 :       rtx out_exp = XVECEXP (out_pat, 0, i);
    4250                 :             : 
    4251                 :           0 :       if (GET_CODE (out_exp) == CLOBBER || GET_CODE (out_exp) == USE)
    4252                 :           0 :         continue;
    4253                 :             : 
    4254                 :           0 :       gcc_assert (GET_CODE (out_exp) == SET);
    4255                 :             : 
    4256                 :           0 :       if (reg_mentioned_p (SET_DEST (out_exp), SET_DEST (in_set)))
    4257                 :             :         return false;
    4258                 :             :     }
    4259                 :             : 
    4260                 :             :   return true;
    4261                 :             : }
    4262                 :             : 
    4263                 :             : /* True if the dependency between OUT_INSN and IN_INSN is on the store
    4264                 :             :    data not the address operand(s) of the store.  IN_INSN and OUT_INSN
    4265                 :             :    must be either a single_set or a PARALLEL with SETs inside.  */
    4266                 :             : 
    4267                 :             : bool
    4268                 :           0 : store_data_bypass_p (rtx_insn *out_insn, rtx_insn *in_insn)
    4269                 :             : {
    4270                 :           0 :   rtx in_set = single_set (in_insn);
    4271                 :           0 :   if (in_set)
    4272                 :           0 :     return store_data_bypass_p_1 (out_insn, in_set);
    4273                 :             : 
    4274                 :           0 :   rtx in_pat = PATTERN (in_insn);
    4275                 :           0 :   if (GET_CODE (in_pat) != PARALLEL)
    4276                 :             :     return false;
    4277                 :             : 
    4278                 :           0 :   for (int i = 0; i < XVECLEN (in_pat, 0); i++)
    4279                 :             :     {
    4280                 :           0 :       rtx in_exp = XVECEXP (in_pat, 0, i);
    4281                 :             : 
    4282                 :           0 :       if (GET_CODE (in_exp) == CLOBBER || GET_CODE (in_exp) == USE)
    4283                 :           0 :         continue;
    4284                 :             : 
    4285                 :           0 :       gcc_assert (GET_CODE (in_exp) == SET);
    4286                 :             : 
    4287                 :           0 :       if (!store_data_bypass_p_1 (out_insn, in_exp))
    4288                 :             :         return false;
    4289                 :             :     }
    4290                 :             : 
    4291                 :             :   return true;
    4292                 :             : }
    4293                 :             : 
    4294                 :             : /* True if the dependency between OUT_INSN and IN_INSN is in the IF_THEN_ELSE
    4295                 :             :    condition, and not the THEN or ELSE branch.  OUT_INSN may be either a single
    4296                 :             :    or multiple set; IN_INSN should be single_set for truth, but for convenience
    4297                 :             :    of insn categorization may be any JUMP or CALL insn.  */
    4298                 :             : 
    4299                 :             : bool
    4300                 :           0 : if_test_bypass_p (rtx_insn *out_insn, rtx_insn *in_insn)
    4301                 :             : {
    4302                 :           0 :   rtx out_set, in_set;
    4303                 :             : 
    4304                 :           0 :   in_set = single_set (in_insn);
    4305                 :           0 :   if (! in_set)
    4306                 :             :     {
    4307                 :           0 :       gcc_assert (JUMP_P (in_insn) || CALL_P (in_insn));
    4308                 :             :       return false;
    4309                 :             :     }
    4310                 :             : 
    4311                 :           0 :   if (GET_CODE (SET_SRC (in_set)) != IF_THEN_ELSE)
    4312                 :             :     return false;
    4313                 :           0 :   in_set = SET_SRC (in_set);
    4314                 :             : 
    4315                 :           0 :   out_set = single_set (out_insn);
    4316                 :           0 :   if (out_set)
    4317                 :             :     {
    4318                 :           0 :       if (reg_mentioned_p (SET_DEST (out_set), XEXP (in_set, 1))
    4319                 :           0 :           || reg_mentioned_p (SET_DEST (out_set), XEXP (in_set, 2)))
    4320                 :           0 :         return false;
    4321                 :             :     }
    4322                 :             :   else
    4323                 :             :     {
    4324                 :           0 :       rtx out_pat;
    4325                 :           0 :       int i;
    4326                 :             : 
    4327                 :           0 :       out_pat = PATTERN (out_insn);
    4328                 :           0 :       gcc_assert (GET_CODE (out_pat) == PARALLEL);
    4329                 :             : 
    4330                 :           0 :       for (i = 0; i < XVECLEN (out_pat, 0); i++)
    4331                 :             :         {
    4332                 :           0 :           rtx exp = XVECEXP (out_pat, 0, i);
    4333                 :             : 
    4334                 :           0 :           if (GET_CODE (exp) == CLOBBER)
    4335                 :           0 :             continue;
    4336                 :             : 
    4337                 :           0 :           gcc_assert (GET_CODE (exp) == SET);
    4338                 :             : 
    4339                 :           0 :           if (reg_mentioned_p (SET_DEST (out_set), XEXP (in_set, 1))
    4340                 :           0 :               || reg_mentioned_p (SET_DEST (out_set), XEXP (in_set, 2)))
    4341                 :           0 :             return false;
    4342                 :             :         }
    4343                 :             :     }
    4344                 :             : 
    4345                 :             :   return true;
    4346                 :             : }
    4347                 :             : 
    4348                 :             : static unsigned int
    4349                 :      914371 : rest_of_handle_peephole2 (void)
    4350                 :             : {
    4351                 :      914371 :   if (HAVE_peephole2)
    4352                 :           0 :     peephole2_optimize ();
    4353                 :             : 
    4354                 :      914371 :   return 0;
    4355                 :             : }
    4356                 :             : 
    4357                 :             : namespace {
    4358                 :             : 
    4359                 :             : const pass_data pass_data_peephole2 =
    4360                 :             : {
    4361                 :             :   RTL_PASS, /* type */
    4362                 :             :   "peephole2", /* name */
    4363                 :             :   OPTGROUP_NONE, /* optinfo_flags */
    4364                 :             :   TV_PEEPHOLE2, /* tv_id */
    4365                 :             :   0, /* properties_required */
    4366                 :             :   0, /* properties_provided */
    4367                 :             :   0, /* properties_destroyed */
    4368                 :             :   0, /* todo_flags_start */
    4369                 :             :   TODO_df_finish, /* todo_flags_finish */
    4370                 :             : };
    4371                 :             : 
    4372                 :             : class pass_peephole2 : public rtl_opt_pass
    4373                 :             : {
    4374                 :             : public:
    4375                 :      281914 :   pass_peephole2 (gcc::context *ctxt)
    4376                 :      563828 :     : rtl_opt_pass (pass_data_peephole2, ctxt)
    4377                 :             :   {}
    4378                 :             : 
    4379                 :             :   /* opt_pass methods: */
    4380                 :             :   /* The epiphany backend creates a second instance of this pass, so we need
    4381                 :             :      a clone method.  */
    4382                 :           0 :   opt_pass * clone () final override { return new pass_peephole2 (m_ctxt); }
    4383                 :     1426773 :   bool gate (function *) final override
    4384                 :             :   {
    4385                 :     1426773 :     return (optimize > 0 && flag_peephole2);
    4386                 :             :   }
    4387                 :      914371 :   unsigned int execute (function *) final override
    4388                 :             :     {
    4389                 :      914371 :       return rest_of_handle_peephole2 ();
    4390                 :             :     }
    4391                 :             : 
    4392                 :             : }; // class pass_peephole2
    4393                 :             : 
    4394                 :             : } // anon namespace
    4395                 :             : 
    4396                 :             : rtl_opt_pass *
    4397                 :      281914 : make_pass_peephole2 (gcc::context *ctxt)
    4398                 :             : {
    4399                 :      281914 :   return new pass_peephole2 (ctxt);
    4400                 :             : }
    4401                 :             : 
    4402                 :             : namespace {
    4403                 :             : 
    4404                 :             : const pass_data pass_data_split_all_insns =
    4405                 :             : {
    4406                 :             :   RTL_PASS, /* type */
    4407                 :             :   "split1", /* name */
    4408                 :             :   OPTGROUP_NONE, /* optinfo_flags */
    4409                 :             :   TV_NONE, /* tv_id */
    4410                 :             :   0, /* properties_required */
    4411                 :             :   PROP_rtl_split_insns, /* properties_provided */
    4412                 :             :   0, /* properties_destroyed */
    4413                 :             :   0, /* todo_flags_start */
    4414                 :             :   0, /* todo_flags_finish */
    4415                 :             : };
    4416                 :             : 
    4417                 :             : class pass_split_all_insns : public rtl_opt_pass
    4418                 :             : {
    4419                 :             : public:
    4420                 :      281914 :   pass_split_all_insns (gcc::context *ctxt)
    4421                 :      563828 :     : rtl_opt_pass (pass_data_split_all_insns, ctxt)
    4422                 :             :   {}
    4423                 :             : 
    4424                 :             :   /* opt_pass methods: */
    4425                 :             :   /* The epiphany backend creates a second instance of this pass, so
    4426                 :             :      we need a clone method.  */
    4427                 :           0 :   opt_pass * clone () final override
    4428                 :             :   {
    4429                 :           0 :     return new pass_split_all_insns (m_ctxt);
    4430                 :             :   }
    4431                 :     1426762 :   unsigned int execute (function *) final override
    4432                 :             :     {
    4433                 :     1426762 :       split_all_insns ();
    4434                 :     1426762 :       return 0;
    4435                 :             :     }
    4436                 :             : 
    4437                 :             : }; // class pass_split_all_insns
    4438                 :             : 
    4439                 :             : } // anon namespace
    4440                 :             : 
    4441                 :             : rtl_opt_pass *
    4442                 :      281914 : make_pass_split_all_insns (gcc::context *ctxt)
    4443                 :             : {
    4444                 :      281914 :   return new pass_split_all_insns (ctxt);
    4445                 :             : }
    4446                 :             : 
    4447                 :             : namespace {
    4448                 :             : 
    4449                 :             : const pass_data pass_data_split_after_reload =
    4450                 :             : {
    4451                 :             :   RTL_PASS, /* type */
    4452                 :             :   "split2", /* name */
    4453                 :             :   OPTGROUP_NONE, /* optinfo_flags */
    4454                 :             :   TV_NONE, /* tv_id */
    4455                 :             :   0, /* properties_required */
    4456                 :             :   0, /* properties_provided */
    4457                 :             :   0, /* properties_destroyed */
    4458                 :             :   0, /* todo_flags_start */
    4459                 :             :   0, /* todo_flags_finish */
    4460                 :             : };
    4461                 :             : 
    4462                 :             : class pass_split_after_reload : public rtl_opt_pass
    4463                 :             : {
    4464                 :             : public:
    4465                 :      281914 :   pass_split_after_reload (gcc::context *ctxt)
    4466                 :      563828 :     : rtl_opt_pass (pass_data_split_after_reload, ctxt)
    4467                 :             :   {}
    4468                 :             : 
    4469                 :             :   /* opt_pass methods: */
    4470                 :     1426773 :   bool gate (function *) final override
    4471                 :             :     {
    4472                 :             :       /* If optimizing, then go ahead and split insns now.  */
    4473                 :     1426773 :       return optimize > 0;
    4474                 :             :     }
    4475                 :             : 
    4476                 :      987683 :   unsigned int execute (function *) final override
    4477                 :             :     {
    4478                 :      987683 :       split_all_insns ();
    4479                 :      987683 :       return 0;
    4480                 :             :     }
    4481                 :             : 
    4482                 :             : }; // class pass_split_after_reload
    4483                 :             : 
    4484                 :             : } // anon namespace
    4485                 :             : 
    4486                 :             : rtl_opt_pass *
    4487                 :      281914 : make_pass_split_after_reload (gcc::context *ctxt)
    4488                 :             : {
    4489                 :      281914 :   return new pass_split_after_reload (ctxt);
    4490                 :             : }
    4491                 :             : 
    4492                 :             : static bool
    4493                 :     2853546 : enable_split_before_sched2 (void)
    4494                 :             : {
    4495                 :             : #ifdef INSN_SCHEDULING
    4496                 :     1975368 :   return optimize > 0 && flag_schedule_insns_after_reload;
    4497                 :             : #else
    4498                 :             :   return false;
    4499                 :             : #endif
    4500                 :             : }
    4501                 :             : 
    4502                 :             : namespace {
    4503                 :             : 
    4504                 :             : const pass_data pass_data_split_before_sched2 =
    4505                 :             : {
    4506                 :             :   RTL_PASS, /* type */
    4507                 :             :   "split3", /* name */
    4508                 :             :   OPTGROUP_NONE, /* optinfo_flags */
    4509                 :             :   TV_NONE, /* tv_id */
    4510                 :             :   0, /* properties_required */
    4511                 :             :   0, /* properties_provided */
    4512                 :             :   0, /* properties_destroyed */
    4513                 :             :   0, /* todo_flags_start */
    4514                 :             :   0, /* todo_flags_finish */
    4515                 :             : };
    4516                 :             : 
    4517                 :             : class pass_split_before_sched2 : public rtl_opt_pass
    4518                 :             : {
    4519                 :             : public:
    4520                 :      281914 :   pass_split_before_sched2 (gcc::context *ctxt)
    4521                 :      563828 :     : rtl_opt_pass (pass_data_split_before_sched2, ctxt)
    4522                 :             :   {}
    4523                 :             : 
    4524                 :             :   /* opt_pass methods: */
    4525                 :     1426773 :   bool gate (function *) final override
    4526                 :             :     {
    4527                 :     1426773 :       return enable_split_before_sched2 ();
    4528                 :             :     }
    4529                 :             : 
    4530                 :      914378 :   unsigned int execute (function *) final override
    4531                 :             :     {
    4532                 :      914378 :       split_all_insns ();
    4533                 :      914378 :       return 0;
    4534                 :             :     }
    4535                 :             : 
    4536                 :             : }; // class pass_split_before_sched2
    4537                 :             : 
    4538                 :             : } // anon namespace
    4539                 :             : 
    4540                 :             : rtl_opt_pass *
    4541                 :      281914 : make_pass_split_before_sched2 (gcc::context *ctxt)
    4542                 :             : {
    4543                 :      281914 :   return new pass_split_before_sched2 (ctxt);
    4544                 :             : }
    4545                 :             : 
    4546                 :             : namespace {
    4547                 :             : 
    4548                 :             : const pass_data pass_data_split_before_regstack =
    4549                 :             : {
    4550                 :             :   RTL_PASS, /* type */
    4551                 :             :   "split4", /* name */
    4552                 :             :   OPTGROUP_NONE, /* optinfo_flags */
    4553                 :             :   TV_NONE, /* tv_id */
    4554                 :             :   0, /* properties_required */
    4555                 :             :   0, /* properties_provided */
    4556                 :             :   0, /* properties_destroyed */
    4557                 :             :   0, /* todo_flags_start */
    4558                 :             :   0, /* todo_flags_finish */
    4559                 :             : };
    4560                 :             : 
    4561                 :             : class pass_split_before_regstack : public rtl_opt_pass
    4562                 :             : {
    4563                 :             : public:
    4564                 :      281914 :   pass_split_before_regstack (gcc::context *ctxt)
    4565                 :      563828 :     : rtl_opt_pass (pass_data_split_before_regstack, ctxt)
    4566                 :             :   {}
    4567                 :             : 
    4568                 :             :   /* opt_pass methods: */
    4569                 :             :   bool gate (function *) final override;
    4570                 :      512480 :   unsigned int execute (function *) final override
    4571                 :             :     {
    4572                 :      512480 :       split_all_insns ();
    4573                 :      512480 :       return 0;
    4574                 :             :     }
    4575                 :             : 
    4576                 :             : }; // class pass_split_before_regstack
    4577                 :             : 
    4578                 :             : bool
    4579                 :     1426773 : pass_split_before_regstack::gate (function *)
    4580                 :             : {
    4581                 :             : #if HAVE_ATTR_length && defined (STACK_REGS)
    4582                 :             :   /* If flow2 creates new instructions which need splitting
    4583                 :             :      and scheduling after reload is not done, they might not be
    4584                 :             :      split until final which doesn't allow splitting
    4585                 :             :      if HAVE_ATTR_length.  Selective scheduling can result in
    4586                 :             :      further instructions that need splitting.  */
    4587                 :             : #ifdef INSN_SCHEDULING
    4588                 :     2341152 :   return !enable_split_before_sched2 () || flag_selective_scheduling2;
    4589                 :             : #else
    4590                 :             :   return !enable_split_before_sched2 ();
    4591                 :             : #endif
    4592                 :             : #else
    4593                 :             :   return false;
    4594                 :             : #endif
    4595                 :             : }
    4596                 :             : 
    4597                 :             : } // anon namespace
    4598                 :             : 
    4599                 :             : rtl_opt_pass *
    4600                 :      281914 : make_pass_split_before_regstack (gcc::context *ctxt)
    4601                 :             : {
    4602                 :      281914 :   return new pass_split_before_regstack (ctxt);
    4603                 :             : }
    4604                 :             : 
    4605                 :             : namespace {
    4606                 :             : 
    4607                 :             : const pass_data pass_data_split_for_shorten_branches =
    4608                 :             : {
    4609                 :             :   RTL_PASS, /* type */
    4610                 :             :   "split5", /* name */
    4611                 :             :   OPTGROUP_NONE, /* optinfo_flags */
    4612                 :             :   TV_NONE, /* tv_id */
    4613                 :             :   0, /* properties_required */
    4614                 :             :   0, /* properties_provided */
    4615                 :             :   0, /* properties_destroyed */
    4616                 :             :   0, /* todo_flags_start */
    4617                 :             :   0, /* todo_flags_finish */
    4618                 :             : };
    4619                 :             : 
    4620                 :             : class pass_split_for_shorten_branches : public rtl_opt_pass
    4621                 :             : {
    4622                 :             : public:
    4623                 :      281914 :   pass_split_for_shorten_branches (gcc::context *ctxt)
    4624                 :      563828 :     : rtl_opt_pass (pass_data_split_for_shorten_branches, ctxt)
    4625                 :             :   {}
    4626                 :             : 
    4627                 :             :   /* opt_pass methods: */
    4628                 :     1426773 :   bool gate (function *) final override
    4629                 :             :     {
    4630                 :             :       /* The placement of the splitting that we do for shorten_branches
    4631                 :             :          depends on whether regstack is used by the target or not.  */
    4632                 :             : #if HAVE_ATTR_length && !defined (STACK_REGS)
    4633                 :             :       return true;
    4634                 :             : #else
    4635                 :     1426773 :       return false;
    4636                 :             : #endif
    4637                 :             :     }
    4638                 :             : 
    4639                 :           0 :   unsigned int execute (function *) final override
    4640                 :             :     {
    4641                 :           0 :       split_all_insns_noflow ();
    4642                 :           0 :       return 0;
    4643                 :             :     }
    4644                 :             : 
    4645                 :             : }; // class pass_split_for_shorten_branches
    4646                 :             : 
    4647                 :             : } // anon namespace
    4648                 :             : 
    4649                 :             : rtl_opt_pass *
    4650                 :      281914 : make_pass_split_for_shorten_branches (gcc::context *ctxt)
    4651                 :             : {
    4652                 :      281914 :   return new pass_split_for_shorten_branches (ctxt);
    4653                 :             : }
    4654                 :             : 
    4655                 :             : /* (Re)initialize the target information after a change in target.  */
    4656                 :             : 
    4657                 :             : void
    4658                 :      211011 : recog_init ()
    4659                 :             : {
    4660                 :             :   /* The information is zero-initialized, so we don't need to do anything
    4661                 :             :      first time round.  */
    4662                 :      211011 :   if (!this_target_recog->x_initialized)
    4663                 :             :     {
    4664                 :      208974 :       this_target_recog->x_initialized = true;
    4665                 :      208974 :       return;
    4666                 :             :     }
    4667                 :        2037 :   memset (this_target_recog->x_bool_attr_masks, 0,
    4668                 :             :           sizeof (this_target_recog->x_bool_attr_masks));
    4669                 :    27444501 :   for (unsigned int i = 0; i < NUM_INSN_CODES; ++i)
    4670                 :    27442464 :     if (this_target_recog->x_op_alt[i])
    4671                 :             :       {
    4672                 :       29970 :         free (this_target_recog->x_op_alt[i]);
    4673                 :       29970 :         this_target_recog->x_op_alt[i] = 0;
    4674                 :             :       }
    4675                 :             : }
        

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.