LCOV - code coverage report
Current view: top level - gcc - stmt.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 83.6 % 615 514
Test Date: 2025-07-26 09:32:30 Functions: 81.0 % 21 17
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* Expands front end tree to back end RTL for GCC
       2                 :             :    Copyright (C) 1987-2025 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 handles the generation of rtl code from tree structure
      21                 :             :    above the level of expressions, using subroutines in exp*.c and emit-rtl.cc.
      22                 :             :    The functions whose names start with `expand_' are called by the
      23                 :             :    expander to generate RTL instructions for various kinds of constructs.  */
      24                 :             : 
      25                 :             : #include "config.h"
      26                 :             : #include "system.h"
      27                 :             : #include "coretypes.h"
      28                 :             : #include "backend.h"
      29                 :             : #include "target.h"
      30                 :             : #include "rtl.h"
      31                 :             : #include "tree.h"
      32                 :             : #include "gimple.h"
      33                 :             : #include "cfghooks.h"
      34                 :             : #include "predict.h"
      35                 :             : #include "memmodel.h"
      36                 :             : #include "tm_p.h"
      37                 :             : #include "optabs.h"
      38                 :             : #include "regs.h"
      39                 :             : #include "emit-rtl.h"
      40                 :             : #include "pretty-print.h"
      41                 :             : #include "diagnostic-core.h"
      42                 :             : #include "output.h"
      43                 :             : #include "gimplify_reg_info.h"
      44                 :             : 
      45                 :             : #include "fold-const.h"
      46                 :             : #include "varasm.h"
      47                 :             : #include "stor-layout.h"
      48                 :             : #include "dojump.h"
      49                 :             : #include "explow.h"
      50                 :             : #include "stmt.h"
      51                 :             : #include "expr.h"
      52                 :             : #include "langhooks.h"
      53                 :             : #include "cfganal.h"
      54                 :             : #include "tree-cfg.h"
      55                 :             : #include "dumpfile.h"
      56                 :             : #include "builtins.h"
      57                 :             : #include "cfgexpand.h"
      58                 :             : #include "output.h"
      59                 :             : 
      60                 :             : 
      61                 :             : /* Functions and data structures for expanding case statements.  */
      62                 :             : 
      63                 :             : /* Case label structure, used to hold info on labels within case
      64                 :             :    statements.  We handle "range" labels; for a single-value label
      65                 :             :    as in C, the high and low limits are the same.
      66                 :             : 
      67                 :             :    We start with a vector of case nodes sorted in ascending order, and
      68                 :             :    the default label as the last element in the vector.
      69                 :             : 
      70                 :             :    Switch statements are expanded in jump table form.
      71                 :             : 
      72                 :             : */
      73                 :             : 
      74                 :             : class simple_case_node
      75                 :             : {
      76                 :             : public:
      77                 :       89954 :   simple_case_node (tree low, tree high, tree code_label):
      78                 :       89954 :     m_low (low), m_high (high), m_code_label (code_label)
      79                 :             :   {}
      80                 :             : 
      81                 :             :   /* Lowest index value for this label.  */
      82                 :             :   tree m_low;
      83                 :             :   /* Highest index value for this label.  */
      84                 :             :   tree m_high;
      85                 :             :   /* Label to jump to when node matches.  */
      86                 :             :   tree m_code_label;
      87                 :             : };
      88                 :             : 
      89                 :             : static bool check_unique_operand_names (tree, tree, tree);
      90                 :             : static char *resolve_operand_name_1 (char *, tree, tree, tree);
      91                 :             : 
      92                 :             : /* Return the rtx-label that corresponds to a LABEL_DECL,
      93                 :             :    creating it if necessary.  */
      94                 :             : 
      95                 :             : rtx_insn *
      96                 :     2731603 : label_rtx (tree label)
      97                 :             : {
      98                 :     2731603 :   gcc_assert (TREE_CODE (label) == LABEL_DECL);
      99                 :             : 
     100                 :     2731603 :   if (!DECL_RTL_SET_P (label))
     101                 :             :     {
     102                 :      639360 :       rtx_code_label *r = gen_label_rtx ();
     103                 :      639360 :       SET_DECL_RTL (label, r);
     104                 :      639360 :       if (FORCED_LABEL (label) || DECL_NONLOCAL (label))
     105                 :       26359 :         LABEL_PRESERVE_P (r) = 1;
     106                 :             :     }
     107                 :             : 
     108                 :     2731603 :   return as_a <rtx_insn *> (DECL_RTL (label));
     109                 :             : }
     110                 :             : 
     111                 :             : /* As above, but also put it on the forced-reference list of the
     112                 :             :    function that contains it.  */
     113                 :             : rtx_insn *
     114                 :           0 : force_label_rtx (tree label)
     115                 :             : {
     116                 :           0 :   rtx_insn *ref = label_rtx (label);
     117                 :           0 :   tree function = decl_function_context (label);
     118                 :             : 
     119                 :           0 :   gcc_assert (function);
     120                 :             : 
     121                 :           0 :   vec_safe_push (forced_labels, ref);
     122                 :           0 :   return ref;
     123                 :             : }
     124                 :             : 
     125                 :             : /* As label_rtx, but ensures (in check build), that returned value is
     126                 :             :    an existing label (i.e. rtx with code CODE_LABEL).  */
     127                 :             : rtx_code_label *
     128                 :      868047 : jump_target_rtx (tree label)
     129                 :             : {
     130                 :      868047 :   return as_a <rtx_code_label *> (label_rtx (label));
     131                 :             : }
     132                 :             : 
     133                 :             : /* Add an unconditional jump to LABEL as the next sequential instruction.  */
     134                 :             : 
     135                 :             : void
     136                 :     3237897 : emit_jump (rtx label)
     137                 :             : {
     138                 :     3237897 :   do_pending_stack_adjust ();
     139                 :     3237897 :   emit_jump_insn (targetm.gen_jump (label));
     140                 :     3237897 :   emit_barrier ();
     141                 :     3237897 : }
     142                 :             : 
     143                 :             : /* Handle goto statements and the labels that they can go to.  */
     144                 :             : 
     145                 :             : /* Specify the location in the RTL code of a label LABEL,
     146                 :             :    which is a LABEL_DECL tree node.
     147                 :             : 
     148                 :             :    This is used for the kind of label that the user can jump to with a
     149                 :             :    goto statement, and for alternatives of a switch or case statement.
     150                 :             :    RTL labels generated for loops and conditionals don't go through here;
     151                 :             :    they are generated directly at the RTL level, by other functions below.
     152                 :             : 
     153                 :             :    Note that this has nothing to do with defining label *names*.
     154                 :             :    Languages vary in how they do that and what that even means.  */
     155                 :             : 
     156                 :             : void
     157                 :      639360 : expand_label (tree label)
     158                 :             : {
     159                 :      639360 :   rtx_code_label *label_r = jump_target_rtx (label);
     160                 :             : 
     161                 :      639360 :   do_pending_stack_adjust ();
     162                 :      639360 :   emit_label (label_r);
     163                 :      639360 :   if (DECL_NAME (label))
     164                 :      103768 :     LABEL_NAME (DECL_RTL (label)) = IDENTIFIER_POINTER (DECL_NAME (label));
     165                 :             : 
     166                 :      639360 :   if (DECL_NONLOCAL (label))
     167                 :             :     {
     168                 :         502 :       expand_builtin_setjmp_receiver (NULL);
     169                 :         502 :       nonlocal_goto_handler_labels
     170                 :         502 :         = gen_rtx_INSN_LIST (VOIDmode, label_r,
     171                 :         502 :                              nonlocal_goto_handler_labels);
     172                 :             :     }
     173                 :             : 
     174                 :      639360 :   if (FORCED_LABEL (label))
     175                 :       25857 :     vec_safe_push<rtx_insn *> (forced_labels, label_r);
     176                 :             : 
     177                 :     1278218 :   if (DECL_NONLOCAL (label) || FORCED_LABEL (label))
     178                 :       26359 :     maybe_set_first_label_num (label_r);
     179                 :      639360 : }
     180                 :             : 
     181                 :             : /* Parse a hard register constraint and return its number or -1 in case of an
     182                 :             :    error.  BEGIN should point to a string of the form `{regname}`.  For the
     183                 :             :    sake of simplicity assume that a register name is not longer than 31
     184                 :             :    characters, if not error out.  */
     185                 :             : 
     186                 :             : int
     187                 :        2865 : decode_hard_reg_constraint (const char *begin)
     188                 :             : {
     189                 :        2865 :   if (*begin != '{')
     190                 :             :     return -1;
     191                 :        2865 :   ++begin;
     192                 :        2865 :   const char *end = begin;
     193                 :       11471 :   while (*end != '}' && *end != '\0')
     194                 :        8606 :     ++end;
     195                 :        2865 :   if (*end != '}' || end == begin)
     196                 :             :     return -1;
     197                 :        2863 :   ptrdiff_t len = end - begin;
     198                 :        2863 :   if (len >= 31)
     199                 :             :     return -1;
     200                 :        2863 :   char regname[32];
     201                 :        2863 :   memcpy (regname, begin, len);
     202                 :        2863 :   regname[len] = '\0';
     203                 :        2863 :   int regno = decode_reg_name (regname);
     204                 :        2863 :   return regno;
     205                 :             : }
     206                 :             : 
     207                 :             : static bool
     208                 :           0 : eliminable_regno_p (int regnum)
     209                 :             : {
     210                 :           0 :   static const struct
     211                 :             :   {
     212                 :             :     const int from;
     213                 :             :     const int to;
     214                 :             :   } eliminables[] = ELIMINABLE_REGS;
     215                 :           0 :   for (size_t i = 0; i < ARRAY_SIZE (eliminables); i++)
     216                 :           0 :     if (regnum == eliminables[i].from)
     217                 :             :       return true;
     218                 :             :   return false;
     219                 :             : }
     220                 :             : 
     221                 :             : /* Perform a similar check as done in make_decl_rtl().  */
     222                 :             : 
     223                 :             : static bool
     224                 :         184 : hardreg_ok_p (int reg_number, machine_mode mode, int operand_num)
     225                 :             : {
     226                 :         184 :   if (mode == BLKmode)
     227                 :           1 :     error ("data type isn%'t suitable for register %s of operand %i",
     228                 :             :            reg_names[reg_number], operand_num);
     229                 :         183 :   else if (!in_hard_reg_set_p (accessible_reg_set, mode, reg_number))
     230                 :           0 :     error ("register %s for operand %i cannot be accessed"
     231                 :             :            " by the current target", reg_names[reg_number], operand_num);
     232                 :         183 :   else if (!in_hard_reg_set_p (operand_reg_set, mode, reg_number))
     233                 :           0 :     error ("register %s for operand %i is not general enough"
     234                 :             :            " to be used as a register variable", reg_names[reg_number], operand_num);
     235                 :         183 :   else if (!targetm.hard_regno_mode_ok (reg_number, mode))
     236                 :           0 :     error ("register %s for operand %i isn%'t suitable for data type",
     237                 :             :            reg_names[reg_number], operand_num);
     238                 :         183 :   else if (reg_number != HARD_FRAME_POINTER_REGNUM
     239                 :         183 :            && (reg_number == FRAME_POINTER_REGNUM
     240                 :             : #ifdef RETURN_ADDRESS_POINTER_REGNUM
     241                 :             :                || reg_number == RETURN_ADDRESS_POINTER_REGNUM
     242                 :             : #endif
     243                 :         183 :                || reg_number == ARG_POINTER_REGNUM)
     244                 :         183 :            && eliminable_regno_p (reg_number))
     245                 :           0 :     error ("register for operand %i is an internal GCC "
     246                 :             :            "implementation detail", operand_num);
     247                 :             :   else
     248                 :             :     return true;
     249                 :             :   return false;
     250                 :             : }
     251                 :             : 
     252                 :             : /* Parse the output constraint pointed to by *CONSTRAINT_P.  It is the
     253                 :             :    OPERAND_NUMth output operand, indexed from zero.  There are NINPUTS
     254                 :             :    inputs and NOUTPUTS outputs to this extended-asm.  Upon return,
     255                 :             :    *ALLOWS_MEM will be TRUE iff the constraint allows the use of a
     256                 :             :    memory operand.  Similarly, *ALLOWS_REG will be TRUE iff the
     257                 :             :    constraint allows the use of a register operand.  And, *IS_INOUT
     258                 :             :    will be true if the operand is read-write, i.e., if it is used as
     259                 :             :    an input as well as an output.  If *CONSTRAINT_P is not in
     260                 :             :    canonical form, it will be made canonical.  (Note that `+' will be
     261                 :             :    replaced with `=' as part of this process.)
     262                 :             : 
     263                 :             :    Returns TRUE if all went well; FALSE if an error occurred.  */
     264                 :             : 
     265                 :             : bool
     266                 :    31756872 : parse_output_constraint (const char **constraint_p, int operand_num,
     267                 :             :                          int ninputs, int noutputs, bool *allows_mem,
     268                 :             :                          bool *allows_reg, bool *is_inout,
     269                 :             :                          gimplify_reg_info *reg_info)
     270                 :             : {
     271                 :    31756872 :   const char *constraint = *constraint_p;
     272                 :    31756872 :   const char *p;
     273                 :             : 
     274                 :             :   /* Assume the constraint doesn't allow the use of either a register
     275                 :             :      or memory.  */
     276                 :    31756872 :   *allows_mem = false;
     277                 :    31756872 :   *allows_reg = false;
     278                 :             : 
     279                 :             :   /* Allow the `=' or `+' to not be at the beginning of the string,
     280                 :             :      since it wasn't explicitly documented that way, and there is a
     281                 :             :      large body of code that puts it last.  Swap the character to
     282                 :             :      the front, so as not to uglify any place else.  */
     283                 :    31756872 :   p = strchr (constraint, '=');
     284                 :    31756872 :   if (!p)
     285                 :       17343 :     p = strchr (constraint, '+');
     286                 :             : 
     287                 :             :   /* If the string doesn't contain an `=', issue an error
     288                 :             :      message.  */
     289                 :       17343 :   if (!p)
     290                 :             :     {
     291                 :          12 :       error ("output operand constraint lacks %<=%>");
     292                 :          12 :       return false;
     293                 :             :     }
     294                 :             : 
     295                 :             :   /* If the constraint begins with `+', then the operand is both read
     296                 :             :      from and written to.  */
     297                 :    31756860 :   *is_inout = (*p == '+');
     298                 :             : 
     299                 :             :   /* Canonicalize the output constraint so that it begins with `='.  */
     300                 :    31756860 :   if (p != constraint || *is_inout)
     301                 :             :     {
     302                 :       17331 :       char *buf;
     303                 :       17331 :       size_t c_len = strlen (constraint);
     304                 :             : 
     305                 :       17331 :       if (p != constraint)
     306                 :           0 :         warning (0, "output constraint %qc for operand %d "
     307                 :             :                  "is not at the beginning",
     308                 :           0 :                  *p, operand_num);
     309                 :             : 
     310                 :             :       /* Make a copy of the constraint.  */
     311                 :       17331 :       buf = XALLOCAVEC (char, c_len + 1);
     312                 :       17331 :       strcpy (buf, constraint);
     313                 :             :       /* Swap the first character and the `=' or `+'.  */
     314                 :       17331 :       buf[p - constraint] = buf[0];
     315                 :             :       /* Make sure the first character is an `='.  (Until we do this,
     316                 :             :          it might be a `+'.)  */
     317                 :       17331 :       buf[0] = '=';
     318                 :             :       /* Replace the constraint with the canonicalized string.  */
     319                 :       17331 :       *constraint_p = ggc_alloc_string (buf, c_len);
     320                 :       17331 :       constraint = *constraint_p;
     321                 :             :     }
     322                 :             : 
     323                 :    31756860 :   unsigned int alt = 0;
     324                 :    31756860 :   bool early_clobbered = false;
     325                 :             : 
     326                 :             :   /* Loop through the constraint string.  */
     327                 :    64337445 :   for (p = constraint + 1; *p; )
     328                 :             :     {
     329                 :    32580600 :       switch (*p)
     330                 :             :         {
     331                 :           0 :         case '+':
     332                 :           0 :         case '=':
     333                 :           0 :           error ("operand constraint contains incorrectly positioned "
     334                 :             :                  "%<+%> or %<=%>");
     335                 :           0 :           return false;
     336                 :             : 
     337                 :           8 :         case '%':
     338                 :           8 :           if (operand_num + 1 == ninputs + noutputs)
     339                 :             :             {
     340                 :           0 :               error ("%<%%%> constraint used with last operand");
     341                 :           0 :               return false;
     342                 :             :             }
     343                 :             :           break;
     344                 :             : 
     345                 :             :         case '&':
     346                 :    32580585 :           early_clobbered = true;
     347                 :             :           break;
     348                 :             : 
     349                 :             :         case '?':  case '!':  case '*':  case '#':
     350                 :             :         case '$':  case '^':
     351                 :             :         case 'E':  case 'F':  case 'G':  case 'H':
     352                 :             :         case 's':  case 'i':  case 'n':
     353                 :             :         case 'I':  case 'J':  case 'K':  case 'L':  case 'M':
     354                 :             :         case 'N':  case 'O':  case 'P':  case '-':
     355                 :             :           break;
     356                 :             : 
     357                 :       86841 :         case ',':
     358                 :       86841 :           ++alt;
     359                 :       86841 :           early_clobbered = false;
     360                 :       86841 :           break;
     361                 :             : 
     362                 :           0 :         case '0':  case '1':  case '2':  case '3':  case '4':
     363                 :           0 :         case '5':  case '6':  case '7':  case '8':  case '9':
     364                 :           0 :         case '[':
     365                 :           0 :           error ("matching constraint not valid in output operand");
     366                 :           0 :           return false;
     367                 :             : 
     368                 :           8 :         case ':':
     369                 :           8 :           error ("%<:%> constraint used for output operand");
     370                 :           8 :           return false;
     371                 :             : 
     372                 :           0 :         case '<':  case '>':
     373                 :             :           /* ??? Before flow, auto inc/dec insns are not supposed to exist,
     374                 :             :              excepting those that expand_call created.  So match memory
     375                 :             :              and hope.  */
     376                 :           0 :           *allows_mem = true;
     377                 :           0 :           break;
     378                 :             : 
     379                 :     1887775 :         case 'g':  case 'X':
     380                 :     1887775 :           *allows_reg = true;
     381                 :     1887775 :           *allows_mem = true;
     382                 :     1887775 :           break;
     383                 :             : 
     384                 :       25744 :         case '{':
     385                 :       25744 :           {
     386                 :       25744 :             if (!targetm.lra_p ())
     387                 :             :               {
     388                 :           0 :                 error ("hard register constraints are only supported while using LRA");
     389                 :           0 :                 return false;
     390                 :             :               }
     391                 :       25744 :             if (reg_info)
     392                 :             :               {
     393                 :          97 :                 int regno = decode_hard_reg_constraint (p);
     394                 :          97 :                 if (regno < 0)
     395                 :             :                   {
     396                 :           0 :                     error ("invalid output constraint: %s", p);
     397                 :           0 :                     return false;
     398                 :             :                   }
     399                 :          97 :                 int overlap_regno = reg_info->test_alt_output (alt, regno);
     400                 :          97 :                 if (overlap_regno < 0)
     401                 :          96 :                   overlap_regno = reg_info->test_reg_asm_output (regno);
     402                 :          96 :                 if (overlap_regno >= 0)
     403                 :             :                   {
     404                 :           1 :                     error ("multiple outputs to hard register: %s",
     405                 :             :                            reg_names[overlap_regno]);
     406                 :           1 :                     return false;
     407                 :             :                   }
     408                 :          96 :                 reg_info->set_output (alt, regno);
     409                 :          96 :                 if (early_clobbered)
     410                 :          16 :                   reg_info->set_early_clobbered (alt, operand_num, regno);
     411                 :          96 :                 if (reg_info->is_clobbered (regno))
     412                 :             :                   {
     413                 :           1 :                     error ("hard register constraint for output %i conflicts "
     414                 :             :                            "with %<asm%> clobber list", operand_num);
     415                 :           1 :                     return false;
     416                 :             :                   }
     417                 :          95 :                 if (VAR_P (reg_info->operand)
     418                 :          95 :                     && DECL_HARD_REGISTER (reg_info->operand))
     419                 :             :                   {
     420                 :           2 :                       tree id = DECL_ASSEMBLER_NAME (reg_info->operand);
     421                 :           2 :                       const char *asmspec = IDENTIFIER_POINTER (id) + 1;
     422                 :           2 :                       int regno_op = decode_reg_name (asmspec);
     423                 :           2 :                       if (regno != regno_op)
     424                 :             :                         {
     425                 :           1 :                           error ("constraint and register %<asm%> for output "
     426                 :             :                                  "operand %i are unsatisfiable", operand_num);
     427                 :           1 :                           return false;
     428                 :             :                         }
     429                 :             :                   }
     430                 :          94 :                 machine_mode mode = TYPE_MODE (TREE_TYPE (reg_info->operand));
     431                 :          94 :                 if (!hardreg_ok_p (regno, mode, operand_num))
     432                 :             :                   return false;
     433                 :             :               }
     434                 :       25741 :             *allows_reg = true;
     435                 :       25741 :             break;
     436                 :             :           }
     437                 :             : 
     438                 :    30034908 :         default:
     439                 :    30034908 :           if (!ISALPHA (*p))
     440                 :             :             break;
     441                 :    30015873 :           enum constraint_num cn = lookup_constraint (p);
     442                 :    30015873 :           if (reg_class_for_constraint (cn) != NO_REGS
     443                 :    30015873 :               || insn_extra_address_constraint (cn))
     444                 :    28223668 :             *allows_reg = true;
     445                 :             :           else if (insn_extra_memory_constraint (cn))
     446                 :     1784443 :             *allows_mem = true;
     447                 :             :           else
     448                 :             :             insn_extra_constraint_allows_reg_mem (cn, allows_reg, allows_mem);
     449                 :       51980 :           if (reg_info && *allows_reg
     450                 :       50676 :               && VAR_P (reg_info->operand)
     451                 :    30047658 :               && DECL_HARD_REGISTER (reg_info->operand))
     452                 :             :             {
     453                 :         949 :                 tree id = DECL_ASSEMBLER_NAME (reg_info->operand);
     454                 :         949 :                 const char *asmspec = IDENTIFIER_POINTER (id) + 1;
     455                 :         949 :                 int regno = decode_reg_name (asmspec);
     456                 :         949 :                 if (regno < 0)
     457                 :             :                   {
     458                 :           4 :                     location_t loc = DECL_SOURCE_LOCATION (reg_info->operand);
     459                 :           4 :                     error_at (loc, "invalid register name for %q+D",
     460                 :             :                               reg_info->operand);
     461                 :           4 :                     return false;
     462                 :             :                   }
     463                 :         945 :                 int overlap_regno = reg_info->test_alt_output (alt, regno);
     464                 :         945 :                 if (overlap_regno >= 0)
     465                 :             :                   {
     466                 :           0 :                     error ("multiple outputs to hard register: %s",
     467                 :             :                            reg_names[overlap_regno]);
     468                 :           0 :                     return false;
     469                 :             :                   }
     470                 :         945 :                 reg_info->set_reg_asm_output (regno);
     471                 :         945 :                 if (early_clobbered)
     472                 :          10 :                   reg_info->set_early_clobbered (alt, operand_num, regno);
     473                 :             :             }
     474                 :             :           break;
     475                 :             :         }
     476                 :             : 
     477                 :    65279180 :       for (size_t len = CONSTRAINT_LEN (*p, p); len; len--, p++)
     478                 :    32699042 :         if (*p == '\0')
     479                 :             :           break;
     480                 :             :     }
     481                 :             : 
     482                 :             :   return true;
     483                 :             : }
     484                 :             : 
     485                 :             : /* Similar, but for input constraints.  */
     486                 :             : 
     487                 :             : bool
     488                 :    20706581 : parse_input_constraint (const char **constraint_p, int input_num,
     489                 :             :                         int ninputs, int noutputs, int ninout,
     490                 :             :                         const char * const * constraints,
     491                 :             :                         bool *allows_mem, bool *allows_reg,
     492                 :             :                         gimplify_reg_info *reg_info)
     493                 :             : {
     494                 :    20706581 :   const char *constraint = *constraint_p;
     495                 :    20706581 :   const char *orig_constraint = constraint;
     496                 :    20706581 :   size_t c_len = strlen (constraint);
     497                 :    20706581 :   size_t j;
     498                 :    20706581 :   bool saw_match = false;
     499                 :    20706581 :   bool at_checked = false;
     500                 :             : 
     501                 :             :   /* Assume the constraint doesn't allow the use of either
     502                 :             :      a register or memory.  */
     503                 :    20706581 :   *allows_mem = false;
     504                 :    20706581 :   *allows_reg = false;
     505                 :             : 
     506                 :             :   /* Make sure constraint has neither `=', `+', nor '&'.  */
     507                 :             : 
     508                 :    20706581 :   unsigned int alt = 0;
     509                 :    20706581 :   unsigned long match = 0;
     510                 :             : 
     511                 :    55149952 :   for (j = 0; j < c_len; j += CONSTRAINT_LEN (constraint[j], constraint+j))
     512                 :    34443424 :     switch (constraint[j])
     513                 :             :       {
     514                 :      476289 :       case '+':  case '=':  case '&':
     515                 :      476289 :         if (constraint == orig_constraint)
     516                 :             :           {
     517                 :           0 :             error ("input operand constraint contains %qc", constraint[j]);
     518                 :           0 :             return false;
     519                 :             :           }
     520                 :             :         break;
     521                 :             : 
     522                 :      378995 :       case '%':
     523                 :      378995 :         if (constraint == orig_constraint
     524                 :      378995 :             && input_num + 1 == ninputs - ninout)
     525                 :             :           {
     526                 :           0 :             error ("%<%%%> constraint used with last operand");
     527                 :           0 :             return false;
     528                 :             :           }
     529                 :             :         break;
     530                 :             : 
     531                 :             :       case '<':  case '>':
     532                 :             :       case '?':  case '!':  case '*':  case '#':
     533                 :             :       case '$':  case '^':
     534                 :             :       case 'E':  case 'F':  case 'G':  case 'H':
     535                 :             :       case 's':  case 'i':  case 'n':
     536                 :             :       case 'I':  case 'J':  case 'K':  case 'L':  case 'M':
     537                 :             :       case 'N':  case 'O':  case 'P':  case '-':
     538                 :             :         break;
     539                 :             : 
     540                 :         112 :       case ':':
     541                 :             :         /* Verify that if : is used, it is just ":" or say ":,:" but not
     542                 :             :            mixed with other constraints or say ",:,," etc.  */
     543                 :         112 :         if (!at_checked)
     544                 :             :           {
     545                 :         204 :             for (size_t k = 0; k < c_len; ++k)
     546                 :         228 :               if (constraint[k] != ((k & 1) ? ',' : ':') || (c_len & 1) == 0)
     547                 :             :                 {
     548                 :          20 :                   error ("%<:%> constraint mixed with other constraints");
     549                 :          20 :                   return false;
     550                 :             :                 } 
     551                 :             :             at_checked = true;
     552                 :             :           }
     553                 :             :         break;
     554                 :             : 
     555                 :       84535 :       case ',':
     556                 :       84535 :         ++alt;
     557                 :       84535 :         break;
     558                 :             : 
     559                 :             :         /* Whether or not a numeric constraint allows a register is
     560                 :             :            decided by the matching constraint, and so there is no need
     561                 :             :            to do anything special with them.  We must handle them in
     562                 :             :            the default case, so that we don't unnecessarily force
     563                 :             :            operands to memory.  */
     564                 :    12092118 :       case '0':  case '1':  case '2':  case '3':  case '4':
     565                 :    12092118 :       case '5':  case '6':  case '7':  case '8':  case '9':
     566                 :    12092118 :         {
     567                 :    12092118 :           char *end;
     568                 :             : 
     569                 :    12092118 :           saw_match = true;
     570                 :             : 
     571                 :    12092118 :           match = strtoul (constraint + j, &end, 10);
     572                 :    12092118 :           if (match >= (unsigned long) noutputs)
     573                 :             :             {
     574                 :           4 :               error ("matching constraint references invalid operand number");
     575                 :           4 :               return false;
     576                 :             :             }
     577                 :             : 
     578                 :             :           /* Try and find the real constraint for this dup.  Only do this
     579                 :             :              if the matching constraint is the only alternative.  */
     580                 :    12092114 :           if (*end == '\0'
     581                 :    12028058 :               && (j == 0 || (j == 1 && constraint[0] == '%')))
     582                 :             :             {
     583                 :    12016769 :               constraint = constraints[match];
     584                 :    12016769 :               *constraint_p = constraint;
     585                 :    12016769 :               c_len = strlen (constraint);
     586                 :    12016769 :               j = 0;
     587                 :             :               /* ??? At the end of the loop, we will skip the first part of
     588                 :             :                  the matched constraint.  This assumes not only that the
     589                 :             :                  other constraint is an output constraint, but also that
     590                 :             :                  the '=' or '+' come first.  */
     591                 :    12016769 :               break;
     592                 :             :             }
     593                 :             :           else
     594                 :       75345 :             j = end - constraint;
     595                 :             :           /* Anticipate increment at end of loop.  */
     596                 :       75345 :           j--;
     597                 :             :         }
     598                 :             :         /* Fall through.  */
     599                 :             : 
     600                 :     2850536 :       case 'g':  case 'X':
     601                 :     2850536 :         *allows_reg = true;
     602                 :     2850536 :         *allows_mem = true;
     603                 :     2850536 :         break;
     604                 :             : 
     605                 :       20503 :       case '{':
     606                 :       20503 :         {
     607                 :       20503 :           if (!targetm.lra_p ())
     608                 :             :             {
     609                 :           0 :               error ("hard register constraints are only supported while using LRA");
     610                 :           0 :               return false;
     611                 :             :             }
     612                 :       20503 :           if (reg_info)
     613                 :             :             {
     614                 :         106 :               int regno = decode_hard_reg_constraint (constraint + j);
     615                 :         106 :               if (regno < 0)
     616                 :             :                 {
     617                 :           3 :                   error ("invalid input constraint: %s", constraint + j);
     618                 :           3 :                   return false;
     619                 :             :                 }
     620                 :         103 :               int overlap_regno = reg_info->test_alt_input (alt, regno);
     621                 :         103 :               if (overlap_regno < 0)
     622                 :          97 :                 overlap_regno = reg_info->test_reg_asm_input (regno);
     623                 :          97 :               if (overlap_regno >= 0)
     624                 :             :                 {
     625                 :           7 :                   error ("multiple inputs to hard register: %s",
     626                 :             :                             reg_names[overlap_regno]);
     627                 :           7 :                   return false;
     628                 :             :                 }
     629                 :          96 :               reg_info->set_input (alt, regno);
     630                 :          96 :               if (reg_info->is_clobbered (regno))
     631                 :             :                 {
     632                 :           1 :                   error ("hard register constraint for input %i conflicts "
     633                 :             :                          "with %<asm%> clobber list", input_num);
     634                 :           1 :                   return false;
     635                 :             :                 }
     636                 :          95 :               if (constraint == orig_constraint
     637                 :          95 :                   && reg_info->test_early_clobbered_alt (alt, regno))
     638                 :             :                 {
     639                 :           3 :                   error ("invalid hard register usage between earlyclobber "
     640                 :             :                          "operand and input operand");
     641                 :           3 :                   return false;
     642                 :             :                 }
     643                 :          92 :               if (VAR_P (reg_info->operand)
     644                 :          92 :                   && DECL_HARD_REGISTER (reg_info->operand))
     645                 :             :                 {
     646                 :           5 :                     tree id = DECL_ASSEMBLER_NAME (reg_info->operand);
     647                 :           5 :                     const char *asmspec = IDENTIFIER_POINTER (id) + 1;
     648                 :           5 :                     int regno_op = decode_reg_name (asmspec);
     649                 :           5 :                     if (regno != regno_op)
     650                 :             :                       {
     651                 :           2 :                         error ("constraint and register %<asm%> for input "
     652                 :             :                                "operand %i are unsatisfiable", input_num);
     653                 :           2 :                         return false;
     654                 :             :                       }
     655                 :             :                 }
     656                 :          90 :               machine_mode mode = TYPE_MODE (TREE_TYPE (reg_info->operand));
     657                 :          90 :               if (!hardreg_ok_p (regno, mode, input_num))
     658                 :             :                 return false;
     659                 :             :             }
     660                 :       20486 :           *allows_reg = true;
     661                 :       20486 :           break;
     662                 :             :         }
     663                 :             : 
     664                 :    18107871 :       default:
     665                 :    18107871 :         if (! ISALPHA (constraint[j]))
     666                 :             :           {
     667                 :           2 :             error ("invalid punctuation %qc in constraint", constraint[j]);
     668                 :           2 :             return false;
     669                 :             :           }
     670                 :    18107869 :         enum constraint_num cn = lookup_constraint (constraint + j);
     671                 :    18107869 :         if (reg_class_for_constraint (cn) != NO_REGS
     672                 :    18107869 :             || insn_extra_address_constraint (cn))
     673                 :    15471231 :           *allows_reg = true;
     674                 :             :         else if (insn_extra_memory_constraint (cn)
     675                 :             :                  || insn_extra_special_memory_constraint (cn)
     676                 :             :                  || insn_extra_relaxed_memory_constraint (cn))
     677                 :     2400768 :           *allows_mem = true;
     678                 :             :         else
     679                 :             :           insn_extra_constraint_allows_reg_mem (cn, allows_reg, allows_mem);
     680                 :       33381 :         if (reg_info && *allows_reg
     681                 :       31701 :             && VAR_P (reg_info->operand)
     682                 :    18112588 :             && DECL_HARD_REGISTER (reg_info->operand))
     683                 :             :           {
     684                 :         873 :               tree id = DECL_ASSEMBLER_NAME (reg_info->operand);
     685                 :         873 :               const char *asmspec = IDENTIFIER_POINTER (id) + 1;
     686                 :         873 :               int regno = decode_reg_name (asmspec);
     687                 :         873 :               if (regno < 0)
     688                 :             :                 {
     689                 :           5 :                   location_t loc = DECL_SOURCE_LOCATION (reg_info->operand);
     690                 :           5 :                   error_at (loc, "invalid register name for %q+D",
     691                 :             :                             reg_info->operand);
     692                 :           5 :                   return false;
     693                 :             :                 }
     694                 :         868 :               int overlap_regno = reg_info->test_alt_input (alt, regno);
     695                 :         868 :               if (overlap_regno >= 0)
     696                 :             :                 {
     697                 :           1 :                   error ("multiple inputs to hard register: %s",
     698                 :             :                          reg_names[overlap_regno]);
     699                 :           1 :                   return false;
     700                 :             :                 }
     701                 :         867 :               reg_info->set_reg_asm_input (regno);
     702                 :         867 :               if ((constraint == orig_constraint
     703                 :         200 :                    && reg_info->test_early_clobbered_alt (alt, regno))
     704                 :        1065 :                   || (constraint != orig_constraint
     705                 :         667 :                       && reg_info->is_early_clobbered_in_any_output_unequal
     706                 :         667 :                           (match, regno)))
     707                 :             :                 {
     708                 :           4 :                   error ("invalid hard register usage between earlyclobber "
     709                 :             :                          "operand and input operand");
     710                 :           4 :                   return false;
     711                 :             :                 }
     712                 :             :           }
     713                 :             :         break;
     714                 :             :       }
     715                 :             : 
     716                 :    20706528 :   if (saw_match && !*allows_reg)
     717                 :           4 :     warning (0, "matching constraint does not allow a register");
     718                 :             : 
     719                 :             :   return true;
     720                 :             : }
     721                 :             : 
     722                 :             : /* Return DECL iff there's an overlap between *REGS and DECL, where DECL
     723                 :             :    can be an asm-declared register.  Called via walk_tree.  */
     724                 :             : 
     725                 :             : static tree
     726                 :      138244 : decl_overlaps_hard_reg_set_p (tree *declp, int *walk_subtrees ATTRIBUTE_UNUSED,
     727                 :             :                               void *data)
     728                 :             : {
     729                 :      138244 :   tree decl = *declp;
     730                 :      138244 :   const HARD_REG_SET *const regs = (const HARD_REG_SET *) data;
     731                 :             : 
     732                 :      138244 :   if (VAR_P (decl))
     733                 :             :     {
     734                 :       20376 :       if (DECL_HARD_REGISTER (decl)
     735                 :        1837 :           && REG_P (DECL_RTL (decl))
     736                 :       22213 :           && REGNO (DECL_RTL (decl)) < FIRST_PSEUDO_REGISTER)
     737                 :             :         {
     738                 :        1837 :           rtx reg = DECL_RTL (decl);
     739                 :             : 
     740                 :        1837 :           if (overlaps_hard_reg_set_p (*regs, GET_MODE (reg), REGNO (reg)))
     741                 :             :             return decl;
     742                 :             :         }
     743                 :             :       walk_subtrees = 0;
     744                 :             :     }
     745                 :             :   else if (TYPE_P (decl) || TREE_CODE (decl) == PARM_DECL)
     746                 :      138244 :     walk_subtrees = 0;
     747                 :             :   return NULL_TREE;
     748                 :             : }
     749                 :             : 
     750                 :             : /* If there is an overlap between *REGS and DECL, return the first overlap
     751                 :             :    found.  */
     752                 :             : tree
     753                 :      123015 : tree_overlaps_hard_reg_set (tree decl, HARD_REG_SET *regs)
     754                 :             : {
     755                 :      123015 :   return walk_tree (&decl, decl_overlaps_hard_reg_set_p, regs, NULL);
     756                 :             : }
     757                 :             : 
     758                 :             : 
     759                 :             : /* A subroutine of expand_asm_operands.  Check that all operand names
     760                 :             :    are unique.  Return true if so.  We rely on the fact that these names
     761                 :             :    are identifiers, and so have been canonicalized by get_identifier,
     762                 :             :    so all we need are pointer comparisons.  */
     763                 :             : 
     764                 :             : static bool
     765                 :      211490 : check_unique_operand_names (tree outputs, tree inputs, tree labels)
     766                 :             : {
     767                 :      211490 :   tree i, j, i_name = NULL_TREE;
     768                 :             : 
     769                 :      565472 :   for (i = outputs; i ; i = TREE_CHAIN (i))
     770                 :             :     {
     771                 :      353982 :       i_name = TREE_PURPOSE (TREE_PURPOSE (i));
     772                 :      353982 :       if (! i_name)
     773                 :      353573 :         continue;
     774                 :             : 
     775                 :        2328 :       for (j = TREE_CHAIN (i); j ; j = TREE_CHAIN (j))
     776                 :        1919 :         if (simple_cst_equal (i_name, TREE_PURPOSE (TREE_PURPOSE (j))))
     777                 :           0 :           goto failure;
     778                 :             :     }
     779                 :             : 
     780                 :      579946 :   for (i = inputs; i ; i = TREE_CHAIN (i))
     781                 :             :     {
     782                 :      368461 :       i_name = TREE_PURPOSE (TREE_PURPOSE (i));
     783                 :      368461 :       if (! i_name)
     784                 :      368323 :         continue;
     785                 :             : 
     786                 :         359 :       for (j = TREE_CHAIN (i); j ; j = TREE_CHAIN (j))
     787                 :         221 :         if (simple_cst_equal (i_name, TREE_PURPOSE (TREE_PURPOSE (j))))
     788                 :           0 :           goto failure;
     789                 :         443 :       for (j = outputs; j ; j = TREE_CHAIN (j))
     790                 :         310 :         if (simple_cst_equal (i_name, TREE_PURPOSE (TREE_PURPOSE (j))))
     791                 :           5 :           goto failure;
     792                 :             :     }
     793                 :             : 
     794                 :      212240 :   for (i = labels; i ; i = TREE_CHAIN (i))
     795                 :             :     {
     796                 :         763 :       i_name = TREE_PURPOSE (i);
     797                 :         763 :       if (! i_name)
     798                 :           0 :         continue;
     799                 :             : 
     800                 :        2101 :       for (j = TREE_CHAIN (i); j ; j = TREE_CHAIN (j))
     801                 :        1342 :         if (simple_cst_equal (i_name, TREE_PURPOSE (j)))
     802                 :           4 :           goto failure;
     803                 :        1069 :       for (j = inputs; j ; j = TREE_CHAIN (j))
     804                 :         314 :         if (simple_cst_equal (i_name, TREE_PURPOSE (TREE_PURPOSE (j))))
     805                 :           4 :           goto failure;
     806                 :             :     }
     807                 :             : 
     808                 :             :   return true;
     809                 :             : 
     810                 :          13 :  failure:
     811                 :          13 :   error ("duplicate %<asm%> operand name %qs", TREE_STRING_POINTER (i_name));
     812                 :          13 :   return false;
     813                 :             : }
     814                 :             : 
     815                 :             : /* Resolve the names of the operands in *POUTPUTS and *PINPUTS to numbers,
     816                 :             :    and replace the name expansions in STRING and in the constraints to
     817                 :             :    those numbers.  This is generally done in the front end while creating
     818                 :             :    the ASM_EXPR generic tree that eventually becomes the GIMPLE_ASM.  */
     819                 :             : 
     820                 :             : tree
     821                 :      211490 : resolve_asm_operand_names (tree string, tree outputs, tree inputs, tree labels)
     822                 :             : {
     823                 :      211490 :   char *buffer;
     824                 :      211490 :   char *p;
     825                 :      211490 :   const char *c;
     826                 :      211490 :   tree t;
     827                 :             : 
     828                 :      211490 :   check_unique_operand_names (outputs, inputs, labels);
     829                 :             : 
     830                 :             :   /* Substitute [<name>] in input constraint strings.  There should be no
     831                 :             :      named operands in output constraints.  */
     832                 :      791441 :   for (t = inputs; t ; t = TREE_CHAIN (t))
     833                 :             :     {
     834                 :      368461 :       c = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t)));
     835                 :      368461 :       if (strchr (c, '[') != NULL)
     836                 :             :         {
     837                 :         179 :           p = buffer = xstrdup (c);
     838                 :         537 :           while ((p = strchr (p, '[')) != NULL)
     839                 :         179 :             p = resolve_operand_name_1 (p, outputs, inputs, NULL);
     840                 :         179 :           TREE_VALUE (TREE_PURPOSE (t))
     841                 :         179 :             = build_string (strlen (buffer), buffer);
     842                 :         179 :           free (buffer);
     843                 :             :         }
     844                 :             :     }
     845                 :             : 
     846                 :             :   /* Now check for any needed substitutions in the template.  */
     847                 :      211490 :   c = TREE_STRING_POINTER (string);
     848                 :      250978 :   while ((c = strchr (c, '%')) != NULL)
     849                 :             :     {
     850                 :       39638 :       if (c[1] == '[')
     851                 :             :         break;
     852                 :       39578 :       else if (ISALPHA (c[1]) && c[2] == '[')
     853                 :             :         break;
     854                 :             :       else
     855                 :             :         {
     856                 :       39488 :           c += 1 + (c[1] == '%');
     857                 :       39488 :           continue;
     858                 :             :         }
     859                 :             :     }
     860                 :             : 
     861                 :      211490 :   if (c)
     862                 :             :     {
     863                 :             :       /* OK, we need to make a copy so we can perform the substitutions.
     864                 :             :          Assume that we will not need extra space--we get to remove '['
     865                 :             :          and ']', which means we cannot have a problem until we have more
     866                 :             :          than 999 operands.  */
     867                 :         150 :       buffer = xstrdup (TREE_STRING_POINTER (string));
     868                 :         150 :       p = buffer + (c - TREE_STRING_POINTER (string));
     869                 :             : 
     870                 :         459 :       while ((p = strchr (p, '%')) != NULL)
     871                 :             :         {
     872                 :         309 :           if (p[1] == '[')
     873                 :         125 :             p += 1;
     874                 :         184 :           else if (ISALPHA (p[1]) && p[2] == '[')
     875                 :         142 :             p += 2;
     876                 :             :           else
     877                 :             :             {
     878                 :          42 :               p += 1 + (p[1] == '%');
     879                 :          42 :               continue;
     880                 :             :             }
     881                 :             : 
     882                 :         267 :           p = resolve_operand_name_1 (p, outputs, inputs, labels);
     883                 :             :         }
     884                 :             : 
     885                 :         150 :       string = build_string (strlen (buffer), buffer);
     886                 :         150 :       free (buffer);
     887                 :             :     }
     888                 :             : 
     889                 :      211490 :   return string;
     890                 :             : }
     891                 :             : 
     892                 :             : /* A subroutine of resolve_operand_names.  P points to the '[' for a
     893                 :             :    potential named operand of the form [<name>].  In place, replace
     894                 :             :    the name and brackets with a number.  Return a pointer to the
     895                 :             :    balance of the string after substitution.  */
     896                 :             : 
     897                 :             : static char *
     898                 :         446 : resolve_operand_name_1 (char *p, tree outputs, tree inputs, tree labels)
     899                 :             : {
     900                 :         446 :   char *q;
     901                 :         446 :   int op, op_inout;
     902                 :         446 :   tree t;
     903                 :             : 
     904                 :             :   /* Collect the operand name.  */
     905                 :         446 :   q = strchr (++p, ']');
     906                 :         446 :   if (!q)
     907                 :             :     {
     908                 :           0 :       error ("missing close brace for named operand");
     909                 :           0 :       return strchr (p, '\0');
     910                 :             :     }
     911                 :         446 :   *q = '\0';
     912                 :             : 
     913                 :             :   /* Resolve the name to a number.  */
     914                 :        1720 :   for (op_inout = op = 0, t = outputs; t ; t = TREE_CHAIN (t), op++)
     915                 :             :     {
     916                 :        1507 :       tree name = TREE_PURPOSE (TREE_PURPOSE (t));
     917                 :        2759 :       if (name && strcmp (TREE_STRING_POINTER (name), p) == 0)
     918                 :         233 :         goto found;
     919                 :        1274 :       tree constraint = TREE_VALUE (TREE_PURPOSE (t));
     920                 :        2548 :       if (constraint && strchr (TREE_STRING_POINTER (constraint), '+') != NULL)
     921                 :          64 :         op_inout++;
     922                 :             :     }
     923                 :         379 :   for (t = inputs; t ; t = TREE_CHAIN (t), op++)
     924                 :             :     {
     925                 :         280 :       tree name = TREE_PURPOSE (TREE_PURPOSE (t));
     926                 :         459 :       if (name && strcmp (TREE_STRING_POINTER (name), p) == 0)
     927                 :         114 :         goto found;
     928                 :             :     }
     929                 :          99 :   op += op_inout;
     930                 :         108 :   for (t = labels; t ; t = TREE_CHAIN (t), op++)
     931                 :             :     {
     932                 :         105 :       tree name = TREE_PURPOSE (t);
     933                 :         210 :       if (name && strcmp (TREE_STRING_POINTER (name), p) == 0)
     934                 :          96 :         goto found;
     935                 :             :     }
     936                 :             : 
     937                 :           3 :   error ("undefined named operand %qs", identifier_to_locale (p));
     938                 :           3 :   op = 0;
     939                 :             : 
     940                 :         446 :  found:
     941                 :             :   /* Replace the name with the number.  Unfortunately, not all libraries
     942                 :             :      get the return value of sprintf correct, so search for the end of the
     943                 :             :      generated string by hand.  */
     944                 :         446 :   sprintf (--p, "%d", op);
     945                 :         446 :   p = strchr (p, '\0');
     946                 :             : 
     947                 :             :   /* Verify the no extra buffer space assumption.  */
     948                 :         446 :   gcc_assert (p <= q);
     949                 :             : 
     950                 :             :   /* Shift the rest of the buffer down to fill the gap.  */
     951                 :         446 :   memmove (p, q + 1, strlen (q + 1) + 1);
     952                 :             : 
     953                 :         446 :   return p;
     954                 :             : }
     955                 :             : 
     956                 :             : 
     957                 :             : /* Generate RTL to return directly from the current function.
     958                 :             :    (That is, we bypass any return value.)  */
     959                 :             : 
     960                 :             : void
     961                 :         379 : expand_naked_return (void)
     962                 :             : {
     963                 :         379 :   rtx_code_label *end_label;
     964                 :             : 
     965                 :         379 :   clear_pending_stack_adjust ();
     966                 :         379 :   do_pending_stack_adjust ();
     967                 :             : 
     968                 :         379 :   end_label = naked_return_label;
     969                 :         379 :   if (end_label == 0)
     970                 :         379 :     end_label = naked_return_label = gen_label_rtx ();
     971                 :             : 
     972                 :         379 :   emit_jump (end_label);
     973                 :         379 : }
     974                 :             : 
     975                 :             : /* Generate code to jump to LABEL if OP0 and OP1 are equal in mode MODE. PROB
     976                 :             :    is the probability of jumping to LABEL.  */
     977                 :             : static void
     978                 :           0 : do_jump_if_equal (machine_mode mode, rtx op0, rtx op1, rtx_code_label *label,
     979                 :             :                   int unsignedp, profile_probability prob)
     980                 :             : {
     981                 :           0 :   do_compare_rtx_and_jump (op0, op1, EQ, unsignedp, mode,
     982                 :             :                            NULL_RTX, NULL, label, prob);
     983                 :           0 : }
     984                 :             : 
     985                 :             : /* Return the sum of probabilities of outgoing edges of basic block BB.  */
     986                 :             : 
     987                 :             : static profile_probability
     988                 :        9249 : get_outgoing_edge_probs (basic_block bb)
     989                 :             : {
     990                 :        9249 :   edge e;
     991                 :        9249 :   edge_iterator ei;
     992                 :        9249 :   profile_probability prob_sum = profile_probability::never ();
     993                 :        9249 :   if (!bb)
     994                 :           0 :     return profile_probability::never ();
     995                 :       95580 :   FOR_EACH_EDGE (e, ei, bb->succs)
     996                 :       86331 :     prob_sum += e->probability;
     997                 :        9249 :   return prob_sum;
     998                 :             : }
     999                 :             : 
    1000                 :             : /* Computes the conditional probability of jumping to a target if the branch
    1001                 :             :    instruction is executed.
    1002                 :             :    TARGET_PROB is the estimated probability of jumping to a target relative
    1003                 :             :    to some basic block BB.
    1004                 :             :    BASE_PROB is the probability of reaching the branch instruction relative
    1005                 :             :    to the same basic block BB.  */
    1006                 :             : 
    1007                 :             : static inline profile_probability
    1008                 :       13233 : conditional_probability (profile_probability target_prob,
    1009                 :             :                          profile_probability base_prob)
    1010                 :             : {
    1011                 :       13233 :   return target_prob / base_prob;
    1012                 :             : }
    1013                 :             : 
    1014                 :             : /* Generate a dispatch tabler, switching on INDEX_EXPR and jumping to
    1015                 :             :    one of the labels in CASE_LIST or to the DEFAULT_LABEL.
    1016                 :             :    MINVAL, MAXVAL, and RANGE are the extrema and range of the case
    1017                 :             :    labels in CASE_LIST. STMT_BB is the basic block containing the statement.
    1018                 :             : 
    1019                 :             :    First, a jump insn is emitted.  First we try "casesi".  If that
    1020                 :             :    fails, try "tablejump".   A target *must* have one of them (or both).
    1021                 :             : 
    1022                 :             :    Then, a table with the target labels is emitted.
    1023                 :             : 
    1024                 :             :    The process is unaware of the CFG.  The caller has to fix up
    1025                 :             :    the CFG itself.  This is done in cfgexpand.cc.  */
    1026                 :             : 
    1027                 :             : static void
    1028                 :        9249 : emit_case_dispatch_table (tree index_expr, tree index_type,
    1029                 :             :                           auto_vec<simple_case_node> &case_list,
    1030                 :             :                           rtx default_label,
    1031                 :             :                           edge default_edge,  tree minval, tree maxval,
    1032                 :             :                           tree range, basic_block stmt_bb)
    1033                 :             : {
    1034                 :        9249 :   int i, ncases;
    1035                 :        9249 :   auto_vec<rtx> labelvec;
    1036                 :        9249 :   rtx_insn *fallback_label = label_rtx (case_list[0].m_code_label);
    1037                 :        9249 :   rtx_code_label *table_label = gen_label_rtx ();
    1038                 :        9249 :   bool has_gaps = false;
    1039                 :        9249 :   profile_probability default_prob = default_edge ? default_edge->probability
    1040                 :        9249 :                                                   : profile_probability::never ();
    1041                 :        9249 :   profile_probability base = get_outgoing_edge_probs (stmt_bb);
    1042                 :        9249 :   bool try_with_tablejump = false;
    1043                 :             : 
    1044                 :        9249 :   profile_probability new_default_prob = conditional_probability (default_prob,
    1045                 :             :                                                                   base);
    1046                 :             : 
    1047                 :        9249 :   if (! try_casesi (index_type, index_expr, minval, range,
    1048                 :             :                     table_label, default_label, fallback_label,
    1049                 :             :                     new_default_prob))
    1050                 :             :     {
    1051                 :             :       /* Index jumptables from zero for suitable values of minval to avoid
    1052                 :             :          a subtraction.  For the rationale see:
    1053                 :             :          "http://gcc.gnu.org/ml/gcc-patches/2001-10/msg01234.html".  */
    1054                 :        9249 :       if (optimize_insn_for_speed_p ()
    1055                 :        9024 :           && compare_tree_int (minval, 0) > 0
    1056                 :       12483 :           && compare_tree_int (minval, 3) < 0)
    1057                 :             :         {
    1058                 :        1019 :           minval = build_int_cst (index_type, 0);
    1059                 :        1019 :           range = maxval;
    1060                 :        1019 :           has_gaps = true;
    1061                 :             :         }
    1062                 :             :       try_with_tablejump = true;
    1063                 :             :     }
    1064                 :             : 
    1065                 :             :   /* Get table of labels to jump to, in order of case index.  */
    1066                 :             : 
    1067                 :        9249 :   ncases = tree_to_shwi (range) + 1;
    1068                 :        9249 :   labelvec.safe_grow_cleared (ncases);
    1069                 :             : 
    1070                 :       99203 :   for (unsigned j = 0; j < case_list.length (); j++)
    1071                 :             :     {
    1072                 :       89954 :       simple_case_node *n = &case_list[j];
    1073                 :             :       /* Compute the low and high bounds relative to the minimum
    1074                 :             :          value since that should fit in a HOST_WIDE_INT while the
    1075                 :             :          actual values may not.  */
    1076                 :       89954 :       HOST_WIDE_INT i_low
    1077                 :       89954 :         = tree_to_uhwi (fold_build2 (MINUS_EXPR, index_type,
    1078                 :       89954 :                                      n->m_low, minval));
    1079                 :       89954 :       HOST_WIDE_INT i_high
    1080                 :       89954 :         = tree_to_uhwi (fold_build2 (MINUS_EXPR, index_type,
    1081                 :       89954 :                                      n->m_high, minval));
    1082                 :       89954 :       HOST_WIDE_INT i;
    1083                 :             : 
    1084                 :      194928 :       for (i = i_low; i <= i_high; i ++)
    1085                 :      314922 :         labelvec[i]
    1086                 :      116319 :           = gen_rtx_LABEL_REF (Pmode, label_rtx (n->m_code_label));
    1087                 :             :     }
    1088                 :             : 
    1089                 :             :   /* The dispatch table may contain gaps, including at the beginning of
    1090                 :             :      the table if we tried to avoid the minval subtraction.  We fill the
    1091                 :             :      dispatch table slots associated with the gaps with the default case label.
    1092                 :             :      However, in the event the default case is unreachable, we then use
    1093                 :             :      any label from one of the case statements.  */
    1094                 :        9249 :   rtx gap_label = (default_label) ? default_label : fallback_label;
    1095                 :             : 
    1096                 :      200918 :   for (i = 0; i < ncases; i++)
    1097                 :      191669 :     if (labelvec[i] == 0)
    1098                 :             :       {
    1099                 :       86695 :         has_gaps = true;
    1100                 :       98462 :         labelvec[i] = gen_rtx_LABEL_REF (Pmode, gap_label);
    1101                 :             :       }
    1102                 :             : 
    1103                 :        9249 :   if (has_gaps && default_label)
    1104                 :             :     {
    1105                 :             :       /* There is at least one entry in the jump table that jumps
    1106                 :             :          to default label. The default label can either be reached
    1107                 :             :          through the indirect jump or the direct conditional jump
    1108                 :             :          before that. Split the probability of reaching the
    1109                 :             :          default label among these two jumps.  */
    1110                 :        3984 :       new_default_prob = conditional_probability (default_prob / 2, base);
    1111                 :        3984 :       default_prob /= 2;
    1112                 :        3984 :       base -= default_prob;
    1113                 :             :     }
    1114                 :             :   else
    1115                 :             :     {
    1116                 :        5265 :       base -= default_prob;
    1117                 :        5265 :       default_prob = profile_probability::never ();
    1118                 :             :     }
    1119                 :             : 
    1120                 :        9249 :   if (default_edge)
    1121                 :        4957 :     default_edge->probability = default_prob;
    1122                 :             : 
    1123                 :             :   /* We have altered the probability of the default edge. So the probabilities
    1124                 :             :      of all other edges need to be adjusted so that it sums up to
    1125                 :             :      REG_BR_PROB_BASE.  */
    1126                 :        9249 :   if (base > profile_probability::never ())
    1127                 :             :     {
    1128                 :        9249 :       edge e;
    1129                 :        9249 :       edge_iterator ei;
    1130                 :       95580 :       FOR_EACH_EDGE (e, ei, stmt_bb->succs)
    1131                 :       86331 :         e->probability /= base;
    1132                 :             :     }
    1133                 :             : 
    1134                 :        9249 :   if (try_with_tablejump)
    1135                 :             :     {
    1136                 :        9249 :       bool ok = try_tablejump (index_type, index_expr, minval, range,
    1137                 :             :                                table_label, default_label, new_default_prob);
    1138                 :        9249 :       gcc_assert (ok);
    1139                 :             :     }
    1140                 :             :   /* Output the table.  */
    1141                 :        9249 :   emit_label (table_label);
    1142                 :             : 
    1143                 :        9249 :   if (CASE_VECTOR_PC_RELATIVE
    1144                 :        9249 :           || (flag_pic && targetm.asm_out.generate_pic_addr_diff_vec ()))
    1145                 :        3375 :     emit_jump_table_data (gen_rtx_ADDR_DIFF_VEC (CASE_VECTOR_MODE,
    1146                 :             :                                                  gen_rtx_LABEL_REF (Pmode,
    1147                 :             :                                                                     table_label),
    1148                 :             :                                                  gen_rtvec_v (ncases, labelvec.address ()),
    1149                 :             :                                                  const0_rtx, const0_rtx));
    1150                 :             :   else
    1151                 :       17059 :     emit_jump_table_data (gen_rtx_ADDR_VEC (CASE_VECTOR_MODE,
    1152                 :             :                                             gen_rtvec_v (ncases, labelvec.address ())));
    1153                 :             : 
    1154                 :             :   /* Record no drop-through after the table.  */
    1155                 :        9249 :   emit_barrier ();
    1156                 :        9249 : }
    1157                 :             : 
    1158                 :             : /* Terminate a case Ada or switch (C) statement
    1159                 :             :    in which ORIG_INDEX is the expression to be tested.
    1160                 :             :    If ORIG_TYPE is not NULL, it is the original ORIG_INDEX
    1161                 :             :    type as given in the source before any compiler conversions.
    1162                 :             :    Generate the code to test it and jump to the right place.  */
    1163                 :             : 
    1164                 :             : void
    1165                 :        9249 : expand_case (gswitch *stmt)
    1166                 :             : {
    1167                 :        9249 :   tree minval = NULL_TREE, maxval = NULL_TREE, range = NULL_TREE;
    1168                 :        9249 :   rtx_code_label *default_label;
    1169                 :        9249 :   unsigned int count;
    1170                 :        9249 :   int i;
    1171                 :        9249 :   int ncases = gimple_switch_num_labels (stmt);
    1172                 :        9249 :   tree index_expr = gimple_switch_index (stmt);
    1173                 :        9249 :   tree index_type = TREE_TYPE (index_expr);
    1174                 :        9249 :   tree elt;
    1175                 :        9249 :   basic_block bb = gimple_bb (stmt);
    1176                 :        9249 :   gimple *def_stmt;
    1177                 :             : 
    1178                 :        9249 :   auto_vec<simple_case_node> case_list;
    1179                 :             : 
    1180                 :             :   /* An ERROR_MARK occurs for various reasons including invalid data type.
    1181                 :             :      ??? Can this still happen, with GIMPLE and all?  */
    1182                 :        9249 :   if (index_type == error_mark_node)
    1183                 :           0 :     return;
    1184                 :             : 
    1185                 :             :   /* cleanup_tree_cfg removes all SWITCH_EXPR with their index
    1186                 :             :      expressions being INTEGER_CST.  */
    1187                 :        9249 :   gcc_assert (TREE_CODE (index_expr) != INTEGER_CST);
    1188                 :             : 
    1189                 :             :   /* Optimization of switch statements with only one label has already
    1190                 :             :      occurred, so we should never see them at this point.  */
    1191                 :        9249 :   gcc_assert (ncases > 1);
    1192                 :             : 
    1193                 :        9249 :   do_pending_stack_adjust ();
    1194                 :             : 
    1195                 :             :   /* Find the default case target label.  */
    1196                 :        9249 :   tree default_lab = CASE_LABEL (gimple_switch_default_label (stmt));
    1197                 :        9249 :   default_label = jump_target_rtx (default_lab);
    1198                 :        9249 :   basic_block default_bb = label_to_block (cfun, default_lab);
    1199                 :        9249 :   edge default_edge = find_edge (bb, default_bb);
    1200                 :             : 
    1201                 :             :   /* Get upper and lower bounds of case values.  */
    1202                 :        9249 :   elt = gimple_switch_label (stmt, 1);
    1203                 :        9249 :   minval = fold_convert (index_type, CASE_LOW (elt));
    1204                 :        9249 :   elt = gimple_switch_label (stmt, ncases - 1);
    1205                 :        9249 :   if (CASE_HIGH (elt))
    1206                 :        2609 :     maxval = fold_convert (index_type, CASE_HIGH (elt));
    1207                 :             :   else
    1208                 :        6640 :     maxval = fold_convert (index_type, CASE_LOW (elt));
    1209                 :             : 
    1210                 :             :   /* Try to narrow the index type if it's larger than a word.
    1211                 :             :      That is mainly for -O0 where an equivalent optimization
    1212                 :             :      done by forward propagation is not run and is aimed at
    1213                 :             :      avoiding a call to a comparison routine of libgcc.  */
    1214                 :        9249 :   if (TYPE_PRECISION (index_type) > BITS_PER_WORD
    1215                 :           6 :       && TREE_CODE (index_expr) == SSA_NAME
    1216                 :           6 :       && (def_stmt = SSA_NAME_DEF_STMT (index_expr))
    1217                 :           6 :       && is_gimple_assign (def_stmt)
    1218                 :        9252 :       && gimple_assign_rhs_code (def_stmt) == NOP_EXPR)
    1219                 :             :     {
    1220                 :           0 :       tree inner_index_expr = gimple_assign_rhs1 (def_stmt);
    1221                 :           0 :       tree inner_index_type = TREE_TYPE (inner_index_expr);
    1222                 :             : 
    1223                 :           0 :       if (INTEGRAL_TYPE_P (inner_index_type)
    1224                 :           0 :           && TYPE_PRECISION (inner_index_type) <= BITS_PER_WORD
    1225                 :           0 :           && int_fits_type_p (minval, inner_index_type)
    1226                 :           0 :           && int_fits_type_p (maxval, inner_index_type))
    1227                 :             :         {
    1228                 :           0 :           index_expr = inner_index_expr;
    1229                 :           0 :           index_type = inner_index_type;
    1230                 :           0 :           minval = fold_convert (index_type, minval);
    1231                 :           0 :           maxval = fold_convert (index_type, maxval);
    1232                 :             :         }
    1233                 :             :     }
    1234                 :             : 
    1235                 :             :   /* Compute span of values.  */
    1236                 :        9249 :   range = fold_build2 (MINUS_EXPR, index_type, maxval, minval);
    1237                 :             : 
    1238                 :             :   /* Listify the labels queue and gather some numbers to decide
    1239                 :             :      how to expand this switch().  */
    1240                 :        9249 :   count = 0;
    1241                 :             : 
    1242                 :       99203 :   for (i = ncases - 1; i >= 1; --i)
    1243                 :             :     {
    1244                 :       89954 :       elt = gimple_switch_label (stmt, i);
    1245                 :       89954 :       tree low = CASE_LOW (elt);
    1246                 :       89954 :       gcc_assert (low);
    1247                 :       89954 :       tree high = CASE_HIGH (elt);
    1248                 :       89954 :       gcc_assert (! high || tree_int_cst_lt (low, high));
    1249                 :       89954 :       tree lab = CASE_LABEL (elt);
    1250                 :             : 
    1251                 :             :       /* Count the elements.
    1252                 :             :          A range counts double, since it requires two compares.  */
    1253                 :       89954 :       count++;
    1254                 :       89954 :       if (high)
    1255                 :        7794 :         count++;
    1256                 :             : 
    1257                 :             :       /* The bounds on the case range, LOW and HIGH, have to be converted
    1258                 :             :          to case's index type TYPE.  Note that the original type of the
    1259                 :             :          case index in the source code is usually "lost" during
    1260                 :             :          gimplification due to type promotion, but the case labels retain the
    1261                 :             :          original type.  Make sure to drop overflow flags.  */
    1262                 :       89954 :       low = fold_convert (index_type, low);
    1263                 :       89954 :       if (TREE_OVERFLOW (low))
    1264                 :           0 :         low = wide_int_to_tree (index_type, wi::to_wide (low));
    1265                 :             : 
    1266                 :             :       /* The canonical from of a case label in GIMPLE is that a simple case
    1267                 :             :          has an empty CASE_HIGH.  For the casesi and tablejump expanders,
    1268                 :             :          the back ends want simple cases to have high == low.  */
    1269                 :       89954 :       if (! high)
    1270                 :       82160 :         high = low;
    1271                 :       89954 :       high = fold_convert (index_type, high);
    1272                 :       89954 :       if (TREE_OVERFLOW (high))
    1273                 :           0 :         high = wide_int_to_tree (index_type, wi::to_wide (high));
    1274                 :             : 
    1275                 :       89954 :       case_list.safe_push (simple_case_node (low, high, lab));
    1276                 :             :     }
    1277                 :             : 
    1278                 :             :   /* cleanup_tree_cfg removes all SWITCH_EXPR with a single
    1279                 :             :      destination, such as one with a default case only.
    1280                 :             :      It also removes cases that are out of range for the switch
    1281                 :             :      type, so we should never get a zero here.  */
    1282                 :        9249 :   gcc_assert (count > 0);
    1283                 :             : 
    1284                 :        9249 :   rtx_insn *before_case = get_last_insn ();
    1285                 :             : 
    1286                 :             :   /* If the default case is unreachable, then set default_label to NULL
    1287                 :             :      so that we omit the range check when generating the dispatch table.
    1288                 :             :      We also remove the edge to the unreachable default case.  The block
    1289                 :             :      itself will be automatically removed later.  */
    1290                 :        9249 :   if (EDGE_COUNT (default_edge->dest->succs) == 0
    1291                 :       14345 :       && gimple_seq_unreachable_p (bb_seq (default_edge->dest)))
    1292                 :             :     {
    1293                 :        4292 :       default_label = NULL;
    1294                 :        4292 :       expand_remove_edge (default_edge);
    1295                 :        4292 :       default_edge = NULL;
    1296                 :             :     }
    1297                 :             : 
    1298                 :        9249 :   emit_case_dispatch_table (index_expr, index_type,
    1299                 :             :                             case_list, default_label, default_edge,
    1300                 :             :                             minval, maxval, range, bb);
    1301                 :             : 
    1302                 :        9249 :   reorder_insns (NEXT_INSN (before_case), get_last_insn (), before_case);
    1303                 :             : 
    1304                 :        9249 :   free_temp_slots ();
    1305                 :        9249 : }
    1306                 :             : 
    1307                 :             : /* Expand the dispatch to a short decrement chain if there are few cases
    1308                 :             :    to dispatch to.  Likewise if neither casesi nor tablejump is available,
    1309                 :             :    or if flag_jump_tables is set.  Otherwise, expand as a casesi or a
    1310                 :             :    tablejump.  The index mode is always the mode of integer_type_node.
    1311                 :             :    Trap if no case matches the index.
    1312                 :             : 
    1313                 :             :    DISPATCH_INDEX is the index expression to switch on.  It should be a
    1314                 :             :    memory or register operand.
    1315                 :             : 
    1316                 :             :    DISPATCH_TABLE is a set of case labels.  The set should be sorted in
    1317                 :             :    ascending order, be contiguous, starting with value 0, and contain only
    1318                 :             :    single-valued case labels.  */
    1319                 :             : 
    1320                 :             : void
    1321                 :           0 : expand_sjlj_dispatch_table (rtx dispatch_index,
    1322                 :             :                             vec<tree> dispatch_table)
    1323                 :             : {
    1324                 :           0 :   tree index_type = integer_type_node;
    1325                 :           0 :   machine_mode index_mode = TYPE_MODE (index_type);
    1326                 :             : 
    1327                 :           0 :   int ncases = dispatch_table.length ();
    1328                 :             : 
    1329                 :           0 :   do_pending_stack_adjust ();
    1330                 :           0 :   rtx_insn *before_case = get_last_insn ();
    1331                 :             : 
    1332                 :             :   /* Expand as a decrement-chain if there are 5 or fewer dispatch
    1333                 :             :      labels.  This covers more than 98% of the cases in libjava,
    1334                 :             :      and seems to be a reasonable compromise between the "old way"
    1335                 :             :      of expanding as a decision tree or dispatch table vs. the "new
    1336                 :             :      way" with decrement chain or dispatch table.  */
    1337                 :           0 :   if (dispatch_table.length () <= 5
    1338                 :           0 :       || (!targetm.have_casesi () && !targetm.have_tablejump ())
    1339                 :           0 :       || !flag_jump_tables)
    1340                 :             :     {
    1341                 :             :       /* Expand the dispatch as a decrement chain:
    1342                 :             : 
    1343                 :             :          "switch(index) {case 0: do_0; case 1: do_1; ...; case N: do_N;}"
    1344                 :             : 
    1345                 :             :          ==>
    1346                 :             : 
    1347                 :             :          if (index == 0) do_0; else index--;
    1348                 :             :          if (index == 0) do_1; else index--;
    1349                 :             :          ...
    1350                 :             :          if (index == 0) do_N; else index--;
    1351                 :             : 
    1352                 :             :          This is more efficient than a dispatch table on most machines.
    1353                 :             :          The last "index--" is redundant but the code is trivially dead
    1354                 :             :          and will be cleaned up by later passes.  */
    1355                 :           0 :       rtx index = copy_to_mode_reg (index_mode, dispatch_index);
    1356                 :           0 :       rtx zero = CONST0_RTX (index_mode);
    1357                 :           0 :       for (int i = 0; i < ncases; i++)
    1358                 :             :         {
    1359                 :           0 :           tree elt = dispatch_table[i];
    1360                 :           0 :           rtx_code_label *lab = jump_target_rtx (CASE_LABEL (elt));
    1361                 :           0 :           do_jump_if_equal (index_mode, index, zero, lab, 0,
    1362                 :             :                             profile_probability::uninitialized ());
    1363                 :           0 :           force_expand_binop (index_mode, sub_optab,
    1364                 :             :                               index, CONST1_RTX (index_mode),
    1365                 :             :                               index, 0, OPTAB_DIRECT);
    1366                 :             :         }
    1367                 :             :     }
    1368                 :             :   else
    1369                 :             :     {
    1370                 :             :       /* Similar to expand_case, but much simpler.  */
    1371                 :           0 :       auto_vec<simple_case_node> case_list;
    1372                 :           0 :       tree index_expr = make_tree (index_type, dispatch_index);
    1373                 :           0 :       tree minval = build_int_cst (index_type, 0);
    1374                 :           0 :       tree maxval = CASE_LOW (dispatch_table.last ());
    1375                 :           0 :       tree range = maxval;
    1376                 :           0 :       rtx_code_label *default_label = gen_label_rtx ();
    1377                 :             : 
    1378                 :           0 :       for (int i = ncases - 1; i >= 0; --i)
    1379                 :             :         {
    1380                 :           0 :           tree elt = dispatch_table[i];
    1381                 :           0 :           tree high = CASE_HIGH (elt);
    1382                 :           0 :           if (high == NULL_TREE)
    1383                 :           0 :             high = CASE_LOW (elt);
    1384                 :           0 :           case_list.safe_push (simple_case_node (CASE_LOW (elt), high,
    1385                 :           0 :                                                  CASE_LABEL (elt)));
    1386                 :             :         }
    1387                 :             : 
    1388                 :           0 :       emit_case_dispatch_table (index_expr, index_type,
    1389                 :             :                                 case_list, default_label, NULL,
    1390                 :             :                                 minval, maxval, range,
    1391                 :           0 :                                 BLOCK_FOR_INSN (before_case));
    1392                 :           0 :       emit_label (default_label);
    1393                 :           0 :     }
    1394                 :             : 
    1395                 :             :   /* Dispatching something not handled?  Trap!  */
    1396                 :           0 :   expand_builtin_trap ();
    1397                 :             : 
    1398                 :           0 :   reorder_insns (NEXT_INSN (before_case), get_last_insn (), before_case);
    1399                 :             : 
    1400                 :           0 :   free_temp_slots ();
    1401                 :           0 : }
    1402                 :             : 
    1403                 :             : 
        

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.