LCOV - code coverage report
Current view: top level - gcc - rtl.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 84.0 % 187 157
Test Date: 2026-02-28 14:20:25 Functions: 81.2 % 16 13
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* RTL utility routines.
       2              :    Copyright (C) 1987-2026 Free Software Foundation, Inc.
       3              : 
       4              : This file is part of GCC.
       5              : 
       6              : GCC is free software; you can redistribute it and/or modify it under
       7              : the terms of the GNU General Public License as published by the Free
       8              : Software Foundation; either version 3, or (at your option) any later
       9              : version.
      10              : 
      11              : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      12              : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      13              : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      14              : for more details.
      15              : 
      16              : You should have received a copy of the GNU General Public License
      17              : along with GCC; see the file COPYING3.  If not see
      18              : <http://www.gnu.org/licenses/>.  */
      19              : 
      20              : /* This file is compiled twice: once for the generator programs
      21              :    once for the compiler.  */
      22              : #ifdef GENERATOR_FILE
      23              : #include "bconfig.h"
      24              : #else
      25              : #include "config.h"
      26              : #endif
      27              : 
      28              : #include "system.h"
      29              : #include "coretypes.h"
      30              : #include "tm.h"
      31              : #include "rtl.h"
      32              : #ifdef GENERATOR_FILE
      33              : # include "errors.h"
      34              : #else
      35              : # include "rtlhash.h"
      36              : # include "diagnostic-core.h"
      37              : #endif
      38              : 
      39              : 
      40              : /* Indexed by rtx code, gives number of operands for an rtx with that code.
      41              :    Does NOT include rtx header data (code and links).  */
      42              : 
      43              : #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS)   sizeof FORMAT - 1 ,
      44              : 
      45              : const unsigned char rtx_length[NUM_RTX_CODE] = {
      46              : #include "rtl.def"
      47              : };
      48              : 
      49              : #undef DEF_RTL_EXPR
      50              : 
      51              : /* Indexed by rtx code, gives the name of that kind of rtx, as a C string.  */
      52              : 
      53              : #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS)   NAME ,
      54              : 
      55              : const char * const rtx_name[NUM_RTX_CODE] = {
      56              : #include "rtl.def"            /* rtl expressions are documented here */
      57              : };
      58              : 
      59              : #undef DEF_RTL_EXPR
      60              : 
      61              : /* Indexed by rtx code, gives a sequence of operand-types for
      62              :    rtx's of that code.  The sequence is a C string in which
      63              :    each character describes one operand.  */
      64              : 
      65              : const char * const rtx_format[NUM_RTX_CODE] = {
      66              :   /* "*" undefined.
      67              :          can cause a warning message
      68              :      "0" field is unused (or used in a phase-dependent manner)
      69              :          prints nothing
      70              :      "i" an integer
      71              :          prints the integer
      72              :      "n" like "i", but prints entries from `note_insn_name'
      73              :      "L" like "i", but correctly sized to hold a location_t,
      74              :          which may be configured as 32- or 64-bit.
      75              :      "w" an integer of width HOST_BITS_PER_WIDE_INT
      76              :          prints the integer
      77              :      "s" a pointer to a string
      78              :          prints the string
      79              :      "S" like "s", but optional:
      80              :          the containing rtx may end before this operand
      81              :      "T" like "s", but treated specially by the RTL reader;
      82              :          only found in machine description patterns.
      83              :      "e" a pointer to an rtl expression
      84              :          prints the expression
      85              :      "E" a pointer to a vector that points to a number of rtl expressions
      86              :          prints a list of the rtl expressions
      87              :      "V" like "E", but optional:
      88              :          the containing rtx may end before this operand
      89              :      "u" a pointer to another insn
      90              :          prints the uid of the insn.
      91              :      "b" is a pointer to a bitmap header.
      92              :      "B" is a basic block pointer.
      93              :      "t" is a tree pointer.
      94              :      "r" a register.
      95              :      "p" is a poly_uint16 offset.  */
      96              : 
      97              : #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS)   FORMAT ,
      98              : #include "rtl.def"            /* rtl expressions are defined here */
      99              : #undef DEF_RTL_EXPR
     100              : };
     101              : 
     102              : /* Indexed by rtx code, gives a character representing the "class" of
     103              :    that rtx code.  See rtl.def for documentation on the defined classes.  */
     104              : 
     105              : const enum rtx_class rtx_class[NUM_RTX_CODE] = {
     106              : #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS)   CLASS,
     107              : #include "rtl.def"            /* rtl expressions are defined here */
     108              : #undef DEF_RTL_EXPR
     109              : };
     110              : 
     111              : /* Whether rtxs with the given code store data in the hwint field.  */
     112              : 
     113              : #define RTX_CODE_HWINT_P_1(ENUM)                                        \
     114              :     ((ENUM) == CONST_INT || (ENUM) == CONST_DOUBLE                      \
     115              :      || (ENUM) == CONST_FIXED || (ENUM) == CONST_WIDE_INT)
     116              : #ifdef GENERATOR_FILE
     117              : #define RTX_CODE_HWINT_P(ENUM)                                          \
     118              :     (RTX_CODE_HWINT_P_1 (ENUM) || (ENUM) == EQ_ATTR_ALT)
     119              : #else
     120              : #define RTX_CODE_HWINT_P RTX_CODE_HWINT_P_1
     121              : #endif
     122              : 
     123              : /* Indexed by rtx code, gives the size of the rtx in bytes.  */
     124              : 
     125              : const unsigned char rtx_code_size[NUM_RTX_CODE] = {
     126              : #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS)                         \
     127              :   (RTX_CODE_HWINT_P (ENUM)                                              \
     128              :    ? RTX_HDR_SIZE + (sizeof FORMAT - 1) * sizeof (HOST_WIDE_INT)        \
     129              :    : (ENUM) == REG                                                      \
     130              :    ? RTX_HDR_SIZE + sizeof (reg_info)                                   \
     131              :    : RTX_HDR_SIZE + (sizeof FORMAT - 1) * sizeof (rtunion)),
     132              : 
     133              : #include "rtl.def"
     134              : #undef DEF_RTL_EXPR
     135              : };
     136              : 
     137              : /* Names for kinds of NOTEs and REG_NOTEs.  */
     138              : 
     139              : const char * const note_insn_name[NOTE_INSN_MAX] =
     140              : {
     141              : #define DEF_INSN_NOTE(NAME) #NAME,
     142              : #include "insn-notes.def"
     143              : #undef DEF_INSN_NOTE
     144              : };
     145              : 
     146              : const char * const reg_note_name[REG_NOTE_MAX] =
     147              : {
     148              : #define DEF_REG_NOTE(NAME) #NAME,
     149              : #include "reg-notes.def"
     150              : #undef DEF_REG_NOTE
     151              : };
     152              : 
     153              : static size_t rtx_alloc_counts[(int) LAST_AND_UNUSED_RTX_CODE];
     154              : static size_t rtx_alloc_sizes[(int) LAST_AND_UNUSED_RTX_CODE];
     155              : static size_t rtvec_alloc_counts;
     156              : static size_t rtvec_alloc_sizes;
     157              : 
     158              : 
     159              : /* Allocate an rtx vector of N elements.
     160              :    Store the length, and initialize all elements to zero.  */
     161              : 
     162              : rtvec
     163    101600241 : rtvec_alloc (size_t n)
     164              : {
     165    101600241 :   rtvec rt;
     166              : 
     167              :   /* rtvec_def.num_elem is an int.  */
     168    101600241 :   gcc_assert (n < INT_MAX);
     169              : 
     170    101600241 :   rt = ggc_alloc_rtvec_sized (n);
     171              :   /* Clear out the vector.  */
     172    101600241 :   memset (&rt->elem[0], 0, n * sizeof (rtx));
     173              : 
     174    101600241 :   PUT_NUM_ELEM (rt, n);
     175              : 
     176    101600241 :   if (GATHER_STATISTICS)
     177              :     {
     178              :       rtvec_alloc_counts++;
     179              :       rtvec_alloc_sizes += n * sizeof (rtx);
     180              :     }
     181              : 
     182    101600241 :   return rt;
     183              : }
     184              : 
     185              : /* Create a bitwise copy of VEC.  */
     186              : 
     187              : rtvec
     188      2258912 : shallow_copy_rtvec (rtvec vec)
     189              : {
     190      2258912 :   rtvec newvec;
     191      2258912 :   int n;
     192              : 
     193      2258912 :   n = GET_NUM_ELEM (vec);
     194      2258912 :   newvec = rtvec_alloc (n);
     195      2258912 :   memcpy (&newvec->elem[0], &vec->elem[0], sizeof (rtx) * n);
     196      2258912 :   return newvec;
     197              : }
     198              : 
     199              : /* Return the number of bytes occupied by rtx value X.  */
     200              : 
     201              : unsigned int
     202    450778001 : rtx_size (const_rtx x)
     203              : {
     204    450778001 :   if (CONST_WIDE_INT_P (x))
     205            0 :     return (RTX_HDR_SIZE
     206              :             + sizeof (struct hwivec_def)
     207            0 :             + ((CONST_WIDE_INT_NUNITS (x) - 1)
     208            0 :                * sizeof (HOST_WIDE_INT)));
     209    450778001 :   if (CONST_POLY_INT_P (x))
     210              :     return (RTX_HDR_SIZE
     211              :             + sizeof (struct const_poly_int_def)
     212              :             + CONST_POLY_INT_COEFFS (x).extra_size ());
     213    450778001 :   if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_HAS_BLOCK_INFO_P (x))
     214              :     return RTX_HDR_SIZE + sizeof (struct block_symbol);
     215    450778001 :   return RTX_CODE_SIZE (GET_CODE (x));
     216              : }
     217              : 
     218              : /* Allocate an rtx of code CODE with EXTRA bytes in it.  The CODE is
     219              :    stored in the rtx; all the rest is initialized to zero.  */
     220              : 
     221              : rtx
     222   2696715907 : rtx_alloc_stat_v (RTX_CODE code MEM_STAT_DECL, int extra)
     223              : {
     224   2696715907 :   rtx rt = ggc_alloc_rtx_def_stat (RTX_CODE_SIZE (code) + extra
     225              :                                    PASS_MEM_STAT);
     226              : 
     227   2696715907 :   rtx_init (rt, code);
     228              : 
     229   2696715907 :   if (GATHER_STATISTICS)
     230              :     {
     231              :       rtx_alloc_counts[code]++;
     232              :       rtx_alloc_sizes[code] += RTX_CODE_SIZE (code);
     233              :     }
     234              : 
     235   2696715907 :   return rt;
     236              : }
     237              : 
     238              : /* Allocate an rtx of code CODE.  The CODE is stored in the rtx;
     239              :    all the rest is initialized to zero.  */
     240              : 
     241              : rtx
     242   2696153830 : rtx_alloc (RTX_CODE code MEM_STAT_DECL)
     243              : {
     244   2696153830 :   return rtx_alloc_stat_v (code PASS_MEM_STAT, 0);
     245              : }
     246              : 
     247              : /* Write the wide constant X to OUTFILE.  */
     248              : 
     249              : void
     250           12 : cwi_output_hex (FILE *outfile, const_rtx x)
     251              : {
     252           12 :   int i = CWI_GET_NUM_ELEM (x);
     253           12 :   gcc_assert (i > 0);
     254           12 :   if (CWI_ELT (x, i - 1) == 0)
     255              :     /* The HOST_WIDE_INT_PRINT_HEX prepends a 0x only if the val is
     256              :        non zero.  We want all numbers to have a 0x prefix.  */
     257           10 :     fprintf (outfile, "0x");
     258           12 :   fprintf (outfile, HOST_WIDE_INT_PRINT_HEX, CWI_ELT (x, --i));
     259           36 :   while (--i >= 0)
     260           12 :     fprintf (outfile, HOST_WIDE_INT_PRINT_PADDED_HEX, CWI_ELT (x, i));
     261           12 : }
     262              : 
     263              : 
     264              : /* Return true if ORIG is a sharable CONST.  */
     265              : 
     266              : bool
     267     48918367 : shared_const_p (const_rtx orig)
     268              : {
     269     48918367 :   gcc_assert (GET_CODE (orig) == CONST);
     270              : 
     271              :   /* CONST can be shared if it contains a SYMBOL_REF.  If it contains
     272              :      a LABEL_REF, it isn't sharable.  */
     273     48918367 :   poly_int64 offset;
     274     48918367 :   return (GET_CODE (XEXP (orig, 0)) == PLUS
     275     40038197 :           && GET_CODE (XEXP (XEXP (orig, 0), 0)) == SYMBOL_REF
     276     88332230 :           && poly_int_rtx_p (XEXP (XEXP (orig, 0), 1), &offset));
     277              : }
     278              : 
     279              : 
     280              : /* Create a new copy of an rtx.
     281              :    Recursively copies the operands of the rtx,
     282              :    except for those few rtx codes that are sharable.  */
     283              : 
     284              : rtx
     285    594034399 : copy_rtx (rtx orig)
     286              : {
     287    594034399 :   rtx copy;
     288    594034399 :   int i, j;
     289    594034399 :   RTX_CODE code;
     290    594034399 :   const char *format_ptr;
     291              : 
     292    594034399 :   code = GET_CODE (orig);
     293              : 
     294    594034399 :   switch (code)
     295              :     {
     296              :     case REG:
     297              :     case DEBUG_EXPR:
     298              :     case VALUE:
     299              :     CASE_CONST_ANY:
     300              :     case SYMBOL_REF:
     301              :     case CODE_LABEL:
     302              :     case PC:
     303              :     case RETURN:
     304              :     case SIMPLE_RETURN:
     305              :     case SCRATCH:
     306              :       /* SCRATCH must be shared because they represent distinct values.  */
     307              :       return orig;
     308       282009 :     case CLOBBER:
     309              :       /* Share clobbers of hard registers, but do not share pseudo reg
     310              :          clobbers or clobbers of hard registers that originated as pseudos.
     311              :          This is needed to allow safe register renaming.  */
     312        64978 :       if (REG_P (XEXP (orig, 0)) && REGNO (XEXP (orig, 0)) < FIRST_PSEUDO_REGISTER
     313       346493 :           && ORIGINAL_REGNO (XEXP (orig, 0)) == REGNO (XEXP (orig, 0)))
     314              :         return orig;
     315              :       break;
     316              : 
     317      4056293 :     case CONST:
     318      4056293 :       if (shared_const_p (orig))
     319              :         return orig;
     320              :       break;
     321              : 
     322              :       /* A MEM with a constant address is not sharable.  The problem is that
     323              :          the constant address may need to be reloaded.  If the mem is shared,
     324              :          then reloading one copy of this mem will cause all copies to appear
     325              :          to have been reloaded.  */
     326              : 
     327              :     default:
     328              :       break;
     329              :     }
     330              : 
     331              :   /* Copy the various flags, fields, and other information.  We assume
     332              :      that all fields need copying, and then clear the fields that should
     333              :      not be copied.  That is the sensible default behavior, and forces
     334              :      us to explicitly document why we are *not* copying a flag.  */
     335    182016573 :   copy = shallow_copy_rtx (orig);
     336              : 
     337    182016573 :   format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
     338              : 
     339    542543964 :   for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
     340    360527391 :     switch (*format_ptr++)
     341              :       {
     342    291899935 :       case 'e':
     343    291899935 :         if (XEXP (orig, i) != NULL)
     344    291723168 :           XEXP (copy, i) = copy_rtx (XEXP (orig, i));
     345              :         break;
     346              : 
     347      2174786 :       case 'E':
     348      2174786 :       case 'V':
     349      2174786 :         if (XVEC (orig, i) != NULL)
     350              :           {
     351      2174786 :             XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
     352      6678061 :             for (j = 0; j < XVECLEN (copy, i); j++)
     353      4503275 :               XVECEXP (copy, i, j) = copy_rtx (XVECEXP (orig, i, j));
     354              :           }
     355              :         break;
     356              : 
     357              :       case 't':
     358              :       case 'w':
     359              :       case 'i':
     360              :       case 'L':
     361              :       case 'p':
     362              :       case 's':
     363              :       case 'S':
     364              :       case 'T':
     365              :       case 'u':
     366              :       case 'B':
     367              :       case '0':
     368              :         /* These are left unchanged.  */
     369              :         break;
     370              : 
     371            0 :       default:
     372            0 :         gcc_unreachable ();
     373              :       }
     374              :   return copy;
     375              : }
     376              : 
     377              : /* Create a new copy of an rtx.  Only copy just one level.  */
     378              : 
     379              : rtx
     380    450778001 : shallow_copy_rtx (const_rtx orig MEM_STAT_DECL)
     381              : {
     382    450778001 :   const unsigned int size = rtx_size (orig);
     383    450778001 :   rtx const copy = ggc_alloc_rtx_def_stat (size PASS_MEM_STAT);
     384    450778001 :   memcpy (copy, orig, size);
     385    450778001 :   switch (GET_CODE (orig))
     386              :     {
     387              :       /* RTX codes copy_rtx_if_shared_1 considers are shareable,
     388              :          the used flag is often used for other purposes.  */
     389              :     case REG:
     390              :     case DEBUG_EXPR:
     391              :     case VALUE:
     392              :     CASE_CONST_ANY:
     393              :     case SYMBOL_REF:
     394              :     case CODE_LABEL:
     395              :     case PC:
     396              :     case RETURN:
     397              :     case SIMPLE_RETURN:
     398              :     case SCRATCH:
     399              :       break;
     400    444011629 :     default:
     401              :       /* For all other RTXes clear the used flag on the copy.
     402              :          CALL_INSN use "used" flag to indicate it's a fake call.  */
     403    444011629 :       if (!INSN_P (orig))
     404    443834862 :         RTX_FLAG (copy, used) = 0;
     405              :       break;
     406              :     }
     407    450778001 :   return copy;
     408              : }
     409              : 
     410              : /* Nonzero when we are generating CONCATs.  */
     411              : int generating_concat_p;
     412              : 
     413              : /* Nonzero when we are expanding trees to RTL.  */
     414              : int currently_expanding_to_rtl;
     415              : 
     416              : 
     417              : 
     418              : /* Return true if X and Y are identical-looking rtx's.
     419              :    This is the Lisp function EQUAL for rtx arguments.
     420              : 
     421              :    Call CB on each pair of rtx if CB is not NULL.
     422              :    When the callback returns true, we continue with the new pair.  */
     423              : 
     424              : bool
     425   5206907012 : rtx_equal_p (const_rtx x, const_rtx y, rtx_equal_p_callback_function cb)
     426              : {
     427   5206907012 :   int i;
     428   5206907012 :   int j;
     429   5206907012 :   enum rtx_code code;
     430   5206907012 :   const char *fmt;
     431   5206907012 :   rtx nx, ny;
     432              : 
     433   5206907012 :   if (x == y)
     434              :     return true;
     435   3889412498 :   if (x == 0 || y == 0)
     436              :     return false;
     437              : 
     438              :   /* Invoke the callback first.  */
     439   3616731953 :   if (cb != NULL
     440   3616731953 :       && ((*cb) (&x, &y, &nx, &ny)))
     441            0 :     return rtx_equal_p (nx, ny, cb);
     442              : 
     443   3616731953 :   code = GET_CODE (x);
     444              :   /* Rtx's of different codes cannot be equal.  */
     445   3616731953 :   if (code != GET_CODE (y))
     446              :     return false;
     447              : 
     448              :   /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent.
     449              :      (REG:SI x) and (REG:HI x) are NOT equivalent.  */
     450              : 
     451   1899702669 :   if (GET_MODE (x) != GET_MODE (y))
     452              :     return false;
     453              : 
     454              :   /* MEMs referring to different address space are not equivalent.  */
     455   1341165598 :   if (code == MEM && MEM_ADDR_SPACE (x) != MEM_ADDR_SPACE (y))
     456              :     return false;
     457              : 
     458              :   /* Some RTL can be compared nonrecursively.  */
     459   1336479892 :   switch (code)
     460              :     {
     461    867056133 :     case REG:
     462    867056133 :       return (REGNO (x) == REGNO (y));
     463              : 
     464        30553 :     case LABEL_REF:
     465        30553 :       return label_ref_label (x) == label_ref_label (y);
     466              : 
     467     68746023 :     case SYMBOL_REF:
     468     68746023 :       return XSTR (x, 0) == XSTR (y, 0);
     469              : 
     470              :     case DEBUG_EXPR:
     471              :     case VALUE:
     472              :     case SCRATCH:
     473              :     CASE_CONST_UNIQUE:
     474              :       return false;
     475              : 
     476              :     case CONST_VECTOR:
     477              :       if (!same_vector_encodings_p (x, y))
     478              :         return false;
     479              :       break;
     480              : 
     481        18488 :     case DEBUG_IMPLICIT_PTR:
     482        18488 :       return DEBUG_IMPLICIT_PTR_DECL (x)
     483        18488 :              == DEBUG_IMPLICIT_PTR_DECL (y);
     484              : 
     485            0 :     case DEBUG_PARAMETER_REF:
     486            0 :       return DEBUG_PARAMETER_REF_DECL (x)
     487            0 :              == DEBUG_PARAMETER_REF_DECL (y);
     488              : 
     489        62593 :     case ENTRY_VALUE:
     490        62593 :       return rtx_equal_p (ENTRY_VALUE_EXP (x), ENTRY_VALUE_EXP (y), cb);
     491              : 
     492              :     default:
     493              :       break;
     494              :     }
     495              : 
     496              :   /* Compare the elements.  If any pair of corresponding elements
     497              :      fail to match, return 0 for the whole thing.  */
     498              : 
     499    312751399 :   fmt = GET_RTX_FORMAT (code);
     500    570309287 :   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
     501              :     {
     502    468550288 :       switch (fmt[i])
     503              :         {
     504            0 :         case 'w':
     505            0 :           if (XWINT (x, i) != XWINT (y, i))
     506              :             return false;
     507              :           break;
     508              : 
     509     43681824 :         case 'n':
     510     43681824 :         case 'i':
     511     43681824 :           if (XINT (x, i) != XINT (y, i))
     512              :             return false;
     513              :           break;
     514              : 
     515        19847 :         case 'L':
     516        19847 :           if (XLOC (x, i) != XLOC (y, i))
     517              :             return false;
     518              :           break;
     519              : 
     520      4675011 :         case 'p':
     521      4675011 :           if (maybe_ne (SUBREG_BYTE (x), SUBREG_BYTE (y)))
     522              :             return false;
     523              :           break;
     524              : 
     525      5432461 :         case 'V':
     526      5432461 :         case 'E':
     527              :           /* Two vectors must have the same length.  */
     528      5432461 :           if (XVECLEN (x, i) != XVECLEN (y, i))
     529              :             return false;
     530              : 
     531              :           /* And the corresponding elements must match.  */
     532      9312118 :           for (j = 0; j < XVECLEN (x, i); j++)
     533      8130597 :             if (!rtx_equal_p (XVECEXP (x, i, j), XVECEXP (y, i, j), cb))
     534              :               return false;
     535              :           break;
     536              : 
     537    355024996 :         case 'e':
     538    355024996 :           if (!rtx_equal_p (XEXP (x, i), XEXP (y, i), cb))
     539              :             return false;
     540              :           break;
     541              : 
     542          471 :         case 'S':
     543          471 :         case 's':
     544          471 :           if ((XSTR (x, i) || XSTR (y, i))
     545          471 :               && (! XSTR (x, i) || ! XSTR (y, i)
     546          471 :                   || strcmp (XSTR (x, i), XSTR (y, i))))
     547              :             return false;
     548              :           break;
     549              : 
     550              :         case 'u':
     551              :           /* These are just backpointers, so they don't matter.  */
     552              :           break;
     553              : 
     554              :         case '0':
     555              :         case 't':
     556              :           break;
     557              : 
     558              :           /* It is believed that rtx's at this level will never
     559              :              contain anything but integers and other rtx's,
     560              :              except for within LABEL_REFs and SYMBOL_REFs.  */
     561            0 :         default:
     562            0 :           gcc_unreachable ();
     563              :         }
     564              :     }
     565              :   return true;
     566              : }
     567              : 
     568              : /* Return true if all elements of VEC are equal.  */
     569              : 
     570              : bool
     571       166105 : rtvec_all_equal_p (const_rtvec vec)
     572              : {
     573       166105 :   const_rtx first = RTVEC_ELT (vec, 0);
     574              :   /* Optimize the important special case of a vector of constants.
     575              :      The main use of this function is to detect whether every element
     576              :      of CONST_VECTOR is the same.  */
     577       166105 :   switch (GET_CODE (first))
     578              :     {
     579       166105 :     CASE_CONST_UNIQUE:
     580       231390 :       for (int i = 1, n = GET_NUM_ELEM (vec); i < n; ++i)
     581       178200 :         if (first != RTVEC_ELT (vec, i))
     582              :           return false;
     583              :       return true;
     584              : 
     585            0 :     default:
     586            0 :       for (int i = 1, n = GET_NUM_ELEM (vec); i < n; ++i)
     587            0 :         if (!rtx_equal_p (first, RTVEC_ELT (vec, i)))
     588              :           return false;
     589              :       return true;
     590              :     }
     591              : }
     592              : 
     593              : /* Return true if VEC contains a linear series of integers
     594              :    { START, START+1, START+2, ... }.  */
     595              : 
     596              : bool
     597      3046822 : rtvec_series_p (rtvec vec, int start)
     598              : {
     599      5572273 :   for (int i = 0; i < GET_NUM_ELEM (vec); i++)
     600              :     {
     601      4822312 :       rtx x = RTVEC_ELT (vec, i);
     602      4822312 :       if (!CONST_INT_P (x) || INTVAL (x) != i + start)
     603              :         return false;
     604              :     }
     605              :   return true;
     606              : }
     607              : 
     608              : /* Return an indication of which type of insn should have X as a body.
     609              :    In generator files, this can be UNKNOWN if the answer is only known
     610              :    at (GCC) runtime.  Otherwise the value is CODE_LABEL, INSN, CALL_INSN
     611              :    or JUMP_INSN.  */
     612              : 
     613              : enum rtx_code
     614     18673411 : classify_insn (rtx x)
     615              : {
     616     18673411 :   if (LABEL_P (x))
     617              :     return CODE_LABEL;
     618     18673411 :   if (GET_CODE (x) == CALL)
     619              :     return CALL_INSN;
     620     18673411 :   if (ANY_RETURN_P (x))
     621              :     return JUMP_INSN;
     622     18618146 :   if (GET_CODE (x) == ASM_OPERANDS && ASM_OPERANDS_LABEL_LENGTH (x))
     623              :     return JUMP_INSN;
     624     18618146 :   if (GET_CODE (x) == SET)
     625              :     {
     626     15760911 :       if (GET_CODE (SET_DEST (x)) == PC)
     627              :         return JUMP_INSN;
     628      6414919 :       else if (GET_CODE (SET_SRC (x)) == CALL)
     629              :         return CALL_INSN;
     630              :       else
     631      6414919 :         return INSN;
     632              :     }
     633      2857235 :   if (GET_CODE (x) == PARALLEL)
     634              :     {
     635      2741396 :       int j;
     636      2741396 :       bool has_return_p = false;
     637      8793630 :       for (j = XVECLEN (x, 0) - 1; j >= 0; j--)
     638      6066539 :         if (GET_CODE (XVECEXP (x, 0, j)) == CALL)
     639              :           return CALL_INSN;
     640      6065469 :         else if (ANY_RETURN_P (XVECEXP (x, 0, j)))
     641              :           has_return_p = true;
     642      6065469 :         else if (GET_CODE (XVECEXP (x, 0, j)) == SET
     643      3327247 :                  && GET_CODE (SET_DEST (XVECEXP (x, 0, j))) == PC)
     644              :           return JUMP_INSN;
     645      6057441 :         else if (GET_CODE (XVECEXP (x, 0, j)) == SET
     646      3319219 :                  && GET_CODE (SET_SRC (XVECEXP (x, 0, j))) == CALL)
     647              :           return CALL_INSN;
     648      2727091 :       if (has_return_p)
     649              :         return JUMP_INSN;
     650      2727091 :       if (GET_CODE (XVECEXP (x, 0, 0)) == ASM_OPERANDS
     651           33 :           && ASM_OPERANDS_LABEL_LENGTH (XVECEXP (x, 0, 0)))
     652            1 :         return JUMP_INSN;
     653              :     }
     654              : #ifdef GENERATOR_FILE
     655              :   if (GET_CODE (x) == MATCH_OPERAND
     656              :       || GET_CODE (x) == MATCH_OPERATOR
     657              :       || GET_CODE (x) == MATCH_PARALLEL
     658              :       || GET_CODE (x) == MATCH_OP_DUP
     659              :       || GET_CODE (x) == MATCH_DUP
     660              :       || GET_CODE (x) == PARALLEL)
     661              :     return UNKNOWN;
     662              : #endif
     663              :   return INSN;
     664              : }
     665              : 
     666              : /* Comparator of indices based on rtx_alloc_counts.  */
     667              : 
     668              : static int
     669            0 : rtx_count_cmp (const void *p1, const void *p2)
     670              : {
     671            0 :   const unsigned *n1 = (const unsigned *)p1;
     672            0 :   const unsigned *n2 = (const unsigned *)p2;
     673              : 
     674            0 :   return rtx_alloc_counts[*n1] - rtx_alloc_counts[*n2];
     675              : }
     676              : 
     677              : void
     678            0 : dump_rtx_statistics (void)
     679              : {
     680            0 :   int total_counts = 0;
     681            0 :   int total_sizes = 0;
     682              : 
     683            0 :   if (! GATHER_STATISTICS)
     684              :     {
     685            0 :       fprintf (stderr, "No RTX statistics\n");
     686            0 :       return;
     687              :     }
     688              : 
     689              :   fprintf (stderr, "\nRTX Kind                   Count     Bytes\n");
     690              :   fprintf (stderr, "-------------------------------------------\n");
     691              : 
     692              :   auto_vec<unsigned> indices (LAST_AND_UNUSED_RTX_CODE);
     693              :   for (unsigned i = 0; i < LAST_AND_UNUSED_RTX_CODE; i++)
     694              :     indices.quick_push (i);
     695              :   indices.qsort (rtx_count_cmp);
     696              : 
     697              :   for (unsigned i = 0; i < LAST_AND_UNUSED_RTX_CODE; i++)
     698              :     {
     699              :       unsigned j = indices[i];
     700              :       if (rtx_alloc_counts[j])
     701              :         {
     702              :           fprintf (stderr, "%-24s " PRsa (6) " " PRsa (9) "\n",
     703              :                    GET_RTX_NAME (j),
     704              :                    SIZE_AMOUNT (rtx_alloc_counts[j]),
     705              :                    SIZE_AMOUNT (rtx_alloc_sizes[j]));
     706              :           total_counts += rtx_alloc_counts[j];
     707              :           total_sizes += rtx_alloc_sizes[j];
     708              :         }
     709              :     }
     710              : 
     711              :   if (rtvec_alloc_counts)
     712              :     {
     713              :       fprintf (stderr, "%-24s " PRsa (6) " " PRsa (9) "\n", "rtvec",
     714              :                SIZE_AMOUNT (rtvec_alloc_counts),
     715              :                SIZE_AMOUNT (rtvec_alloc_sizes));
     716              :       total_counts += rtvec_alloc_counts;
     717              :       total_sizes += rtvec_alloc_sizes;
     718              :     }
     719              :   fprintf (stderr, "-----------------------------------------------\n");
     720              :   fprintf (stderr, "%-24s " PRsa (6) " " PRsa (9) "\n",
     721              :            "Total", SIZE_AMOUNT (total_counts),
     722              :            SIZE_AMOUNT (total_sizes));
     723              :   fprintf (stderr, "-----------------------------------------------\n");
     724              : }
     725              : 
     726              : #if defined ENABLE_RTL_CHECKING && (GCC_VERSION >= 2007)
     727              : 
     728              : /* Disable warnings about missing quoting in GCC diagnostics for
     729              :    the internal_error calls.  Their format strings deliberately don't
     730              :    follow GCC diagnostic conventions.  */
     731              : #if __GNUC__ >= 10
     732              : #pragma GCC diagnostic push
     733              : #pragma GCC diagnostic ignored "-Wformat-diag"
     734              : #endif
     735              : 
     736              : void
     737              : rtl_check_failed_bounds (const_rtx r, int n, const char *file, int line,
     738              :                          const char *func)
     739              : {
     740              :   internal_error
     741              :     ("RTL check: access of elt %d of '%s' with last elt %d in %s, at %s:%d",
     742              :      n, GET_RTX_NAME (GET_CODE (r)), GET_RTX_LENGTH (GET_CODE (r)) - 1,
     743              :      func, trim_filename (file), line);
     744              : }
     745              : 
     746              : void
     747              : rtl_check_failed_type1 (const_rtx r, int n, int c1, const char *file, int line,
     748              :                         const char *func)
     749              : {
     750              :   internal_error
     751              :     ("RTL check: expected elt %d type '%c', have '%c' (rtx %s) in %s, at %s:%d",
     752              :      n, c1, GET_RTX_FORMAT (GET_CODE (r))[n], GET_RTX_NAME (GET_CODE (r)),
     753              :      func, trim_filename (file), line);
     754              : }
     755              : 
     756              : void
     757              : rtl_check_failed_type2 (const_rtx r, int n, int c1, int c2, const char *file,
     758              :                         int line, const char *func)
     759              : {
     760              :   internal_error
     761              :     ("RTL check: expected elt %d type '%c' or '%c', have '%c' (rtx %s) in %s, at %s:%d",
     762              :      n, c1, c2, GET_RTX_FORMAT (GET_CODE (r))[n], GET_RTX_NAME (GET_CODE (r)),
     763              :      func, trim_filename (file), line);
     764              : }
     765              : 
     766              : void
     767              : rtl_check_failed_code1 (const_rtx r, enum rtx_code code, const char *file,
     768              :                         int line, const char *func)
     769              : {
     770              :   internal_error ("RTL check: expected code '%s', have '%s' in %s, at %s:%d",
     771              :                   GET_RTX_NAME (code), GET_RTX_NAME (GET_CODE (r)), func,
     772              :                   trim_filename (file), line);
     773              : }
     774              : 
     775              : void
     776              : rtl_check_failed_code2 (const_rtx r, enum rtx_code code1, enum rtx_code code2,
     777              :                         const char *file, int line, const char *func)
     778              : {
     779              :   internal_error
     780              :     ("RTL check: expected code '%s' or '%s', have '%s' in %s, at %s:%d",
     781              :      GET_RTX_NAME (code1), GET_RTX_NAME (code2), GET_RTX_NAME (GET_CODE (r)),
     782              :      func, trim_filename (file), line);
     783              : }
     784              : 
     785              : void
     786              : rtl_check_failed_code3 (const_rtx r, enum rtx_code code1, enum rtx_code code2,
     787              :                         enum rtx_code code3, const char *file, int line,
     788              :                         const char *func)
     789              : {
     790              :   internal_error
     791              :     ("RTL check: expected code '%s', '%s' or '%s', have '%s' in %s, at %s:%d",
     792              :      GET_RTX_NAME (code1), GET_RTX_NAME (code2), GET_RTX_NAME (code3),
     793              :      GET_RTX_NAME (GET_CODE (r)), func, trim_filename (file), line);
     794              : }
     795              : 
     796              : void
     797              : rtl_check_failed_code_mode (const_rtx r, enum rtx_code code, machine_mode mode,
     798              :                             bool not_mode, const char *file, int line,
     799              :                             const char *func)
     800              : {
     801              :   internal_error ((not_mode
     802              :                    ? ("RTL check: expected code '%s' and not mode '%s', "
     803              :                       "have code '%s' and mode '%s' in %s, at %s:%d")
     804              :                    : ("RTL check: expected code '%s' and mode '%s', "
     805              :                       "have code '%s' and mode '%s' in %s, at %s:%d")),
     806              :                   GET_RTX_NAME (code), GET_MODE_NAME (mode),
     807              :                   GET_RTX_NAME (GET_CODE (r)), GET_MODE_NAME (GET_MODE (r)),
     808              :                   func, trim_filename (file), line);
     809              : }
     810              : 
     811              : #if __GNUC__ >= 10
     812              : #pragma GCC diagnostic pop
     813              : #endif
     814              : 
     815              : /* Report that line LINE of FILE tried to access the block symbol fields
     816              :    of a non-block symbol.  FUNC is the function that contains the line.  */
     817              : 
     818              : void
     819              : rtl_check_failed_block_symbol (const char *file, int line, const char *func)
     820              : {
     821              :   internal_error
     822              :     ("RTL check: attempt to treat non-block symbol as a block symbol "
     823              :      "in %s, at %s:%d", func, trim_filename (file), line);
     824              : }
     825              : 
     826              : /* XXX Maybe print the vector?  */
     827              : void
     828              : cwi_check_failed_bounds (const_rtx x, int n, const char *file, int line,
     829              :                          const char *func)
     830              : {
     831              :   internal_error
     832              :     ("RTL check: access of hwi elt %d of vector with last elt %d in %s, at %s:%d",
     833              :      n, CWI_GET_NUM_ELEM (x) - 1, func, trim_filename (file), line);
     834              : }
     835              : 
     836              : /* XXX Maybe print the vector?  */
     837              : void
     838              : rtvec_check_failed_bounds (const_rtvec r, int n, const char *file, int line,
     839              :                            const char *func)
     840              : {
     841              :   internal_error
     842              :     ("RTL check: access of elt %d of vector with last elt %d in %s, at %s:%d",
     843              :      n, GET_NUM_ELEM (r) - 1, func, trim_filename (file), line);
     844              : }
     845              : #endif /* ENABLE_RTL_CHECKING */
     846              : 
     847              : #if defined ENABLE_RTL_FLAG_CHECKING
     848              : void
     849            0 : rtl_check_failed_flag (const char *name, const_rtx r, const char *file,
     850              :                        int line, const char *func)
     851              : {
     852            0 :   internal_error
     853            0 :     ("RTL flag check: %s used with unexpected rtx code '%s' in %s, at %s:%d",
     854            0 :      name, GET_RTX_NAME (GET_CODE (r)), func, trim_filename (file), line);
     855              : }
     856              : #endif /* ENABLE_RTL_FLAG_CHECKING */
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.