LCOV - code coverage report
Current view: top level - gcc - stmt.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 84.7 % 648 549
Test Date: 2026-02-28 14:20:25 Functions: 81.0 % 21 17
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Expands front end tree to back end RTL for GCC
       2              :    Copyright (C) 1987-2026 Free Software Foundation, Inc.
       3              : 
       4              : This file is part of GCC.
       5              : 
       6              : GCC is free software; you can redistribute it and/or modify it under
       7              : the terms of the GNU General Public License as published by the Free
       8              : Software Foundation; either version 3, or (at your option) any later
       9              : version.
      10              : 
      11              : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      12              : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      13              : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      14              : for more details.
      15              : 
      16              : You should have received a copy of the GNU General Public License
      17              : along with GCC; see the file COPYING3.  If not see
      18              : <http://www.gnu.org/licenses/>.  */
      19              : 
      20              : /* This file 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        79052 :   simple_case_node (tree low, tree high, tree code_label):
      78        79052 :     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      2561847 : label_rtx (tree label)
      97              : {
      98      2561847 :   gcc_assert (TREE_CODE (label) == LABEL_DECL);
      99              : 
     100      2561847 :   if (!DECL_RTL_SET_P (label))
     101              :     {
     102       622783 :       rtx_code_label *r = gen_label_rtx ();
     103       622783 :       SET_DECL_RTL (label, r);
     104       622783 :       if (FORCED_LABEL (label) || DECL_NONLOCAL (label))
     105        26407 :         LABEL_PRESERVE_P (r) = 1;
     106              :     }
     107              : 
     108      2561847 :   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       842397 : jump_target_rtx (tree label)
     129              : {
     130       842397 :   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      3152123 : emit_jump (rtx label)
     137              : {
     138      3152123 :   do_pending_stack_adjust ();
     139      3152123 :   emit_jump_insn (targetm.gen_jump (label));
     140      3152123 :   emit_barrier ();
     141      3152123 : }
     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       622783 : expand_label (tree label)
     158              : {
     159       622783 :   rtx_code_label *label_r = jump_target_rtx (label);
     160              : 
     161       622783 :   do_pending_stack_adjust ();
     162       622783 :   emit_label (label_r);
     163       622783 :   if (DECL_NAME (label))
     164       115306 :     LABEL_NAME (DECL_RTL (label)) = IDENTIFIER_POINTER (DECL_NAME (label));
     165              : 
     166       622783 :   if (DECL_NONLOCAL (label))
     167              :     {
     168          504 :       expand_builtin_setjmp_receiver (NULL);
     169          504 :       nonlocal_goto_handler_labels
     170          504 :         = gen_rtx_INSN_LIST (VOIDmode, label_r,
     171          504 :                              nonlocal_goto_handler_labels);
     172              :     }
     173              : 
     174       622783 :   if (FORCED_LABEL (label))
     175        25903 :     vec_safe_push<rtx_insn *> (forced_labels, label_r);
     176              : 
     177      1245062 :   if (DECL_NONLOCAL (label) || FORCED_LABEL (label))
     178        26407 :     maybe_set_first_label_num (label_r);
     179       622783 : }
     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         1784 : decode_hard_reg_constraint (const char *begin)
     188              : {
     189         1784 :   if (*begin != '{')
     190              :     return -1;
     191         1784 :   ++begin;
     192         1784 :   const char *end = begin;
     193         7124 :   while (*end != '}' && *end != '\0')
     194         5340 :     ++end;
     195         1784 :   if (*end != '}' || end == begin)
     196              :     return -1;
     197         1782 :   ptrdiff_t len = end - begin;
     198         1782 :   if (len >= 31)
     199              :     return -1;
     200         1782 :   char regname[32];
     201         1782 :   memcpy (regname, begin, len);
     202         1782 :   regname[len] = '\0';
     203         1782 :   int regno = decode_reg_name (regname);
     204         1782 :   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          189 : hardreg_ok_p (int reg_number, machine_mode mode, int operand_num)
     225              : {
     226          189 :   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          188 :   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          188 :   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          188 :   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          188 :   else if (reg_number != HARD_FRAME_POINTER_REGNUM
     239          188 :            && (reg_number == FRAME_POINTER_REGNUM
     240              : #ifdef RETURN_ADDRESS_POINTER_REGNUM
     241              :                || reg_number == RETURN_ADDRESS_POINTER_REGNUM
     242              : #endif
     243          188 :                || reg_number == ARG_POINTER_REGNUM)
     244          188 :            && 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     33438787 : 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     33438787 :   const char *constraint = *constraint_p;
     272     33438787 :   const char *p;
     273              : 
     274              :   /* Assume the constraint doesn't allow the use of either a register
     275              :      or memory.  */
     276     33438787 :   *allows_mem = false;
     277     33438787 :   *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     33438787 :   p = strchr (constraint, '=');
     284     33438787 :   if (!p)
     285        17359 :     p = strchr (constraint, '+');
     286              : 
     287              :   /* If the string doesn't contain an `=', issue an error
     288              :      message.  */
     289        17359 :   if (!p)
     290              :     {
     291            9 :       error ("output operand constraint lacks %<=%>");
     292            9 :       return false;
     293              :     }
     294              : 
     295              :   /* If the constraint begins with `+', then the operand is both read
     296              :      from and written to.  */
     297     33438778 :   *is_inout = (*p == '+');
     298              : 
     299              :   /* Canonicalize the output constraint so that it begins with `='.  */
     300     33438778 :   if (p != constraint || *is_inout)
     301              :     {
     302        17358 :       char *buf;
     303        17358 :       size_t c_len = strlen (constraint);
     304              : 
     305        17358 :       if (p != constraint)
     306            8 :         warning (0, "output constraint %qc for operand %d "
     307              :                  "is not at the beginning",
     308            8 :                  *p, operand_num);
     309              : 
     310              :       /* Make a copy of the constraint.  */
     311        17358 :       buf = XALLOCAVEC (char, c_len + 1);
     312        17358 :       strcpy (buf, constraint);
     313              :       /* Swap the first character and the `=' or `+'.  */
     314        17358 :       buf[p - constraint] = buf[0];
     315              :       /* Make sure the first character is an `='.  (Until we do this,
     316              :          it might be a `+'.)  */
     317        17358 :       buf[0] = '=';
     318              :       /* Replace the constraint with the canonicalized string.  */
     319        17358 :       *constraint_p = ggc_alloc_string (buf, c_len);
     320        17358 :       constraint = *constraint_p;
     321              :     }
     322              : 
     323     33438778 :   unsigned int alt = 0;
     324     33438778 :   bool early_clobbered = false;
     325              :   /* Currently, multiple hard register constraints in one alternative are not
     326              :      supported.  A combination of hard register constraints and regular
     327              :      register constraints is also not supported.  */
     328     33438778 :   bool alt_has_hard_reg_cstr = false;
     329     33438778 :   bool alt_has_reg_cstr = false;
     330              : 
     331              :   /* Loop through the constraint string.  */
     332     67704121 :   for (p = constraint + 1; *p; )
     333              :     {
     334     34265362 :       switch (*p)
     335              :         {
     336            0 :         case '+':
     337            0 :         case '=':
     338            0 :           error ("operand constraint contains incorrectly positioned "
     339              :                  "%<+%> or %<=%>");
     340            0 :           return false;
     341              : 
     342            8 :         case '%':
     343            8 :           if (operand_num + 1 == ninputs + noutputs)
     344              :             {
     345            0 :               error ("%<%%%> constraint used with last operand");
     346            0 :               return false;
     347              :             }
     348              :           break;
     349              : 
     350              :         case '&':
     351     34265343 :           early_clobbered = true;
     352              :           break;
     353              : 
     354              :         case '?':  case '!':  case '*':  case '#':
     355              :         case '$':  case '^':
     356              :         case 'E':  case 'F':  case 'G':  case 'H':
     357              :         case 's':  case 'i':  case 'n':
     358              :         case 'I':  case 'J':  case 'K':  case 'L':  case 'M':
     359              :         case 'N':  case 'O':  case 'P':  case '-':
     360              :           break;
     361              : 
     362        86867 :         case ',':
     363        86867 :           ++alt;
     364        86867 :           early_clobbered = false;
     365        86867 :           alt_has_hard_reg_cstr = false;
     366        86867 :           alt_has_reg_cstr = false;
     367        86867 :           break;
     368              : 
     369            0 :         case '0':  case '1':  case '2':  case '3':  case '4':
     370            0 :         case '5':  case '6':  case '7':  case '8':  case '9':
     371            0 :         case '[':
     372            0 :           error ("matching constraint not valid in output operand");
     373            0 :           return false;
     374              : 
     375            8 :         case ':':
     376            8 :           error ("%<:%> constraint used for output operand");
     377            8 :           return false;
     378              : 
     379            0 :         case '<':  case '>':
     380              :           /* ??? Before flow, auto inc/dec insns are not supposed to exist,
     381              :              excepting those that expand_call created.  So match memory
     382              :              and hope.  */
     383            0 :           *allows_mem = true;
     384            0 :           break;
     385              : 
     386      2029523 :         case 'g':  case 'X':
     387      2029523 :           *allows_reg = true;
     388      2029523 :           *allows_mem = true;
     389      2029523 :           break;
     390              : 
     391        25736 :         case '{':
     392        25736 :           {
     393        25736 :             if (!targetm.lra_p ())
     394              :               {
     395            0 :                 error ("hard register constraints are only supported while using LRA");
     396            0 :                 return false;
     397              :               }
     398        25736 :             if (reg_info)
     399              :               {
     400          103 :                 if (alt_has_reg_cstr)
     401              :                   {
     402            1 :                     error (
     403              :                         "hard register constraints and regular register "
     404              :                         "constraints in one alternative are not supported");
     405            1 :                     return false;
     406              :                   }
     407          102 :                 if (alt_has_hard_reg_cstr)
     408              :                   {
     409            2 :                     error (
     410              :                         "multiple hard register constraints in one "
     411              :                         "alternative are not supported");
     412            2 :                     return false;
     413              :                   }
     414          100 :                 alt_has_hard_reg_cstr = true;
     415          100 :                 int regno = decode_hard_reg_constraint (p);
     416          100 :                 if (regno < 0)
     417              :                   {
     418            0 :                     error ("invalid output constraint: %s", p);
     419            0 :                     return false;
     420              :                   }
     421          100 :                 int overlap_regno = reg_info->test_alt_output (alt, regno);
     422          100 :                 if (overlap_regno < 0)
     423           99 :                   overlap_regno = reg_info->test_reg_asm_output (regno);
     424           99 :                 if (overlap_regno >= 0)
     425              :                   {
     426            1 :                     error ("multiple outputs to hard register: %s",
     427              :                            reg_names[overlap_regno]);
     428            1 :                     return false;
     429              :                   }
     430           99 :                 reg_info->set_output (alt, regno);
     431           99 :                 if (early_clobbered)
     432           16 :                   reg_info->set_early_clobbered (alt, operand_num, regno);
     433           99 :                 if (reg_info->is_clobbered (regno))
     434              :                   {
     435            1 :                     error ("hard register constraint for output %i conflicts "
     436              :                            "with %<asm%> clobber list", operand_num);
     437            1 :                     return false;
     438              :                   }
     439           98 :                 if (VAR_P (reg_info->operand)
     440           98 :                     && DECL_HARD_REGISTER (reg_info->operand))
     441              :                   {
     442            2 :                       tree id = DECL_ASSEMBLER_NAME (reg_info->operand);
     443            2 :                       const char *asmspec = IDENTIFIER_POINTER (id) + 1;
     444            2 :                       int regno_op = decode_reg_name (asmspec);
     445            2 :                       if (regno != regno_op)
     446              :                         {
     447            1 :                           error ("constraint and register %<asm%> for output "
     448              :                                  "operand %i are unsatisfiable", operand_num);
     449            1 :                           return false;
     450              :                         }
     451              :                   }
     452           97 :                 machine_mode mode = TYPE_MODE (TREE_TYPE (reg_info->operand));
     453           97 :                 if (!hardreg_ok_p (regno, mode, operand_num))
     454              :                   return false;
     455              :               }
     456        25730 :             *allows_reg = true;
     457        25730 :             break;
     458              :           }
     459              : 
     460     31576531 :         default:
     461     31576531 :           if (!ISALPHA (*p))
     462              :             break;
     463     31556972 :           enum constraint_num cn = lookup_constraint (p);
     464     31556972 :           if (reg_class_for_constraint (cn) != NO_REGS
     465     31556972 :               || insn_extra_address_constraint (cn))
     466              :             {
     467     29464232 :               if (alt_has_hard_reg_cstr)
     468              :                 {
     469            1 :                   error (
     470              :                       "hard register constraints and regular register "
     471              :                       "constraints in one alternative are not supported");
     472            1 :                   return false;
     473              :                 }
     474     29464231 :               alt_has_reg_cstr = true;
     475     29464231 :               *allows_reg = true;
     476              :             }
     477              :           else if (insn_extra_memory_constraint (cn))
     478      2084508 :             *allows_mem = true;
     479              :           else
     480              :             insn_extra_constraint_allows_reg_mem (cn, allows_reg, allows_mem);
     481        54559 :           if (reg_info && *allows_reg
     482        52871 :               && VAR_P (reg_info->operand)
     483     31590087 :               && DECL_HARD_REGISTER (reg_info->operand))
     484              :             {
     485          949 :                 tree id = DECL_ASSEMBLER_NAME (reg_info->operand);
     486          949 :                 const char *asmspec = IDENTIFIER_POINTER (id) + 1;
     487          949 :                 int regno = decode_reg_name (asmspec);
     488          949 :                 if (regno < 0)
     489              :                   {
     490            4 :                     location_t loc = DECL_SOURCE_LOCATION (reg_info->operand);
     491            4 :                     error_at (loc, "invalid register name for %q+D",
     492              :                               reg_info->operand);
     493            4 :                     return false;
     494              :                   }
     495          945 :                 int overlap_regno = reg_info->test_alt_output (alt, regno);
     496          945 :                 if (overlap_regno >= 0)
     497              :                   {
     498            0 :                     error ("multiple outputs to hard register: %s",
     499              :                            reg_names[overlap_regno]);
     500            0 :                     return false;
     501              :                   }
     502          945 :                 reg_info->set_reg_asm_output (regno);
     503          945 :                 if (early_clobbered)
     504           10 :                   reg_info->set_early_clobbered (alt, operand_num, regno);
     505              :             }
     506              :           break;
     507              :         }
     508              : 
     509     68648572 :       for (size_t len = CONSTRAINT_LEN (*p, p); len; len--, p++)
     510     34383675 :         if (*p == '\0')
     511              :           break;
     512              :     }
     513              : 
     514              :   return true;
     515              : }
     516              : 
     517              : /* Similar, but for input constraints.  */
     518              : 
     519              : bool
     520     21834468 : parse_input_constraint (const char **constraint_p, int input_num,
     521              :                         int ninputs, int noutputs, int ninout,
     522              :                         const char * const * constraints,
     523              :                         bool *allows_mem, bool *allows_reg,
     524              :                         gimplify_reg_info *reg_info)
     525              : {
     526     21834468 :   const char *constraint = *constraint_p;
     527     21834468 :   const char *orig_constraint = constraint;
     528     21834468 :   size_t c_len = strlen (constraint);
     529     21834468 :   size_t j;
     530     21834468 :   bool saw_match = false;
     531     21834468 :   bool at_checked = false;
     532              : 
     533              :   /* Assume the constraint doesn't allow the use of either
     534              :      a register or memory.  */
     535     21834468 :   *allows_mem = false;
     536     21834468 :   *allows_reg = false;
     537              : 
     538     21834468 :   bool alt_has_hard_reg_cstr = false;
     539     21834468 :   bool alt_has_reg_cstr = false;
     540              : 
     541              :   /* Make sure constraint has neither `=', `+', nor '&'.  */
     542              : 
     543     21834468 :   unsigned int alt = 0;
     544     21834468 :   unsigned long match = 0;
     545              : 
     546     34383220 : repeat:
     547     70481607 :   for (j = 0; j < c_len; j += CONSTRAINT_LEN (constraint[j], constraint+j))
     548     48647198 :     switch (constraint[j])
     549              :       {
     550     13024075 :       case '+':  case '=':  case '&':
     551     13024075 :         if (constraint == orig_constraint)
     552              :           {
     553            0 :             error ("input operand constraint contains %qc", constraint[j]);
     554            0 :             return false;
     555              :           }
     556              :         break;
     557              : 
     558       377677 :       case '%':
     559       377677 :         if (constraint == orig_constraint
     560       377677 :             && input_num + 1 == ninputs - ninout)
     561              :           {
     562            0 :             error ("%<%%%> constraint used with last operand");
     563            0 :             return false;
     564              :           }
     565              :         break;
     566              : 
     567              :       case '<':  case '>':
     568              :       case '?':  case '!':  case '*':  case '#':
     569              :       case '$':  case '^':
     570              :       case 'E':  case 'F':  case 'G':  case 'H':
     571              :       case 's':  case 'i':  case 'n':
     572              :       case 'I':  case 'J':  case 'K':  case 'L':  case 'M':
     573              :       case 'N':  case 'O':  case 'P':  case '-':
     574              :         break;
     575              : 
     576          166 :       case ':':
     577              :         /* Verify that if : is used, it is just ":" or say ":,:" but not
     578              :            mixed with other constraints or say ",:,," etc.  */
     579          166 :         if (!at_checked)
     580              :           {
     581          312 :             for (size_t k = 0; k < c_len; ++k)
     582          336 :               if (constraint[k] != ((k & 1) ? ',' : ':') || (c_len & 1) == 0)
     583              :                 {
     584           20 :                   error ("%<:%> constraint mixed with other constraints");
     585           20 :                   return false;
     586              :                 } 
     587              :             at_checked = true;
     588              :           }
     589              :         break;
     590              : 
     591        84539 :       case ',':
     592        84539 :         ++alt;
     593        84539 :         alt_has_hard_reg_cstr = false;
     594        84539 :         alt_has_reg_cstr = false;
     595        84539 :         break;
     596              : 
     597              :         /* Whether or not a numeric constraint allows a register is
     598              :            decided by the matching constraint, and so there is no need
     599              :            to do anything special with them.  We must handle them in
     600              :            the default case, so that we don't unnecessarily force
     601              :            operands to memory.  */
     602     12624120 :       case '0':  case '1':  case '2':  case '3':  case '4':
     603     12624120 :       case '5':  case '6':  case '7':  case '8':  case '9':
     604     12624120 :         {
     605     12624120 :           char *end;
     606              : 
     607     12624120 :           saw_match = true;
     608              : 
     609     12624120 :           match = strtoul (constraint + j, &end, 10);
     610     12624120 :           if (match >= (unsigned long) noutputs)
     611              :             {
     612            4 :               error ("matching constraint references invalid operand number");
     613            4 :               return false;
     614              :             }
     615              : 
     616              :           /* Try and find the real constraint for this dup.  Only do this
     617              :              if the matching constraint is the only alternative.  */
     618     12624116 :           if (*end == '\0'
     619     12560046 :               && (j == 0 || (j == 1 && constraint[0] == '%')))
     620              :             {
     621     12548752 :               constraint = constraints[match];
     622     12548752 :               *constraint_p = constraint;
     623     12548752 :               c_len = strlen (constraint);
     624     12548752 :               goto repeat;
     625              :             }
     626              :           else
     627        75364 :             j = end - constraint;
     628              :           /* Anticipate increment at end of loop.  */
     629        75364 :           j--;
     630              :         }
     631              :         /* Fall through.  */
     632              : 
     633      3025190 :       case 'g':  case 'X':
     634      3025190 :         *allows_reg = true;
     635      3025190 :         *allows_mem = true;
     636      3025190 :         break;
     637              : 
     638        20950 :       case '{':
     639        20950 :         {
     640        20950 :           if (!targetm.lra_p ())
     641              :             {
     642            0 :               error ("hard register constraints are only supported while using LRA");
     643            0 :               return false;
     644              :             }
     645        20950 :           if (reg_info)
     646              :             {
     647          110 :               if (alt_has_reg_cstr)
     648              :                 {
     649            1 :                   error (
     650              :                       "hard register constraints and regular register "
     651              :                       "constraints in one alternative are not supported");
     652            1 :                   return false;
     653              :                 }
     654          109 :               if (alt_has_hard_reg_cstr)
     655              :                 {
     656            2 :                   error (
     657              :                       "multiple hard register constraints in one "
     658              :                       "alternative are not supported");
     659            2 :                   return false;
     660              :                 }
     661          107 :               alt_has_hard_reg_cstr = true;
     662          107 :               int regno = decode_hard_reg_constraint (constraint + j);
     663          107 :               if (regno < 0)
     664              :                 {
     665            3 :                   error ("invalid input constraint: %s", constraint + j);
     666            3 :                   return false;
     667              :                 }
     668          104 :               int overlap_regno = reg_info->test_alt_input (alt, regno);
     669          104 :               if (overlap_regno < 0)
     670           99 :                 overlap_regno = reg_info->test_reg_asm_input (regno);
     671           99 :               if (overlap_regno >= 0)
     672              :                 {
     673            6 :                   error ("multiple inputs to hard register: %s",
     674              :                             reg_names[overlap_regno]);
     675            6 :                   return false;
     676              :                 }
     677           98 :               reg_info->set_input (alt, regno);
     678           98 :               if (reg_info->is_clobbered (regno))
     679              :                 {
     680            1 :                   error ("hard register constraint for input %i conflicts "
     681              :                          "with %<asm%> clobber list", input_num);
     682            1 :                   return false;
     683              :                 }
     684           97 :               if (constraint == orig_constraint
     685           97 :                   && reg_info->test_early_clobbered_alt (alt, regno))
     686              :                 {
     687            3 :                   error ("invalid hard register usage between earlyclobber "
     688              :                          "operand and input operand");
     689            3 :                   return false;
     690              :                 }
     691           94 :               if (VAR_P (reg_info->operand)
     692           94 :                   && DECL_HARD_REGISTER (reg_info->operand))
     693              :                 {
     694            4 :                     tree id = DECL_ASSEMBLER_NAME (reg_info->operand);
     695            4 :                     const char *asmspec = IDENTIFIER_POINTER (id) + 1;
     696            4 :                     int regno_op = decode_reg_name (asmspec);
     697            4 :                     if (regno != regno_op)
     698              :                       {
     699            2 :                         error ("constraint and register %<asm%> for input "
     700              :                                "operand %i are unsatisfiable", input_num);
     701            2 :                         return false;
     702              :                       }
     703              :                 }
     704           92 :               machine_mode mode = TYPE_MODE (TREE_TYPE (reg_info->operand));
     705           92 :               if (!hardreg_ok_p (regno, mode, input_num))
     706              :                 return false;
     707              :             }
     708        20931 :           *allows_reg = true;
     709        20931 :           break;
     710              :         }
     711              : 
     712     18902579 :       default:
     713     18902579 :         if (! ISALPHA (constraint[j]))
     714              :           {
     715            5 :             error ("invalid punctuation %qc in constraint", constraint[j]);
     716            5 :             return false;
     717              :           }
     718     18902574 :         enum constraint_num cn = lookup_constraint (constraint + j);
     719     18902574 :         if (reg_class_for_constraint (cn) != NO_REGS
     720     18902574 :             || insn_extra_address_constraint (cn))
     721              :           {
     722     15977998 :             if (alt_has_hard_reg_cstr)
     723              :               {
     724            1 :                 error (
     725              :                     "hard register constraints and regular register "
     726              :                     "constraints in one alternative are not supported");
     727            1 :                 return false;
     728              :               }
     729     15977997 :             alt_has_reg_cstr = true;
     730     15977997 :             *allows_reg = true;
     731              :           }
     732              :         else if (insn_extra_memory_constraint (cn)
     733              :                  || insn_extra_special_memory_constraint (cn)
     734              :                  || insn_extra_relaxed_memory_constraint (cn))
     735      2689760 :           *allows_mem = true;
     736              :         else
     737              :           insn_extra_constraint_allows_reg_mem (cn, allows_reg, allows_mem);
     738        34640 :         if (reg_info && *allows_reg
     739        32598 :             && VAR_P (reg_info->operand)
     740     18907388 :             && DECL_HARD_REGISTER (reg_info->operand))
     741              :           {
     742          873 :               tree id = DECL_ASSEMBLER_NAME (reg_info->operand);
     743          873 :               const char *asmspec = IDENTIFIER_POINTER (id) + 1;
     744          873 :               int regno = decode_reg_name (asmspec);
     745          873 :               if (regno < 0)
     746              :                 {
     747            5 :                   location_t loc = DECL_SOURCE_LOCATION (reg_info->operand);
     748            5 :                   error_at (loc, "invalid register name for %q+D",
     749              :                             reg_info->operand);
     750            5 :                   return false;
     751              :                 }
     752          868 :               int overlap_regno = reg_info->test_alt_input (alt, regno);
     753          868 :               if (overlap_regno >= 0)
     754              :                 {
     755            1 :                   error ("multiple inputs to hard register: %s",
     756              :                          reg_names[overlap_regno]);
     757            1 :                   return false;
     758              :                 }
     759          867 :               reg_info->set_reg_asm_input (regno);
     760          867 :               if ((constraint == orig_constraint
     761          200 :                    && reg_info->test_early_clobbered_alt (alt, regno))
     762         1065 :                   || (constraint != orig_constraint
     763          667 :                       && reg_info->is_early_clobbered_in_any_output_unequal
     764          667 :                           (match, regno)))
     765              :                 {
     766            4 :                   error ("invalid hard register usage between earlyclobber "
     767              :                          "operand and input operand");
     768            4 :                   return false;
     769              :                 }
     770              :           }
     771              :         break;
     772              :       }
     773              : 
     774     21834409 :   if (saw_match && !*allows_reg)
     775            4 :     warning (0, "matching constraint does not allow a register");
     776              : 
     777              :   return true;
     778              : }
     779              : 
     780              : /* Return DECL iff there's an overlap between *REGS and DECL, where DECL
     781              :    can be an asm-declared register.  Called via walk_tree.  */
     782              : 
     783              : static tree
     784       148699 : decl_overlaps_hard_reg_set_p (tree *declp, int *walk_subtrees ATTRIBUTE_UNUSED,
     785              :                               void *data)
     786              : {
     787       148699 :   tree decl = *declp;
     788       148699 :   const HARD_REG_SET *const regs = (const HARD_REG_SET *) data;
     789              : 
     790       148699 :   if (VAR_P (decl))
     791              :     {
     792        21935 :       if (DECL_HARD_REGISTER (decl)
     793         1837 :           && REG_P (DECL_RTL (decl))
     794        23772 :           && REGNO (DECL_RTL (decl)) < FIRST_PSEUDO_REGISTER)
     795              :         {
     796         1837 :           rtx reg = DECL_RTL (decl);
     797              : 
     798         1837 :           if (overlaps_hard_reg_set_p (*regs, GET_MODE (reg), REGNO (reg)))
     799              :             return decl;
     800              :         }
     801              :       walk_subtrees = 0;
     802              :     }
     803              :   else if (TYPE_P (decl) || TREE_CODE (decl) == PARM_DECL)
     804       148699 :     walk_subtrees = 0;
     805              :   return NULL_TREE;
     806              : }
     807              : 
     808              : /* If there is an overlap between *REGS and DECL, return the first overlap
     809              :    found.  */
     810              : tree
     811       129873 : tree_overlaps_hard_reg_set (tree decl, HARD_REG_SET *regs)
     812              : {
     813       129873 :   return walk_tree (&decl, decl_overlaps_hard_reg_set_p, regs, NULL);
     814              : }
     815              : 
     816              : 
     817              : /* A subroutine of expand_asm_operands.  Check that all operand names
     818              :    are unique.  Return true if so.  We rely on the fact that these names
     819              :    are identifiers, and so have been canonicalized by get_identifier,
     820              :    so all we need are pointer comparisons.  */
     821              : 
     822              : static bool
     823       217308 : check_unique_operand_names (tree outputs, tree inputs, tree labels)
     824              : {
     825       217308 :   tree i, j, i_name = NULL_TREE;
     826              : 
     827       584136 :   for (i = outputs; i ; i = TREE_CHAIN (i))
     828              :     {
     829       366828 :       i_name = TREE_PURPOSE (TREE_PURPOSE (i));
     830       366828 :       if (! i_name)
     831       366414 :         continue;
     832              : 
     833         2333 :       for (j = TREE_CHAIN (i); j ; j = TREE_CHAIN (j))
     834         1919 :         if (simple_cst_equal (i_name, TREE_PURPOSE (TREE_PURPOSE (j))))
     835            0 :           goto failure;
     836              :     }
     837              : 
     838       597875 :   for (i = inputs; i ; i = TREE_CHAIN (i))
     839              :     {
     840       380572 :       i_name = TREE_PURPOSE (TREE_PURPOSE (i));
     841       380572 :       if (! i_name)
     842       379948 :         continue;
     843              : 
     844         1190 :       for (j = TREE_CHAIN (i); j ; j = TREE_CHAIN (j))
     845          566 :         if (simple_cst_equal (i_name, TREE_PURPOSE (TREE_PURPOSE (j))))
     846            0 :           goto failure;
     847         1042 :       for (j = outputs; j ; j = TREE_CHAIN (j))
     848          423 :         if (simple_cst_equal (i_name, TREE_PURPOSE (TREE_PURPOSE (j))))
     849            5 :           goto failure;
     850              :     }
     851              : 
     852       218177 :   for (i = labels; i ; i = TREE_CHAIN (i))
     853              :     {
     854          882 :       i_name = TREE_PURPOSE (i);
     855          882 :       if (! i_name)
     856            0 :         continue;
     857              : 
     858         2252 :       for (j = TREE_CHAIN (i); j ; j = TREE_CHAIN (j))
     859         1374 :         if (simple_cst_equal (i_name, TREE_PURPOSE (j)))
     860            4 :           goto failure;
     861         1209 :       for (j = inputs; j ; j = TREE_CHAIN (j))
     862          335 :         if (simple_cst_equal (i_name, TREE_PURPOSE (TREE_PURPOSE (j))))
     863            4 :           goto failure;
     864              :     }
     865              : 
     866              :   return true;
     867              : 
     868           13 :  failure:
     869           13 :   error ("duplicate %<asm%> operand name %qs", TREE_STRING_POINTER (i_name));
     870           13 :   return false;
     871              : }
     872              : 
     873              : /* Resolve the names of the operands in *POUTPUTS and *PINPUTS to numbers,
     874              :    and replace the name expansions in STRING and in the constraints to
     875              :    those numbers.  This is generally done in the front end while creating
     876              :    the ASM_EXPR generic tree that eventually becomes the GIMPLE_ASM.  */
     877              : 
     878              : tree
     879       217308 : resolve_asm_operand_names (tree string, tree outputs, tree inputs, tree labels)
     880              : {
     881       217308 :   char *buffer;
     882       217308 :   char *p;
     883       217308 :   const char *c;
     884       217308 :   tree t;
     885              : 
     886       217308 :   check_unique_operand_names (outputs, inputs, labels);
     887              : 
     888              :   /* Substitute [<name>] in input constraint strings.  There should be no
     889              :      named operands in output constraints.  */
     890       815188 :   for (t = inputs; t ; t = TREE_CHAIN (t))
     891              :     {
     892       380572 :       c = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t)));
     893       380572 :       if (strchr (c, '[') != NULL)
     894              :         {
     895          179 :           p = buffer = xstrdup (c);
     896          537 :           while ((p = strchr (p, '[')) != NULL)
     897          179 :             p = resolve_operand_name_1 (p, outputs, inputs, NULL);
     898          179 :           TREE_VALUE (TREE_PURPOSE (t))
     899          179 :             = build_string (strlen (buffer), buffer);
     900          179 :           free (buffer);
     901              :         }
     902              :     }
     903              : 
     904              :   /* Now check for any needed substitutions in the template.  */
     905       217308 :   c = TREE_STRING_POINTER (string);
     906       257869 :   while ((c = strchr (c, '%')) != NULL)
     907              :     {
     908        40981 :       if (c[1] == '[')
     909              :         break;
     910        40880 :       else if (ISALPHA (c[1])
     911         2115 :                && (c[2] == '[' || (ISALPHA (c[2]) && c[3] == '[')))
     912              :         break;
     913              :       else
     914              :         {
     915        40561 :           c += 1 + (c[1] == '%');
     916        40561 :           continue;
     917              :         }
     918              :     }
     919              : 
     920       217308 :   if (c)
     921              :     {
     922              :       /* OK, we need to make a copy so we can perform the substitutions.
     923              :          Assume that we will not need extra space--we get to remove '['
     924              :          and ']', which means we cannot have a problem until we have more
     925              :          than 999 operands.  */
     926          420 :       buffer = xstrdup (TREE_STRING_POINTER (string));
     927          420 :       p = buffer + (c - TREE_STRING_POINTER (string));
     928              : 
     929         2278 :       while ((p = strchr (p, '%')) != NULL)
     930              :         {
     931         1858 :           if (p[1] == '[')
     932          183 :             p += 1;
     933         1675 :           else if (ISALPHA (p[1]) && p[2] == '[')
     934          990 :             p += 2;
     935          685 :           else if (ISALPHA (p[1]) && ISALPHA (p[2]) && p[3] == '[')
     936           24 :             p += 3;
     937              :           else
     938              :             {
     939          661 :               p += 1 + (p[1] == '%');
     940          661 :               continue;
     941              :             }
     942              : 
     943         1197 :           p = resolve_operand_name_1 (p, outputs, inputs, labels);
     944              :         }
     945              : 
     946          420 :       string = build_string (strlen (buffer), buffer);
     947          420 :       free (buffer);
     948              :     }
     949              : 
     950       217308 :   return string;
     951              : }
     952              : 
     953              : /* A subroutine of resolve_operand_names.  P points to the '[' for a
     954              :    potential named operand of the form [<name>].  In place, replace
     955              :    the name and brackets with a number.  Return a pointer to the
     956              :    balance of the string after substitution.  */
     957              : 
     958              : static char *
     959         1376 : resolve_operand_name_1 (char *p, tree outputs, tree inputs, tree labels)
     960              : {
     961         1376 :   char *q;
     962         1376 :   int op, op_inout;
     963         1376 :   tree t;
     964              : 
     965              :   /* Collect the operand name.  */
     966         1376 :   q = strchr (++p, ']');
     967         1376 :   if (!q)
     968              :     {
     969            0 :       error ("missing close brace for named operand");
     970            0 :       return strchr (p, '\0');
     971              :     }
     972         1376 :   *q = '\0';
     973              : 
     974              :   /* Resolve the name to a number.  */
     975         2848 :   for (op_inout = op = 0, t = outputs; t ; t = TREE_CHAIN (t), op++)
     976              :     {
     977         1710 :       tree name = TREE_PURPOSE (TREE_PURPOSE (t));
     978         2972 :       if (name && strcmp (TREE_STRING_POINTER (name), p) == 0)
     979          238 :         goto found;
     980         1472 :       tree constraint = TREE_VALUE (TREE_PURPOSE (t));
     981         2944 :       if (constraint && strchr (TREE_STRING_POINTER (constraint), '+') != NULL)
     982           64 :         op_inout++;
     983              :     }
     984         2369 :   for (t = inputs; t ; t = TREE_CHAIN (t), op++)
     985              :     {
     986         2264 :       tree name = TREE_PURPOSE (TREE_PURPOSE (t));
     987         3968 :       if (name && strcmp (TREE_STRING_POINTER (name), p) == 0)
     988         1033 :         goto found;
     989              :     }
     990          105 :   op += op_inout;
     991          114 :   for (t = labels; t ; t = TREE_CHAIN (t), op++)
     992              :     {
     993          111 :       tree name = TREE_PURPOSE (t);
     994          222 :       if (name && strcmp (TREE_STRING_POINTER (name), p) == 0)
     995          102 :         goto found;
     996              :     }
     997              : 
     998            3 :   error ("undefined named operand %qs", identifier_to_locale (p));
     999            3 :   op = 0;
    1000              : 
    1001         1376 :  found:
    1002              :   /* Replace the name with the number.  Unfortunately, not all libraries
    1003              :      get the return value of sprintf correct, so search for the end of the
    1004              :      generated string by hand.  */
    1005         1376 :   sprintf (--p, "%d", op);
    1006         1376 :   p = strchr (p, '\0');
    1007              : 
    1008              :   /* Verify the no extra buffer space assumption.  */
    1009         1376 :   gcc_assert (p <= q);
    1010              : 
    1011              :   /* Shift the rest of the buffer down to fill the gap.  */
    1012         1376 :   memmove (p, q + 1, strlen (q + 1) + 1);
    1013              : 
    1014         1376 :   return p;
    1015              : }
    1016              : 
    1017              : 
    1018              : /* Generate RTL to return directly from the current function.
    1019              :    (That is, we bypass any return value.)  */
    1020              : 
    1021              : void
    1022          379 : expand_naked_return (void)
    1023              : {
    1024          379 :   rtx_code_label *end_label;
    1025              : 
    1026          379 :   clear_pending_stack_adjust ();
    1027          379 :   do_pending_stack_adjust ();
    1028              : 
    1029          379 :   end_label = naked_return_label;
    1030          379 :   if (end_label == 0)
    1031          379 :     end_label = naked_return_label = gen_label_rtx ();
    1032              : 
    1033          379 :   emit_jump (end_label);
    1034          379 : }
    1035              : 
    1036              : /* Generate code to jump to LABEL if OP0 and OP1 are equal in mode MODE. PROB
    1037              :    is the probability of jumping to LABEL.  */
    1038              : static void
    1039            0 : do_jump_if_equal (machine_mode mode, rtx op0, rtx op1, rtx_code_label *label,
    1040              :                   int unsignedp, profile_probability prob)
    1041              : {
    1042            0 :   do_compare_rtx_and_jump (op0, op1, EQ, unsignedp, mode,
    1043              :                            NULL_RTX, NULL, label, prob);
    1044            0 : }
    1045              : 
    1046              : /* Return the sum of probabilities of outgoing edges of basic block BB.  */
    1047              : 
    1048              : static profile_probability
    1049         8028 : get_outgoing_edge_probs (basic_block bb)
    1050              : {
    1051         8028 :   edge e;
    1052         8028 :   edge_iterator ei;
    1053         8028 :   profile_probability prob_sum = profile_probability::never ();
    1054         8028 :   if (!bb)
    1055            0 :     return profile_probability::never ();
    1056        84649 :   FOR_EACH_EDGE (e, ei, bb->succs)
    1057        76621 :     prob_sum += e->probability;
    1058         8028 :   return prob_sum;
    1059              : }
    1060              : 
    1061              : /* Computes the conditional probability of jumping to a target if the branch
    1062              :    instruction is executed.
    1063              :    TARGET_PROB is the estimated probability of jumping to a target relative
    1064              :    to some basic block BB.
    1065              :    BASE_PROB is the probability of reaching the branch instruction relative
    1066              :    to the same basic block BB.  */
    1067              : 
    1068              : static inline profile_probability
    1069        11720 : conditional_probability (profile_probability target_prob,
    1070              :                          profile_probability base_prob)
    1071              : {
    1072        11720 :   return target_prob / base_prob;
    1073              : }
    1074              : 
    1075              : /* Generate a dispatch tabler, switching on INDEX_EXPR and jumping to
    1076              :    one of the labels in CASE_LIST or to the DEFAULT_LABEL.
    1077              :    MINVAL, MAXVAL, and RANGE are the extrema and range of the case
    1078              :    labels in CASE_LIST. STMT_BB is the basic block containing the statement.
    1079              : 
    1080              :    First, a jump insn is emitted.  First we try "casesi".  If that
    1081              :    fails, try "tablejump".   A target *must* have one of them (or both).
    1082              : 
    1083              :    Then, a table with the target labels is emitted.
    1084              : 
    1085              :    The process is unaware of the CFG.  The caller has to fix up
    1086              :    the CFG itself.  This is done in cfgexpand.cc.  */
    1087              : 
    1088              : static void
    1089         8028 : emit_case_dispatch_table (tree index_expr, tree index_type,
    1090              :                           auto_vec<simple_case_node> &case_list,
    1091              :                           rtx default_label,
    1092              :                           edge default_edge,  tree minval, tree maxval,
    1093              :                           tree range, basic_block stmt_bb)
    1094              : {
    1095         8028 :   int i, ncases;
    1096         8028 :   auto_vec<rtx> labelvec;
    1097         8028 :   rtx_insn *fallback_label = label_rtx (case_list[0].m_code_label);
    1098         8028 :   rtx_code_label *table_label = gen_label_rtx ();
    1099         8028 :   bool has_gaps = false;
    1100         8028 :   profile_probability default_prob = default_edge ? default_edge->probability
    1101         8028 :                                                   : profile_probability::never ();
    1102         8028 :   profile_probability base = get_outgoing_edge_probs (stmt_bb);
    1103         8028 :   bool try_with_tablejump = false;
    1104              : 
    1105         8028 :   profile_probability new_default_prob = conditional_probability (default_prob,
    1106              :                                                                   base);
    1107              : 
    1108         8028 :   if (! try_casesi (index_type, index_expr, minval, range,
    1109              :                     table_label, default_label, fallback_label,
    1110              :                     new_default_prob))
    1111              :     {
    1112              :       /* Index jumptables from zero for suitable values of minval to avoid
    1113              :          a subtraction.  For the rationale see:
    1114              :          "http://gcc.gnu.org/ml/gcc-patches/2001-10/msg01234.html".  */
    1115         8028 :       if (optimize_insn_for_speed_p ()
    1116         7801 :           && compare_tree_int (minval, 0) > 0
    1117        11032 :           && compare_tree_int (minval, 3) < 0)
    1118              :         {
    1119          957 :           minval = build_int_cst (index_type, 0);
    1120          957 :           range = maxval;
    1121          957 :           has_gaps = true;
    1122              :         }
    1123              :       try_with_tablejump = true;
    1124              :     }
    1125              : 
    1126              :   /* Get table of labels to jump to, in order of case index.  */
    1127              : 
    1128         8028 :   ncases = tree_to_shwi (range) + 1;
    1129         8028 :   labelvec.safe_grow_cleared (ncases);
    1130              : 
    1131        87080 :   for (unsigned j = 0; j < case_list.length (); j++)
    1132              :     {
    1133        79052 :       simple_case_node *n = &case_list[j];
    1134              :       /* Compute the low and high bounds relative to the minimum
    1135              :          value since that should fit in a HOST_WIDE_INT while the
    1136              :          actual values may not.  */
    1137        79052 :       HOST_WIDE_INT i_low
    1138        79052 :         = tree_to_uhwi (fold_build2 (MINUS_EXPR, index_type,
    1139        79052 :                                      n->m_low, minval));
    1140        79052 :       HOST_WIDE_INT i_high
    1141        79052 :         = tree_to_uhwi (fold_build2 (MINUS_EXPR, index_type,
    1142        79052 :                                      n->m_high, minval));
    1143        79052 :       HOST_WIDE_INT i;
    1144              : 
    1145       168896 :       for (i = i_low; i <= i_high; i ++)
    1146       269532 :         labelvec[i]
    1147       101269 :           = gen_rtx_LABEL_REF (Pmode, label_rtx (n->m_code_label));
    1148              :     }
    1149              : 
    1150              :   /* The dispatch table may contain gaps, including at the beginning of
    1151              :      the table if we tried to avoid the minval subtraction.  We fill the
    1152              :      dispatch table slots associated with the gaps with the default case label.
    1153              :      However, in the event the default case is unreachable, we then use
    1154              :      any label from one of the case statements.  */
    1155         8028 :   rtx gap_label = (default_label) ? default_label : fallback_label;
    1156              : 
    1157       170456 :   for (i = 0; i < ncases; i++)
    1158       162428 :     if (labelvec[i] == 0)
    1159              :       {
    1160        72584 :         has_gaps = true;
    1161        84619 :         labelvec[i] = gen_rtx_LABEL_REF (Pmode, gap_label);
    1162              :       }
    1163              : 
    1164         8028 :   if (has_gaps && default_label)
    1165              :     {
    1166              :       /* There is at least one entry in the jump table that jumps
    1167              :          to default label. The default label can either be reached
    1168              :          through the indirect jump or the direct conditional jump
    1169              :          before that. Split the probability of reaching the
    1170              :          default label among these two jumps.  */
    1171         3692 :       new_default_prob = conditional_probability (default_prob / 2, base);
    1172         3692 :       default_prob /= 2;
    1173         3692 :       base -= default_prob;
    1174              :     }
    1175              :   else
    1176              :     {
    1177         4336 :       base -= default_prob;
    1178         4336 :       default_prob = profile_probability::never ();
    1179              :     }
    1180              : 
    1181         8028 :   if (default_edge)
    1182         4725 :     default_edge->probability = default_prob;
    1183              : 
    1184              :   /* We have altered the probability of the default edge. So the probabilities
    1185              :      of all other edges need to be adjusted so that it sums up to
    1186              :      REG_BR_PROB_BASE.  */
    1187         8028 :   if (base > profile_probability::never ())
    1188              :     {
    1189         8024 :       edge e;
    1190         8024 :       edge_iterator ei;
    1191        84513 :       FOR_EACH_EDGE (e, ei, stmt_bb->succs)
    1192        76489 :         e->probability /= base;
    1193              :     }
    1194              : 
    1195         8028 :   if (try_with_tablejump)
    1196              :     {
    1197         8028 :       bool ok = try_tablejump (index_type, index_expr, minval, range,
    1198              :                                table_label, default_label, new_default_prob);
    1199         8028 :       gcc_assert (ok);
    1200              :     }
    1201              :   /* Output the table.  */
    1202         8028 :   emit_label (table_label);
    1203              : 
    1204         8028 :   if (CASE_VECTOR_PC_RELATIVE
    1205         8028 :           || (flag_pic && targetm.asm_out.generate_pic_addr_diff_vec ()))
    1206         3411 :     emit_jump_table_data (gen_rtx_ADDR_DIFF_VEC (CASE_VECTOR_MODE,
    1207              :                                                  gen_rtx_LABEL_REF (Pmode,
    1208              :                                                                     table_label),
    1209              :                                                  gen_rtvec_v (ncases, labelvec.address ()),
    1210              :                                                  const0_rtx, const0_rtx));
    1211              :   else
    1212        14595 :     emit_jump_table_data (gen_rtx_ADDR_VEC (CASE_VECTOR_MODE,
    1213              :                                             gen_rtvec_v (ncases, labelvec.address ())));
    1214              : 
    1215              :   /* Record no drop-through after the table.  */
    1216         8028 :   emit_barrier ();
    1217         8028 : }
    1218              : 
    1219              : /* Terminate a case Ada or switch (C) statement
    1220              :    in which ORIG_INDEX is the expression to be tested.
    1221              :    If ORIG_TYPE is not NULL, it is the original ORIG_INDEX
    1222              :    type as given in the source before any compiler conversions.
    1223              :    Generate the code to test it and jump to the right place.  */
    1224              : 
    1225              : void
    1226         8028 : expand_case (gswitch *stmt)
    1227              : {
    1228         8028 :   tree minval = NULL_TREE, maxval = NULL_TREE, range = NULL_TREE;
    1229         8028 :   rtx_code_label *default_label;
    1230         8028 :   unsigned int count;
    1231         8028 :   int i;
    1232         8028 :   int ncases = gimple_switch_num_labels (stmt);
    1233         8028 :   tree index_expr = gimple_switch_index (stmt);
    1234         8028 :   tree index_type = TREE_TYPE (index_expr);
    1235         8028 :   tree elt;
    1236         8028 :   basic_block bb = gimple_bb (stmt);
    1237         8028 :   gimple *def_stmt;
    1238              : 
    1239         8028 :   auto_vec<simple_case_node> case_list;
    1240              : 
    1241              :   /* An ERROR_MARK occurs for various reasons including invalid data type.
    1242              :      ??? Can this still happen, with GIMPLE and all?  */
    1243         8028 :   if (index_type == error_mark_node)
    1244            0 :     return;
    1245              : 
    1246              :   /* cleanup_tree_cfg removes all SWITCH_EXPR with their index
    1247              :      expressions being INTEGER_CST.  */
    1248         8028 :   gcc_assert (TREE_CODE (index_expr) != INTEGER_CST);
    1249              : 
    1250              :   /* Optimization of switch statements with only one label has already
    1251              :      occurred, so we should never see them at this point.  */
    1252         8028 :   gcc_assert (ncases > 1);
    1253              : 
    1254         8028 :   do_pending_stack_adjust ();
    1255              : 
    1256              :   /* Find the default case target label.  */
    1257         8028 :   tree default_lab = CASE_LABEL (gimple_switch_default_label (stmt));
    1258         8028 :   default_label = jump_target_rtx (default_lab);
    1259         8028 :   basic_block default_bb = label_to_block (cfun, default_lab);
    1260         8028 :   edge default_edge = find_edge (bb, default_bb);
    1261              : 
    1262              :   /* Get upper and lower bounds of case values.  */
    1263         8028 :   elt = gimple_switch_label (stmt, 1);
    1264         8028 :   minval = fold_convert (index_type, CASE_LOW (elt));
    1265         8028 :   elt = gimple_switch_label (stmt, ncases - 1);
    1266         8028 :   if (CASE_HIGH (elt))
    1267         1801 :     maxval = fold_convert (index_type, CASE_HIGH (elt));
    1268              :   else
    1269         6227 :     maxval = fold_convert (index_type, CASE_LOW (elt));
    1270              : 
    1271              :   /* Try to narrow the index type if it's larger than a word.
    1272              :      That is mainly for -O0 where an equivalent optimization
    1273              :      done by forward propagation is not run and is aimed at
    1274              :      avoiding a call to a comparison routine of libgcc.  */
    1275         8028 :   if (TYPE_PRECISION (index_type) > BITS_PER_WORD
    1276            6 :       && TREE_CODE (index_expr) == SSA_NAME
    1277            6 :       && (def_stmt = SSA_NAME_DEF_STMT (index_expr))
    1278            6 :       && is_gimple_assign (def_stmt)
    1279         8031 :       && gimple_assign_rhs_code (def_stmt) == NOP_EXPR)
    1280              :     {
    1281            0 :       tree inner_index_expr = gimple_assign_rhs1 (def_stmt);
    1282            0 :       tree inner_index_type = TREE_TYPE (inner_index_expr);
    1283              : 
    1284            0 :       if (INTEGRAL_TYPE_P (inner_index_type)
    1285            0 :           && TYPE_PRECISION (inner_index_type) <= BITS_PER_WORD
    1286            0 :           && int_fits_type_p (minval, inner_index_type)
    1287            0 :           && int_fits_type_p (maxval, inner_index_type))
    1288              :         {
    1289            0 :           index_expr = inner_index_expr;
    1290            0 :           index_type = inner_index_type;
    1291            0 :           minval = fold_convert (index_type, minval);
    1292            0 :           maxval = fold_convert (index_type, maxval);
    1293              :         }
    1294              :     }
    1295              : 
    1296              :   /* Compute span of values.  */
    1297         8028 :   range = fold_build2 (MINUS_EXPR, index_type, maxval, minval);
    1298              : 
    1299              :   /* Listify the labels queue and gather some numbers to decide
    1300              :      how to expand this switch().  */
    1301         8028 :   count = 0;
    1302              : 
    1303        87080 :   for (i = ncases - 1; i >= 1; --i)
    1304              :     {
    1305        79052 :       elt = gimple_switch_label (stmt, i);
    1306        79052 :       tree low = CASE_LOW (elt);
    1307        79052 :       gcc_assert (low);
    1308        79052 :       tree high = CASE_HIGH (elt);
    1309        79052 :       gcc_assert (! high || tree_int_cst_lt (low, high));
    1310        79052 :       tree lab = CASE_LABEL (elt);
    1311              : 
    1312              :       /* Count the elements.
    1313              :          A range counts double, since it requires two compares.  */
    1314        79052 :       count++;
    1315        79052 :       if (high)
    1316         5554 :         count++;
    1317              : 
    1318              :       /* The bounds on the case range, LOW and HIGH, have to be converted
    1319              :          to case's index type TYPE.  Note that the original type of the
    1320              :          case index in the source code is usually "lost" during
    1321              :          gimplification due to type promotion, but the case labels retain the
    1322              :          original type.  Make sure to drop overflow flags.  */
    1323        79052 :       low = fold_convert (index_type, low);
    1324        79052 :       if (TREE_OVERFLOW (low))
    1325            0 :         low = wide_int_to_tree (index_type, wi::to_wide (low));
    1326              : 
    1327              :       /* The canonical from of a case label in GIMPLE is that a simple case
    1328              :          has an empty CASE_HIGH.  For the casesi and tablejump expanders,
    1329              :          the back ends want simple cases to have high == low.  */
    1330        79052 :       if (! high)
    1331        73498 :         high = low;
    1332        79052 :       high = fold_convert (index_type, high);
    1333        79052 :       if (TREE_OVERFLOW (high))
    1334            0 :         high = wide_int_to_tree (index_type, wi::to_wide (high));
    1335              : 
    1336        79052 :       case_list.safe_push (simple_case_node (low, high, lab));
    1337              :     }
    1338              : 
    1339              :   /* cleanup_tree_cfg removes all SWITCH_EXPR with a single
    1340              :      destination, such as one with a default case only.
    1341              :      It also removes cases that are out of range for the switch
    1342              :      type, so we should never get a zero here.  */
    1343         8028 :   gcc_assert (count > 0);
    1344              : 
    1345         8028 :   rtx_insn *before_case = get_last_insn ();
    1346              : 
    1347              :   /* If the default case is unreachable, then set default_label to NULL
    1348              :      so that we omit the range check when generating the dispatch table.
    1349              :      We also remove the edge to the unreachable default case.  The block
    1350              :      itself will be automatically removed later.  */
    1351         8028 :   if (EDGE_COUNT (default_edge->dest->succs) == 0
    1352        12090 :       && gimple_seq_unreachable_p (bb_seq (default_edge->dest)))
    1353              :     {
    1354         3303 :       default_label = NULL;
    1355         3303 :       expand_remove_edge (default_edge);
    1356         3303 :       default_edge = NULL;
    1357              :     }
    1358              : 
    1359         8028 :   emit_case_dispatch_table (index_expr, index_type,
    1360              :                             case_list, default_label, default_edge,
    1361              :                             minval, maxval, range, bb);
    1362              : 
    1363         8028 :   reorder_insns (NEXT_INSN (before_case), get_last_insn (), before_case);
    1364              : 
    1365         8028 :   free_temp_slots ();
    1366         8028 : }
    1367              : 
    1368              : /* Expand the dispatch to a short decrement chain if there are few cases
    1369              :    to dispatch to.  Likewise if neither casesi nor tablejump is available,
    1370              :    or if flag_jump_tables is set.  Otherwise, expand as a casesi or a
    1371              :    tablejump.  The index mode is always the mode of integer_type_node.
    1372              :    Trap if no case matches the index.
    1373              : 
    1374              :    DISPATCH_INDEX is the index expression to switch on.  It should be a
    1375              :    memory or register operand.
    1376              : 
    1377              :    DISPATCH_TABLE is a set of case labels.  The set should be sorted in
    1378              :    ascending order, be contiguous, starting with value 0, and contain only
    1379              :    single-valued case labels.  */
    1380              : 
    1381              : void
    1382            0 : expand_sjlj_dispatch_table (rtx dispatch_index,
    1383              :                             vec<tree> dispatch_table)
    1384              : {
    1385            0 :   tree index_type = integer_type_node;
    1386            0 :   machine_mode index_mode = TYPE_MODE (index_type);
    1387              : 
    1388            0 :   int ncases = dispatch_table.length ();
    1389              : 
    1390            0 :   do_pending_stack_adjust ();
    1391            0 :   rtx_insn *before_case = get_last_insn ();
    1392              : 
    1393              :   /* Expand as a decrement-chain if there are 5 or fewer dispatch
    1394              :      labels.  This covers more than 98% of the cases in libjava,
    1395              :      and seems to be a reasonable compromise between the "old way"
    1396              :      of expanding as a decision tree or dispatch table vs. the "new
    1397              :      way" with decrement chain or dispatch table.  */
    1398            0 :   if (dispatch_table.length () <= 5
    1399            0 :       || (!targetm.have_casesi () && !targetm.have_tablejump ())
    1400            0 :       || !flag_jump_tables)
    1401              :     {
    1402              :       /* Expand the dispatch as a decrement chain:
    1403              : 
    1404              :          "switch(index) {case 0: do_0; case 1: do_1; ...; case N: do_N;}"
    1405              : 
    1406              :          ==>
    1407              : 
    1408              :          if (index == 0) do_0; else index--;
    1409              :          if (index == 0) do_1; else index--;
    1410              :          ...
    1411              :          if (index == 0) do_N; else index--;
    1412              : 
    1413              :          This is more efficient than a dispatch table on most machines.
    1414              :          The last "index--" is redundant but the code is trivially dead
    1415              :          and will be cleaned up by later passes.  */
    1416            0 :       rtx index = copy_to_mode_reg (index_mode, dispatch_index);
    1417            0 :       rtx zero = CONST0_RTX (index_mode);
    1418            0 :       for (int i = 0; i < ncases; i++)
    1419              :         {
    1420            0 :           tree elt = dispatch_table[i];
    1421            0 :           rtx_code_label *lab = jump_target_rtx (CASE_LABEL (elt));
    1422            0 :           do_jump_if_equal (index_mode, index, zero, lab, 0,
    1423              :                             profile_probability::uninitialized ());
    1424            0 :           force_expand_binop (index_mode, sub_optab,
    1425              :                               index, CONST1_RTX (index_mode),
    1426              :                               index, 0, OPTAB_DIRECT);
    1427              :         }
    1428              :     }
    1429              :   else
    1430              :     {
    1431              :       /* Similar to expand_case, but much simpler.  */
    1432            0 :       auto_vec<simple_case_node> case_list;
    1433            0 :       tree index_expr = make_tree (index_type, dispatch_index);
    1434            0 :       tree minval = build_int_cst (index_type, 0);
    1435            0 :       tree maxval = CASE_LOW (dispatch_table.last ());
    1436            0 :       tree range = maxval;
    1437            0 :       rtx_code_label *default_label = gen_label_rtx ();
    1438              : 
    1439            0 :       for (int i = ncases - 1; i >= 0; --i)
    1440              :         {
    1441            0 :           tree elt = dispatch_table[i];
    1442            0 :           tree high = CASE_HIGH (elt);
    1443            0 :           if (high == NULL_TREE)
    1444            0 :             high = CASE_LOW (elt);
    1445            0 :           case_list.safe_push (simple_case_node (CASE_LOW (elt), high,
    1446            0 :                                                  CASE_LABEL (elt)));
    1447              :         }
    1448              : 
    1449            0 :       emit_case_dispatch_table (index_expr, index_type,
    1450              :                                 case_list, default_label, NULL,
    1451              :                                 minval, maxval, range,
    1452            0 :                                 BLOCK_FOR_INSN (before_case));
    1453            0 :       emit_label (default_label);
    1454            0 :     }
    1455              : 
    1456              :   /* Dispatching something not handled?  Trap!  */
    1457            0 :   expand_builtin_trap ();
    1458              : 
    1459            0 :   reorder_insns (NEXT_INSN (before_case), get_last_insn (), before_case);
    1460              : 
    1461            0 :   free_temp_slots ();
    1462            0 : }
    1463              : 
    1464              : 
        

Generated by: LCOV version 2.4-beta

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