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

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