LCOV - code coverage report
Current view: top level - gcc - stmt.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 81.6 % 463 378
Test Date: 2024-12-21 13:15:12 Functions: 83.3 % 18 15
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* Expands front end tree to back end RTL for GCC
       2                 :             :    Copyright (C) 1987-2024 Free Software Foundation, Inc.
       3                 :             : 
       4                 :             : This file is part of GCC.
       5                 :             : 
       6                 :             : GCC is free software; you can redistribute it and/or modify it under
       7                 :             : the terms of the GNU General Public License as published by the Free
       8                 :             : Software Foundation; either version 3, or (at your option) any later
       9                 :             : version.
      10                 :             : 
      11                 :             : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      12                 :             : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      13                 :             : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      14                 :             : for more details.
      15                 :             : 
      16                 :             : You should have received a copy of the GNU General Public License
      17                 :             : along with GCC; see the file COPYING3.  If not see
      18                 :             : <http://www.gnu.org/licenses/>.  */
      19                 :             : 
      20                 :             : /* 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                 :             : 
      43                 :             : #include "fold-const.h"
      44                 :             : #include "varasm.h"
      45                 :             : #include "stor-layout.h"
      46                 :             : #include "dojump.h"
      47                 :             : #include "explow.h"
      48                 :             : #include "stmt.h"
      49                 :             : #include "expr.h"
      50                 :             : #include "langhooks.h"
      51                 :             : #include "cfganal.h"
      52                 :             : #include "tree-cfg.h"
      53                 :             : #include "dumpfile.h"
      54                 :             : #include "builtins.h"
      55                 :             : 
      56                 :             : 
      57                 :             : /* Functions and data structures for expanding case statements.  */
      58                 :             : 
      59                 :             : /* Case label structure, used to hold info on labels within case
      60                 :             :    statements.  We handle "range" labels; for a single-value label
      61                 :             :    as in C, the high and low limits are the same.
      62                 :             : 
      63                 :             :    We start with a vector of case nodes sorted in ascending order, and
      64                 :             :    the default label as the last element in the vector.
      65                 :             : 
      66                 :             :    Switch statements are expanded in jump table form.
      67                 :             : 
      68                 :             : */
      69                 :             : 
      70                 :             : class simple_case_node
      71                 :             : {
      72                 :             : public:
      73                 :       75704 :   simple_case_node (tree low, tree high, tree code_label):
      74                 :       75704 :     m_low (low), m_high (high), m_code_label (code_label)
      75                 :             :   {}
      76                 :             : 
      77                 :             :   /* Lowest index value for this label.  */
      78                 :             :   tree m_low;
      79                 :             :   /* Highest index value for this label.  */
      80                 :             :   tree m_high;
      81                 :             :   /* Label to jump to when node matches.  */
      82                 :             :   tree m_code_label;
      83                 :             : };
      84                 :             : 
      85                 :             : static bool check_unique_operand_names (tree, tree, tree);
      86                 :             : static char *resolve_operand_name_1 (char *, tree, tree, tree);
      87                 :             : 
      88                 :             : /* Return the rtx-label that corresponds to a LABEL_DECL,
      89                 :             :    creating it if necessary.  */
      90                 :             : 
      91                 :             : rtx_insn *
      92                 :     2480459 : label_rtx (tree label)
      93                 :             : {
      94                 :     2480459 :   gcc_assert (TREE_CODE (label) == LABEL_DECL);
      95                 :             : 
      96                 :     2480459 :   if (!DECL_RTL_SET_P (label))
      97                 :             :     {
      98                 :      587178 :       rtx_code_label *r = gen_label_rtx ();
      99                 :      587178 :       SET_DECL_RTL (label, r);
     100                 :      587178 :       if (FORCED_LABEL (label) || DECL_NONLOCAL (label))
     101                 :       24981 :         LABEL_PRESERVE_P (r) = 1;
     102                 :             :     }
     103                 :             : 
     104                 :     2480459 :   return as_a <rtx_insn *> (DECL_RTL (label));
     105                 :             : }
     106                 :             : 
     107                 :             : /* As above, but also put it on the forced-reference list of the
     108                 :             :    function that contains it.  */
     109                 :             : rtx_insn *
     110                 :           0 : force_label_rtx (tree label)
     111                 :             : {
     112                 :           0 :   rtx_insn *ref = label_rtx (label);
     113                 :           0 :   tree function = decl_function_context (label);
     114                 :             : 
     115                 :           0 :   gcc_assert (function);
     116                 :             : 
     117                 :           0 :   vec_safe_push (forced_labels, ref);
     118                 :           0 :   return ref;
     119                 :             : }
     120                 :             : 
     121                 :             : /* As label_rtx, but ensures (in check build), that returned value is
     122                 :             :    an existing label (i.e. rtx with code CODE_LABEL).  */
     123                 :             : rtx_code_label *
     124                 :      790596 : jump_target_rtx (tree label)
     125                 :             : {
     126                 :      790596 :   return as_a <rtx_code_label *> (label_rtx (label));
     127                 :             : }
     128                 :             : 
     129                 :             : /* Add an unconditional jump to LABEL as the next sequential instruction.  */
     130                 :             : 
     131                 :             : void
     132                 :     3041546 : emit_jump (rtx label)
     133                 :             : {
     134                 :     3041546 :   do_pending_stack_adjust ();
     135                 :     3041546 :   emit_jump_insn (targetm.gen_jump (label));
     136                 :     3041546 :   emit_barrier ();
     137                 :     3041546 : }
     138                 :             : 
     139                 :             : /* Handle goto statements and the labels that they can go to.  */
     140                 :             : 
     141                 :             : /* Specify the location in the RTL code of a label LABEL,
     142                 :             :    which is a LABEL_DECL tree node.
     143                 :             : 
     144                 :             :    This is used for the kind of label that the user can jump to with a
     145                 :             :    goto statement, and for alternatives of a switch or case statement.
     146                 :             :    RTL labels generated for loops and conditionals don't go through here;
     147                 :             :    they are generated directly at the RTL level, by other functions below.
     148                 :             : 
     149                 :             :    Note that this has nothing to do with defining label *names*.
     150                 :             :    Languages vary in how they do that and what that even means.  */
     151                 :             : 
     152                 :             : void
     153                 :      587178 : expand_label (tree label)
     154                 :             : {
     155                 :      587178 :   rtx_code_label *label_r = jump_target_rtx (label);
     156                 :             : 
     157                 :      587178 :   do_pending_stack_adjust ();
     158                 :      587178 :   emit_label (label_r);
     159                 :      587178 :   if (DECL_NAME (label))
     160                 :       92471 :     LABEL_NAME (DECL_RTL (label)) = IDENTIFIER_POINTER (DECL_NAME (label));
     161                 :             : 
     162                 :      587178 :   if (DECL_NONLOCAL (label))
     163                 :             :     {
     164                 :         501 :       expand_builtin_setjmp_receiver (NULL);
     165                 :         501 :       nonlocal_goto_handler_labels
     166                 :         501 :         = gen_rtx_INSN_LIST (VOIDmode, label_r,
     167                 :         501 :                              nonlocal_goto_handler_labels);
     168                 :             :     }
     169                 :             : 
     170                 :      587178 :   if (FORCED_LABEL (label))
     171                 :       24480 :     vec_safe_push<rtx_insn *> (forced_labels, label_r);
     172                 :             : 
     173                 :     1173855 :   if (DECL_NONLOCAL (label) || FORCED_LABEL (label))
     174                 :       24981 :     maybe_set_first_label_num (label_r);
     175                 :      587178 : }
     176                 :             : 
     177                 :             : /* Parse the output constraint pointed to by *CONSTRAINT_P.  It is the
     178                 :             :    OPERAND_NUMth output operand, indexed from zero.  There are NINPUTS
     179                 :             :    inputs and NOUTPUTS outputs to this extended-asm.  Upon return,
     180                 :             :    *ALLOWS_MEM will be TRUE iff the constraint allows the use of a
     181                 :             :    memory operand.  Similarly, *ALLOWS_REG will be TRUE iff the
     182                 :             :    constraint allows the use of a register operand.  And, *IS_INOUT
     183                 :             :    will be true if the operand is read-write, i.e., if it is used as
     184                 :             :    an input as well as an output.  If *CONSTRAINT_P is not in
     185                 :             :    canonical form, it will be made canonical.  (Note that `+' will be
     186                 :             :    replaced with `=' as part of this process.)
     187                 :             : 
     188                 :             :    Returns TRUE if all went well; FALSE if an error occurred.  */
     189                 :             : 
     190                 :             : bool
     191                 :    31526523 : parse_output_constraint (const char **constraint_p, int operand_num,
     192                 :             :                          int ninputs, int noutputs, bool *allows_mem,
     193                 :             :                          bool *allows_reg, bool *is_inout)
     194                 :             : {
     195                 :    31526523 :   const char *constraint = *constraint_p;
     196                 :    31526523 :   const char *p;
     197                 :             : 
     198                 :             :   /* Assume the constraint doesn't allow the use of either a register
     199                 :             :      or memory.  */
     200                 :    31526523 :   *allows_mem = false;
     201                 :    31526523 :   *allows_reg = false;
     202                 :             : 
     203                 :             :   /* Allow the `=' or `+' to not be at the beginning of the string,
     204                 :             :      since it wasn't explicitly documented that way, and there is a
     205                 :             :      large body of code that puts it last.  Swap the character to
     206                 :             :      the front, so as not to uglify any place else.  */
     207                 :    31526523 :   p = strchr (constraint, '=');
     208                 :    31526523 :   if (!p)
     209                 :       17296 :     p = strchr (constraint, '+');
     210                 :             : 
     211                 :             :   /* If the string doesn't contain an `=', issue an error
     212                 :             :      message.  */
     213                 :       17296 :   if (!p)
     214                 :             :     {
     215                 :          12 :       error ("output operand constraint lacks %<=%>");
     216                 :          12 :       return false;
     217                 :             :     }
     218                 :             : 
     219                 :             :   /* If the constraint begins with `+', then the operand is both read
     220                 :             :      from and written to.  */
     221                 :    31526511 :   *is_inout = (*p == '+');
     222                 :             : 
     223                 :             :   /* Canonicalize the output constraint so that it begins with `='.  */
     224                 :    31526511 :   if (p != constraint || *is_inout)
     225                 :             :     {
     226                 :       17284 :       char *buf;
     227                 :       17284 :       size_t c_len = strlen (constraint);
     228                 :             : 
     229                 :       17284 :       if (p != constraint)
     230                 :           0 :         warning (0, "output constraint %qc for operand %d "
     231                 :             :                  "is not at the beginning",
     232                 :           0 :                  *p, operand_num);
     233                 :             : 
     234                 :             :       /* Make a copy of the constraint.  */
     235                 :       17284 :       buf = XALLOCAVEC (char, c_len + 1);
     236                 :       17284 :       strcpy (buf, constraint);
     237                 :             :       /* Swap the first character and the `=' or `+'.  */
     238                 :       17284 :       buf[p - constraint] = buf[0];
     239                 :             :       /* Make sure the first character is an `='.  (Until we do this,
     240                 :             :          it might be a `+'.)  */
     241                 :       17284 :       buf[0] = '=';
     242                 :             :       /* Replace the constraint with the canonicalized string.  */
     243                 :       17284 :       *constraint_p = ggc_alloc_string (buf, c_len);
     244                 :       17284 :       constraint = *constraint_p;
     245                 :             :     }
     246                 :             : 
     247                 :             :   /* Loop through the constraint string.  */
     248                 :    63869460 :   for (p = constraint + 1; *p; )
     249                 :             :     {
     250                 :    32342957 :       switch (*p)
     251                 :             :         {
     252                 :           0 :         case '+':
     253                 :           0 :         case '=':
     254                 :           0 :           error ("operand constraint contains incorrectly positioned "
     255                 :             :                  "%<+%> or %<=%>");
     256                 :           0 :           return false;
     257                 :             : 
     258                 :           8 :         case '%':
     259                 :           8 :           if (operand_num + 1 == ninputs + noutputs)
     260                 :             :             {
     261                 :           0 :               error ("%<%%%> constraint used with last operand");
     262                 :           0 :               return false;
     263                 :             :             }
     264                 :             :           break;
     265                 :             : 
     266                 :             :         case '?':  case '!':  case '*':  case '&':  case '#':
     267                 :             :         case '$':  case '^':
     268                 :             :         case 'E':  case 'F':  case 'G':  case 'H':
     269                 :             :         case 's':  case 'i':  case 'n':
     270                 :             :         case 'I':  case 'J':  case 'K':  case 'L':  case 'M':
     271                 :             :         case 'N':  case 'O':  case 'P':  case ',':  case '-':
     272                 :             :           break;
     273                 :             : 
     274                 :           0 :         case '0':  case '1':  case '2':  case '3':  case '4':
     275                 :           0 :         case '5':  case '6':  case '7':  case '8':  case '9':
     276                 :           0 :         case '[':
     277                 :           0 :           error ("matching constraint not valid in output operand");
     278                 :           0 :           return false;
     279                 :             : 
     280                 :           8 :         case ':':
     281                 :           8 :           error ("%<:%> constraint used for output operand");
     282                 :           8 :           return false;
     283                 :             : 
     284                 :           0 :         case '<':  case '>':
     285                 :             :           /* ??? Before flow, auto inc/dec insns are not supposed to exist,
     286                 :             :              excepting those that expand_call created.  So match memory
     287                 :             :              and hope.  */
     288                 :           0 :           *allows_mem = true;
     289                 :           0 :           break;
     290                 :             : 
     291                 :     1887675 :         case 'g':  case 'X':
     292                 :     1887675 :           *allows_reg = true;
     293                 :     1887675 :           *allows_mem = true;
     294                 :     1887675 :           break;
     295                 :             : 
     296                 :    29830055 :         default:
     297                 :    29830055 :           if (!ISALPHA (*p))
     298                 :             :             break;
     299                 :    29811020 :           enum constraint_num cn = lookup_constraint (p);
     300                 :    29811020 :           if (reg_class_for_constraint (cn) != NO_REGS
     301                 :    29811020 :               || insn_extra_address_constraint (cn))
     302                 :    28024294 :             *allows_reg = true;
     303                 :             :           else if (insn_extra_memory_constraint (cn))
     304                 :     1778964 :             *allows_mem = true;
     305                 :             :           else
     306                 :             :             insn_extra_constraint_allows_reg_mem (cn, allows_reg, allows_mem);
     307                 :             :           break;
     308                 :             :         }
     309                 :             : 
     310                 :    64700306 :       for (size_t len = CONSTRAINT_LEN (*p, p); len; len--, p++)
     311                 :    32357804 :         if (*p == '\0')
     312                 :             :           break;
     313                 :             :     }
     314                 :             : 
     315                 :             :   return true;
     316                 :             : }
     317                 :             : 
     318                 :             : /* Similar, but for input constraints.  */
     319                 :             : 
     320                 :             : bool
     321                 :    20611569 : parse_input_constraint (const char **constraint_p, int input_num,
     322                 :             :                         int ninputs, int noutputs, int ninout,
     323                 :             :                         const char * const * constraints,
     324                 :             :                         bool *allows_mem, bool *allows_reg)
     325                 :             : {
     326                 :    20611569 :   const char *constraint = *constraint_p;
     327                 :    20611569 :   const char *orig_constraint = constraint;
     328                 :    20611569 :   size_t c_len = strlen (constraint);
     329                 :    20611569 :   size_t j;
     330                 :    20611569 :   bool saw_match = false;
     331                 :    20611569 :   bool at_checked = false;
     332                 :             : 
     333                 :             :   /* Assume the constraint doesn't allow the use of either
     334                 :             :      a register or memory.  */
     335                 :    20611569 :   *allows_mem = false;
     336                 :    20611569 :   *allows_reg = false;
     337                 :             : 
     338                 :             :   /* Make sure constraint has neither `=', `+', nor '&'.  */
     339                 :             : 
     340                 :    54900103 :   for (j = 0; j < c_len; j += CONSTRAINT_LEN (constraint[j], constraint+j))
     341                 :    34288560 :     switch (constraint[j])
     342                 :             :       {
     343                 :      476166 :       case '+':  case '=':  case '&':
     344                 :      476166 :         if (constraint == orig_constraint)
     345                 :             :           {
     346                 :           0 :             error ("input operand constraint contains %qc", constraint[j]);
     347                 :           0 :             return false;
     348                 :             :           }
     349                 :             :         break;
     350                 :             : 
     351                 :      383543 :       case '%':
     352                 :      383543 :         if (constraint == orig_constraint
     353                 :      383543 :             && input_num + 1 == ninputs - ninout)
     354                 :             :           {
     355                 :           0 :             error ("%<%%%> constraint used with last operand");
     356                 :           0 :             return false;
     357                 :             :           }
     358                 :             :         break;
     359                 :             : 
     360                 :             :       case '<':  case '>':
     361                 :             :       case '?':  case '!':  case '*':  case '#':
     362                 :             :       case '$':  case '^':
     363                 :             :       case 'E':  case 'F':  case 'G':  case 'H':
     364                 :             :       case 's':  case 'i':  case 'n':
     365                 :             :       case 'I':  case 'J':  case 'K':  case 'L':  case 'M':
     366                 :             :       case 'N':  case 'O':  case 'P':  case ',':  case '-':
     367                 :             :         break;
     368                 :             : 
     369                 :         112 :       case ':':
     370                 :             :         /* Verify that if : is used, it is just ":" or say ":,:" but not
     371                 :             :            mixed with other constraints or say ",:,," etc.  */
     372                 :         112 :         if (!at_checked)
     373                 :             :           {
     374                 :         204 :             for (size_t k = 0; k < c_len; ++k)
     375                 :         228 :               if (constraint[k] != ((k & 1) ? ',' : ':') || (c_len & 1) == 0)
     376                 :             :                 {
     377                 :          20 :                   error ("%<:%> constraint mixed with other constraints");
     378                 :          20 :                   return false;
     379                 :             :                 } 
     380                 :             :             at_checked = true;
     381                 :             :           }
     382                 :             :         break;
     383                 :             : 
     384                 :             :         /* Whether or not a numeric constraint allows a register is
     385                 :             :            decided by the matching constraint, and so there is no need
     386                 :             :            to do anything special with them.  We must handle them in
     387                 :             :            the default case, so that we don't unnecessarily force
     388                 :             :            operands to memory.  */
     389                 :    12030481 :       case '0':  case '1':  case '2':  case '3':  case '4':
     390                 :    12030481 :       case '5':  case '6':  case '7':  case '8':  case '9':
     391                 :    12030481 :         {
     392                 :    12030481 :           char *end;
     393                 :    12030481 :           unsigned long match;
     394                 :             : 
     395                 :    12030481 :           saw_match = true;
     396                 :             : 
     397                 :    12030481 :           match = strtoul (constraint + j, &end, 10);
     398                 :    12030481 :           if (match >= (unsigned long) noutputs)
     399                 :             :             {
     400                 :           4 :               error ("matching constraint references invalid operand number");
     401                 :           4 :               return false;
     402                 :             :             }
     403                 :             : 
     404                 :             :           /* Try and find the real constraint for this dup.  Only do this
     405                 :             :              if the matching constraint is the only alternative.  */
     406                 :    12030477 :           if (*end == '\0'
     407                 :    11966421 :               && (j == 0 || (j == 1 && constraint[0] == '%')))
     408                 :             :             {
     409                 :    11955132 :               constraint = constraints[match];
     410                 :    11955132 :               *constraint_p = constraint;
     411                 :    11955132 :               c_len = strlen (constraint);
     412                 :    11955132 :               j = 0;
     413                 :             :               /* ??? At the end of the loop, we will skip the first part of
     414                 :             :                  the matched constraint.  This assumes not only that the
     415                 :             :                  other constraint is an output constraint, but also that
     416                 :             :                  the '=' or '+' come first.  */
     417                 :    11955132 :               break;
     418                 :             :             }
     419                 :             :           else
     420                 :       75345 :             j = end - constraint;
     421                 :             :           /* Anticipate increment at end of loop.  */
     422                 :       75345 :           j--;
     423                 :             :         }
     424                 :             :         /* Fall through.  */
     425                 :             : 
     426                 :     2871911 :       case 'g':  case 'X':
     427                 :     2871911 :         *allows_reg = true;
     428                 :     2871911 :         *allows_mem = true;
     429                 :     2871911 :         break;
     430                 :             : 
     431                 :    18011089 :       default:
     432                 :    18011089 :         if (! ISALPHA (constraint[j]))
     433                 :             :           {
     434                 :           2 :             error ("invalid punctuation %qc in constraint", constraint[j]);
     435                 :           2 :             return false;
     436                 :             :           }
     437                 :    18011087 :         enum constraint_num cn = lookup_constraint (constraint + j);
     438                 :    18011087 :         if (reg_class_for_constraint (cn) != NO_REGS
     439                 :    18011087 :             || insn_extra_address_constraint (cn))
     440                 :    15378442 :           *allows_reg = true;
     441                 :             :         else if (insn_extra_memory_constraint (cn)
     442                 :             :                  || insn_extra_special_memory_constraint (cn)
     443                 :             :                  || insn_extra_relaxed_memory_constraint (cn))
     444                 :     2393727 :           *allows_mem = true;
     445                 :             :         else
     446                 :             :           insn_extra_constraint_allows_reg_mem (cn, allows_reg, allows_mem);
     447                 :             :         break;
     448                 :             :       }
     449                 :             : 
     450                 :    20611543 :   if (saw_match && !*allows_reg)
     451                 :           4 :     warning (0, "matching constraint does not allow a register");
     452                 :             : 
     453                 :             :   return true;
     454                 :             : }
     455                 :             : 
     456                 :             : /* Return DECL iff there's an overlap between *REGS and DECL, where DECL
     457                 :             :    can be an asm-declared register.  Called via walk_tree.  */
     458                 :             : 
     459                 :             : static tree
     460                 :      139826 : decl_overlaps_hard_reg_set_p (tree *declp, int *walk_subtrees ATTRIBUTE_UNUSED,
     461                 :             :                               void *data)
     462                 :             : {
     463                 :      139826 :   tree decl = *declp;
     464                 :      139826 :   const HARD_REG_SET *const regs = (const HARD_REG_SET *) data;
     465                 :             : 
     466                 :      139826 :   if (VAR_P (decl))
     467                 :             :     {
     468                 :       20367 :       if (DECL_HARD_REGISTER (decl)
     469                 :        1834 :           && REG_P (DECL_RTL (decl))
     470                 :       22201 :           && REGNO (DECL_RTL (decl)) < FIRST_PSEUDO_REGISTER)
     471                 :             :         {
     472                 :        1834 :           rtx reg = DECL_RTL (decl);
     473                 :             : 
     474                 :        1834 :           if (overlaps_hard_reg_set_p (*regs, GET_MODE (reg), REGNO (reg)))
     475                 :             :             return decl;
     476                 :             :         }
     477                 :             :       walk_subtrees = 0;
     478                 :             :     }
     479                 :             :   else if (TYPE_P (decl) || TREE_CODE (decl) == PARM_DECL)
     480                 :      139826 :     walk_subtrees = 0;
     481                 :             :   return NULL_TREE;
     482                 :             : }
     483                 :             : 
     484                 :             : /* If there is an overlap between *REGS and DECL, return the first overlap
     485                 :             :    found.  */
     486                 :             : tree
     487                 :      123539 : tree_overlaps_hard_reg_set (tree decl, HARD_REG_SET *regs)
     488                 :             : {
     489                 :      123539 :   return walk_tree (&decl, decl_overlaps_hard_reg_set_p, regs, NULL);
     490                 :             : }
     491                 :             : 
     492                 :             : 
     493                 :             : /* A subroutine of expand_asm_operands.  Check that all operand names
     494                 :             :    are unique.  Return true if so.  We rely on the fact that these names
     495                 :             :    are identifiers, and so have been canonicalized by get_identifier,
     496                 :             :    so all we need are pointer comparisons.  */
     497                 :             : 
     498                 :             : static bool
     499                 :      211381 : check_unique_operand_names (tree outputs, tree inputs, tree labels)
     500                 :             : {
     501                 :      211381 :   tree i, j, i_name = NULL_TREE;
     502                 :             : 
     503                 :      566903 :   for (i = outputs; i ; i = TREE_CHAIN (i))
     504                 :             :     {
     505                 :      355522 :       i_name = TREE_PURPOSE (TREE_PURPOSE (i));
     506                 :      355522 :       if (! i_name)
     507                 :      355115 :         continue;
     508                 :             : 
     509                 :        2326 :       for (j = TREE_CHAIN (i); j ; j = TREE_CHAIN (j))
     510                 :        1919 :         if (simple_cst_equal (i_name, TREE_PURPOSE (TREE_PURPOSE (j))))
     511                 :           0 :           goto failure;
     512                 :             :     }
     513                 :             : 
     514                 :      580846 :   for (i = inputs; i ; i = TREE_CHAIN (i))
     515                 :             :     {
     516                 :      369470 :       i_name = TREE_PURPOSE (TREE_PURPOSE (i));
     517                 :      369470 :       if (! i_name)
     518                 :      369336 :         continue;
     519                 :             : 
     520                 :         353 :       for (j = TREE_CHAIN (i); j ; j = TREE_CHAIN (j))
     521                 :         219 :         if (simple_cst_equal (i_name, TREE_PURPOSE (TREE_PURPOSE (j))))
     522                 :           0 :           goto failure;
     523                 :         435 :       for (j = outputs; j ; j = TREE_CHAIN (j))
     524                 :         306 :         if (simple_cst_equal (i_name, TREE_PURPOSE (TREE_PURPOSE (j))))
     525                 :           5 :           goto failure;
     526                 :             :     }
     527                 :             : 
     528                 :      212131 :   for (i = labels; i ; i = TREE_CHAIN (i))
     529                 :             :     {
     530                 :         763 :       i_name = TREE_PURPOSE (i);
     531                 :         763 :       if (! i_name)
     532                 :           0 :         continue;
     533                 :             : 
     534                 :        2101 :       for (j = TREE_CHAIN (i); j ; j = TREE_CHAIN (j))
     535                 :        1342 :         if (simple_cst_equal (i_name, TREE_PURPOSE (j)))
     536                 :           4 :           goto failure;
     537                 :        1069 :       for (j = inputs; j ; j = TREE_CHAIN (j))
     538                 :         314 :         if (simple_cst_equal (i_name, TREE_PURPOSE (TREE_PURPOSE (j))))
     539                 :           4 :           goto failure;
     540                 :             :     }
     541                 :             : 
     542                 :             :   return true;
     543                 :             : 
     544                 :          13 :  failure:
     545                 :          13 :   error ("duplicate %<asm%> operand name %qs", TREE_STRING_POINTER (i_name));
     546                 :          13 :   return false;
     547                 :             : }
     548                 :             : 
     549                 :             : /* Resolve the names of the operands in *POUTPUTS and *PINPUTS to numbers,
     550                 :             :    and replace the name expansions in STRING and in the constraints to
     551                 :             :    those numbers.  This is generally done in the front end while creating
     552                 :             :    the ASM_EXPR generic tree that eventually becomes the GIMPLE_ASM.  */
     553                 :             : 
     554                 :             : tree
     555                 :      211381 : resolve_asm_operand_names (tree string, tree outputs, tree inputs, tree labels)
     556                 :             : {
     557                 :      211381 :   char *buffer;
     558                 :      211381 :   char *p;
     559                 :      211381 :   const char *c;
     560                 :      211381 :   tree t;
     561                 :             : 
     562                 :      211381 :   check_unique_operand_names (outputs, inputs, labels);
     563                 :             : 
     564                 :             :   /* Substitute [<name>] in input constraint strings.  There should be no
     565                 :             :      named operands in output constraints.  */
     566                 :      792232 :   for (t = inputs; t ; t = TREE_CHAIN (t))
     567                 :             :     {
     568                 :      369470 :       c = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t)));
     569                 :      369470 :       if (strchr (c, '[') != NULL)
     570                 :             :         {
     571                 :         179 :           p = buffer = xstrdup (c);
     572                 :         537 :           while ((p = strchr (p, '[')) != NULL)
     573                 :         179 :             p = resolve_operand_name_1 (p, outputs, inputs, NULL);
     574                 :         179 :           TREE_VALUE (TREE_PURPOSE (t))
     575                 :         179 :             = build_string (strlen (buffer), buffer);
     576                 :         179 :           free (buffer);
     577                 :             :         }
     578                 :             :     }
     579                 :             : 
     580                 :             :   /* Now check for any needed substitutions in the template.  */
     581                 :      211381 :   c = TREE_STRING_POINTER (string);
     582                 :      251417 :   while ((c = strchr (c, '%')) != NULL)
     583                 :             :     {
     584                 :       40184 :       if (c[1] == '[')
     585                 :             :         break;
     586                 :       40126 :       else if (ISALPHA (c[1]) && c[2] == '[')
     587                 :             :         break;
     588                 :             :       else
     589                 :             :         {
     590                 :       40036 :           c += 1 + (c[1] == '%');
     591                 :       40036 :           continue;
     592                 :             :         }
     593                 :             :     }
     594                 :             : 
     595                 :      211381 :   if (c)
     596                 :             :     {
     597                 :             :       /* OK, we need to make a copy so we can perform the substitutions.
     598                 :             :          Assume that we will not need extra space--we get to remove '['
     599                 :             :          and ']', which means we cannot have a problem until we have more
     600                 :             :          than 999 operands.  */
     601                 :         148 :       buffer = xstrdup (TREE_STRING_POINTER (string));
     602                 :         148 :       p = buffer + (c - TREE_STRING_POINTER (string));
     603                 :             : 
     604                 :         448 :       while ((p = strchr (p, '%')) != NULL)
     605                 :             :         {
     606                 :         300 :           if (p[1] == '[')
     607                 :         119 :             p += 1;
     608                 :         181 :           else if (ISALPHA (p[1]) && p[2] == '[')
     609                 :         142 :             p += 2;
     610                 :             :           else
     611                 :             :             {
     612                 :          39 :               p += 1 + (p[1] == '%');
     613                 :          39 :               continue;
     614                 :             :             }
     615                 :             : 
     616                 :         261 :           p = resolve_operand_name_1 (p, outputs, inputs, labels);
     617                 :             :         }
     618                 :             : 
     619                 :         148 :       string = build_string (strlen (buffer), buffer);
     620                 :         148 :       free (buffer);
     621                 :             :     }
     622                 :             : 
     623                 :      211381 :   return string;
     624                 :             : }
     625                 :             : 
     626                 :             : /* A subroutine of resolve_operand_names.  P points to the '[' for a
     627                 :             :    potential named operand of the form [<name>].  In place, replace
     628                 :             :    the name and brackets with a number.  Return a pointer to the
     629                 :             :    balance of the string after substitution.  */
     630                 :             : 
     631                 :             : static char *
     632                 :         440 : resolve_operand_name_1 (char *p, tree outputs, tree inputs, tree labels)
     633                 :             : {
     634                 :         440 :   char *q;
     635                 :         440 :   int op, op_inout;
     636                 :         440 :   tree t;
     637                 :             : 
     638                 :             :   /* Collect the operand name.  */
     639                 :         440 :   q = strchr (++p, ']');
     640                 :         440 :   if (!q)
     641                 :             :     {
     642                 :           0 :       error ("missing close brace for named operand");
     643                 :           0 :       return strchr (p, '\0');
     644                 :             :     }
     645                 :         440 :   *q = '\0';
     646                 :             : 
     647                 :             :   /* Resolve the name to a number.  */
     648                 :        1710 :   for (op_inout = op = 0, t = outputs; t ; t = TREE_CHAIN (t), op++)
     649                 :             :     {
     650                 :        1501 :       tree name = TREE_PURPOSE (TREE_PURPOSE (t));
     651                 :        2747 :       if (name && strcmp (TREE_STRING_POINTER (name), p) == 0)
     652                 :         231 :         goto found;
     653                 :        1270 :       tree constraint = TREE_VALUE (TREE_PURPOSE (t));
     654                 :        2540 :       if (constraint && strchr (TREE_STRING_POINTER (constraint), '+') != NULL)
     655                 :          64 :         op_inout++;
     656                 :             :     }
     657                 :         373 :   for (t = inputs; t ; t = TREE_CHAIN (t), op++)
     658                 :             :     {
     659                 :         274 :       tree name = TREE_PURPOSE (TREE_PURPOSE (t));
     660                 :         447 :       if (name && strcmp (TREE_STRING_POINTER (name), p) == 0)
     661                 :         110 :         goto found;
     662                 :             :     }
     663                 :          99 :   op += op_inout;
     664                 :         108 :   for (t = labels; t ; t = TREE_CHAIN (t), op++)
     665                 :             :     {
     666                 :         105 :       tree name = TREE_PURPOSE (t);
     667                 :         210 :       if (name && strcmp (TREE_STRING_POINTER (name), p) == 0)
     668                 :          96 :         goto found;
     669                 :             :     }
     670                 :             : 
     671                 :           3 :   error ("undefined named operand %qs", identifier_to_locale (p));
     672                 :           3 :   op = 0;
     673                 :             : 
     674                 :         440 :  found:
     675                 :             :   /* Replace the name with the number.  Unfortunately, not all libraries
     676                 :             :      get the return value of sprintf correct, so search for the end of the
     677                 :             :      generated string by hand.  */
     678                 :         440 :   sprintf (--p, "%d", op);
     679                 :         440 :   p = strchr (p, '\0');
     680                 :             : 
     681                 :             :   /* Verify the no extra buffer space assumption.  */
     682                 :         440 :   gcc_assert (p <= q);
     683                 :             : 
     684                 :             :   /* Shift the rest of the buffer down to fill the gap.  */
     685                 :         440 :   memmove (p, q + 1, strlen (q + 1) + 1);
     686                 :             : 
     687                 :         440 :   return p;
     688                 :             : }
     689                 :             : 
     690                 :             : 
     691                 :             : /* Generate RTL to return directly from the current function.
     692                 :             :    (That is, we bypass any return value.)  */
     693                 :             : 
     694                 :             : void
     695                 :         378 : expand_naked_return (void)
     696                 :             : {
     697                 :         378 :   rtx_code_label *end_label;
     698                 :             : 
     699                 :         378 :   clear_pending_stack_adjust ();
     700                 :         378 :   do_pending_stack_adjust ();
     701                 :             : 
     702                 :         378 :   end_label = naked_return_label;
     703                 :         378 :   if (end_label == 0)
     704                 :         378 :     end_label = naked_return_label = gen_label_rtx ();
     705                 :             : 
     706                 :         378 :   emit_jump (end_label);
     707                 :         378 : }
     708                 :             : 
     709                 :             : /* Generate code to jump to LABEL if OP0 and OP1 are equal in mode MODE. PROB
     710                 :             :    is the probability of jumping to LABEL.  */
     711                 :             : static void
     712                 :           0 : do_jump_if_equal (machine_mode mode, rtx op0, rtx op1, rtx_code_label *label,
     713                 :             :                   int unsignedp, profile_probability prob)
     714                 :             : {
     715                 :           0 :   do_compare_rtx_and_jump (op0, op1, EQ, unsignedp, mode,
     716                 :             :                            NULL_RTX, NULL, label, prob);
     717                 :           0 : }
     718                 :             : 
     719                 :             : /* Return the sum of probabilities of outgoing edges of basic block BB.  */
     720                 :             : 
     721                 :             : static profile_probability
     722                 :        6565 : get_outgoing_edge_probs (basic_block bb)
     723                 :             : {
     724                 :        6565 :   edge e;
     725                 :        6565 :   edge_iterator ei;
     726                 :        6565 :   profile_probability prob_sum = profile_probability::never ();
     727                 :        6565 :   if (!bb)
     728                 :           0 :     return profile_probability::never ();
     729                 :       79718 :   FOR_EACH_EDGE (e, ei, bb->succs)
     730                 :       73153 :     prob_sum += e->probability;
     731                 :        6565 :   return prob_sum;
     732                 :             : }
     733                 :             : 
     734                 :             : /* Computes the conditional probability of jumping to a target if the branch
     735                 :             :    instruction is executed.
     736                 :             :    TARGET_PROB is the estimated probability of jumping to a target relative
     737                 :             :    to some basic block BB.
     738                 :             :    BASE_PROB is the probability of reaching the branch instruction relative
     739                 :             :    to the same basic block BB.  */
     740                 :             : 
     741                 :             : static inline profile_probability
     742                 :       10559 : conditional_probability (profile_probability target_prob,
     743                 :             :                          profile_probability base_prob)
     744                 :             : {
     745                 :       10559 :   return target_prob / base_prob;
     746                 :             : }
     747                 :             : 
     748                 :             : /* Generate a dispatch tabler, switching on INDEX_EXPR and jumping to
     749                 :             :    one of the labels in CASE_LIST or to the DEFAULT_LABEL.
     750                 :             :    MINVAL, MAXVAL, and RANGE are the extrema and range of the case
     751                 :             :    labels in CASE_LIST. STMT_BB is the basic block containing the statement.
     752                 :             : 
     753                 :             :    First, a jump insn is emitted.  First we try "casesi".  If that
     754                 :             :    fails, try "tablejump".   A target *must* have one of them (or both).
     755                 :             : 
     756                 :             :    Then, a table with the target labels is emitted.
     757                 :             : 
     758                 :             :    The process is unaware of the CFG.  The caller has to fix up
     759                 :             :    the CFG itself.  This is done in cfgexpand.cc.  */
     760                 :             : 
     761                 :             : static void
     762                 :        6565 : emit_case_dispatch_table (tree index_expr, tree index_type,
     763                 :             :                           auto_vec<simple_case_node> &case_list,
     764                 :             :                           rtx default_label,
     765                 :             :                           edge default_edge,  tree minval, tree maxval,
     766                 :             :                           tree range, basic_block stmt_bb)
     767                 :             : {
     768                 :        6565 :   int i, ncases;
     769                 :        6565 :   auto_vec<rtx> labelvec;
     770                 :        6565 :   rtx_insn *fallback_label = label_rtx (case_list[0].m_code_label);
     771                 :        6565 :   rtx_code_label *table_label = gen_label_rtx ();
     772                 :        6565 :   bool has_gaps = false;
     773                 :        6565 :   profile_probability default_prob = default_edge ? default_edge->probability
     774                 :        6565 :                                                   : profile_probability::never ();
     775                 :        6565 :   profile_probability base = get_outgoing_edge_probs (stmt_bb);
     776                 :        6565 :   bool try_with_tablejump = false;
     777                 :             : 
     778                 :        6565 :   profile_probability new_default_prob = conditional_probability (default_prob,
     779                 :             :                                                                   base);
     780                 :             : 
     781                 :        6565 :   if (! try_casesi (index_type, index_expr, minval, range,
     782                 :             :                     table_label, default_label, fallback_label,
     783                 :             :                     new_default_prob))
     784                 :             :     {
     785                 :             :       /* Index jumptables from zero for suitable values of minval to avoid
     786                 :             :          a subtraction.  For the rationale see:
     787                 :             :          "http://gcc.gnu.org/ml/gcc-patches/2001-10/msg01234.html".  */
     788                 :        6565 :       if (optimize_insn_for_speed_p ()
     789                 :        6341 :           && compare_tree_int (minval, 0) > 0
     790                 :        9919 :           && compare_tree_int (minval, 3) < 0)
     791                 :             :         {
     792                 :        1058 :           minval = build_int_cst (index_type, 0);
     793                 :        1058 :           range = maxval;
     794                 :        1058 :           has_gaps = true;
     795                 :             :         }
     796                 :             :       try_with_tablejump = true;
     797                 :             :     }
     798                 :             : 
     799                 :             :   /* Get table of labels to jump to, in order of case index.  */
     800                 :             : 
     801                 :        6565 :   ncases = tree_to_shwi (range) + 1;
     802                 :        6565 :   labelvec.safe_grow_cleared (ncases);
     803                 :             : 
     804                 :       82269 :   for (unsigned j = 0; j < case_list.length (); j++)
     805                 :             :     {
     806                 :       75704 :       simple_case_node *n = &case_list[j];
     807                 :             :       /* Compute the low and high bounds relative to the minimum
     808                 :             :          value since that should fit in a HOST_WIDE_INT while the
     809                 :             :          actual values may not.  */
     810                 :       75704 :       HOST_WIDE_INT i_low
     811                 :       75704 :         = tree_to_uhwi (fold_build2 (MINUS_EXPR, index_type,
     812                 :       75704 :                                      n->m_low, minval));
     813                 :       75704 :       HOST_WIDE_INT i_high
     814                 :       75704 :         = tree_to_uhwi (fold_build2 (MINUS_EXPR, index_type,
     815                 :       75704 :                                      n->m_high, minval));
     816                 :       75704 :       HOST_WIDE_INT i;
     817                 :             : 
     818                 :      160425 :       for (i = i_low; i <= i_high; i ++)
     819                 :      254163 :         labelvec[i]
     820                 :       84721 :           = gen_rtx_LABEL_REF (Pmode, label_rtx (n->m_code_label));
     821                 :             :     }
     822                 :             : 
     823                 :             :   /* The dispatch table may contain gaps, including at the beginning of
     824                 :             :      the table if we tried to avoid the minval subtraction.  We fill the
     825                 :             :      dispatch table slots associated with the gaps with the default case label.
     826                 :             :      However, in the event the default case is unreachable, we then use
     827                 :             :      any label from one of the case statements.  */
     828                 :        6565 :   rtx gap_label = (default_label) ? default_label : fallback_label;
     829                 :             : 
     830                 :      173287 :   for (i = 0; i < ncases; i++)
     831                 :      166722 :     if (labelvec[i] == 0)
     832                 :             :       {
     833                 :       82001 :         has_gaps = true;
     834                 :       82001 :         labelvec[i] = gen_rtx_LABEL_REF (Pmode, gap_label);
     835                 :             :       }
     836                 :             : 
     837                 :        6565 :   if (has_gaps && default_label)
     838                 :             :     {
     839                 :             :       /* There is at least one entry in the jump table that jumps
     840                 :             :          to default label. The default label can either be reached
     841                 :             :          through the indirect jump or the direct conditional jump
     842                 :             :          before that. Split the probability of reaching the
     843                 :             :          default label among these two jumps.  */
     844                 :        3994 :       new_default_prob = conditional_probability (default_prob / 2, base);
     845                 :        3994 :       default_prob /= 2;
     846                 :        3994 :       base -= default_prob;
     847                 :             :     }
     848                 :             :   else
     849                 :             :     {
     850                 :        2571 :       base -= default_prob;
     851                 :        2571 :       default_prob = profile_probability::never ();
     852                 :             :     }
     853                 :             : 
     854                 :        6565 :   if (default_edge)
     855                 :        5516 :     default_edge->probability = default_prob;
     856                 :             : 
     857                 :             :   /* We have altered the probability of the default edge. So the probabilities
     858                 :             :      of all other edges need to be adjusted so that it sums up to
     859                 :             :      REG_BR_PROB_BASE.  */
     860                 :        6565 :   if (base > profile_probability::never ())
     861                 :             :     {
     862                 :        6565 :       edge e;
     863                 :        6565 :       edge_iterator ei;
     864                 :       79718 :       FOR_EACH_EDGE (e, ei, stmt_bb->succs)
     865                 :       73153 :         e->probability /= base;
     866                 :             :     }
     867                 :             : 
     868                 :        6565 :   if (try_with_tablejump)
     869                 :             :     {
     870                 :        6565 :       bool ok = try_tablejump (index_type, index_expr, minval, range,
     871                 :             :                                table_label, default_label, new_default_prob);
     872                 :        6565 :       gcc_assert (ok);
     873                 :             :     }
     874                 :             :   /* Output the table.  */
     875                 :        6565 :   emit_label (table_label);
     876                 :             : 
     877                 :        6565 :   if (CASE_VECTOR_PC_RELATIVE
     878                 :        6565 :           || (flag_pic && targetm.asm_out.generate_pic_addr_diff_vec ()))
     879                 :        3171 :     emit_jump_table_data (gen_rtx_ADDR_DIFF_VEC (CASE_VECTOR_MODE,
     880                 :             :                                                  gen_rtx_LABEL_REF (Pmode,
     881                 :             :                                                                     table_label),
     882                 :             :                                                  gen_rtvec_v (ncases, labelvec.address ()),
     883                 :             :                                                  const0_rtx, const0_rtx));
     884                 :             :   else
     885                 :       11551 :     emit_jump_table_data (gen_rtx_ADDR_VEC (CASE_VECTOR_MODE,
     886                 :             :                                             gen_rtvec_v (ncases, labelvec.address ())));
     887                 :             : 
     888                 :             :   /* Record no drop-through after the table.  */
     889                 :        6565 :   emit_barrier ();
     890                 :        6565 : }
     891                 :             : 
     892                 :             : /* Terminate a case Ada or switch (C) statement
     893                 :             :    in which ORIG_INDEX is the expression to be tested.
     894                 :             :    If ORIG_TYPE is not NULL, it is the original ORIG_INDEX
     895                 :             :    type as given in the source before any compiler conversions.
     896                 :             :    Generate the code to test it and jump to the right place.  */
     897                 :             : 
     898                 :             : void
     899                 :        6565 : expand_case (gswitch *stmt)
     900                 :             : {
     901                 :        6565 :   tree minval = NULL_TREE, maxval = NULL_TREE, range = NULL_TREE;
     902                 :        6565 :   rtx_code_label *default_label;
     903                 :        6565 :   unsigned int count;
     904                 :        6565 :   int i;
     905                 :        6565 :   int ncases = gimple_switch_num_labels (stmt);
     906                 :        6565 :   tree index_expr = gimple_switch_index (stmt);
     907                 :        6565 :   tree index_type = TREE_TYPE (index_expr);
     908                 :        6565 :   tree elt;
     909                 :        6565 :   basic_block bb = gimple_bb (stmt);
     910                 :        6565 :   gimple *def_stmt;
     911                 :             : 
     912                 :        6565 :   auto_vec<simple_case_node> case_list;
     913                 :             : 
     914                 :             :   /* An ERROR_MARK occurs for various reasons including invalid data type.
     915                 :             :      ??? Can this still happen, with GIMPLE and all?  */
     916                 :        6565 :   if (index_type == error_mark_node)
     917                 :           0 :     return;
     918                 :             : 
     919                 :             :   /* cleanup_tree_cfg removes all SWITCH_EXPR with their index
     920                 :             :      expressions being INTEGER_CST.  */
     921                 :        6565 :   gcc_assert (TREE_CODE (index_expr) != INTEGER_CST);
     922                 :             : 
     923                 :             :   /* Optimization of switch statements with only one label has already
     924                 :             :      occurred, so we should never see them at this point.  */
     925                 :        6565 :   gcc_assert (ncases > 1);
     926                 :             : 
     927                 :        6565 :   do_pending_stack_adjust ();
     928                 :             : 
     929                 :             :   /* Find the default case target label.  */
     930                 :        6565 :   tree default_lab = CASE_LABEL (gimple_switch_default_label (stmt));
     931                 :        6565 :   default_label = jump_target_rtx (default_lab);
     932                 :        6565 :   basic_block default_bb = label_to_block (cfun, default_lab);
     933                 :        6565 :   edge default_edge = find_edge (bb, default_bb);
     934                 :             : 
     935                 :             :   /* Get upper and lower bounds of case values.  */
     936                 :        6565 :   elt = gimple_switch_label (stmt, 1);
     937                 :        6565 :   minval = fold_convert (index_type, CASE_LOW (elt));
     938                 :        6565 :   elt = gimple_switch_label (stmt, ncases - 1);
     939                 :        6565 :   if (CASE_HIGH (elt))
     940                 :         139 :     maxval = fold_convert (index_type, CASE_HIGH (elt));
     941                 :             :   else
     942                 :        6426 :     maxval = fold_convert (index_type, CASE_LOW (elt));
     943                 :             : 
     944                 :             :   /* Try to narrow the index type if it's larger than a word.
     945                 :             :      That is mainly for -O0 where an equivalent optimization
     946                 :             :      done by forward propagation is not run and is aimed at
     947                 :             :      avoiding a call to a comparison routine of libgcc.  */
     948                 :        6565 :   if (TYPE_PRECISION (index_type) > BITS_PER_WORD
     949                 :           6 :       && TREE_CODE (index_expr) == SSA_NAME
     950                 :           6 :       && (def_stmt = SSA_NAME_DEF_STMT (index_expr))
     951                 :           6 :       && is_gimple_assign (def_stmt)
     952                 :        6568 :       && gimple_assign_rhs_code (def_stmt) == NOP_EXPR)
     953                 :             :     {
     954                 :           0 :       tree inner_index_expr = gimple_assign_rhs1 (def_stmt);
     955                 :           0 :       tree inner_index_type = TREE_TYPE (inner_index_expr);
     956                 :             : 
     957                 :           0 :       if (INTEGRAL_TYPE_P (inner_index_type)
     958                 :           0 :           && TYPE_PRECISION (inner_index_type) <= BITS_PER_WORD
     959                 :           0 :           && int_fits_type_p (minval, inner_index_type)
     960                 :           0 :           && int_fits_type_p (maxval, inner_index_type))
     961                 :             :         {
     962                 :           0 :           index_expr = inner_index_expr;
     963                 :           0 :           index_type = inner_index_type;
     964                 :           0 :           minval = fold_convert (index_type, minval);
     965                 :           0 :           maxval = fold_convert (index_type, maxval);
     966                 :             :         }
     967                 :             :     }
     968                 :             : 
     969                 :             :   /* Compute span of values.  */
     970                 :        6565 :   range = fold_build2 (MINUS_EXPR, index_type, maxval, minval);
     971                 :             : 
     972                 :             :   /* Listify the labels queue and gather some numbers to decide
     973                 :             :      how to expand this switch().  */
     974                 :        6565 :   count = 0;
     975                 :             : 
     976                 :       82269 :   for (i = ncases - 1; i >= 1; --i)
     977                 :             :     {
     978                 :       75704 :       elt = gimple_switch_label (stmt, i);
     979                 :       75704 :       tree low = CASE_LOW (elt);
     980                 :       75704 :       gcc_assert (low);
     981                 :       75704 :       tree high = CASE_HIGH (elt);
     982                 :       75704 :       gcc_assert (! high || tree_int_cst_lt (low, high));
     983                 :       75704 :       tree lab = CASE_LABEL (elt);
     984                 :             : 
     985                 :             :       /* Count the elements.
     986                 :             :          A range counts double, since it requires two compares.  */
     987                 :       75704 :       count++;
     988                 :       75704 :       if (high)
     989                 :        3852 :         count++;
     990                 :             : 
     991                 :             :       /* The bounds on the case range, LOW and HIGH, have to be converted
     992                 :             :          to case's index type TYPE.  Note that the original type of the
     993                 :             :          case index in the source code is usually "lost" during
     994                 :             :          gimplification due to type promotion, but the case labels retain the
     995                 :             :          original type.  Make sure to drop overflow flags.  */
     996                 :       75704 :       low = fold_convert (index_type, low);
     997                 :       75704 :       if (TREE_OVERFLOW (low))
     998                 :           0 :         low = wide_int_to_tree (index_type, wi::to_wide (low));
     999                 :             : 
    1000                 :             :       /* The canonical from of a case label in GIMPLE is that a simple case
    1001                 :             :          has an empty CASE_HIGH.  For the casesi and tablejump expanders,
    1002                 :             :          the back ends want simple cases to have high == low.  */
    1003                 :       75704 :       if (! high)
    1004                 :       71852 :         high = low;
    1005                 :       75704 :       high = fold_convert (index_type, high);
    1006                 :       75704 :       if (TREE_OVERFLOW (high))
    1007                 :           0 :         high = wide_int_to_tree (index_type, wi::to_wide (high));
    1008                 :             : 
    1009                 :       75704 :       case_list.safe_push (simple_case_node (low, high, lab));
    1010                 :             :     }
    1011                 :             : 
    1012                 :             :   /* cleanup_tree_cfg removes all SWITCH_EXPR with a single
    1013                 :             :      destination, such as one with a default case only.
    1014                 :             :      It also removes cases that are out of range for the switch
    1015                 :             :      type, so we should never get a zero here.  */
    1016                 :        6565 :   gcc_assert (count > 0);
    1017                 :             : 
    1018                 :        6565 :   rtx_insn *before_case = get_last_insn ();
    1019                 :             : 
    1020                 :             :   /* If the default case is unreachable, then set default_label to NULL
    1021                 :             :      so that we omit the range check when generating the dispatch table.
    1022                 :             :      We also remove the edge to the unreachable default case.  The block
    1023                 :             :      itself will be automatically removed later.  */
    1024                 :        6565 :   if (EDGE_COUNT (default_edge->dest->succs) == 0
    1025                 :        8337 :       && gimple_seq_unreachable_p (bb_seq (default_edge->dest)))
    1026                 :             :     {
    1027                 :        1049 :       default_label = NULL;
    1028                 :        1049 :       remove_edge (default_edge);
    1029                 :        1049 :       default_edge = NULL;
    1030                 :             :     }
    1031                 :             : 
    1032                 :        6565 :   emit_case_dispatch_table (index_expr, index_type,
    1033                 :             :                             case_list, default_label, default_edge,
    1034                 :             :                             minval, maxval, range, bb);
    1035                 :             : 
    1036                 :        6565 :   reorder_insns (NEXT_INSN (before_case), get_last_insn (), before_case);
    1037                 :             : 
    1038                 :        6565 :   free_temp_slots ();
    1039                 :        6565 : }
    1040                 :             : 
    1041                 :             : /* Expand the dispatch to a short decrement chain if there are few cases
    1042                 :             :    to dispatch to.  Likewise if neither casesi nor tablejump is available,
    1043                 :             :    or if flag_jump_tables is set.  Otherwise, expand as a casesi or a
    1044                 :             :    tablejump.  The index mode is always the mode of integer_type_node.
    1045                 :             :    Trap if no case matches the index.
    1046                 :             : 
    1047                 :             :    DISPATCH_INDEX is the index expression to switch on.  It should be a
    1048                 :             :    memory or register operand.
    1049                 :             : 
    1050                 :             :    DISPATCH_TABLE is a set of case labels.  The set should be sorted in
    1051                 :             :    ascending order, be contiguous, starting with value 0, and contain only
    1052                 :             :    single-valued case labels.  */
    1053                 :             : 
    1054                 :             : void
    1055                 :           0 : expand_sjlj_dispatch_table (rtx dispatch_index,
    1056                 :             :                             vec<tree> dispatch_table)
    1057                 :             : {
    1058                 :           0 :   tree index_type = integer_type_node;
    1059                 :           0 :   machine_mode index_mode = TYPE_MODE (index_type);
    1060                 :             : 
    1061                 :           0 :   int ncases = dispatch_table.length ();
    1062                 :             : 
    1063                 :           0 :   do_pending_stack_adjust ();
    1064                 :           0 :   rtx_insn *before_case = get_last_insn ();
    1065                 :             : 
    1066                 :             :   /* Expand as a decrement-chain if there are 5 or fewer dispatch
    1067                 :             :      labels.  This covers more than 98% of the cases in libjava,
    1068                 :             :      and seems to be a reasonable compromise between the "old way"
    1069                 :             :      of expanding as a decision tree or dispatch table vs. the "new
    1070                 :             :      way" with decrement chain or dispatch table.  */
    1071                 :           0 :   if (dispatch_table.length () <= 5
    1072                 :           0 :       || (!targetm.have_casesi () && !targetm.have_tablejump ())
    1073                 :           0 :       || !flag_jump_tables)
    1074                 :             :     {
    1075                 :             :       /* Expand the dispatch as a decrement chain:
    1076                 :             : 
    1077                 :             :          "switch(index) {case 0: do_0; case 1: do_1; ...; case N: do_N;}"
    1078                 :             : 
    1079                 :             :          ==>
    1080                 :             : 
    1081                 :             :          if (index == 0) do_0; else index--;
    1082                 :             :          if (index == 0) do_1; else index--;
    1083                 :             :          ...
    1084                 :             :          if (index == 0) do_N; else index--;
    1085                 :             : 
    1086                 :             :          This is more efficient than a dispatch table on most machines.
    1087                 :             :          The last "index--" is redundant but the code is trivially dead
    1088                 :             :          and will be cleaned up by later passes.  */
    1089                 :           0 :       rtx index = copy_to_mode_reg (index_mode, dispatch_index);
    1090                 :           0 :       rtx zero = CONST0_RTX (index_mode);
    1091                 :           0 :       for (int i = 0; i < ncases; i++)
    1092                 :             :         {
    1093                 :           0 :           tree elt = dispatch_table[i];
    1094                 :           0 :           rtx_code_label *lab = jump_target_rtx (CASE_LABEL (elt));
    1095                 :           0 :           do_jump_if_equal (index_mode, index, zero, lab, 0,
    1096                 :             :                             profile_probability::uninitialized ());
    1097                 :           0 :           force_expand_binop (index_mode, sub_optab,
    1098                 :             :                               index, CONST1_RTX (index_mode),
    1099                 :             :                               index, 0, OPTAB_DIRECT);
    1100                 :             :         }
    1101                 :             :     }
    1102                 :             :   else
    1103                 :             :     {
    1104                 :             :       /* Similar to expand_case, but much simpler.  */
    1105                 :           0 :       auto_vec<simple_case_node> case_list;
    1106                 :           0 :       tree index_expr = make_tree (index_type, dispatch_index);
    1107                 :           0 :       tree minval = build_int_cst (index_type, 0);
    1108                 :           0 :       tree maxval = CASE_LOW (dispatch_table.last ());
    1109                 :           0 :       tree range = maxval;
    1110                 :           0 :       rtx_code_label *default_label = gen_label_rtx ();
    1111                 :             : 
    1112                 :           0 :       for (int i = ncases - 1; i >= 0; --i)
    1113                 :             :         {
    1114                 :           0 :           tree elt = dispatch_table[i];
    1115                 :           0 :           tree high = CASE_HIGH (elt);
    1116                 :           0 :           if (high == NULL_TREE)
    1117                 :           0 :             high = CASE_LOW (elt);
    1118                 :           0 :           case_list.safe_push (simple_case_node (CASE_LOW (elt), high,
    1119                 :           0 :                                                  CASE_LABEL (elt)));
    1120                 :             :         }
    1121                 :             : 
    1122                 :           0 :       emit_case_dispatch_table (index_expr, index_type,
    1123                 :             :                                 case_list, default_label, NULL,
    1124                 :             :                                 minval, maxval, range,
    1125                 :           0 :                                 BLOCK_FOR_INSN (before_case));
    1126                 :           0 :       emit_label (default_label);
    1127                 :           0 :     }
    1128                 :             : 
    1129                 :             :   /* Dispatching something not handled?  Trap!  */
    1130                 :           0 :   expand_builtin_trap ();
    1131                 :             : 
    1132                 :           0 :   reorder_insns (NEXT_INSN (before_case), get_last_insn (), before_case);
    1133                 :             : 
    1134                 :           0 :   free_temp_slots ();
    1135                 :           0 : }
    1136                 :             : 
    1137                 :             : 
        

Generated by: LCOV version 2.1-beta

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