LCOV - code coverage report
Current view: top level - gcc - stmt.c (source / functions) Hit Total Coverage
Test: gcc.info Lines: 366 457 80.1 %
Date: 2020-04-04 11:58:09 Functions: 15 18 83.3 %
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-2020 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.c.
      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                 :      87033 :   simple_case_node (tree low, tree high, tree code_label):
      74                 :      87033 :     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                 :    1750080 : label_rtx (tree label)
      93                 :            : {
      94                 :    1750080 :   gcc_assert (TREE_CODE (label) == LABEL_DECL);
      95                 :            : 
      96                 :    1750080 :   if (!DECL_RTL_SET_P (label))
      97                 :            :     {
      98                 :     377175 :       rtx_code_label *r = gen_label_rtx ();
      99                 :     377175 :       SET_DECL_RTL (label, r);
     100                 :     744063 :       if (FORCED_LABEL (label) || DECL_NONLOCAL (label))
     101                 :      10790 :         LABEL_PRESERVE_P (r) = 1;
     102                 :            :     }
     103                 :            : 
     104                 :    1750080 :   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                 :     506599 : jump_target_rtx (tree label)
     125                 :            : {
     126                 :     506599 :   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                 :    1989770 : emit_jump (rtx label)
     133                 :            : {
     134                 :    1989770 :   do_pending_stack_adjust ();
     135                 :    1989770 :   emit_jump_insn (targetm.gen_jump (label));
     136                 :    1989770 :   emit_barrier ();
     137                 :    1989770 : }
     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                 :     377175 : expand_label (tree label)
     154                 :            : {
     155                 :     377175 :   rtx_code_label *label_r = jump_target_rtx (label);
     156                 :            : 
     157                 :     377175 :   do_pending_stack_adjust ();
     158                 :     377175 :   emit_label (label_r);
     159                 :     377175 :   if (DECL_NAME (label))
     160                 :      17955 :     LABEL_NAME (DECL_RTL (label)) = IDENTIFIER_POINTER (DECL_NAME (label));
     161                 :            : 
     162                 :     377175 :   if (DECL_NONLOCAL (label))
     163                 :            :     {
     164                 :        503 :       expand_builtin_setjmp_receiver (NULL);
     165                 :        503 :       nonlocal_goto_handler_labels
     166                 :        503 :         = gen_rtx_INSN_LIST (VOIDmode, label_r,
     167                 :        503 :                              nonlocal_goto_handler_labels);
     168                 :            :     }
     169                 :            : 
     170                 :     377175 :   if (FORCED_LABEL (label))
     171                 :       9501 :     vec_safe_push<rtx_insn *> (forced_labels, label_r);
     172                 :            : 
     173                 :     753847 :   if (DECL_NONLOCAL (label) || FORCED_LABEL (label))
     174                 :      10004 :     maybe_set_first_label_num (label_r);
     175                 :     377175 : }
     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                 :   30391000 : 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                 :   30391000 :   const char *constraint = *constraint_p;
     196                 :   30391000 :   const char *p;
     197                 :            : 
     198                 :            :   /* Assume the constraint doesn't allow the use of either a register
     199                 :            :      or memory.  */
     200                 :   30391000 :   *allows_mem = false;
     201                 :   30391000 :   *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                 :   30391000 :   p = strchr (constraint, '=');
     208                 :   30391000 :   if (!p)
     209                 :      19238 :     p = strchr (constraint, '+');
     210                 :            : 
     211                 :            :   /* If the string doesn't contain an `=', issue an error
     212                 :            :      message.  */
     213                 :   30391000 :   if (!p)
     214                 :            :     {
     215                 :         14 :       error ("output operand constraint lacks %<=%>");
     216                 :         14 :       return false;
     217                 :            :     }
     218                 :            : 
     219                 :            :   /* If the constraint begins with `+', then the operand is both read
     220                 :            :      from and written to.  */
     221                 :   30391000 :   *is_inout = (*p == '+');
     222                 :            : 
     223                 :            :   /* Canonicalize the output constraint so that it begins with `='.  */
     224                 :   30391000 :   if (p != constraint || *is_inout)
     225                 :            :     {
     226                 :      19224 :       char *buf;
     227                 :      19224 :       size_t c_len = strlen (constraint);
     228                 :            : 
     229                 :      19224 :       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                 :      19224 :       buf = XALLOCAVEC (char, c_len + 1);
     236                 :      19224 :       strcpy (buf, constraint);
     237                 :            :       /* Swap the first character and the `=' or `+'.  */
     238                 :      19224 :       buf[p - constraint] = buf[0];
     239                 :            :       /* Make sure the first character is an `='.  (Until we do this,
     240                 :            :          it might be a `+'.)  */
     241                 :      19224 :       buf[0] = '=';
     242                 :            :       /* Replace the constraint with the canonicalized string.  */
     243                 :      19224 :       *constraint_p = ggc_alloc_string (buf, c_len);
     244                 :      19224 :       constraint = *constraint_p;
     245                 :            :     }
     246                 :            : 
     247                 :            :   /* Loop through the constraint string.  */
     248                 :   61363800 :   for (p = constraint + 1; *p; )
     249                 :            :     {
     250                 :   30972800 :       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                 :          0 :         case '%':
     259                 :          0 :           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 ',':
     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                 :          0 :         case '<':  case '>':
     281                 :            :           /* ??? Before flow, auto inc/dec insns are not supposed to exist,
     282                 :            :              excepting those that expand_call created.  So match memory
     283                 :            :              and hope.  */
     284                 :          0 :           *allows_mem = true;
     285                 :          0 :           break;
     286                 :            : 
     287                 :    2727340 :         case 'g':  case 'X':
     288                 :    2727340 :           *allows_reg = true;
     289                 :    2727340 :           *allows_mem = true;
     290                 :    2727340 :           break;
     291                 :            : 
     292                 :   27791100 :         default:
     293                 :   27791100 :           if (!ISALPHA (*p))
     294                 :            :             break;
     295                 :   27775400 :           enum constraint_num cn = lookup_constraint (p);
     296                 :   27775400 :           if (reg_class_for_constraint (cn) != NO_REGS
     297                 :   27775400 :               || insn_extra_address_constraint (cn))
     298                 :   27402300 :             *allows_reg = true;
     299                 :     373127 :           else if (insn_extra_memory_constraint (cn))
     300                 :     366921 :             *allows_mem = true;
     301                 :            :           else
     302                 :       6206 :             insn_extra_constraint_allows_reg_mem (cn, allows_reg, allows_mem);
     303                 :            :           break;
     304                 :            :         }
     305                 :            : 
     306                 :   92931000 :       for (size_t len = CONSTRAINT_LEN (*p, p); len; len--, p++)
     307                 :   30985800 :         if (*p == '\0')
     308                 :            :           break;
     309                 :            :     }
     310                 :            : 
     311                 :            :   return true;
     312                 :            : }
     313                 :            : 
     314                 :            : /* Similar, but for input constraints.  */
     315                 :            : 
     316                 :            : bool
     317                 :   17251400 : parse_input_constraint (const char **constraint_p, int input_num,
     318                 :            :                         int ninputs, int noutputs, int ninout,
     319                 :            :                         const char * const * constraints,
     320                 :            :                         bool *allows_mem, bool *allows_reg)
     321                 :            : {
     322                 :   17251400 :   const char *constraint = *constraint_p;
     323                 :   17251400 :   const char *orig_constraint = constraint;
     324                 :   17251400 :   size_t c_len = strlen (constraint);
     325                 :   17251400 :   size_t j;
     326                 :   17251400 :   bool saw_match = false;
     327                 :            : 
     328                 :            :   /* Assume the constraint doesn't allow the use of either
     329                 :            :      a register or memory.  */
     330                 :   17251400 :   *allows_mem = false;
     331                 :   17251400 :   *allows_reg = false;
     332                 :            : 
     333                 :            :   /* Make sure constraint has neither `=', `+', nor '&'.  */
     334                 :            : 
     335                 :   47341900 :   for (j = 0; j < c_len; j += CONSTRAINT_LEN (constraint[j], constraint+j))
     336                 :   30090500 :     switch (constraint[j])
     337                 :            :       {
     338                 :     344828 :       case '+':  case '=':  case '&':
     339                 :     344828 :         if (constraint == orig_constraint)
     340                 :            :           {
     341                 :          0 :             error ("input operand constraint contains %qc", constraint[j]);
     342                 :          0 :             return false;
     343                 :            :           }
     344                 :            :         break;
     345                 :            : 
     346                 :     270823 :       case '%':
     347                 :     270823 :         if (constraint == orig_constraint
     348                 :     270823 :             && input_num + 1 == ninputs - ninout)
     349                 :            :           {
     350                 :          0 :             error ("%<%%%> constraint used with last operand");
     351                 :          0 :             return false;
     352                 :            :           }
     353                 :            :         break;
     354                 :            : 
     355                 :            :       case '<':  case '>':
     356                 :            :       case '?':  case '!':  case '*':  case '#':
     357                 :            :       case '$':  case '^':
     358                 :            :       case 'E':  case 'F':  case 'G':  case 'H':
     359                 :            :       case 's':  case 'i':  case 'n':
     360                 :            :       case 'I':  case 'J':  case 'K':  case 'L':  case 'M':
     361                 :            :       case 'N':  case 'O':  case 'P':  case ',':
     362                 :            :         break;
     363                 :            : 
     364                 :            :         /* Whether or not a numeric constraint allows a register is
     365                 :            :            decided by the matching constraint, and so there is no need
     366                 :            :            to do anything special with them.  We must handle them in
     367                 :            :            the default case, so that we don't unnecessarily force
     368                 :            :            operands to memory.  */
     369                 :   11633400 :       case '0':  case '1':  case '2':  case '3':  case '4':
     370                 :   11633400 :       case '5':  case '6':  case '7':  case '8':  case '9':
     371                 :   11633400 :         {
     372                 :   11633400 :           char *end;
     373                 :   11633400 :           unsigned long match;
     374                 :            : 
     375                 :   11633400 :           saw_match = true;
     376                 :            : 
     377                 :   11633400 :           match = strtoul (constraint + j, &end, 10);
     378                 :   11633400 :           if (match >= (unsigned long) noutputs)
     379                 :            :             {
     380                 :          0 :               error ("matching constraint references invalid operand number");
     381                 :          0 :               return false;
     382                 :            :             }
     383                 :            : 
     384                 :            :           /* Try and find the real constraint for this dup.  Only do this
     385                 :            :              if the matching constraint is the only alternative.  */
     386                 :   11633400 :           if (*end == '\0'
     387                 :   11576800 :               && (j == 0 || (j == 1 && constraint[0] == '%')))
     388                 :            :             {
     389                 :   11566700 :               constraint = constraints[match];
     390                 :   11566700 :               *constraint_p = constraint;
     391                 :   11566700 :               c_len = strlen (constraint);
     392                 :   11566700 :               j = 0;
     393                 :            :               /* ??? At the end of the loop, we will skip the first part of
     394                 :            :                  the matched constraint.  This assumes not only that the
     395                 :            :                  other constraint is an output constraint, but also that
     396                 :            :                  the '=' or '+' come first.  */
     397                 :   11566700 :               break;
     398                 :            :             }
     399                 :            :           else
     400                 :      66736 :             j = end - constraint;
     401                 :            :           /* Anticipate increment at end of loop.  */
     402                 :      66736 :           j--;
     403                 :            :         }
     404                 :            :         /* Fall through.  */
     405                 :            : 
     406                 :    3528640 :       case 'g':  case 'X':
     407                 :    3528640 :         *allows_reg = true;
     408                 :    3528640 :         *allows_mem = true;
     409                 :    3528640 :         break;
     410                 :            : 
     411                 :   14188300 :       default:
     412                 :   14188300 :         if (! ISALPHA (constraint[j]))
     413                 :            :           {
     414                 :          2 :             error ("invalid punctuation %qc in constraint", constraint[j]);
     415                 :          2 :             return false;
     416                 :            :           }
     417                 :   14188300 :         enum constraint_num cn = lookup_constraint (constraint + j);
     418                 :   14188300 :         if (reg_class_for_constraint (cn) != NO_REGS
     419                 :   14188300 :             || insn_extra_address_constraint (cn))
     420                 :   13088700 :           *allows_reg = true;
     421                 :    1099570 :         else if (insn_extra_memory_constraint (cn)
     422                 :    1099570 :                  || insn_extra_special_memory_constraint (cn))
     423                 :     924316 :           *allows_mem = true;
     424                 :            :         else
     425                 :   30090500 :           insn_extra_constraint_allows_reg_mem (cn, allows_reg, allows_mem);
     426                 :            :         break;
     427                 :            :       }
     428                 :            : 
     429                 :   17251400 :   if (saw_match && !*allows_reg)
     430                 :          0 :     warning (0, "matching constraint does not allow a register");
     431                 :            : 
     432                 :            :   return true;
     433                 :            : }
     434                 :            : 
     435                 :            : /* Return DECL iff there's an overlap between *REGS and DECL, where DECL
     436                 :            :    can be an asm-declared register.  Called via walk_tree.  */
     437                 :            : 
     438                 :            : static tree
     439                 :     128265 : decl_overlaps_hard_reg_set_p (tree *declp, int *walk_subtrees ATTRIBUTE_UNUSED,
     440                 :            :                               void *data)
     441                 :            : {
     442                 :     128265 :   tree decl = *declp;
     443                 :     128265 :   const HARD_REG_SET *const regs = (const HARD_REG_SET *) data;
     444                 :            : 
     445                 :     128265 :   if (VAR_P (decl))
     446                 :            :     {
     447                 :       9402 :       if (DECL_HARD_REGISTER (decl)
     448                 :       1305 :           && REG_P (DECL_RTL (decl))
     449                 :      10707 :           && REGNO (DECL_RTL (decl)) < FIRST_PSEUDO_REGISTER)
     450                 :            :         {
     451                 :       1305 :           rtx reg = DECL_RTL (decl);
     452                 :            : 
     453                 :       2589 :           if (overlaps_hard_reg_set_p (*regs, GET_MODE (reg), REGNO (reg)))
     454                 :         21 :             return decl;
     455                 :            :         }
     456                 :            :       walk_subtrees = 0;
     457                 :            :     }
     458                 :            :   else if (TYPE_P (decl) || TREE_CODE (decl) == PARM_DECL)
     459                 :     128265 :     walk_subtrees = 0;
     460                 :            :   return NULL_TREE;
     461                 :            : }
     462                 :            : 
     463                 :            : /* If there is an overlap between *REGS and DECL, return the first overlap
     464                 :            :    found.  */
     465                 :            : tree
     466                 :     115538 : tree_overlaps_hard_reg_set (tree decl, HARD_REG_SET *regs)
     467                 :            : {
     468                 :     115538 :   return walk_tree (&decl, decl_overlaps_hard_reg_set_p, regs, NULL);
     469                 :            : }
     470                 :            : 
     471                 :            : 
     472                 :            : /* A subroutine of expand_asm_operands.  Check that all operand names
     473                 :            :    are unique.  Return true if so.  We rely on the fact that these names
     474                 :            :    are identifiers, and so have been canonicalized by get_identifier,
     475                 :            :    so all we need are pointer comparisons.  */
     476                 :            : 
     477                 :            : static bool
     478                 :     171989 : check_unique_operand_names (tree outputs, tree inputs, tree labels)
     479                 :            : {
     480                 :     171989 :   tree i, j, i_name = NULL_TREE;
     481                 :            : 
     482                 :     435729 :   for (i = outputs; i ; i = TREE_CHAIN (i))
     483                 :            :     {
     484                 :     263740 :       i_name = TREE_PURPOSE (TREE_PURPOSE (i));
     485                 :     263740 :       if (! i_name)
     486                 :     263341 :         continue;
     487                 :            : 
     488                 :       2314 :       for (j = TREE_CHAIN (i); j ; j = TREE_CHAIN (j))
     489                 :       1915 :         if (simple_cst_equal (i_name, TREE_PURPOSE (TREE_PURPOSE (j))))
     490                 :          0 :           goto failure;
     491                 :            :     }
     492                 :            : 
     493                 :     453829 :   for (i = inputs; i ; i = TREE_CHAIN (i))
     494                 :            :     {
     495                 :     281846 :       i_name = TREE_PURPOSE (TREE_PURPOSE (i));
     496                 :     281846 :       if (! i_name)
     497                 :     281757 :         continue;
     498                 :            : 
     499                 :        116 :       for (j = TREE_CHAIN (i); j ; j = TREE_CHAIN (j))
     500                 :         27 :         if (simple_cst_equal (i_name, TREE_PURPOSE (TREE_PURPOSE (j))))
     501                 :          0 :           goto failure;
     502                 :        147 :       for (j = outputs; j ; j = TREE_CHAIN (j))
     503                 :         64 :         if (simple_cst_equal (i_name, TREE_PURPOSE (TREE_PURPOSE (j))))
     504                 :          6 :           goto failure;
     505                 :            :     }
     506                 :            : 
     507                 :     172324 :   for (i = labels; i ; i = TREE_CHAIN (i))
     508                 :            :     {
     509                 :        351 :       i_name = TREE_PURPOSE (i);
     510                 :        351 :       if (! i_name)
     511                 :          0 :         continue;
     512                 :            : 
     513                 :       1297 :       for (j = TREE_CHAIN (i); j ; j = TREE_CHAIN (j))
     514                 :        951 :         if (simple_cst_equal (i_name, TREE_PURPOSE (j)))
     515                 :          5 :           goto failure;
     516                 :        527 :       for (j = inputs; j ; j = TREE_CHAIN (j))
     517                 :        186 :         if (simple_cst_equal (i_name, TREE_PURPOSE (TREE_PURPOSE (j))))
     518                 :          5 :           goto failure;
     519                 :            :     }
     520                 :            : 
     521                 :            :   return true;
     522                 :            : 
     523                 :         16 :  failure:
     524                 :         16 :   error ("duplicate %<asm%> operand name %qs", TREE_STRING_POINTER (i_name));
     525                 :         16 :   return false;
     526                 :            : }
     527                 :            : 
     528                 :            : /* Resolve the names of the operands in *POUTPUTS and *PINPUTS to numbers,
     529                 :            :    and replace the name expansions in STRING and in the constraints to
     530                 :            :    those numbers.  This is generally done in the front end while creating
     531                 :            :    the ASM_EXPR generic tree that eventually becomes the GIMPLE_ASM.  */
     532                 :            : 
     533                 :            : tree
     534                 :     171989 : resolve_asm_operand_names (tree string, tree outputs, tree inputs, tree labels)
     535                 :            : {
     536                 :     171989 :   char *buffer;
     537                 :     171989 :   char *p;
     538                 :     171989 :   const char *c;
     539                 :     171989 :   tree t;
     540                 :            : 
     541                 :     171989 :   check_unique_operand_names (outputs, inputs, labels);
     542                 :            : 
     543                 :            :   /* Substitute [<name>] in input constraint strings.  There should be no
     544                 :            :      named operands in output constraints.  */
     545                 :     453835 :   for (t = inputs; t ; t = TREE_CHAIN (t))
     546                 :            :     {
     547                 :     281846 :       c = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t)));
     548                 :     281846 :       if (strchr (c, '[') != NULL)
     549                 :            :         {
     550                 :        181 :           p = buffer = xstrdup (c);
     551                 :        362 :           while ((p = strchr (p, '[')) != NULL)
     552                 :        181 :             p = resolve_operand_name_1 (p, outputs, inputs, NULL);
     553                 :        181 :           TREE_VALUE (TREE_PURPOSE (t))
     554                 :        362 :             = build_string (strlen (buffer), buffer);
     555                 :        181 :           free (buffer);
     556                 :            :         }
     557                 :            :     }
     558                 :            : 
     559                 :            :   /* Now check for any needed substitutions in the template.  */
     560                 :     171989 :   c = TREE_STRING_POINTER (string);
     561                 :     213503 :   while ((c = strchr (c, '%')) != NULL)
     562                 :            :     {
     563                 :      41609 :       if (c[1] == '[')
     564                 :            :         break;
     565                 :      41559 :       else if (ISALPHA (c[1]) && c[2] == '[')
     566                 :            :         break;
     567                 :            :       else
     568                 :            :         {
     569                 :      41514 :           c += 1 + (c[1] == '%');
     570                 :      41514 :           continue;
     571                 :            :         }
     572                 :            :     }
     573                 :            : 
     574                 :     171989 :   if (c)
     575                 :            :     {
     576                 :            :       /* OK, we need to make a copy so we can perform the substitutions.
     577                 :            :          Assume that we will not need extra space--we get to remove '['
     578                 :            :          and ']', which means we cannot have a problem until we have more
     579                 :            :          than 999 operands.  */
     580                 :         95 :       buffer = xstrdup (TREE_STRING_POINTER (string));
     581                 :         95 :       p = buffer + (c - TREE_STRING_POINTER (string));
     582                 :            : 
     583                 :        254 :       while ((p = strchr (p, '%')) != NULL)
     584                 :            :         {
     585                 :        159 :           if (p[1] == '[')
     586                 :        107 :             p += 1;
     587                 :         52 :           else if (ISALPHA (p[1]) && p[2] == '[')
     588                 :         52 :             p += 2;
     589                 :            :           else
     590                 :            :             {
     591                 :          0 :               p += 1 + (p[1] == '%');
     592                 :          0 :               continue;
     593                 :            :             }
     594                 :            : 
     595                 :        159 :           p = resolve_operand_name_1 (p, outputs, inputs, labels);
     596                 :            :         }
     597                 :            : 
     598                 :         95 :       string = build_string (strlen (buffer), buffer);
     599                 :         95 :       free (buffer);
     600                 :            :     }
     601                 :            : 
     602                 :     171989 :   return string;
     603                 :            : }
     604                 :            : 
     605                 :            : /* A subroutine of resolve_operand_names.  P points to the '[' for a
     606                 :            :    potential named operand of the form [<name>].  In place, replace
     607                 :            :    the name and brackets with a number.  Return a pointer to the
     608                 :            :    balance of the string after substitution.  */
     609                 :            : 
     610                 :            : static char *
     611                 :        340 : resolve_operand_name_1 (char *p, tree outputs, tree inputs, tree labels)
     612                 :            : {
     613                 :        340 :   char *q;
     614                 :        340 :   int op;
     615                 :        340 :   tree t;
     616                 :            : 
     617                 :            :   /* Collect the operand name.  */
     618                 :        340 :   q = strchr (++p, ']');
     619                 :        340 :   if (!q)
     620                 :            :     {
     621                 :          0 :       error ("missing close brace for named operand");
     622                 :          0 :       return strchr (p, '\0');
     623                 :            :     }
     624                 :        340 :   *q = '\0';
     625                 :            : 
     626                 :            :   /* Resolve the name to a number.  */
     627                 :       1352 :   for (op = 0, t = outputs; t ; t = TREE_CHAIN (t), op++)
     628                 :            :     {
     629                 :       1235 :       tree name = TREE_PURPOSE (TREE_PURPOSE (t));
     630                 :       2470 :       if (name && strcmp (TREE_STRING_POINTER (name), p) == 0)
     631                 :        223 :         goto found;
     632                 :            :     }
     633                 :        165 :   for (t = inputs; t ; t = TREE_CHAIN (t), op++)
     634                 :            :     {
     635                 :        111 :       tree name = TREE_PURPOSE (TREE_PURPOSE (t));
     636                 :        195 :       if (name && strcmp (TREE_STRING_POINTER (name), p) == 0)
     637                 :         63 :         goto found;
     638                 :            :     }
     639                 :         63 :   for (t = labels; t ; t = TREE_CHAIN (t), op++)
     640                 :            :     {
     641                 :         60 :       tree name = TREE_PURPOSE (t);
     642                 :        120 :       if (name && strcmp (TREE_STRING_POINTER (name), p) == 0)
     643                 :         51 :         goto found;
     644                 :            :     }
     645                 :            : 
     646                 :          3 :   error ("undefined named operand %qs", identifier_to_locale (p));
     647                 :          3 :   op = 0;
     648                 :            : 
     649                 :        340 :  found:
     650                 :            :   /* Replace the name with the number.  Unfortunately, not all libraries
     651                 :            :      get the return value of sprintf correct, so search for the end of the
     652                 :            :      generated string by hand.  */
     653                 :        340 :   sprintf (--p, "%d", op);
     654                 :        340 :   p = strchr (p, '\0');
     655                 :            : 
     656                 :            :   /* Verify the no extra buffer space assumption.  */
     657                 :        340 :   gcc_assert (p <= q);
     658                 :            : 
     659                 :            :   /* Shift the rest of the buffer down to fill the gap.  */
     660                 :        340 :   memmove (p, q + 1, strlen (q + 1) + 1);
     661                 :            : 
     662                 :        340 :   return p;
     663                 :            : }
     664                 :            : 
     665                 :            : 
     666                 :            : /* Generate RTL to return directly from the current function.
     667                 :            :    (That is, we bypass any return value.)  */
     668                 :            : 
     669                 :            : void
     670                 :        106 : expand_naked_return (void)
     671                 :            : {
     672                 :        106 :   rtx_code_label *end_label;
     673                 :            : 
     674                 :        106 :   clear_pending_stack_adjust ();
     675                 :        106 :   do_pending_stack_adjust ();
     676                 :            : 
     677                 :        106 :   end_label = naked_return_label;
     678                 :        106 :   if (end_label == 0)
     679                 :        106 :     end_label = naked_return_label = gen_label_rtx ();
     680                 :            : 
     681                 :        106 :   emit_jump (end_label);
     682                 :        106 : }
     683                 :            : 
     684                 :            : /* Generate code to jump to LABEL if OP0 and OP1 are equal in mode MODE. PROB
     685                 :            :    is the probability of jumping to LABEL.  */
     686                 :            : static void
     687                 :          0 : do_jump_if_equal (machine_mode mode, rtx op0, rtx op1, rtx_code_label *label,
     688                 :            :                   int unsignedp, profile_probability prob)
     689                 :            : {
     690                 :          0 :   do_compare_rtx_and_jump (op0, op1, EQ, unsignedp, mode,
     691                 :            :                            NULL_RTX, NULL, label, prob);
     692                 :          0 : }
     693                 :            : 
     694                 :            : /* Return the sum of probabilities of outgoing edges of basic block BB.  */
     695                 :            : 
     696                 :            : static profile_probability
     697                 :       9878 : get_outgoing_edge_probs (basic_block bb)
     698                 :            : {
     699                 :       9878 :   edge e;
     700                 :       9878 :   edge_iterator ei;
     701                 :       9878 :   profile_probability prob_sum = profile_probability::never ();
     702                 :       9878 :   if (!bb)
     703                 :          0 :     return profile_probability::never ();
     704                 :      83703 :   FOR_EACH_EDGE (e, ei, bb->succs)
     705                 :      73825 :     prob_sum += e->probability;
     706                 :       9878 :   return prob_sum;
     707                 :            : }
     708                 :            : 
     709                 :            : /* Computes the conditional probability of jumping to a target if the branch
     710                 :            :    instruction is executed.
     711                 :            :    TARGET_PROB is the estimated probability of jumping to a target relative
     712                 :            :    to some basic block BB.
     713                 :            :    BASE_PROB is the probability of reaching the branch instruction relative
     714                 :            :    to the same basic block BB.  */
     715                 :            : 
     716                 :            : static inline profile_probability
     717                 :      18413 : conditional_probability (profile_probability target_prob,
     718                 :            :                          profile_probability base_prob)
     719                 :            : {
     720                 :       8535 :   return target_prob / base_prob;
     721                 :            : }
     722                 :            : 
     723                 :            : /* Generate a dispatch tabler, switching on INDEX_EXPR and jumping to
     724                 :            :    one of the labels in CASE_LIST or to the DEFAULT_LABEL.
     725                 :            :    MINVAL, MAXVAL, and RANGE are the extrema and range of the case
     726                 :            :    labels in CASE_LIST. STMT_BB is the basic block containing the statement.
     727                 :            : 
     728                 :            :    First, a jump insn is emitted.  First we try "casesi".  If that
     729                 :            :    fails, try "tablejump".   A target *must* have one of them (or both).
     730                 :            : 
     731                 :            :    Then, a table with the target labels is emitted.
     732                 :            : 
     733                 :            :    The process is unaware of the CFG.  The caller has to fix up
     734                 :            :    the CFG itself.  This is done in cfgexpand.c.  */     
     735                 :            : 
     736                 :            : static void
     737                 :       9878 : emit_case_dispatch_table (tree index_expr, tree index_type,
     738                 :            :                           auto_vec<simple_case_node> &case_list,
     739                 :            :                           rtx default_label,
     740                 :            :                           edge default_edge,  tree minval, tree maxval,
     741                 :            :                           tree range, basic_block stmt_bb)
     742                 :            : {
     743                 :       9878 :   int i, ncases;
     744                 :       9878 :   rtx *labelvec;
     745                 :       9878 :   rtx_insn *fallback_label = label_rtx (case_list[0].m_code_label);
     746                 :       9878 :   rtx_code_label *table_label = gen_label_rtx ();
     747                 :       9878 :   bool has_gaps = false;
     748                 :       9878 :   profile_probability default_prob = default_edge ? default_edge->probability
     749                 :       9878 :                                                   : profile_probability::never ();
     750                 :       9878 :   profile_probability base = get_outgoing_edge_probs (stmt_bb);
     751                 :       9878 :   bool try_with_tablejump = false;
     752                 :            : 
     753                 :       9878 :   profile_probability new_default_prob = conditional_probability (default_prob,
     754                 :       9878 :                                                                   base);
     755                 :            : 
     756                 :       9878 :   if (! try_casesi (index_type, index_expr, minval, range,
     757                 :            :                     table_label, default_label, fallback_label,
     758                 :            :                     new_default_prob))
     759                 :            :     {
     760                 :            :       /* Index jumptables from zero for suitable values of minval to avoid
     761                 :            :          a subtraction.  For the rationale see:
     762                 :            :          "http://gcc.gnu.org/ml/gcc-patches/2001-10/msg01234.html".  */
     763                 :       9878 :       if (optimize_insn_for_speed_p ()
     764                 :       9742 :           && compare_tree_int (minval, 0) > 0
     765                 :      18129 :           && compare_tree_int (minval, 3) < 0)
     766                 :            :         {
     767                 :       1059 :           minval = build_int_cst (index_type, 0);
     768                 :       1059 :           range = maxval;
     769                 :       1059 :           has_gaps = true;
     770                 :            :         }
     771                 :            :       try_with_tablejump = true;
     772                 :            :     }
     773                 :            : 
     774                 :            :   /* Get table of labels to jump to, in order of case index.  */
     775                 :            : 
     776                 :       9878 :   ncases = tree_to_shwi (range) + 1;
     777                 :       9878 :   labelvec = XALLOCAVEC (rtx, ncases);
     778                 :       9878 :   memset (labelvec, 0, ncases * sizeof (rtx));
     779                 :            : 
     780                 :     193822 :   for (unsigned j = 0; j < case_list.length (); j++)
     781                 :            :     {
     782                 :      87033 :       simple_case_node *n = &case_list[j];
     783                 :            :       /* Compute the low and high bounds relative to the minimum
     784                 :            :          value since that should fit in a HOST_WIDE_INT while the
     785                 :            :          actual values may not.  */
     786                 :      87033 :       HOST_WIDE_INT i_low
     787                 :      87033 :         = tree_to_uhwi (fold_build2 (MINUS_EXPR, index_type,
     788                 :      87033 :                                      n->m_low, minval));
     789                 :      87033 :       HOST_WIDE_INT i_high
     790                 :      87033 :         = tree_to_uhwi (fold_build2 (MINUS_EXPR, index_type,
     791                 :      87033 :                                      n->m_high, minval));
     792                 :      87033 :       HOST_WIDE_INT i;
     793                 :            : 
     794                 :     193997 :       for (i = i_low; i <= i_high; i ++)
     795                 :     106964 :         labelvec[i]
     796                 :     120157 :           = gen_rtx_LABEL_REF (Pmode, label_rtx (n->m_code_label));
     797                 :            :     }
     798                 :            : 
     799                 :            :   /* The dispatch table may contain gaps, including at the beginning of
     800                 :            :      the table if we tried to avoid the minval subtraction.  We fill the
     801                 :            :      dispatch table slots associated with the gaps with the default case label.
     802                 :            :      However, in the event the default case is unreachable, we then use
     803                 :            :      any label from one of the case statements.  */
     804                 :       9878 :   rtx gap_label = (default_label) ? default_label : fallback_label;
     805                 :            : 
     806                 :     226883 :   for (i = 0; i < ncases; i++)
     807                 :     217005 :     if (labelvec[i] == 0)
     808                 :            :       {
     809                 :     110041 :         has_gaps = true;
     810                 :     126964 :         labelvec[i] = gen_rtx_LABEL_REF (Pmode, gap_label);
     811                 :            :       }
     812                 :            : 
     813                 :       9878 :   if (has_gaps && default_label)
     814                 :            :     {
     815                 :            :       /* There is at least one entry in the jump table that jumps
     816                 :            :          to default label. The default label can either be reached
     817                 :            :          through the indirect jump or the direct conditional jump
     818                 :            :          before that. Split the probability of reaching the
     819                 :            :          default label among these two jumps.  */
     820                 :       8535 :       new_default_prob
     821                 :       8535 :         = conditional_probability (default_prob.apply_scale (1, 2), base);
     822                 :       8535 :       default_prob = default_prob.apply_scale (1, 2);
     823                 :       8535 :       base -= default_prob;
     824                 :            :     }
     825                 :            :   else
     826                 :            :     {
     827                 :       1343 :       base -= default_prob;
     828                 :       1343 :       default_prob = profile_probability::never ();
     829                 :            :     }
     830                 :            : 
     831                 :       9878 :   if (default_edge)
     832                 :       9416 :     default_edge->probability = default_prob;
     833                 :            : 
     834                 :            :   /* We have altered the probability of the default edge. So the probabilities
     835                 :            :      of all other edges need to be adjusted so that it sums up to
     836                 :            :      REG_BR_PROB_BASE.  */
     837                 :       9878 :   if (base > profile_probability::never ())
     838                 :            :     {
     839                 :       9878 :       edge e;
     840                 :       9878 :       edge_iterator ei;
     841                 :      83703 :       FOR_EACH_EDGE (e, ei, stmt_bb->succs)
     842                 :      73825 :         e->probability /= base;
     843                 :            :     }
     844                 :            : 
     845                 :       9878 :   if (try_with_tablejump)
     846                 :            :     {
     847                 :       9878 :       bool ok = try_tablejump (index_type, index_expr, minval, range,
     848                 :       9878 :                                table_label, default_label, new_default_prob);
     849                 :       9878 :       gcc_assert (ok);
     850                 :            :     }
     851                 :            :   /* Output the table.  */
     852                 :       9878 :   emit_label (table_label);
     853                 :            : 
     854                 :       9878 :   if (CASE_VECTOR_PC_RELATIVE
     855                 :       9878 :           || (flag_pic && targetm.asm_out.generate_pic_addr_diff_vec ()))
     856                 :       1572 :     emit_jump_table_data (gen_rtx_ADDR_DIFF_VEC (CASE_VECTOR_MODE,
     857                 :            :                                                  gen_rtx_LABEL_REF (Pmode,
     858                 :            :                                                                     table_label),
     859                 :            :                                                  gen_rtvec_v (ncases, labelvec),
     860                 :            :                                                  const0_rtx, const0_rtx));
     861                 :            :   else
     862                 :      17017 :     emit_jump_table_data (gen_rtx_ADDR_VEC (CASE_VECTOR_MODE,
     863                 :            :                                             gen_rtvec_v (ncases, labelvec)));
     864                 :            : 
     865                 :            :   /* Record no drop-through after the table.  */
     866                 :       9878 :   emit_barrier ();
     867                 :       9878 : }
     868                 :            : 
     869                 :            : /* Terminate a case Ada or switch (C) statement
     870                 :            :    in which ORIG_INDEX is the expression to be tested.
     871                 :            :    If ORIG_TYPE is not NULL, it is the original ORIG_INDEX
     872                 :            :    type as given in the source before any compiler conversions.
     873                 :            :    Generate the code to test it and jump to the right place.  */
     874                 :            : 
     875                 :            : void
     876                 :       9878 : expand_case (gswitch *stmt)
     877                 :            : {
     878                 :       9878 :   tree minval = NULL_TREE, maxval = NULL_TREE, range = NULL_TREE;
     879                 :       9878 :   rtx_code_label *default_label;
     880                 :       9878 :   unsigned int count;
     881                 :       9878 :   int i;
     882                 :       9878 :   int ncases = gimple_switch_num_labels (stmt);
     883                 :       9878 :   tree index_expr = gimple_switch_index (stmt);
     884                 :       9878 :   tree index_type = TREE_TYPE (index_expr);
     885                 :       9878 :   tree elt;
     886                 :       9878 :   basic_block bb = gimple_bb (stmt);
     887                 :       9878 :   gimple *def_stmt;
     888                 :            : 
     889                 :      19756 :   auto_vec<simple_case_node> case_list;
     890                 :            : 
     891                 :            :   /* An ERROR_MARK occurs for various reasons including invalid data type.
     892                 :            :      ??? Can this still happen, with GIMPLE and all?  */
     893                 :       9878 :   if (index_type == error_mark_node)
     894                 :          0 :     return;
     895                 :            : 
     896                 :            :   /* cleanup_tree_cfg removes all SWITCH_EXPR with their index
     897                 :            :      expressions being INTEGER_CST.  */
     898                 :       9878 :   gcc_assert (TREE_CODE (index_expr) != INTEGER_CST);
     899                 :            : 
     900                 :            :   /* Optimization of switch statements with only one label has already
     901                 :            :      occurred, so we should never see them at this point.  */
     902                 :       9878 :   gcc_assert (ncases > 1);
     903                 :            : 
     904                 :       9878 :   do_pending_stack_adjust ();
     905                 :            : 
     906                 :            :   /* Find the default case target label.  */
     907                 :       9878 :   tree default_lab = CASE_LABEL (gimple_switch_default_label (stmt));
     908                 :       9878 :   default_label = jump_target_rtx (default_lab);
     909                 :       9878 :   basic_block default_bb = label_to_block (cfun, default_lab);
     910                 :       9878 :   edge default_edge = find_edge (bb, default_bb);
     911                 :            : 
     912                 :            :   /* Get upper and lower bounds of case values.  */
     913                 :       9878 :   elt = gimple_switch_label (stmt, 1);
     914                 :       9878 :   minval = fold_convert (index_type, CASE_LOW (elt));
     915                 :       9878 :   elt = gimple_switch_label (stmt, ncases - 1);
     916                 :       9878 :   if (CASE_HIGH (elt))
     917                 :        192 :     maxval = fold_convert (index_type, CASE_HIGH (elt));
     918                 :            :   else
     919                 :       9686 :     maxval = fold_convert (index_type, CASE_LOW (elt));
     920                 :            : 
     921                 :            :   /* Try to narrow the index type if it's larger than a word.
     922                 :            :      That is mainly for -O0 where an equivalent optimization
     923                 :            :      done by forward propagation is not run and is aimed at
     924                 :            :      avoiding a call to a comparison routine of libgcc.  */
     925                 :       9878 :   if (TYPE_PRECISION (index_type) > BITS_PER_WORD
     926                 :          6 :       && TREE_CODE (index_expr) == SSA_NAME
     927                 :          6 :       && (def_stmt = SSA_NAME_DEF_STMT (index_expr))
     928                 :          6 :       && is_gimple_assign (def_stmt)
     929                 :       9881 :       && gimple_assign_rhs_code (def_stmt) == NOP_EXPR)
     930                 :            :     {
     931                 :          0 :       tree inner_index_expr = gimple_assign_rhs1 (def_stmt);
     932                 :          0 :       tree inner_index_type = TREE_TYPE (inner_index_expr);
     933                 :            : 
     934                 :          0 :       if (INTEGRAL_TYPE_P (inner_index_type)
     935                 :          0 :           && TYPE_PRECISION (inner_index_type) <= BITS_PER_WORD
     936                 :          0 :           && int_fits_type_p (minval, inner_index_type)
     937                 :          0 :           && int_fits_type_p (maxval, inner_index_type))
     938                 :            :         {
     939                 :          0 :           index_expr = inner_index_expr;
     940                 :          0 :           index_type = inner_index_type;
     941                 :          0 :           minval = fold_convert (index_type, minval);
     942                 :          0 :           maxval = fold_convert (index_type, maxval);
     943                 :            :         }
     944                 :            :     }
     945                 :            : 
     946                 :            :   /* Compute span of values.  */
     947                 :       9878 :   range = fold_build2 (MINUS_EXPR, index_type, maxval, minval);
     948                 :            : 
     949                 :            :   /* Listify the labels queue and gather some numbers to decide
     950                 :            :      how to expand this switch().  */
     951                 :       9878 :   count = 0;
     952                 :            : 
     953                 :      96911 :   for (i = ncases - 1; i >= 1; --i)
     954                 :            :     {
     955                 :      87033 :       elt = gimple_switch_label (stmt, i);
     956                 :      87033 :       tree low = CASE_LOW (elt);
     957                 :      87033 :       gcc_assert (low);
     958                 :      87033 :       tree high = CASE_HIGH (elt);
     959                 :      87033 :       gcc_assert (! high || tree_int_cst_lt (low, high));
     960                 :      87033 :       tree lab = CASE_LABEL (elt);
     961                 :            : 
     962                 :            :       /* Count the elements.
     963                 :            :          A range counts double, since it requires two compares.  */
     964                 :      87033 :       count++;
     965                 :      87033 :       if (high)
     966                 :      14540 :         count++;
     967                 :            : 
     968                 :            :       /* The bounds on the case range, LOW and HIGH, have to be converted
     969                 :            :          to case's index type TYPE.  Note that the original type of the
     970                 :            :          case index in the source code is usually "lost" during
     971                 :            :          gimplification due to type promotion, but the case labels retain the
     972                 :            :          original type.  Make sure to drop overflow flags.  */
     973                 :      87033 :       low = fold_convert (index_type, low);
     974                 :      87033 :       if (TREE_OVERFLOW (low))
     975                 :          0 :         low = wide_int_to_tree (index_type, wi::to_wide (low));
     976                 :            : 
     977                 :            :       /* The canonical from of a case label in GIMPLE is that a simple case
     978                 :            :          has an empty CASE_HIGH.  For the casesi and tablejump expanders,
     979                 :            :          the back ends want simple cases to have high == low.  */
     980                 :      87033 :       if (! high)
     981                 :      72493 :         high = low;
     982                 :      87033 :       high = fold_convert (index_type, high);
     983                 :      87033 :       if (TREE_OVERFLOW (high))
     984                 :          0 :         high = wide_int_to_tree (index_type, wi::to_wide (high));
     985                 :            : 
     986                 :      87033 :       case_list.safe_push (simple_case_node (low, high, lab));
     987                 :            :     }
     988                 :            : 
     989                 :            :   /* cleanup_tree_cfg removes all SWITCH_EXPR with a single
     990                 :            :      destination, such as one with a default case only.
     991                 :            :      It also removes cases that are out of range for the switch
     992                 :            :      type, so we should never get a zero here.  */
     993                 :       9878 :   gcc_assert (count > 0);
     994                 :            : 
     995                 :       9878 :   rtx_insn *before_case = get_last_insn ();
     996                 :            : 
     997                 :            :   /* If the default case is unreachable, then set default_label to NULL
     998                 :            :      so that we omit the range check when generating the dispatch table.
     999                 :            :      We also remove the edge to the unreachable default case.  The block
    1000                 :            :      itself will be automatically removed later.  */
    1001                 :       9878 :   if (EDGE_COUNT (default_edge->dest->succs) == 0
    1002                 :      10900 :       && gimple_seq_unreachable_p (bb_seq (default_edge->dest)))
    1003                 :            :     {
    1004                 :        462 :       default_label = NULL;
    1005                 :        462 :       remove_edge (default_edge);
    1006                 :        462 :       default_edge = NULL;
    1007                 :            :     }
    1008                 :            : 
    1009                 :       9878 :   emit_case_dispatch_table (index_expr, index_type,
    1010                 :            :                             case_list, default_label, default_edge,
    1011                 :            :                             minval, maxval, range, bb);
    1012                 :            : 
    1013                 :       9878 :   reorder_insns (NEXT_INSN (before_case), get_last_insn (), before_case);
    1014                 :            : 
    1015                 :       9878 :   free_temp_slots ();
    1016                 :            : }
    1017                 :            : 
    1018                 :            : /* Expand the dispatch to a short decrement chain if there are few cases
    1019                 :            :    to dispatch to.  Likewise if neither casesi nor tablejump is available,
    1020                 :            :    or if flag_jump_tables is set.  Otherwise, expand as a casesi or a
    1021                 :            :    tablejump.  The index mode is always the mode of integer_type_node.
    1022                 :            :    Trap if no case matches the index.
    1023                 :            : 
    1024                 :            :    DISPATCH_INDEX is the index expression to switch on.  It should be a
    1025                 :            :    memory or register operand.
    1026                 :            :    
    1027                 :            :    DISPATCH_TABLE is a set of case labels.  The set should be sorted in
    1028                 :            :    ascending order, be contiguous, starting with value 0, and contain only
    1029                 :            :    single-valued case labels.  */
    1030                 :            : 
    1031                 :            : void
    1032                 :          0 : expand_sjlj_dispatch_table (rtx dispatch_index,
    1033                 :            :                             vec<tree> dispatch_table)
    1034                 :            : {
    1035                 :          0 :   tree index_type = integer_type_node;
    1036                 :          0 :   machine_mode index_mode = TYPE_MODE (index_type);
    1037                 :            : 
    1038                 :          0 :   int ncases = dispatch_table.length ();
    1039                 :            : 
    1040                 :          0 :   do_pending_stack_adjust ();
    1041                 :          0 :   rtx_insn *before_case = get_last_insn ();
    1042                 :            : 
    1043                 :            :   /* Expand as a decrement-chain if there are 5 or fewer dispatch
    1044                 :            :      labels.  This covers more than 98% of the cases in libjava,
    1045                 :            :      and seems to be a reasonable compromise between the "old way"
    1046                 :            :      of expanding as a decision tree or dispatch table vs. the "new
    1047                 :            :      way" with decrement chain or dispatch table.  */
    1048                 :          0 :   if (dispatch_table.length () <= 5
    1049                 :          0 :       || (!targetm.have_casesi () && !targetm.have_tablejump ())
    1050                 :          0 :       || !flag_jump_tables)
    1051                 :            :     {
    1052                 :            :       /* Expand the dispatch as a decrement chain:
    1053                 :            : 
    1054                 :            :          "switch(index) {case 0: do_0; case 1: do_1; ...; case N: do_N;}"
    1055                 :            : 
    1056                 :            :          ==>
    1057                 :            : 
    1058                 :            :          if (index == 0) do_0; else index--;
    1059                 :            :          if (index == 0) do_1; else index--;
    1060                 :            :          ...
    1061                 :            :          if (index == 0) do_N; else index--;
    1062                 :            : 
    1063                 :            :          This is more efficient than a dispatch table on most machines.
    1064                 :            :          The last "index--" is redundant but the code is trivially dead
    1065                 :            :          and will be cleaned up by later passes.  */
    1066                 :          0 :       rtx index = copy_to_mode_reg (index_mode, dispatch_index);
    1067                 :          0 :       rtx zero = CONST0_RTX (index_mode);
    1068                 :          0 :       for (int i = 0; i < ncases; i++)
    1069                 :            :         {
    1070                 :          0 :           tree elt = dispatch_table[i];
    1071                 :          0 :           rtx_code_label *lab = jump_target_rtx (CASE_LABEL (elt));
    1072                 :          0 :           do_jump_if_equal (index_mode, index, zero, lab, 0,
    1073                 :            :                             profile_probability::uninitialized ());
    1074                 :          0 :           force_expand_binop (index_mode, sub_optab,
    1075                 :            :                               index, CONST1_RTX (index_mode),
    1076                 :            :                               index, 0, OPTAB_DIRECT);
    1077                 :            :         }
    1078                 :            :     }
    1079                 :            :   else
    1080                 :            :     {
    1081                 :            :       /* Similar to expand_case, but much simpler.  */
    1082                 :          0 :       auto_vec<simple_case_node> case_list;
    1083                 :          0 :       tree index_expr = make_tree (index_type, dispatch_index);
    1084                 :          0 :       tree minval = build_int_cst (index_type, 0);
    1085                 :          0 :       tree maxval = CASE_LOW (dispatch_table.last ());
    1086                 :          0 :       tree range = maxval;
    1087                 :          0 :       rtx_code_label *default_label = gen_label_rtx ();
    1088                 :            : 
    1089                 :          0 :       for (int i = ncases - 1; i >= 0; --i)
    1090                 :            :         {
    1091                 :          0 :           tree elt = dispatch_table[i];
    1092                 :          0 :           tree high = CASE_HIGH (elt);
    1093                 :          0 :           if (high == NULL_TREE)
    1094                 :          0 :             high = CASE_LOW (elt);
    1095                 :          0 :           case_list.safe_push (simple_case_node (CASE_LOW (elt), high,
    1096                 :          0 :                                                  CASE_LABEL (elt)));
    1097                 :            :         }
    1098                 :            : 
    1099                 :          0 :       emit_case_dispatch_table (index_expr, index_type,
    1100                 :            :                                 case_list, default_label, NULL,
    1101                 :            :                                 minval, maxval, range,
    1102                 :          0 :                                 BLOCK_FOR_INSN (before_case));
    1103                 :          0 :       emit_label (default_label);
    1104                 :            :     }
    1105                 :            : 
    1106                 :            :   /* Dispatching something not handled?  Trap!  */
    1107                 :          0 :   expand_builtin_trap ();
    1108                 :            : 
    1109                 :          0 :   reorder_insns (NEXT_INSN (before_case), get_last_insn (), before_case);
    1110                 :            : 
    1111                 :          0 :   free_temp_slots ();
    1112                 :          0 : }
    1113                 :            : 
    1114                 :            : 

Generated by: LCOV version 1.0

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 --enable-host-shared. GCC test suite is run with the built compiler.